From 52771b92e2ea28299a7be4880faa096c24031bfb Mon Sep 17 00:00:00 2001 From: tisilent Date: Thu, 6 Apr 2023 23:33:52 +0800 Subject: [PATCH 0001/1180] Fix #178135 --- .../browser/find/simpleFindWidget.css | 11 ++++ .../browser/find/simpleFindWidget.ts | 52 ++++++++++++++++++- .../find/browser/terminalFindWidget.ts | 6 ++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.css b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.css index e15ab55dacb1b..5d6ea3106c3d1 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.css +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.css @@ -99,3 +99,14 @@ div.simple-find-part-wrapper div.button:hover:not(.disabled) { outline: 1px dashed var(--vscode-toolbar-hoverOutline); outline-offset: -1px; } + +.monaco-workbench .simple-find-part .monaco-sash { + left: 0 !important; + border-left: 1px solid; + border-bottom-left-radius: 4px; +} + +.monaco-workbench .simple-find-part .monaco-sash.vertical:before{ + width: 2px; + left: calc(50% - (var(--vscode-sash-hover-size) / 4)); +} diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index a59a6decbd5b3..3bdb003f59fdd 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -17,12 +17,15 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { ContextScopedFindInput } from 'vs/platform/history/browser/contextScopedHistoryWidget'; import { widgetClose } from 'vs/platform/theme/common/iconRegistry'; +import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import * as strings from 'vs/base/common/strings'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { showHistoryKeybindingHint } from 'vs/platform/history/browser/historyWidgetKeybindingHint'; import { alert as alertFn } from 'vs/base/browser/ui/aria/aria'; import { defaultInputBoxStyles, defaultToggleStyles } from 'vs/platform/theme/browser/defaultStyles'; +import { ISashEvent, IVerticalSashLayoutProvider, Orientation, Sash } from 'vs/base/browser/ui/sash/sash'; +import { registerColor } from 'vs/platform/theme/common/colorRegistry'; const NLS_FIND_INPUT_LABEL = nls.localize('label.find', "Find"); const NLS_FIND_INPUT_PLACEHOLDER = nls.localize('placeholder.find', "Find (\u21C5 for history)"); @@ -38,12 +41,14 @@ interface IFindOptions { appendRegexLabel?: string; appendWholeWordsLabel?: string; type?: 'Terminal' | 'Webview'; + initialWidth?: number; + disableSash?: boolean; } const SIMPLE_FIND_WIDGET_INITIAL_WIDTH = 310; const MATCHES_COUNT_WIDTH = 68; -export abstract class SimpleFindWidget extends Widget { +export abstract class SimpleFindWidget extends Widget implements IVerticalSashLayoutProvider { private readonly _findInput: FindInput; private readonly _domNode: HTMLElement; private readonly _innerDomNode: HTMLElement; @@ -197,6 +202,42 @@ export abstract class SimpleFindWidget extends Widget { this._delayedUpdateHistory(); })); } + + if (options?.initialWidth) { + this._domNode.style.width = `${options.initialWidth}px`; + } + + if (options?.disableSash) { + const initialMinWidth = options?.initialWidth ?? SIMPLE_FIND_WIDGET_INITIAL_WIDTH; + let originalWidth = dom.getTotalWidth(this._domNode); + + // sash + const resizeSash = new Sash(this._innerDomNode, this, { orientation: Orientation.VERTICAL, size: 1 }); + this._register(resizeSash.onDidStart(() => { + originalWidth = parseFloat(dom.getComputedStyle(this._domNode).width); + })); + + this._register(resizeSash.onDidChange((e: ISashEvent) => { + const width = originalWidth + e.startX - e.currentX; + if (width < initialMinWidth) { + return; + } + this._domNode.style.width = `${width}px`; + })); + + this._register(resizeSash.onDidReset(e => { + const currentWidth = parseFloat(dom.getComputedStyle(this._domNode).width); + if (currentWidth === initialMinWidth) { + this._domNode.style.width = '100%'; + } else { + this._domNode.style.width = `${initialMinWidth}px`; + } + })); + } + } + + public getVerticalSashLeft(_sash: Sash): number { + return 0; } public abstract find(previous: boolean): void; @@ -363,6 +404,8 @@ export abstract class SimpleFindWidget extends Widget { } } else if (count?.resultCount) { label = strings.format(NLS_MATCHES_LOCATION, count.resultIndex + 1, count?.resultCount); + } else { + label = NLS_NO_RESULTS; } alertFn(this._announceSearchResults(label, this.inputValue)); this._matchesCount.appendChild(document.createTextNode(label)); @@ -387,3 +430,10 @@ export abstract class SimpleFindWidget extends Widget { return nls.localize('ariaSearchNoResultWithLineNumNoCurrentMatch', "{0} found for '{1}'", label, searchString); } } + +export const simpleFindWidgetSashBorder = registerColor('simpleFindWidget.sashBorder', { dark: '#454545', light: '#C8C8C8', hcDark: '6FC3DF', hcLight: '0F4A85' }, nls.localize('simpleFindWidget.sashBorder', 'Border color of the sash border.')); + +registerThemingParticipant((theme, collector) => { + const resizeBorderBackground = theme.getColor(simpleFindWidgetSashBorder); + collector.addRule(`.monaco-workbench .simple-find-part .monaco-sash { background-color: ${resizeBorderBackground}; border-color: ${resizeBorderBackground} }`); +}); diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts index 8a7d706834cee..bcea9177225a8 100644 --- a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts @@ -14,6 +14,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Event } from 'vs/base/common/event'; import { ISearchOptions } from 'xterm-addon-search'; +const TERMINAL_FIND_WIDGET_INITIAL_WIDTH = 419; + export class TerminalFindWidget extends SimpleFindWidget { private _findInputFocused: IContextKey; private _findWidgetFocused: IContextKey; @@ -27,7 +29,7 @@ export class TerminalFindWidget extends SimpleFindWidget { @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService ) { - super({ showCommonFindToggles: true, checkImeCompletionState: true, showResultCount: true, type: 'Terminal' }, _contextViewService, _contextKeyService, keybindingService); + super({ showCommonFindToggles: true, checkImeCompletionState: true, showResultCount: true, type: 'Terminal', initialWidth: TERMINAL_FIND_WIDGET_INITIAL_WIDTH, disableSash: true }, _contextViewService, _contextKeyService, keybindingService); this._register(this.state.onFindReplaceStateChange(() => { this.show(); @@ -45,6 +47,8 @@ export class TerminalFindWidget extends SimpleFindWidget { this.find(true, true); } })); + + this.updateResultCount(); } find(previous: boolean, update?: boolean) { From 0676fe42b1daab8dd7e39fc56bfee798d45061d8 Mon Sep 17 00:00:00 2001 From: tisilent Date: Fri, 7 Apr 2023 14:36:22 +0800 Subject: [PATCH 0002/1180] Rename enableSash --- .../browser/find/simpleFindWidget.ts | 20 ++++++++++--------- .../find/browser/terminalFindWidget.ts | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index 3bdb003f59fdd..3181551d61df3 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -42,7 +42,7 @@ interface IFindOptions { appendWholeWordsLabel?: string; type?: 'Terminal' | 'Webview'; initialWidth?: number; - disableSash?: boolean; + enableSash?: boolean; } const SIMPLE_FIND_WIDGET_INITIAL_WIDTH = 310; @@ -203,13 +203,15 @@ export abstract class SimpleFindWidget extends Widget implements IVerticalSashLa })); } - if (options?.initialWidth) { - this._domNode.style.width = `${options.initialWidth}px`; + let initialMinWidth = options?.initialWidth; + if (initialMinWidth) { + initialMinWidth = initialMinWidth < SIMPLE_FIND_WIDGET_INITIAL_WIDTH ? SIMPLE_FIND_WIDGET_INITIAL_WIDTH : initialMinWidth; + this._domNode.style.width = `${initialMinWidth}px`; } - if (options?.disableSash) { - const initialMinWidth = options?.initialWidth ?? SIMPLE_FIND_WIDGET_INITIAL_WIDTH; - let originalWidth = dom.getTotalWidth(this._domNode); + if (options?.enableSash) { + const _initialMinWidth = initialMinWidth ?? SIMPLE_FIND_WIDGET_INITIAL_WIDTH; + let originalWidth = _initialMinWidth; // sash const resizeSash = new Sash(this._innerDomNode, this, { orientation: Orientation.VERTICAL, size: 1 }); @@ -219,7 +221,7 @@ export abstract class SimpleFindWidget extends Widget implements IVerticalSashLa this._register(resizeSash.onDidChange((e: ISashEvent) => { const width = originalWidth + e.startX - e.currentX; - if (width < initialMinWidth) { + if (width < _initialMinWidth) { return; } this._domNode.style.width = `${width}px`; @@ -227,10 +229,10 @@ export abstract class SimpleFindWidget extends Widget implements IVerticalSashLa this._register(resizeSash.onDidReset(e => { const currentWidth = parseFloat(dom.getComputedStyle(this._domNode).width); - if (currentWidth === initialMinWidth) { + if (currentWidth === _initialMinWidth) { this._domNode.style.width = '100%'; } else { - this._domNode.style.width = `${initialMinWidth}px`; + this._domNode.style.width = `${_initialMinWidth}px`; } })); } diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts index bcea9177225a8..bb781e3307051 100644 --- a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts @@ -29,7 +29,7 @@ export class TerminalFindWidget extends SimpleFindWidget { @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService ) { - super({ showCommonFindToggles: true, checkImeCompletionState: true, showResultCount: true, type: 'Terminal', initialWidth: TERMINAL_FIND_WIDGET_INITIAL_WIDTH, disableSash: true }, _contextViewService, _contextKeyService, keybindingService); + super({ showCommonFindToggles: true, checkImeCompletionState: true, showResultCount: true, type: 'Terminal', initialWidth: TERMINAL_FIND_WIDGET_INITIAL_WIDTH, enableSash: true }, _contextViewService, _contextKeyService, keybindingService); this._register(this.state.onFindReplaceStateChange(() => { this.show(); From 01586a4d44779ff7f0cbed7976ab6654bbbd08c3 Mon Sep 17 00:00:00 2001 From: tisilent Date: Fri, 7 Apr 2023 17:59:06 +0800 Subject: [PATCH 0003/1180] fix color --- .../contrib/codeEditor/browser/find/simpleFindWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index 3181551d61df3..93828af2c52db 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -433,7 +433,7 @@ export abstract class SimpleFindWidget extends Widget implements IVerticalSashLa } } -export const simpleFindWidgetSashBorder = registerColor('simpleFindWidget.sashBorder', { dark: '#454545', light: '#C8C8C8', hcDark: '6FC3DF', hcLight: '0F4A85' }, nls.localize('simpleFindWidget.sashBorder', 'Border color of the sash border.')); +export const simpleFindWidgetSashBorder = registerColor('simpleFindWidget.sashBorder', { dark: '#454545', light: '#C8C8C8', hcDark: '#6FC3DF', hcLight: '#0F4A85' }, nls.localize('simpleFindWidget.sashBorder', 'Border color of the sash border.')); registerThemingParticipant((theme, collector) => { const resizeBorderBackground = theme.getColor(simpleFindWidgetSashBorder); From 85586bd1f4858870568b4e1c5c40e9213c0d9b9c Mon Sep 17 00:00:00 2001 From: Jean Pierre Date: Mon, 8 May 2023 12:49:36 -0500 Subject: [PATCH 0004/1180] Fix continuation #175107 when the remote takes more than 20s to resolve, e.g. codespaces --- .../browser/terminalProfileService.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts index 73efd09b3f7f5..d161a40cb6eca 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts @@ -31,7 +31,8 @@ export class TerminalProfileService implements ITerminalProfileService { declare _serviceBrand: undefined; private _webExtensionContributedProfileContextKey: IContextKey; - private _profilesReadyBarrier: AutoOpenBarrier; + private _profilesReadyBarrier: AutoOpenBarrier | undefined; + private _profilesReadyPromise: Promise; private _availableProfiles: ITerminalProfile[] | undefined; private _contributedProfiles: IExtensionTerminalProfile[] = []; private _defaultProfileName?: string; @@ -41,7 +42,7 @@ export class TerminalProfileService implements ITerminalProfileService { private readonly _onDidChangeAvailableProfiles = new Emitter(); get onDidChangeAvailableProfiles(): Event { return this._onDidChangeAvailableProfiles.event; } - get profilesReady(): Promise { return this._profilesReadyBarrier.wait().then(() => { }); } + get profilesReady(): Promise { return this._profilesReadyPromise; } get availableProfiles(): ITerminalProfile[] { if (!this._platformConfigJustRefreshed) { this.refreshAvailableProfiles(); @@ -67,10 +68,14 @@ export class TerminalProfileService implements ITerminalProfileService { this._webExtensionContributedProfileContextKey = TerminalContextKeys.webExtensionContributedProfile.bindTo(this._contextKeyService); this._updateWebContextKey(); - // Wait up to 5 seconds for profiles to be ready so it's assured that we know the actual - // default terminal before launching the first terminal. This isn't expected to ever take - // this long. - this._profilesReadyBarrier = new AutoOpenBarrier(20000); + this._profilesReadyPromise = this._remoteAgentService.getEnvironment() + .then(() => { + // Wait up to 20 seconds for profiles to be ready so it's assured that we know the actual + // default terminal before launching the first terminal. This isn't expected to ever take + // this long. + this._profilesReadyBarrier = new AutoOpenBarrier(20000); + return this._profilesReadyBarrier.wait().then(() => { }); + }); this.refreshAvailableProfiles(); this._setupConfigListener(); } @@ -138,7 +143,7 @@ export class TerminalProfileService implements ITerminalProfileService { if (profilesChanged || contributedProfilesChanged) { this._availableProfiles = profiles; this._onDidChangeAvailableProfiles.fire(this._availableProfiles); - this._profilesReadyBarrier.open(); + this._profilesReadyBarrier!.open(); this._updateWebContextKey(); await this._refreshPlatformConfig(this._availableProfiles); } From 8d1a21408fd25c8977fb417b68b3197b879262da Mon Sep 17 00:00:00 2001 From: Daniel McCormack <52194107+demccormack@users.noreply.github.com> Date: Sat, 17 Jun 2023 17:46:01 +1200 Subject: [PATCH 0005/1180] Enable zsh and bash shell integration with set -u --- .../terminal/browser/media/shellIntegration-bash.sh | 10 +++++----- .../terminal/browser/media/shellIntegration-rc.zsh | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index 8c4f4fbbef02a..292b77cdfdc1c 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -46,7 +46,7 @@ if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then fi # Apply EnvironmentVariableCollections if needed -if [ -n "$VSCODE_ENV_REPLACE" ]; then +if [ -n "${VSCODE_ENV_REPLACE:-}" ]; then IFS=':' read -ra ADDR <<< "$VSCODE_ENV_REPLACE" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo $ITEM | cut -d "=" -f 1)" @@ -55,7 +55,7 @@ if [ -n "$VSCODE_ENV_REPLACE" ]; then done builtin unset VSCODE_ENV_REPLACE fi -if [ -n "$VSCODE_ENV_PREPEND" ]; then +if [ -n "${VSCODE_ENV_PREPEND:-}" ]; then IFS=':' read -ra ADDR <<< "$VSCODE_ENV_PREPEND" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo $ITEM | cut -d "=" -f 1)" @@ -64,7 +64,7 @@ if [ -n "$VSCODE_ENV_PREPEND" ]; then done builtin unset VSCODE_ENV_PREPEND fi -if [ -n "$VSCODE_ENV_APPEND" ]; then +if [ -n "${VSCODE_ENV_APPEND:-}" ]; then IFS=':' read -ra ADDR <<< "$VSCODE_ENV_APPEND" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo $ITEM | cut -d "=" -f 1)" @@ -275,10 +275,10 @@ __vsc_prompt_cmd() { # PROMPT_COMMAND arrays and strings seem to be handled the same (handling only the first entry of # the array?) -__vsc_original_prompt_command=$PROMPT_COMMAND +__vsc_original_prompt_command=${PROMPT_COMMAND:-} if [[ -z "${bash_preexec_imported:-}" ]]; then - if [[ -n "$__vsc_original_prompt_command" && "$__vsc_original_prompt_command" != "__vsc_prompt_cmd" ]]; then + if [[ -n "${__vsc_original_prompt_command:-}" && "${__vsc_original_prompt_command:-}" != "__vsc_prompt_cmd" ]]; then PROMPT_COMMAND=__vsc_prompt_cmd_original else PROMPT_COMMAND=__vsc_prompt_cmd 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 d4e21dacda7c2..09718cfbab235 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh @@ -39,7 +39,7 @@ if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then fi # Apply EnvironmentVariableCollections if needed -if [ -n "$VSCODE_ENV_REPLACE" ]; then +if [ -n "${VSCODE_ENV_REPLACE:-}" ]; then IFS=':' read -rA ADDR <<< "$VSCODE_ENV_REPLACE" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo ${ITEM%%=*})" @@ -47,7 +47,7 @@ if [ -n "$VSCODE_ENV_REPLACE" ]; then done unset VSCODE_ENV_REPLACE fi -if [ -n "$VSCODE_ENV_PREPEND" ]; then +if [ -n "${VSCODE_ENV_PREPEND:-}" ]; then IFS=':' read -rA ADDR <<< "$VSCODE_ENV_PREPEND" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo ${ITEM%%=*})" @@ -55,7 +55,7 @@ if [ -n "$VSCODE_ENV_PREPEND" ]; then done unset VSCODE_ENV_PREPEND fi -if [ -n "$VSCODE_ENV_APPEND" ]; then +if [ -n "${VSCODE_ENV_APPEND:-}" ]; then IFS=':' read -rA ADDR <<< "$VSCODE_ENV_APPEND" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo ${ITEM%%=*})" From f0c543908ad0435605ee5845bb6339cb9d8d7790 Mon Sep 17 00:00:00 2001 From: weartist Date: Sat, 17 Jun 2023 16:31:21 +0800 Subject: [PATCH 0006/1180] Fix #185343 --- .../contrib/terminal/common/terminalConfiguration.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index f247f2193443c..62275b88a3a48 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -503,16 +503,13 @@ const terminalConfiguration: IConfigurationNode = { [TerminalSettingId.LocalEchoStyle]: { description: localize('terminal.integrated.localEchoStyle', "Terminal style of locally echoed text; either a font style or an RGB color."), default: 'dim', - oneOf: [ + anyOf: [ { - type: 'string', - default: 'dim', - enum: ['bold', 'dim', 'italic', 'underlined', 'inverted'], + enum: ['bold', 'dim', 'italic', 'underlined', 'inverted', '#ff0000'], }, { type: 'string', format: 'color-hex', - default: '#ff0000', } ] }, From c6bcad53df7bef121bf804aa7add13f861469caf Mon Sep 17 00:00:00 2001 From: Sandeep Sen Date: Mon, 26 Jun 2023 21:02:27 +0000 Subject: [PATCH 0007/1180] Initial code for go telemetry --- .../electron-sandbox/workspaceTagsService.ts | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index 39a65eac89638..b832b1d639dec 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -244,6 +244,32 @@ const PyModulesToLookFor = [ 'playwright' ]; +const GoMetaModulesToLookFor = [ + 'github.com/Azure/azure-sdk-for-go/sdk/' +]; + +const GoModulesToLookFor = [ + 'github.com/Azure/azure-sdk-for-go/sdk/storage/azblob', + 'github.com/Azure/azure-sdk-for-go/sdk/storage/azfile', + 'github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue', + 'github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel', + 'github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azadmin', + 'github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates', + 'github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys', + 'github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets', + 'github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery', + 'github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs', + 'github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus', + 'github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig', + 'github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos', + 'github.com/Azure/azure-sdk-for-go/sdk/data/aztables', + 'github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry', + 'github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai', + 'github.com/Azure/azure-sdk-for-go/sdk/azidentity', + 'github.com/Azure/azure-sdk-for-go/sdk/azcore' +]; + + export class WorkspaceTagsService implements IWorkspaceTagsService { declare readonly _serviceBrand: undefined; private _tags: Tags | undefined; @@ -566,6 +592,24 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { "workspace.py.azure-security-attestation" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-data-nspkg" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-data-tables" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azfile" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azadmin" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/aztables" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/azidentity" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/azcore" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } } */ private async resolveWorkspaceTags(): Promise { @@ -624,6 +668,8 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { tags['workspace.py.app'] = nameSet.has('app.py'); tags['workspace.py.pyproject'] = nameSet.has('pyproject.toml'); + tags['workspace.go.mod'] = nameSet.has('go.mod'); + const mainActivity = nameSet.has('mainactivity.cs') || nameSet.has('mainactivity.fs'); const appDelegate = nameSet.has('appdelegate.cs') || nameSet.has('appdelegate.fs'); const androidManifest = nameSet.has('androidmanifest.xml'); @@ -752,6 +798,29 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { } }); + const goModPromises = getFilePromises('go.mod', this.fileService, this.textFileService, content => { + // TODO: Richard to write the code for parsing the go.mod file + // look for everything in require() and get the string value only discard version + const dependencies: string[] = splitLines(content.value); + for (const dependency of dependencies) { + // Dependencies in requirements.txt can have 3 formats: `foo==3.1, foo>=3.1, foo` + const format1 = dependency.split('=='); + const format2 = dependency.split('>='); + const packageName = (format1.length === 2 ? format1[0] : format2[0]).trim(); + + // copied from line 728 function addPythonTags + if (GoModulesToLookFor.indexOf(packageName) > -1) { + tags['workspace.go.mod' + packageName] = true; + } + // not sure if we should keep this + for (const metaModule of GoMetaModulesToLookFor) { + if (packageName.startsWith(metaModule)) { + tags['workspace.go.mod' + metaModule] = true; + } + } + } + }); + const pomPromises = getFilePromises('pom.xml', this.fileService, this.textFileService, content => { try { let dependenciesContent; @@ -792,7 +861,7 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { }); }); - return Promise.all([...packageJsonPromises, ...requirementsTxtPromises, ...pipfilePromises, ...pomPromises, ...gradlePromises, ...androidPromises]).then(() => tags); + return Promise.all([...packageJsonPromises, ...requirementsTxtPromises, ...pipfilePromises, ...pomPromises, ...gradlePromises, ...androidPromises, ...goModPromises]).then(() => tags); }); } From b62087b19d5fd3525dab5481500cde91c795a4cb Mon Sep 17 00:00:00 2001 From: Sandeep Sen Date: Mon, 26 Jun 2023 21:58:54 +0000 Subject: [PATCH 0008/1180] Adding go mod parser --- .../electron-sandbox/workspaceTagsService.ts | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index b832b1d639dec..4d5ff69fa1d91 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -801,21 +801,36 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { const goModPromises = getFilePromises('go.mod', this.fileService, this.textFileService, content => { // TODO: Richard to write the code for parsing the go.mod file // look for everything in require() and get the string value only discard version - const dependencies: string[] = splitLines(content.value); - for (const dependency of dependencies) { - // Dependencies in requirements.txt can have 3 formats: `foo==3.1, foo>=3.1, foo` - const format1 = dependency.split('=='); - const format2 = dependency.split('>='); - const packageName = (format1.length === 2 ? format1[0] : format2[0]).trim(); + const lines: string[] = splitLines(content.value); + let firstRequireBlockFound: boolean = false; + + for (let i = 0; i < lines.length; i++) { + const line: string = lines[i].trim(); + + if (line.startsWith('require (')) { + if (!firstRequireBlockFound) { + firstRequireBlockFound = true; + continue; + } else { + break; + } + } - // copied from line 728 function addPythonTags - if (GoModulesToLookFor.indexOf(packageName) > -1) { - tags['workspace.go.mod' + packageName] = true; + if (line.startsWith(')')) { + break; } - // not sure if we should keep this - for (const metaModule of GoMetaModulesToLookFor) { - if (packageName.startsWith(metaModule)) { - tags['workspace.go.mod' + metaModule] = true; + + if (firstRequireBlockFound && line !== '') { + const packageName: string = line.split(' ')[0].trim(); + // copied from line 728 function addPythonTags + if (GoModulesToLookFor.indexOf(packageName) > -1) { + tags['workspace.go.mod' + packageName] = true; + } + // not sure if we should keep this + for (const metaModule of GoMetaModulesToLookFor) { + if (packageName.startsWith(metaModule)) { + tags['workspace.go.mod' + metaModule] = true; + } } } } From af15aac09c3ed2df82bdc774fa539aa9e4751417 Mon Sep 17 00:00:00 2001 From: Sandeep Sen Date: Tue, 27 Jun 2023 20:54:56 +0000 Subject: [PATCH 0009/1180] Removing meta modules as Go does not need it --- .../electron-sandbox/workspaceTagsService.ts | 56 ++++++++----------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index 4d5ff69fa1d91..10be76329c4b6 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -244,10 +244,6 @@ const PyModulesToLookFor = [ 'playwright' ]; -const GoMetaModulesToLookFor = [ - 'github.com/Azure/azure-sdk-for-go/sdk/' -]; - const GoModulesToLookFor = [ 'github.com/Azure/azure-sdk-for-go/sdk/storage/azblob', 'github.com/Azure/azure-sdk-for-go/sdk/storage/azfile', @@ -799,41 +795,33 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { }); const goModPromises = getFilePromises('go.mod', this.fileService, this.textFileService, content => { - // TODO: Richard to write the code for parsing the go.mod file - // look for everything in require() and get the string value only discard version - const lines: string[] = splitLines(content.value); - let firstRequireBlockFound: boolean = false; - - for (let i = 0; i < lines.length; i++) { - const line: string = lines[i].trim(); - - if (line.startsWith('require (')) { - if (!firstRequireBlockFound) { - firstRequireBlockFound = true; - continue; - } else { - break; - } - } - - if (line.startsWith(')')) { - break; - } - - if (firstRequireBlockFound && line !== '') { - const packageName: string = line.split(' ')[0].trim(); - // copied from line 728 function addPythonTags - if (GoModulesToLookFor.indexOf(packageName) > -1) { - tags['workspace.go.mod' + packageName] = true; + try { + const lines: string[] = splitLines(content.value); + let firstRequireBlockFound: boolean = false; + for (let i = 0; i < lines.length; i++) { + const line: string = lines[i].trim(); + if (line.startsWith('require (')) { + if (!firstRequireBlockFound) { + firstRequireBlockFound = true; + continue; + } else { + break; + } } - // not sure if we should keep this - for (const metaModule of GoMetaModulesToLookFor) { - if (packageName.startsWith(metaModule)) { - tags['workspace.go.mod' + metaModule] = true; + if (line.startsWith(')')) { + break; + } + if (firstRequireBlockFound && line !== '') { + const packageName: string = line.split(' ')[0].trim(); + if (GoModulesToLookFor.indexOf(packageName) > -1) { + tags['workspace.go.mod' + packageName] = true; } } } } + catch (e) { + // Ignore errors when resolving file or parsing file contents + } }); const pomPromises = getFilePromises('pom.xml', this.fileService, this.textFileService, content => { From a98595156a09ccdad70b12844653e3c0632be59c Mon Sep 17 00:00:00 2001 From: Sandeep Sen Date: Tue, 27 Jun 2023 21:57:31 -0700 Subject: [PATCH 0010/1180] adding missing commas to GDPR segment --- .../electron-sandbox/workspaceTagsService.ts | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index 10be76329c4b6..04d93982b2a86 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -587,24 +587,24 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { "workspace.py.azure-communication-administration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-security-attestation" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-data-nspkg" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workspace.py.azure-data-tables" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azfile" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azadmin" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/aztables" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/azidentity" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "workspace.py.azure-data-tables" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azfile" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/storage/azqueue" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azadmin" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/data/aztables" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/azidentity" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.go.mod.github.com/Azure/azure-sdk-for-go/sdk/azcore" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } } */ From fd89ea0423bccce0df5a38f8956bfe0aac88c3f7 Mon Sep 17 00:00:00 2001 From: kernel-sanders <1490292+kernel-sanders@users.noreply.github.com> Date: Wed, 28 Jun 2023 19:13:34 -0400 Subject: [PATCH 0011/1180] fix: spawn code_serer with CREATE_NO_WINDOW fixes #184058 --- cli/src/tunnels/code_server.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cli/src/tunnels/code_server.rs b/cli/src/tunnels/code_server.rs index 1246e1c944146..fe257a64314ac 100644 --- a/cli/src/tunnels/code_server.rs +++ b/cli/src/tunnels/code_server.rs @@ -541,6 +541,15 @@ impl<'a> ServerBuilder<'a> { debug!(self.logger, "Starting server with command... {:?}", cmd); + // On Windows spawning a code-server binary will run cmd.exe /c C:\path\to\code-server.cmd... + // This spawns a cmd.exe window for the user, which if they close will kill the code-server process + // and disconnect the tunnel. To prevent this, pass the CREATE_NO_WINDOW flag to the Command + // only on Windows. + // Original issue: https://github.com/microsoft/vscode/issues/184058 + // Partial fix: https://github.com/microsoft/vscode/pull/184621 + #[cfg(target_os = "windows")] + let cmd = cmd.creation_flags(0x08000000); // 0x08000000 == CREATE_NO_WINDOW see https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags + let child = cmd .stderr(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) From 7a5f6f0007d43b772f5a1e5a0a2da2328b53d709 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 30 Jun 2023 16:12:57 +0600 Subject: [PATCH 0012/1180] when the content is not focused it should not disappear --- .../editor/contrib/hover/browser/contentHover.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index f03cf308b61b4..a00c9943d9297 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -195,7 +195,9 @@ export class ContentHoverController extends Disposable { private _setCurrentResult(hoverResult: HoverResult | null): void { if (this._currentResult === hoverResult) { - // avoid updating the DOM to avoid resetting the user selection + if (hoverResult === null && !this._widget.isFocused) { + this._widget.hide(); + } return; } if (hoverResult && hoverResult.messages.length === 0) { @@ -205,6 +207,9 @@ export class ContentHoverController extends Disposable { if (this._currentResult) { this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { + if (this._widget.isFocused) { + return; + } this._widget.hide(); } } @@ -479,6 +484,10 @@ export class ContentHoverWidget extends ResizableContentWidget { return this._hoverVisibleKey.get() ?? false; } + public get isFocused(): boolean { + return this._hoverFocusedKey.get() ?? false; + } + constructor( editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService @@ -727,10 +736,7 @@ export class ContentHoverWidget extends ResizableContentWidget { } public hide(): void { - if (!this._visibleData) { - return; - } - const stoleFocus = this._visibleData.stoleFocus; + const stoleFocus = this._visibleData?.stoleFocus; this._setHoverData(undefined); this._resizableNode.maxSize = new dom.Dimension(Infinity, Infinity); this._resizableNode.clearSashHoverState(); From 721629bd1a78ef1f3facfae766f3ba2f05556eab Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 30 Jun 2023 17:15:37 +0600 Subject: [PATCH 0013/1180] removing the assert type on the active session to be able to spawn several sessions one after the other --- .../workbench/contrib/inlineChat/browser/inlineChatController.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index ba825ebb44a9f..1e975917f3dc6 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -214,7 +214,6 @@ export class InlineChatController implements IEditorContribution { } private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { - assertType(this._activeSession === undefined); assertType(this._editor.hasModel()); let session: Session | undefined = options.existingSession; From cc92e04a08a1d4f0b94ac26696a2aa1bebbbf142 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 30 Jun 2023 17:32:10 +0600 Subject: [PATCH 0014/1180] adding some code, need to verify what causes the error in dev tools --- .../contrib/inlineChat/browser/inlineChatController.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 1e975917f3dc6..8f6bc67f54a3c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -214,6 +214,12 @@ export class InlineChatController implements IEditorContribution { } private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { + if (this._activeSession) { + this._sessionStore.clear(); + this._inlineChatSessionService.releaseSession(this._activeSession); + await this[State.PAUSE](); + } + assertType(this._activeSession === undefined); assertType(this._editor.hasModel()); let session: Session | undefined = options.existingSession; From 7389ceeaded34c2d9d7186bc9141522cd9376f85 Mon Sep 17 00:00:00 2001 From: yshaojun Date: Mon, 3 Jul 2023 23:43:31 +0800 Subject: [PATCH 0015/1180] fix: color hints may display twice(#175476) --- src/vs/editor/common/viewModel/modelLineProjection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/viewModel/modelLineProjection.ts b/src/vs/editor/common/viewModel/modelLineProjection.ts index 81be5db0a101f..e66499cd98e18 100644 --- a/src/vs/editor/common/viewModel/modelLineProjection.ts +++ b/src/vs/editor/common/viewModel/modelLineProjection.ts @@ -193,7 +193,7 @@ class ModelLineProjection implements IModelLineProjection { if (options.inlineClassName) { const offset = (outputLineIndex > 0 ? lineBreakData.wrappedTextIndentLength : 0); const start = offset + Math.max(injectedTextStartOffsetInInputWithInjections - lineStartOffsetInInputWithInjections, 0); - const end = offset + Math.min(injectedTextEndOffsetInInputWithInjections - lineStartOffsetInInputWithInjections, lineEndOffsetInInputWithInjections); + const end = offset + Math.min(injectedTextEndOffsetInInputWithInjections - lineStartOffsetInInputWithInjections, lineEndOffsetInInputWithInjections - lineStartOffsetInInputWithInjections); if (start !== end) { inlineDecorations.push(new SingleLineInlineDecoration(start, end, options.inlineClassName, options.inlineClassNameAffectsLetterSpacing!)); } From 7fd34784adde658e335489da69e71262ca1e1340 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 3 Jul 2023 10:24:58 -0700 Subject: [PATCH 0016/1180] defer buffer creation --- .../browser/terminal.accessibility.contribution.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 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 a121b0c4019ab..23a3f64034751 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 @@ -26,6 +26,7 @@ import { Terminal } from 'xterm'; class AccessibleBufferContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.accessible-buffer'; + private _xterm: IXtermTerminal & { raw: Terminal } | undefined; static get(instance: ITerminalInstance): AccessibleBufferContribution | null { return instance.getContribution(AccessibleBufferContribution.ID); } @@ -40,11 +41,15 @@ class AccessibleBufferContribution extends DisposableStore implements ITerminalC super(); } layout(xterm: IXtermTerminal & { raw: Terminal }): void { - if (!this._accessibleBufferWidget) { - this._accessibleBufferWidget = this.add(this._instantiationService.createInstance(AccessibleBufferWidget, this._instance, xterm)); - } + this._xterm = xterm; } async show(): Promise { + if (!this._xterm) { + return; + } + if (!this._accessibleBufferWidget) { + this._accessibleBufferWidget = this.add(this._instantiationService.createInstance(AccessibleBufferWidget, this._instance, this._xterm)); + } await this._accessibleBufferWidget?.show(); } From 0ef9e9a0fa1d13e8b20f96fb7f142daabc4b6e8e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 3 Jul 2023 10:27:04 -0700 Subject: [PATCH 0017/1180] rm ? --- .../browser/terminal.accessibility.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 23a3f64034751..c59c6db03e221 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 @@ -50,7 +50,7 @@ class AccessibleBufferContribution extends DisposableStore implements ITerminalC if (!this._accessibleBufferWidget) { this._accessibleBufferWidget = this.add(this._instantiationService.createInstance(AccessibleBufferWidget, this._instance, this._xterm)); } - await this._accessibleBufferWidget?.show(); + await this._accessibleBufferWidget.show(); } async createCommandQuickPick(): Promise | undefined> { From c4ab63fb37198ce82609149be50c86d19d1a9a25 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Fri, 7 Jul 2023 11:19:12 -0700 Subject: [PATCH 0018/1180] treat soon-to-be-autosaved as saving --- .../contrib/customEditor/browser/customEditorInput.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index 964a6a0443ba7..3f40d26457497 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -22,7 +22,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { ICustomEditorModel, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { IOverlayWebview, IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'; import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; interface CustomEditorInputInitInfo { @@ -302,6 +302,14 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { return (await this.rename(groupId, target))?.editor; } + override isSaving(): boolean { + if (this.isDirty() && !this.hasCapability(EditorInputCapabilities.Untitled) && this.filesConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + return true; // will be saved soon + } + + return super.isSaving(); + } + public override async revert(group: GroupIdentifier, options?: IRevertOptions): Promise { if (this._modelRef) { return this._modelRef.object.revert(options); From 7eaae680dc341be01f6563bdd0e43c7519ecd086 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 10 Jul 2023 10:59:42 +0200 Subject: [PATCH 0019/1180] adding some comments that will be removed later --- .../inlineChat/browser/inlineChatController.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 8f6bc67f54a3c..7a9d3d2ee993d 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -215,10 +215,14 @@ export class InlineChatController implements IEditorContribution { private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { if (this._activeSession) { + console.log('before clearing the session store'); this._sessionStore.clear(); + console.log('before releasing teh session'); this._inlineChatSessionService.releaseSession(this._activeSession); + console.log('before calling pause'); await this[State.PAUSE](); } + console.log('this._activeSession after the cleaning : ', this._activeSession); assertType(this._activeSession === undefined); assertType(this._editor.hasModel()); @@ -282,6 +286,8 @@ export class InlineChatController implements IEditorContribution { } private async [State.INIT_UI](options: InlineChatRunOptions): Promise { + console.log('inside of init ui'); + console.log('this._activeSession : ', this._activeSession); assertType(this._activeSession); // hide/cancel inline completions when invoking IE @@ -347,11 +353,14 @@ export class InlineChatController implements IEditorContribution { })); if (!this._activeSession.lastExchange) { + console.log('before waiting for input'); return State.WAIT_FOR_INPUT; } else if (options.isUnstashed) { delete options.isUnstashed; + console.log('before apply response'); return State.APPLY_RESPONSE; } else { + console.log('before show response'); return State.SHOW_RESPONSE; } } @@ -631,6 +640,8 @@ export class InlineChatController implements IEditorContribution { private async [State.PAUSE]() { + console.log('entered into pause state'); + this._ctxDidEdit.reset(); this._ctxUserDidEdit.reset(); this._ctxLastResponseType.reset(); @@ -650,6 +661,7 @@ export class InlineChatController implements IEditorContribution { } private async [State.ACCEPT]() { + console.log('inside of accept'); assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); From 55613b5f13d009a2c0d32eb95b45b88024d4eecd Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 10 Jul 2023 15:31:45 +0200 Subject: [PATCH 0020/1180] adding some console logs, added todo --- .../browser/inlineChatController.ts | 50 ++++++++++++++++--- .../browser/inlineChatStrategies.ts | 5 +- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 7a9d3d2ee993d..05cb6b8e8df7c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -134,6 +134,7 @@ export class InlineChatController implements IEditorContribution { } this._log('session RESUMING', e); + console.log('before calling create session of the constructor'); await this._nextState(State.CREATE_SESSION, { existingSession }); this._log('session done or paused'); })); @@ -141,6 +142,7 @@ export class InlineChatController implements IEditorContribution { } dispose(): void { + console.log('inside of dispose'); this._stashedSession.clear(); this.finishExistingSession(); this._store.dispose(); @@ -174,10 +176,10 @@ export class InlineChatController implements IEditorContribution { } async run(options: InlineChatRunOptions | undefined = {}): Promise { - this._log('session starting'); + this._log('session starting inside of run'); await this.finishExistingSession(); this._stashedSession.clear(); - + console.log('before calling create session inside of run'); await this._nextState(State.CREATE_SESSION, options); this._log('session done or paused'); } @@ -214,6 +216,8 @@ export class InlineChatController implements IEditorContribution { } private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { + console.log('inside of CREATE_SESSION'); + console.log('this._activeSession : ', this._activeSession); if (this._activeSession) { console.log('before clearing the session store'); this._sessionStore.clear(); @@ -235,6 +239,7 @@ export class InlineChatController implements IEditorContribution { if (!session) { const createSessionCts = new CancellationTokenSource(); const msgListener = Event.once(this._messages.event)(m => { + console.log('inside of the msgListener code of CREATE_SESSION'); this._log('state=_createSession) message received', m); if (m === Message.ACCEPT_INPUT) { // user accepted the input before having a session @@ -348,6 +353,7 @@ export class InlineChatController implements IEditorContribution { if (editIsOutsideOfWholeRange) { this._log('text changed outside of whole range, FINISH session'); + console.log('before the third finish existing session'); this.finishExistingSession(); } })); @@ -379,7 +385,7 @@ export class InlineChatController implements IEditorContribution { } - private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions): Promise { + private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions): Promise { assertType(this._activeSession); assertType(this._strategy); @@ -400,6 +406,7 @@ export class InlineChatController implements IEditorContribution { } else { const barrier = new Barrier(); const msgListener = Event.once(this._messages.event)(m => { + console.log('inside of msgListener of WAIT FOR INPUT'); this._log('state=_waitForInput) message received', m); message = m; barrier.open(); @@ -411,11 +418,19 @@ export class InlineChatController implements IEditorContribution { this._zone.value.widget.selectAll(); if (message & (Message.CANCEL_INPUT | Message.CANCEL_SESSION)) { - return State.CANCEL; + console.log('inside of wait for input'); + console.log('entered into the case when message cancel session'); + await this[State.CANCEL](); + return; + // return State.CANCEL; } if (message & Message.ACCEPT_SESSION) { - return State.ACCEPT; + console.log('inside of wait for input'); + console.log('entered into the case when message accept'); + await this[State.ACCEPT](); + return; + // return State.ACCEPT; } if (message & Message.PAUSE_SESSION) { @@ -467,6 +482,7 @@ export class InlineChatController implements IEditorContribution { let message = Message.NONE; const msgListener = Event.once(this._messages.event)(m => { + console.log('inside of msgListener of MAKE REQUEST'); this._log('state=_makeRequest) message received', m); message = m; requestCts.cancel(); @@ -521,10 +537,14 @@ export class InlineChatController implements IEditorContribution { this._activeSession.addExchange(new SessionExchange(this._activeSession.lastInput, response)); if (message & Message.CANCEL_SESSION) { + console.log('inside of make request'); + console.log('cancelling the session'); return State.CANCEL; } else if (message & Message.PAUSE_SESSION) { return State.PAUSE; } else if (message & Message.ACCEPT_SESSION) { + console.log('inside of make request'); + console.log('accepting'); return State.ACCEPT; } else { return State.APPLY_RESPONSE; @@ -665,21 +685,31 @@ export class InlineChatController implements IEditorContribution { assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); + console.log('after assert type'); try { + console.log('before strategy apply'); await this._strategy.apply(); + console.log('after strategy apply'); + // TODO: ASK WHY DESPITE AWAIT AFTER STRATEFY NOT PRINTED BEFORE CREATE SESSION } catch (err) { + console.log('when error obtained'); this._dialogService.error(localize('err.apply', "Failed to apply changes.", toErrorMessage(err))); this._log('FAILED to apply changes'); this._log(err); } - this._inlineChatSessionService.releaseSession(this._activeSession); + console.log('before release session'); - this[State.PAUSE](); + await this._inlineChatSessionService.releaseSession(this._activeSession); + + console.log('before state pause'); + await this[State.PAUSE](); } private async [State.CANCEL]() { + console.log('inside of cancel the session'); + assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); @@ -694,7 +724,7 @@ export class InlineChatController implements IEditorContribution { this._log(err); } - this[State.PAUSE](); + await this[State.PAUSE](); this._stashedSession.clear(); if (!mySession.isUnstashed && mySession.lastExchange) { @@ -780,10 +810,12 @@ export class InlineChatController implements IEditorContribution { } acceptSession(): void { + console.log('inside of acceptSession method'); this._messages.fire(Message.ACCEPT_SESSION); } cancelSession() { + console.log('inside of cancelSession'); let result: string | undefined; if (this._strategy && this._activeSession) { const changedText = this._activeSession.asChangedText(); @@ -798,6 +830,8 @@ export class InlineChatController implements IEditorContribution { } async finishExistingSession(): Promise { + console.log('inside of finish existing session'); + console.log(this._activeSession); if (this._activeSession) { if (this._activeSession.editMode === EditMode.Preview) { this._log('finishing existing session, using CANCEL', this._activeSession.editMode); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index 36e64ebf09af5..019a4ecfd58d5 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -86,7 +86,7 @@ export class PreviewStrategy extends EditModeStrategy { } async apply() { - + console.log('at the beginning of the apply method of preview strategy'); if (!(this._session.lastExchange?.response instanceof EditResponse)) { return; } @@ -107,6 +107,7 @@ export class PreviewStrategy extends EditModeStrategy { modelN.pushStackElement(); } } + console.log('at the end of the apply method of preview strategy'); } async cancel(): Promise { @@ -279,6 +280,7 @@ export class LiveStrategy extends EditModeStrategy { } async apply() { + console.log('inside of apply of live strategy'); if (this._editCount > 0) { this._editor.pushUndoStop(); } @@ -286,6 +288,7 @@ export class LiveStrategy extends EditModeStrategy { await this._bulkEditService.apply(this._lastResponse.workspaceEdits); this._instaService.invokeFunction(showSingleCreateFile, this._lastResponse); } + console.log('at the end of apply for live strategy'); } async cancel() { From 29f37cc240b394df6fd5494514a153e55686d81b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 11 Jul 2023 14:54:06 +0200 Subject: [PATCH 0021/1180] adding code in order to make the picked color representation disappear when resizing if it overlaps with the icon --- .../colorPicker/browser/colorPickerWidget.ts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts index 24b6e6408b3dd..6466b09430c60 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts @@ -22,10 +22,22 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; const $ = dom.$; +function elementsOverlap(el1: HTMLElement, el2: HTMLElement) { + const domRect1 = el1.getBoundingClientRect(); + const domRect2 = el2.getBoundingClientRect(); + return !( + domRect1.top > domRect2.bottom || + domRect1.right < domRect2.left || + domRect1.bottom < domRect2.top || + domRect1.left > domRect2.right + ); +} + export class ColorPickerHeader extends Disposable { private readonly _domNode: HTMLElement; private readonly _pickedColorNode: HTMLElement; + private readonly _pickedColorRepresentation: HTMLElement; private readonly _originalColorNode: HTMLElement; private readonly _closeButton: CloseButton | null = null; private backgroundColor: Color; @@ -37,6 +49,8 @@ export class ColorPickerHeader extends Disposable { dom.append(container, this._domNode); this._pickedColorNode = dom.append(this._domNode, $('.picked-color')); + this._pickedColorRepresentation = dom.append(this._pickedColorNode, document.createElement('div')); + const icon = dom.append(this._pickedColorNode, $('.codicon.codicon-color-mode')); const tooltip = localize('clickToToggleColorOptions', "Click to toggle color options (rgb/hsl/hex)"); this._pickedColorNode.setAttribute('title', tooltip); @@ -66,6 +80,16 @@ export class ColorPickerHeader extends Disposable { this._domNode.classList.add('standalone-colorpicker'); this._closeButton = this._register(new CloseButton(this._domNode)); } + + const resizeObserver = new ResizeObserver(() => { + this._pickedColorRepresentation.style.display = 'block'; + if (elementsOverlap(this._pickedColorRepresentation, icon)) { + this._pickedColorRepresentation.style.display = 'none'; + } else { + this._pickedColorRepresentation.style.display = 'block'; + } + }); + resizeObserver.observe(this._domNode); } public get domNode(): HTMLElement { @@ -91,8 +115,7 @@ export class ColorPickerHeader extends Disposable { } private onDidChangePresentation(): void { - this._pickedColorNode.textContent = this.model.presentation ? this.model.presentation.label : ''; - this._pickedColorNode.prepend($('.codicon.codicon-color-mode')); + this._pickedColorRepresentation.textContent = this.model.presentation ? this.model.presentation.label : ''; } } From 65b21886d07e23bc34aba2acdec46c7f43e3ffb2 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 11 Jul 2023 15:04:55 +0200 Subject: [PATCH 0022/1180] Removing the check on top and bottom which are not needed --- .../editor/contrib/colorPicker/browser/colorPickerWidget.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts index 6466b09430c60..2f267fcaf0ca4 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts @@ -22,13 +22,11 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; const $ = dom.$; -function elementsOverlap(el1: HTMLElement, el2: HTMLElement) { +function elementsOverlapHorizontally(el1: HTMLElement, el2: HTMLElement) { const domRect1 = el1.getBoundingClientRect(); const domRect2 = el2.getBoundingClientRect(); return !( - domRect1.top > domRect2.bottom || domRect1.right < domRect2.left || - domRect1.bottom < domRect2.top || domRect1.left > domRect2.right ); } @@ -83,7 +81,7 @@ export class ColorPickerHeader extends Disposable { const resizeObserver = new ResizeObserver(() => { this._pickedColorRepresentation.style.display = 'block'; - if (elementsOverlap(this._pickedColorRepresentation, icon)) { + if (elementsOverlapHorizontally(this._pickedColorRepresentation, icon)) { this._pickedColorRepresentation.style.display = 'none'; } else { this._pickedColorRepresentation.style.display = 'block'; From d363a2fd7666c5efcad397132ebe21bb7e4f35e4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 11 Jul 2023 15:37:41 +0200 Subject: [PATCH 0023/1180] setting some minimum dimensions on the content hover. --- src/vs/editor/contrib/hover/browser/contentHover.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index f03cf308b61b4..5cc8ab5028e18 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -504,6 +504,7 @@ export class ContentHoverWidget extends ResizableContentWidget { this._hoverFocusedKey.set(false); })); this._setHoverData(undefined); + this._setMinimumDimensions(); this._layout(); this._editor.addContentWidget(this); } @@ -518,6 +519,15 @@ export class ContentHoverWidget extends ResizableContentWidget { return ContentHoverWidget.ID; } + private _setMinimumDimensions(): void { + const width = 50; + const height = this._editor.getOption(EditorOption.lineHeight) + 8; + const contentsDomNode = this._hover.contentsDomNode; + contentsDomNode.style.minWidth = width + 'px'; + contentsDomNode.style.minHeight = height + 'px'; + this._resizableNode.minSize = new dom.Dimension(width, height); + } + private static _applyDimensions(container: HTMLElement, width: number | string, height: number | string): void { const transformedWidth = typeof width === 'number' ? `${width}px` : width; const transformedHeight = typeof height === 'number' ? `${height}px` : height; From 9b8e6edaf1280d0f698d363b3f238365ede2c02a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 11 Jul 2023 16:28:24 +0200 Subject: [PATCH 0024/1180] using instead the CSS to set size --- .../colorPicker/browser/colorPicker.css | 6 +++++ .../colorPicker/browser/colorPickerWidget.ts | 22 ++----------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css index 62f891080feb9..9b588999dd70b 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css +++ b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css @@ -50,6 +50,12 @@ flex: 1; } +.colorpicker-header .picked-color .picked-color-representation { + white-space: nowrap; + margin-left: 30px; + margin-right: 5px; +} + .colorpicker-header .picked-color .codicon { color: inherit; font-size: 14px; diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts index 2f267fcaf0ca4..efc7053fe2634 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts @@ -22,15 +22,6 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; const $ = dom.$; -function elementsOverlapHorizontally(el1: HTMLElement, el2: HTMLElement) { - const domRect1 = el1.getBoundingClientRect(); - const domRect2 = el2.getBoundingClientRect(); - return !( - domRect1.right < domRect2.left || - domRect1.left > domRect2.right - ); -} - export class ColorPickerHeader extends Disposable { private readonly _domNode: HTMLElement; @@ -48,7 +39,8 @@ export class ColorPickerHeader extends Disposable { this._pickedColorNode = dom.append(this._domNode, $('.picked-color')); this._pickedColorRepresentation = dom.append(this._pickedColorNode, document.createElement('div')); - const icon = dom.append(this._pickedColorNode, $('.codicon.codicon-color-mode')); + this._pickedColorRepresentation.classList.add('picked-color-representation'); + dom.append(this._pickedColorNode, $('.codicon.codicon-color-mode')); const tooltip = localize('clickToToggleColorOptions', "Click to toggle color options (rgb/hsl/hex)"); this._pickedColorNode.setAttribute('title', tooltip); @@ -78,16 +70,6 @@ export class ColorPickerHeader extends Disposable { this._domNode.classList.add('standalone-colorpicker'); this._closeButton = this._register(new CloseButton(this._domNode)); } - - const resizeObserver = new ResizeObserver(() => { - this._pickedColorRepresentation.style.display = 'block'; - if (elementsOverlapHorizontally(this._pickedColorRepresentation, icon)) { - this._pickedColorRepresentation.style.display = 'none'; - } else { - this._pickedColorRepresentation.style.display = 'block'; - } - }); - resizeObserver.observe(this._domNode); } public get domNode(): HTMLElement { From 0e34605600704b03450880c4cf8368f312049d6a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 11 Jul 2023 16:36:41 +0200 Subject: [PATCH 0025/1180] changing the word representation to presentation --- src/vs/editor/contrib/colorPicker/browser/colorPicker.css | 2 +- .../contrib/colorPicker/browser/colorPickerWidget.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css index 9b588999dd70b..f84c7ba6f2b8f 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css +++ b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css @@ -50,7 +50,7 @@ flex: 1; } -.colorpicker-header .picked-color .picked-color-representation { +.colorpicker-header .picked-color .picked-color-presentation { white-space: nowrap; margin-left: 30px; margin-right: 5px; diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts index efc7053fe2634..6c8cc3ab4e00c 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts @@ -26,7 +26,7 @@ export class ColorPickerHeader extends Disposable { private readonly _domNode: HTMLElement; private readonly _pickedColorNode: HTMLElement; - private readonly _pickedColorRepresentation: HTMLElement; + private readonly _pickedColorPresentation: HTMLElement; private readonly _originalColorNode: HTMLElement; private readonly _closeButton: CloseButton | null = null; private backgroundColor: Color; @@ -38,8 +38,8 @@ export class ColorPickerHeader extends Disposable { dom.append(container, this._domNode); this._pickedColorNode = dom.append(this._domNode, $('.picked-color')); - this._pickedColorRepresentation = dom.append(this._pickedColorNode, document.createElement('div')); - this._pickedColorRepresentation.classList.add('picked-color-representation'); + this._pickedColorPresentation = dom.append(this._pickedColorNode, document.createElement('div')); + this._pickedColorPresentation.classList.add('picked-color-presentation'); dom.append(this._pickedColorNode, $('.codicon.codicon-color-mode')); const tooltip = localize('clickToToggleColorOptions', "Click to toggle color options (rgb/hsl/hex)"); @@ -95,7 +95,7 @@ export class ColorPickerHeader extends Disposable { } private onDidChangePresentation(): void { - this._pickedColorRepresentation.textContent = this.model.presentation ? this.model.presentation.label : ''; + this._pickedColorPresentation.textContent = this.model.presentation ? this.model.presentation.label : ''; } } From b912246257d36a43bd0bf50a2658322ccaa6a091 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 11 Jul 2023 14:26:34 -0700 Subject: [PATCH 0026/1180] fix when clause --- .../terminal.accessibility.contribution.ts | 2 +- .../browser/terminalAccessibleBuffer.ts | 18 +++++++++--------- .../browser/terminalAccessibleWidget.ts | 1 + 3 files changed, 11 insertions(+), 10 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 50d519feb79c1..fa198f5464f10 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 @@ -92,7 +92,7 @@ registerTerminalAction({ { primary: KeyMod.Shift | KeyCode.Tab, weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, terminalTabFocusContextKey, TerminalContextKeys.accessibleBufferFocus.negate()) + when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, ContextKeyExpr.or(terminalTabFocusContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } ], run: async (c) => { diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index 2b58c3592530c..48cc9dec78d1a 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -4,23 +4,23 @@ *--------------------------------------------------------------------------------------------*/ import { Event } from 'vs/base/common/event'; +import { withNullAsUndefined } from 'vs/base/common/types'; +import { IEditorViewState } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { IModelService } from 'vs/editor/common/services/model'; import { localize } from 'vs/nls'; +import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; -import type { Terminal } from 'xterm'; -import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { withNullAsUndefined } from 'vs/base/common/types'; +import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; +import { ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { BufferContentTracker } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/bufferContentTracker'; -import { IEditorViewState } from 'vs/editor/common/editorCommon'; import { TerminalAccessibleWidget } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget'; -import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; -import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; +import type { Terminal } from 'xterm'; export const enum NavigationType { Next = 'next', diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index d1316db9bee1f..6754d0a263595 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -118,6 +118,7 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._terminalService.setActiveInstance(this._instance as ITerminalInstance); this._xtermElement.classList.add(ClassName.Hide); })); + this.layout(); } registerListeners(): void { From fe98d08c7e9ebda9a3f957195579d971e6daabcc Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 11 Jul 2023 14:28:24 -0700 Subject: [PATCH 0027/1180] improve name --- src/vs/platform/terminal/common/terminal.ts | 2 +- src/vs/workbench/browser/parts/editor/tabFocus.ts | 4 ++-- .../browser/terminal.accessibility.contribution.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index a73f7a7f9fa8b..1f019a69053c6 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -17,7 +17,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import type * as performance from 'vs/base/common/performance'; import { ILogService } from 'vs/platform/log/common/log'; -export const terminalTabFocusContextKey = new RawContextKey('terminalTabFocusMode', false, true); +export const terminalTabFocusModeContextKey = new RawContextKey('terminalTabFocusMode', false, true); export const enum TerminalSettingPrefix { DefaultProfile = 'terminal.integrated.defaultProfile.', diff --git a/src/vs/workbench/browser/parts/editor/tabFocus.ts b/src/vs/workbench/browser/parts/editor/tabFocus.ts index 3d770eb885792..52f2e0d7199fa 100644 --- a/src/vs/workbench/browser/parts/editor/tabFocus.ts +++ b/src/vs/workbench/browser/parts/editor/tabFocus.ts @@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { TabFocusContext, TabFocus } from 'vs/editor/browser/config/tabFocus'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { TerminalSettingId, terminalTabFocusContextKey } from 'vs/platform/terminal/common/terminal'; +import { TerminalSettingId, terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; export const editorTabFocusContextKey = new RawContextKey('editorTabFocusMode', false, true); @@ -26,7 +26,7 @@ export class TabFocusMode extends Disposable { super(); this._editorContext = editorTabFocusContextKey.bindTo(contextKeyService); - this._terminalContext = terminalTabFocusContextKey.bindTo(contextKeyService); + this._terminalContext = terminalTabFocusModeContextKey.bindTo(contextKeyService); const editorConfig: boolean = configurationService.getValue('editor.tabFocusMode'); const terminalConfig: boolean = configurationService.getValue(TerminalSettingId.TabFocusMode) ?? editorConfig; this._editorContext.set(editorConfig); 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 fa198f5464f10..acff267d59c9e 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 @@ -11,7 +11,7 @@ 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 { terminalTabFocusContextKey } from 'vs/platform/terminal/common/terminal'; +import { terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -92,7 +92,7 @@ registerTerminalAction({ { primary: KeyMod.Shift | KeyCode.Tab, weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, ContextKeyExpr.or(terminalTabFocusContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) + when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } ], run: async (c) => { From 018a8d2ebd39924b5085b8ec5b2d30d95068cabe Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 11 Jul 2023 14:29:14 -0700 Subject: [PATCH 0028/1180] revert unneeded change --- .../accessibility/browser/terminalAccessibleWidget.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index 6754d0a263595..d1316db9bee1f 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -118,7 +118,6 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._terminalService.setActiveInstance(this._instance as ITerminalInstance); this._xtermElement.classList.add(ClassName.Hide); })); - this.layout(); } registerListeners(): void { From fbd39c1ac25434c6bb12caf1c157b273bd629f15 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 10 Jul 2023 09:35:25 -0700 Subject: [PATCH 0029/1180] moved optimization to model --- .../view/renderers/backLayerWebView.ts | 14 ++--- .../model/notebookCellOutputTextModel.ts | 35 ++++++++++++- .../common/model/notebookCellTextModel.ts | 33 +----------- .../test/browser/notebookTextModel.test.ts | 52 +++++++++++++++++++ 4 files changed, 91 insertions(+), 43 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 06a4054a668d4..0fdc7c3c6120d 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1413,15 +1413,11 @@ export class BackLayerWebView extends Themable { } // create new output - const createOutput = () => { - const { message, renderer, transfer: transferable } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, false, false); - this._sendMessageToWebview(message, transferable); - this.insetMapping.set(content.source, { outputId: message.outputId, versionId: content.source.model.versionId, cellInfo: cellInfo, renderer, cachedCreation: message }); - this.hiddenInsetMapping.delete(content.source); - this.reversedInsetMapping.set(message.outputId, content.source); - }; - - createOutput(); + const { message, renderer, transfer: transferable } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, false, false); + this._sendMessageToWebview(message, transferable); + this.insetMapping.set(content.source, { outputId: message.outputId, versionId: content.source.model.versionId, cellInfo: cellInfo, renderer, cachedCreation: message }); + this.hiddenInsetMapping.delete(content.source); + this.reversedInsetMapping.set(message.outputId, content.source); } private createMetadata(output: ICellOutput, mimeType: string) { diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts index 5d7ac8195b6ae..3c9e16931fdb2 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts @@ -5,7 +5,7 @@ import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { ICellOutput, IOutputDto, IOutputItemDto } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ICellOutput, IOutputDto, IOutputItemDto, compressOutputItemStreams, isTextStreamMime } from 'vs/workbench/contrib/notebook/common/notebookCommon'; export class NotebookCellOutputTextModel extends Disposable implements ICellOutput { @@ -38,17 +38,46 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp replaceData(rawData: IOutputDto) { this._rawOutput = rawData; + this.optimizeOutputItems(); this._versionId = this._versionId + 1; - this._onDidChangeData.fire(); } appendData(items: IOutputItemDto[]) { this._rawOutput.outputs.push(...items); + this.optimizeOutputItems(); this._versionId = this._versionId + 1; this._onDidChangeData.fire(); } + private optimizeOutputItems() { + if (this.outputs.length > 1 && this.outputs.every(item => isTextStreamMime(item.mime))) { + // Look for the mimes in the items, and keep track of their order. + // Merge the streams into one output item, per mime type. + const mimeOutputs = new Map(); + const mimeTypes: string[] = []; + this.outputs.forEach(item => { + let items: Uint8Array[]; + if (mimeOutputs.has(item.mime)) { + items = mimeOutputs.get(item.mime)!; + } else { + items = []; + mimeOutputs.set(item.mime, items); + mimeTypes.push(item.mime); + } + items.push(item.data.buffer); + }); + this.outputs.length = 0; + mimeTypes.forEach(mime => { + const compressed = compressOutputItemStreams(mimeOutputs.get(mime)!); + this.outputs.push({ + mime, + data: compressed + }); + }); + } + } + toJSON(): IOutputDto { return { // data: this._data, @@ -57,4 +86,6 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp outputId: this._rawOutput.outputId }; } + + } diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts index c5d927de5800c..e32021676e5b5 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts @@ -16,7 +16,7 @@ import { TextModel } from 'vs/editor/common/model/textModel'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { NotebookCellOutputTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel'; -import { CellInternalMetadataChangedEvent, CellKind, compressOutputItemStreams, ICell, ICellDto2, ICellOutput, IOutputDto, IOutputItemDto, isTextStreamMime, NotebookCellCollapseState, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellOutputsSplice, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellInternalMetadataChangedEvent, CellKind, ICell, ICellDto2, ICellOutput, IOutputDto, IOutputItemDto, NotebookCellCollapseState, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellOutputsSplice, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; export class NotebookCellTextModel extends Disposable implements ICell { private readonly _onDidChangeOutputs = this._register(new Emitter()); @@ -298,34 +298,6 @@ export class NotebookCellTextModel extends Disposable implements ICell { } } - private _optimizeOutputItems(output: ICellOutput) { - if (output.outputs.length > 1 && output.outputs.every(item => isTextStreamMime(item.mime))) { - // Look for the mimes in the items, and keep track of their order. - // Merge the streams into one output item, per mime type. - const mimeOutputs = new Map(); - const mimeTypes: string[] = []; - output.outputs.forEach(item => { - let items: Uint8Array[]; - if (mimeOutputs.has(item.mime)) { - items = mimeOutputs.get(item.mime)!; - } else { - items = []; - mimeOutputs.set(item.mime, items); - mimeTypes.push(item.mime); - } - items.push(item.data.buffer); - }); - output.outputs.length = 0; - mimeTypes.forEach(mime => { - const compressed = compressOutputItemStreams(mimeOutputs.get(mime)!); - output.outputs.push({ - mime, - data: compressed - }); - }); - } - } - replaceOutput(outputId: string, newOutputItem: ICellOutput) { const outputIndex = this.outputs.findIndex(output => output.outputId === outputId); @@ -335,7 +307,6 @@ export class NotebookCellTextModel extends Disposable implements ICell { const output = this.outputs[outputIndex]; output.replaceData(newOutputItem); - this._optimizeOutputItems(output); this._onDidChangeOutputItems.fire(); return true; } @@ -353,8 +324,6 @@ export class NotebookCellTextModel extends Disposable implements ICell { } else { output.replaceData({ outputId: outputId, outputs: items, metadata: output.metadata }); } - - this._optimizeOutputItems(output); this._onDidChangeOutputItems.fire(); return true; } diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts index 4da03a9f24814..362619bf1b750 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts @@ -311,6 +311,58 @@ suite('NotebookTextModel', () => { ); }); + test('appending streaming outputs', async function () { + await withTestNotebook( + [ + ['var a = 1;', 'javascript', CellKind.Code, [], {}], + ], + (editor) => { + const textModel = editor.textModel; + + textModel.applyEdits([ + { + index: 0, + editType: CellEditType.Output, + append: true, + outputs: [{ + outputId: 'append1', + outputs: [{ mime: 'application/vnd.code.notebook.stdout', data: valueBytesFromString('append 1') }] + }] + }], true, undefined, () => undefined, undefined, true); + const [output] = textModel.cells[0].outputs; + assert.strictEqual(output.versionId, 0, 'initial output version is 0'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: true, + outputId: 'append1', + items: [{ + mime: 'application/vnd.code.notebook.stdout', data: valueBytesFromString('append 2') + }] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 1, 'version should bump per append'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: true, + outputId: 'append1', + items: [{ + mime: 'application/vnd.code.notebook.stdout', data: valueBytesFromString('append 3') + }] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 2, 'version should bump per append'); + + assert.strictEqual(textModel.cells.length, 1); + assert.strictEqual(textModel.cells[0].outputs.length, 1, 'has 1 output'); + assert.strictEqual(output.outputId, 'append1'); + assert.strictEqual(output.outputs.length, 1, 'outputs are compressed'); + assert.strictEqual(output.outputs[0].data.toString(), 'append 1append 2append 3'); + } + ); + }); + test('metadata', async function () { await withTestNotebook( [ From 79c495444e2e689594da40642730a85ee46dfa05 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 10 Jul 2023 10:48:20 -0700 Subject: [PATCH 0030/1180] track output buffer lengths per version --- .../model/notebookCellOutputTextModel.ts | 27 ++++ .../contrib/notebook/common/notebookCommon.ts | 1 + .../test/browser/notebookTextModel.test.ts | 133 ++++++++++++++++-- 3 files changed, 152 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts index 3c9e16931fdb2..7b989ef0076c9 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { ICellOutput, IOutputDto, IOutputItemDto, compressOutputItemStreams, isTextStreamMime } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -37,6 +38,7 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp } replaceData(rawData: IOutputDto) { + this.versionedBufferLengths = {}; this._rawOutput = rawData; this.optimizeOutputItems(); this._versionId = this._versionId + 1; @@ -44,12 +46,37 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp } appendData(items: IOutputItemDto[]) { + this.trackBufferLengths(); this._rawOutput.outputs.push(...items); this.optimizeOutputItems(); this._versionId = this._versionId + 1; this._onDidChangeData.fire(); } + private trackBufferLengths() { + this.outputs.forEach(output => { + if (isTextStreamMime(output.mime)) { + if (!this.versionedBufferLengths[output.mime]) { + this.versionedBufferLengths[output.mime] = {}; + } + this.versionedBufferLengths[output.mime][this.versionId] = output.data.byteLength; + } + }); + } + + // mime: versionId: buffer length + private versionedBufferLengths: Record> = {}; + + appendedSinceVersion(versionId: number, mime: string): VSBuffer | undefined { + const bufferLength = this.versionedBufferLengths[mime]?.[versionId]; + const output = this.outputs.find(output => output.mime === mime); + if (bufferLength && output) { + return output.data.slice(bufferLength); + } + + return undefined; + } + private optimizeOutputItems() { if (this.outputs.length > 1 && this.outputs.every(item => isTextStreamMime(item.mime))) { // Look for the mimes in the items, and keep track of their order. diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 558f6c047655d..c2c0e5a9f08da 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -217,6 +217,7 @@ export interface ICellOutput { onDidChangeData: Event; replaceData(items: IOutputDto): void; appendData(items: IOutputItemDto[]): void; + appendedSinceVersion(versionId: number, mime: string): VSBuffer | undefined; } export interface CellInternalMetadataChangedEvent { diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts index 362619bf1b750..a0759f0043d0e 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts @@ -311,6 +311,9 @@ suite('NotebookTextModel', () => { ); }); + const stdOutMime = 'application/vnd.code.notebook.stdout'; + const stdErrMime = 'application/vnd.code.notebook.stderr'; + test('appending streaming outputs', async function () { await withTestNotebook( [ @@ -326,20 +329,21 @@ suite('NotebookTextModel', () => { append: true, outputs: [{ outputId: 'append1', - outputs: [{ mime: 'application/vnd.code.notebook.stdout', data: valueBytesFromString('append 1') }] + outputs: [{ mime: stdOutMime, data: valueBytesFromString('append 1') }] }] }], true, undefined, () => undefined, undefined, true); const [output] = textModel.cells[0].outputs; - assert.strictEqual(output.versionId, 0, 'initial output version is 0'); + assert.strictEqual(output.versionId, 0, 'initial output version should be 0'); textModel.applyEdits([ { editType: CellEditType.OutputItems, append: true, outputId: 'append1', - items: [{ - mime: 'application/vnd.code.notebook.stdout', data: valueBytesFromString('append 2') - }] + items: [ + { mime: stdOutMime, data: valueBytesFromString('append 2') }, + { mime: stdOutMime, data: valueBytesFromString('append 3') } + ] }], true, undefined, () => undefined, undefined, true); assert.strictEqual(output.versionId, 1, 'version should bump per append'); @@ -348,9 +352,10 @@ suite('NotebookTextModel', () => { editType: CellEditType.OutputItems, append: true, outputId: 'append1', - items: [{ - mime: 'application/vnd.code.notebook.stdout', data: valueBytesFromString('append 3') - }] + items: [ + { mime: stdOutMime, data: valueBytesFromString('append 4') }, + { mime: stdOutMime, data: valueBytesFromString('append 5') } + ] }], true, undefined, () => undefined, undefined, true); assert.strictEqual(output.versionId, 2, 'version should bump per append'); @@ -358,7 +363,117 @@ suite('NotebookTextModel', () => { assert.strictEqual(textModel.cells[0].outputs.length, 1, 'has 1 output'); assert.strictEqual(output.outputId, 'append1'); assert.strictEqual(output.outputs.length, 1, 'outputs are compressed'); - assert.strictEqual(output.outputs[0].data.toString(), 'append 1append 2append 3'); + assert.strictEqual(output.outputs[0].data.toString(), 'append 1append 2append 3append 4append 5'); + assert.strictEqual(output.appendedSinceVersion(0, stdOutMime)?.toString(), 'append 2append 3append 4append 5'); + assert.strictEqual(output.appendedSinceVersion(1, stdOutMime)?.toString(), 'append 4append 5'); + assert.strictEqual(output.appendedSinceVersion(2, stdOutMime), undefined); + assert.strictEqual(output.appendedSinceVersion(2, stdErrMime), undefined); + } + ); + }); + + test('replacing streaming outputs', async function () { + await withTestNotebook( + [ + ['var a = 1;', 'javascript', CellKind.Code, [], {}], + ], + (editor) => { + const textModel = editor.textModel; + + textModel.applyEdits([ + { + index: 0, + editType: CellEditType.Output, + append: true, + outputs: [{ + outputId: 'append1', + outputs: [{ mime: stdOutMime, data: valueBytesFromString('append 1') }] + }] + }], true, undefined, () => undefined, undefined, true); + const [output] = textModel.cells[0].outputs; + assert.strictEqual(output.versionId, 0, 'initial output version should be 0'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: true, + outputId: 'append1', + items: [{ + mime: stdOutMime, data: valueBytesFromString('append 2') + }] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 1, 'version should bump per append'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: false, + outputId: 'append1', + items: [{ + mime: stdOutMime, data: valueBytesFromString('replace 3') + }] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 2, 'version should bump per replace'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: true, + outputId: 'append1', + items: [{ + mime: stdOutMime, data: valueBytesFromString('append 4') + }] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 3, 'version should bump per append'); + + assert.strictEqual(output.outputs[0].data.toString(), 'replace 3append 4'); + assert.strictEqual(output.appendedSinceVersion(0, stdOutMime), undefined, + 'replacing output should clear out previous versioned output buffers'); + assert.strictEqual(output.appendedSinceVersion(1, stdOutMime), undefined, + 'replacing output should clear out previous versioned output buffers'); + assert.strictEqual(output.appendedSinceVersion(2, stdOutMime)?.toString(), 'append 4'); + } + ); + }); + + test('appending multiple different mime streaming outputs', async function () { + await withTestNotebook( + [ + ['var a = 1;', 'javascript', CellKind.Code, [], {}], + ], + (editor) => { + const textModel = editor.textModel; + + textModel.applyEdits([ + { + index: 0, + editType: CellEditType.Output, + append: true, + outputs: [{ + outputId: 'append1', + outputs: [ + { mime: stdOutMime, data: valueBytesFromString('stdout 1') }, + { mime: stdErrMime, data: valueBytesFromString('stderr 1') } + ] + }] + }], true, undefined, () => undefined, undefined, true); + const [output] = textModel.cells[0].outputs; + assert.strictEqual(output.versionId, 0, 'initial output version should be 0'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: true, + outputId: 'append1', + items: [ + { mime: stdOutMime, data: valueBytesFromString('stdout 2') }, + { mime: stdErrMime, data: valueBytesFromString('stderr 2') } + ] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 1, 'version should bump per replace'); + + assert.strictEqual(output.appendedSinceVersion(0, stdErrMime)?.toString(), 'stderr 2'); + assert.strictEqual(output.appendedSinceVersion(0, stdOutMime)?.toString(), 'stdout 2'); } ); }); From 0edc352ebc037c0bd179aa2ef48decbcfd472fdb Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 10 Jul 2023 11:16:53 -0700 Subject: [PATCH 0031/1180] test for ouput compression --- .../model/notebookCellOutputTextModel.ts | 8 +++- .../contrib/notebook/common/notebookCommon.ts | 14 ++++-- .../test/browser/notebookTextModel.test.ts | 44 ++++++++++++++++++- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts index 7b989ef0076c9..74ed0aaf1583a 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts @@ -96,11 +96,15 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp }); this.outputs.length = 0; mimeTypes.forEach(mime => { - const compressed = compressOutputItemStreams(mimeOutputs.get(mime)!); + const compressionResult = compressOutputItemStreams(mimeOutputs.get(mime)!); this.outputs.push({ mime, - data: compressed + data: compressionResult.data }); + if (compressionResult.didCompression) { + // we can't rely on knowing buffer lengths if we've erased previous lines + this.versionedBufferLengths = {}; + } }); } } diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index c2c0e5a9f08da..d031650968a14 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -996,6 +996,7 @@ const textDecoder = new TextDecoder(); * Given a stream of individual stdout outputs, this function will return the compressed lines, escaping some of the common terminal escape codes. * E.g. some terminal escape codes would result in the previous line getting cleared, such if we had 3 lines and * last line contained such a code, then the result string would be just the first two lines. + * @returns a single VSBuffer with the concatenated and compressed data, and whether any compression was done. */ export function compressOutputItemStreams(outputs: Uint8Array[]) { const buffers: Uint8Array[] = []; @@ -1008,13 +1009,17 @@ export function compressOutputItemStreams(outputs: Uint8Array[]) { startAppending = true; } } - compressStreamBuffer(buffers); - return formatStreamText(VSBuffer.concat(buffers.map(buffer => VSBuffer.wrap(buffer)))); + + const didCompression = compressStreamBuffer(buffers); + const data = formatStreamText(VSBuffer.concat(buffers.map(buffer => VSBuffer.wrap(buffer)))); + return { data, didCompression }; } -const MOVE_CURSOR_1_LINE_COMMAND = `${String.fromCharCode(27)}[A`; + +export const MOVE_CURSOR_1_LINE_COMMAND = `${String.fromCharCode(27)}[A`; const MOVE_CURSOR_1_LINE_COMMAND_BYTES = MOVE_CURSOR_1_LINE_COMMAND.split('').map(c => c.charCodeAt(0)); const LINE_FEED = 10; function compressStreamBuffer(streams: Uint8Array[]) { + let didCompress = false; streams.forEach((stream, index) => { if (index === 0 || stream.length < MOVE_CURSOR_1_LINE_COMMAND.length) { return; @@ -1029,10 +1034,13 @@ function compressStreamBuffer(streams: Uint8Array[]) { if (lastIndexOfLineFeed === -1) { return; } + + didCompress = true; streams[index - 1] = previousStream.subarray(0, lastIndexOfLineFeed); streams[index] = stream.subarray(MOVE_CURSOR_1_LINE_COMMAND.length); } }); + return didCompress; } diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts index a0759f0043d0e..c2cce9c8e78b3 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts @@ -11,7 +11,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { CellEditType, CellKind, ICellEditOperation, NotebookTextModelChangedEvent, NotebookTextModelWillAddRemoveEvent, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, ICellEditOperation, MOVE_CURSOR_1_LINE_COMMAND, NotebookTextModelChangedEvent, NotebookTextModelWillAddRemoveEvent, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { setupInstantiationService, TestCell, valueBytesFromString, withTestNotebook } from 'vs/workbench/contrib/notebook/test/browser/testNotebookEditor'; suite('NotebookTextModel', () => { @@ -436,6 +436,48 @@ suite('NotebookTextModel', () => { ); }); + test('appending streaming outputs with compression', async function () { + + await withTestNotebook( + [ + ['var a = 1;', 'javascript', CellKind.Code, [], {}], + ], + (editor) => { + const textModel = editor.textModel; + + textModel.applyEdits([ + { + index: 0, + editType: CellEditType.Output, + append: true, + outputs: [{ + outputId: 'append1', + outputs: [ + { mime: stdOutMime, data: valueBytesFromString('append 1') }, + { mime: stdOutMime, data: valueBytesFromString('\nappend 1') }] + }] + }], true, undefined, () => undefined, undefined, true); + const [output] = textModel.cells[0].outputs; + assert.strictEqual(output.versionId, 0, 'initial output version should be 0'); + + textModel.applyEdits([ + { + editType: CellEditType.OutputItems, + append: true, + outputId: 'append1', + items: [{ + mime: stdOutMime, data: valueBytesFromString(MOVE_CURSOR_1_LINE_COMMAND + '\nappend 2') + }] + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(output.versionId, 1, 'version should bump per append'); + + assert.strictEqual(output.outputs[0].data.toString(), 'append 1\nappend 2'); + assert.strictEqual(output.appendedSinceVersion(0, stdOutMime), undefined, + 'compressing outputs should clear out previous versioned output buffers'); + } + ); + }); + test('appending multiple different mime streaming outputs', async function () { await withTestNotebook( [ From c5511d5eec85db570ca81384aed9d4556a1c74e6 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 10 Jul 2023 14:22:07 -0700 Subject: [PATCH 0032/1180] pipe appended data info to webview --- extensions/notebook-renderers/src/index.ts | 13 ++++++++++++- .../api/common/extHostNotebookDocument.ts | 2 +- .../browser/view/renderers/backLayerWebView.ts | 3 +++ .../browser/view/renderers/webviewMessages.ts | 9 ++++++++- .../browser/view/renderers/webviewPreloads.ts | 16 +++++++++++++--- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index df67435363384..0450aa54f10a4 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -265,12 +265,20 @@ function scrollingEnabled(output: OutputItem, options: RenderOptions) { metadata.scrollable : options.outputScrolling; } +interface OutputWithAppend extends OutputItem { + appendedText?(): string | undefined; +} + // div.cell_container // div.output_container // div.output.output-stream <-- outputElement parameter // div.scrollable? tabindex="0" <-- contentParent // div output-item-id="{guid}" <-- content from outputItem parameter -function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { +function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { + const appendedText = outputInfo.appendedText?.(); + if (appendedText) { + console.log(`appending output version ${appendedText}`); + } const disposableStore = createDisposableStore(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); @@ -301,6 +309,9 @@ function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: const existingContent = outputElement.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; let contentParent = existingContent?.parentElement; if (existingContent && contentParent) { + if (appendedText){ + existingContent + } existingContent.replaceWith(newContent); while (newContent.nextSibling) { // clear out any stale content if we had previously combined streaming outputs into this one diff --git a/src/vs/workbench/api/common/extHostNotebookDocument.ts b/src/vs/workbench/api/common/extHostNotebookDocument.ts index 6f48147c9e44c..e8970f70dee6f 100644 --- a/src/vs/workbench/api/common/extHostNotebookDocument.ts +++ b/src/vs/workbench/api/common/extHostNotebookDocument.ts @@ -132,7 +132,7 @@ export class ExtHostCell { const compressed = notebookCommon.compressOutputItemStreams(mimeOutputs.get(mime)!); output.items.push({ mime, - data: compressed.buffer + data: compressed.data.buffer }); }); } 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 0fdc7c3c6120d..4e3b2573ec390 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1506,6 +1506,8 @@ export class BackLayerWebView extends Themable { if (content.type === RenderOutputType.Extension) { const output = content.source.model; const firstBuffer = output.outputs.find(op => op.mime === content.mimeType)!; + const appenededData = output.appendedSinceVersion(outputCache.versionId, content.mimeType); + const appended = appenededData ? { valueBytes: appenededData.buffer, previousVersion: outputCache.versionId } : undefined; const valueBytes = copyBufferIfNeeded(firstBuffer.data.buffer, transfer); updatedContent = { @@ -1515,6 +1517,7 @@ export class BackLayerWebView extends Themable { output: { mime: content.mimeType, valueBytes, + appended: appended }, allOutputs: output.outputs.map(output => ({ mime: output.mime })) }; 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 15fc1f19790be..1927f9497dc1a 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -188,11 +188,18 @@ export interface IOutputRequestDto { export interface OutputItemEntry { readonly mime: string; readonly valueBytes: Uint8Array; + readonly appended?: { valueBytes: Uint8Array; previousVersion: number }; } export type ICreationContent = | { readonly type: RenderOutputType.Html; readonly htmlContent: string } - | { readonly type: RenderOutputType.Extension; readonly outputId: string; readonly metadata: unknown; readonly output: OutputItemEntry; readonly allOutputs: ReadonlyArray<{ readonly mime: string }> }; + | { + readonly type: RenderOutputType.Extension; + readonly outputId: string; + readonly metadata: unknown; + readonly output: OutputItemEntry; + readonly allOutputs: ReadonlyArray<{ readonly mime: string }>; + }; export interface ICreationRequestMessage { readonly type: 'html'; 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 25dab44de718b..190980671a026 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -804,6 +804,7 @@ async function webviewPreloads(ctx: PreloadContext) { interface ExtendedOutputItem extends rendererApi.OutputItem { readonly _allOutputItems: ReadonlyArray; + appendedText?(): string | undefined; } let hasWarnedAboutAllOutputItemsProposal = false; @@ -813,7 +814,8 @@ async function webviewPreloads(ctx: PreloadContext) { mime: string, metadata: unknown, valueBytes: Uint8Array, - allOutputItemData: ReadonlyArray<{ readonly mime: string }> + allOutputItemData: ReadonlyArray<{ readonly mime: string }>, + appended?: { valueBytes: Uint8Array; previousVersion: number } ): ExtendedOutputItem { function create( @@ -821,12 +823,20 @@ async function webviewPreloads(ctx: PreloadContext) { mime: string, metadata: unknown, valueBytes: Uint8Array, + appended?: { valueBytes: Uint8Array; previousVersion: number } ): ExtendedOutputItem { return Object.freeze({ id, mime, metadata, + appendedText(): string | undefined { + if (appended) { + return textDecoder.decode(appended.valueBytes); + } + return undefined; + }, + data(): Uint8Array { return valueBytes; }, @@ -874,7 +884,7 @@ async function webviewPreloads(ctx: PreloadContext) { }); })); - const item = create(id, mime, metadata, valueBytes); + const item = create(id, mime, metadata, valueBytes, appended); allOutputItemCache.set(mime, Promise.resolve(item)); return item; } @@ -2542,7 +2552,7 @@ async function webviewPreloads(ctx: PreloadContext) { const errors = preloadErrors.filter((e): e is Error => e instanceof Error); showRenderError(`Error loading preloads`, this.element, errors); } else { - const item = createOutputItem(this.outputId, content.output.mime, content.metadata, content.output.valueBytes, content.allOutputs); + const item = createOutputItem(this.outputId, content.output.mime, content.metadata, content.output.valueBytes, content.allOutputs, content.output.appended); const controller = new AbortController(); this.renderTaskAbort = controller; From e1becd2eb899b7da53bc7c8d0a6bdf12587a69ba Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 12:49:48 +0200 Subject: [PATCH 0033/1180] cleaning the code, it works now --- .../lib/stylelint/vscode-known-variables.json | 2 ++ src/vs/base/browser/ui/hover/hover.css | 3 +- .../contrib/hover/browser/contentHover.ts | 30 +++++++++++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index 67ec595ed30d8..7ff08b74263de 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -306,6 +306,8 @@ "--vscode-extensionIcon-verifiedForeground", "--vscode-focusBorder", "--vscode-foreground", + "--vscode-hover-whiteSpace", + "--vscode-hoverSource-whiteSpace", "--vscode-icon-foreground", "--vscode-inlineChat-background", "--vscode-inlineChat-border", diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 0ce581993549b..68907c6a0626f 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -12,6 +12,7 @@ box-sizing: border-box; animation: fadein 100ms linear; line-height: 1.5em; + white-space: var(--vscode-hover-whiteSpace); } .monaco-hover.hidden { @@ -105,7 +106,7 @@ } .monaco-hover .monaco-tokenized-source { - white-space: pre-wrap; + white-space: var(--vscode-hoverSource-whiteSpace); } .monaco-hover .hover-row.status-bar { diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e284a83811646..885b1f41c7d91 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -459,6 +459,7 @@ export class ContentHoverWidget extends ResizableContentWidget { private _visibleData: ContentHoverVisibleData | undefined; private _positionPreference: ContentWidgetPositionPreference | undefined; + private _initialWidth: number | undefined; private readonly _hover: HoverWidget = this._register(new HoverWidget()); private readonly _hoverVisibleKey: IContextKey; @@ -612,13 +613,29 @@ export class ContentHoverWidget extends ResizableContentWidget { return Math.min(availableSpace, maximumHeight); } + private _isHoverTextOverflowing(): boolean { + let overflowing = false; + Array.from(this._hover.contentsDomNode.children).forEach((hoverPart) => { + overflowing = overflowing || hoverPart.scrollWidth > hoverPart.clientWidth; + }); + return overflowing; + } + private _findMaximumRenderingWidth(): number | undefined { if (!this._editor || !this._editor.hasModel()) { return; } - const bodyBoxWidth = dom.getClientArea(document.body).width; - const horizontalPadding = 14; - return bodyBoxWidth - horizontalPadding; + this._setWhiteSpaceProperties('nowrap', 'nowrap'); + const overflowing = this._isHoverTextOverflowing(); + this._setWhiteSpaceProperties('normal', 'pre-wrap'); + + if (overflowing || this._initialWidth && this._hover.containerDomNode.clientWidth < this._initialWidth) { + const bodyBoxWidth = dom.getClientArea(document.body).width; + const horizontalPadding = 14; + return bodyBoxWidth - horizontalPadding; + } else { + return this._hover.containerDomNode.clientWidth + 2; + } } public isMouseGettingCloser(posx: number, posy: number): boolean { @@ -707,10 +724,16 @@ export class ContentHoverWidget extends ResizableContentWidget { }; } + private _setWhiteSpaceProperties(hoverWhiteSpace: 'normal' | 'nowrap', hoverSourceWhiteSpace: 'pre-wrap' | 'nowrap') { + this._hover.containerDomNode.style.setProperty('--vscode-hover-whiteSpace', hoverWhiteSpace); + this._hover.containerDomNode.style.setProperty('--vscode-hoverSource-whiteSpace', hoverSourceWhiteSpace); + } + public showAt(node: DocumentFragment, hoverData: ContentHoverVisibleData): void { if (!this._editor || !this._editor.hasModel()) { return; } + this._setWhiteSpaceProperties('normal', 'pre-wrap'); this._render(node, hoverData); const widgetHeight = dom.getTotalHeight(this._hover.containerDomNode); const widgetPosition = hoverData.showAtPosition; @@ -774,6 +797,7 @@ export class ContentHoverWidget extends ResizableContentWidget { this._adjustHoverHeightForScrollbar(height); } this._layoutContentWidget(); + this._initialWidth = this._hover.containerDomNode.clientWidth; } public focus(): void { From 2fce05e8b33083d2067727e15490655a6998b53a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 15:08:25 +0200 Subject: [PATCH 0034/1180] initial code --- .../inlineChat/browser/inlineChatActions.ts | 6 ++--- .../browser/inlineChatStrategies.ts | 22 ++++++++++++++----- .../inlineChat/browser/inlineChatWidget.ts | 19 +++++++++++++--- .../contrib/inlineChat/common/inlineChat.ts | 12 ++++++++++ 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index b5cf33298e695..6772dcbaef729 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -10,7 +10,7 @@ import { EditorAction2 } from 'vs/editor/browser/editorExtensions'; import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { InlineChatController, InlineChatRunOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; -import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_LAST_FEEDBACK, CTX_INLINE_CHAT_SHOWING_DIFF, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, InlineChatResponseType, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChateResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_LAST_FEEDBACK, CTX_INLINE_CHAT_SHOWING_DIFF, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, InlineChatResponseType, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChateResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT, MENU_INLINE_CHAT_WIDGET_TOGGLE } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { localize } from 'vs/nls'; import { IAction2Options, MenuRegistry } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -452,10 +452,10 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { id: 'inlineChat.toggleDiff', title: localize('toggleDiff', 'Toggle Diff'), icon: Codicon.diff, - precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_DID_EDIT), + precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE), toggled: { condition: CTX_INLINE_CHAT_SHOWING_DIFF, title: localize('toggleDiff2', "Show Inline Diff") }, menu: { - id: MENU_INLINE_CHAT_WIDGET_DISCARD, + id: MENU_INLINE_CHAT_WIDGET_TOGGLE, when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview), group: '1_config', order: 9 diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index 36e64ebf09af5..31351a13c3d2c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -5,7 +5,7 @@ import { Event } from 'vs/base/common/event'; import { Lazy } from 'vs/base/common/lazy'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { StableEditorScrollState } from 'vs/editor/browser/stableEditorScroll'; @@ -17,9 +17,10 @@ import { IEditorDecorationsCollection } from 'vs/editor/common/editorCommon'; import { ICursorStateComputer, IModelDecorationOptions, IModelDeltaDecoration, ITextModel, IValidEditOperation } from 'vs/editor/common/model'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; import { localize } from 'vs/nls'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { InlineChatFileCreatePreviewWidget, InlineChatLivePreviewWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget'; import { EditResponse, Session } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession'; import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatWidget'; @@ -222,11 +223,12 @@ class InlineDiffDecorations { export class LiveStrategy extends EditModeStrategy { - private static _inlineDiffStorageKey: string = 'interactiveEditor.storage.inlineDiff'; protected _diffEnabled: boolean = false; private readonly _inlineDiffDecorations: InlineDiffDecorations; private readonly _ctxShowingDiff: IContextKey; + private readonly _store: DisposableStore = new DisposableStore(); + private _lastResponse?: EditResponse; private _editCount: number = 0; @@ -235,29 +237,36 @@ export class LiveStrategy extends EditModeStrategy { protected readonly _editor: ICodeEditor, protected readonly _widget: InlineChatWidget, @IContextKeyService contextKeyService: IContextKeyService, + @IConfigurationService configService: IConfigurationService, @IStorageService protected _storageService: IStorageService, @IBulkEditService protected readonly _bulkEditService: IBulkEditService, @IEditorWorkerService protected readonly _editorWorkerService: IEditorWorkerService, @IInstantiationService private readonly _instaService: IInstantiationService, ) { super(); - this._diffEnabled = _storageService.getBoolean(LiveStrategy._inlineDiffStorageKey, StorageScope.PROFILE, true); + this._diffEnabled = configService.getValue('inlineChat.showDiff'); this._inlineDiffDecorations = new InlineDiffDecorations(this._editor, this._diffEnabled); this._ctxShowingDiff = CTX_INLINE_CHAT_SHOWING_DIFF.bindTo(contextKeyService); this._ctxShowingDiff.set(this._diffEnabled); this._inlineDiffDecorations.visible = this._diffEnabled; + + this._store.add(configService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('inlineChat.showDiff')) { + this.toggleDiff(); + } + })); } override dispose(): void { this._inlineDiffDecorations.clear(); this._ctxShowingDiff.reset(); + this._store.dispose(); } toggleDiff(): void { this._diffEnabled = !this._diffEnabled; this._ctxShowingDiff.set(this._diffEnabled); - this._storageService.store(LiveStrategy._inlineDiffStorageKey, this._diffEnabled, StorageScope.PROFILE, StorageTarget.USER); this._doToggleDiff(); } @@ -384,12 +393,13 @@ export class LivePreviewStrategy extends LiveStrategy { editor: ICodeEditor, widget: InlineChatWidget, @IContextKeyService contextKeyService: IContextKeyService, + @IConfigurationService configService: IConfigurationService, @IStorageService storageService: IStorageService, @IBulkEditService bulkEditService: IBulkEditService, @IEditorWorkerService editorWorkerService: IEditorWorkerService, @IInstantiationService instaService: IInstantiationService, ) { - super(session, editor, widget, contextKeyService, storageService, bulkEditService, editorWorkerService, instaService); + super(session, editor, widget, contextKeyService, configService, storageService, bulkEditService, editorWorkerService, instaService); this._diffZone = new Lazy(() => instaService.createInstance(InlineChatLivePreviewWidget, editor, session)); this._previewZone = new Lazy(() => instaService.createInstance(InlineChatFileCreatePreviewWidget, editor)); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index adb0b77635e8f..3218470917dc4 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -12,9 +12,9 @@ import { localize } from 'vs/nls'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget'; -import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_STATUS, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, IInlineChatSlashCommand, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_STATUS, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, IInlineChatSlashCommand, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, MENU_INLINE_CHAT_WIDGET_TOGGLE } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; -import { Dimension, addDisposableListener, getActiveElement, getTotalHeight, getTotalWidth, h, reset } from 'vs/base/browser/dom'; +import { EventType, Dimension, addDisposableListener, getActiveElement, getTotalHeight, getTotalWidth, h, reset } from 'vs/base/browser/dom'; import { Emitter, Event, MicrotaskEmitter } from 'vs/base/common/event'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; @@ -49,6 +49,7 @@ import { ExpansionState } from 'vs/workbench/contrib/inlineChat/browser/inlineCh import { IdleValue } from 'vs/base/common/async'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IMenuWorkbenchButtonBarOptions, MenuWorkbenchButtonBar } from 'vs/platform/actions/browser/buttonbar'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; const defaultAriaLabel = localize('aria-label', "Inline Chat Input"); @@ -189,7 +190,8 @@ export class InlineChatWidget { @IKeybindingService private readonly _keybindingService: IKeybindingService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IAccessibilityService private readonly _accessibilityService: IAccessibilityService, - @IConfigurationService private readonly _configurationService: IConfigurationService + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IContextMenuService private readonly _contextMenuService: IContextMenuService, ) { // input editor logic @@ -328,6 +330,17 @@ export class InlineChatWidget { const markdownMessageToolbar = this._instantiationService.createInstance(MenuWorkbenchToolBar, this._elements.messageActions, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, workbenchToolbarOptions); this._store.add(markdownMessageToolbar.onDidChangeMenuItems(() => this._onDidChangeHeight.fire())); this._store.add(markdownMessageToolbar); + + this._store.add(addDisposableListener(this._elements.root, EventType.CONTEXT_MENU, async (event: MouseEvent) => { + this.onContextMenu(event); + })); + } + + private onContextMenu(event: MouseEvent) { + this._contextMenuService.showContextMenu({ + menuId: MENU_INLINE_CHAT_WIDGET_TOGGLE, + getAnchor: () => event, + }); } private _updateAriaLabel(): void { diff --git a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts index e8bbb5cb9408a..2c7d8c4a708d0 100644 --- a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts +++ b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts @@ -140,6 +140,7 @@ export const MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE = MenuId.for('inlineChatWi export const MENU_INLINE_CHAT_WIDGET_STATUS = MenuId.for('inlineChatWidget.status'); export const MENU_INLINE_CHAT_WIDGET_FEEDBACK = MenuId.for('inlineChatWidget.feedback'); export const MENU_INLINE_CHAT_WIDGET_DISCARD = MenuId.for('inlineChatWidget.undo'); +export const MENU_INLINE_CHAT_WIDGET_TOGGLE = MenuId.for('inlineChatWidget.toggle'); // --- colors @@ -188,3 +189,14 @@ Registry.as(Extensions.Configuration).registerConfigurat } } }); + +Registry.as(Extensions.Configuration).registerConfiguration({ + id: 'editor', + properties: { + 'inlineChat.showDiff': { + description: localize('showDiff', "Enable/disable showing the diff when edits are generated."), + default: true, + type: 'boolean' + } + } +}); From 101c247b5bb061d9274509745175b5cd5a2bb840 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 15:12:37 +0200 Subject: [PATCH 0035/1180] commiting in order to retrigger the checks on github --- src/vs/editor/contrib/hover/browser/contentHover.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 885b1f41c7d91..12c126e30bd13 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -604,8 +604,8 @@ export class ContentHoverWidget extends ResizableContentWidget { } // Padding needed in order to stop the resizing down to a smaller height let maximumHeight = CONTAINER_HEIGHT_PADDING; - Array.from(this._hover.contentsDomNode.children).forEach((hoverPart) => { - maximumHeight += hoverPart.clientHeight; + Array.from(this._hover.contentsDomNode.children).forEach((hoverElement) => { + maximumHeight += hoverElement.clientHeight; }); if (this._hasHorizontalScrollbar()) { maximumHeight += SCROLLBAR_WIDTH; @@ -615,8 +615,8 @@ export class ContentHoverWidget extends ResizableContentWidget { private _isHoverTextOverflowing(): boolean { let overflowing = false; - Array.from(this._hover.contentsDomNode.children).forEach((hoverPart) => { - overflowing = overflowing || hoverPart.scrollWidth > hoverPart.clientWidth; + Array.from(this._hover.contentsDomNode.children).forEach((hoverElement) => { + overflowing = overflowing || hoverElement.scrollWidth > hoverElement.clientWidth; }); return overflowing; } From d405515685c70de946cdcdcfac4fc90a99965b3a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 15:27:45 +0200 Subject: [PATCH 0036/1180] instead of using the toggle diff method, we update directly the value in the settings --- .../inlineChat/browser/inlineChatActions.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 6772dcbaef729..62a20bff378f2 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -30,6 +30,8 @@ import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/brow import { Disposable } from 'vs/base/common/lifecycle'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { Position } from 'vs/editor/common/core/position'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { Categories } from 'vs/platform/action/common/actionCommonCategories'; CommandsRegistry.registerCommandAlias('interactiveEditor.start', 'inlineChat.start'); @@ -453,18 +455,22 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { title: localize('toggleDiff', 'Toggle Diff'), icon: Codicon.diff, precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE), - toggled: { condition: CTX_INLINE_CHAT_SHOWING_DIFF, title: localize('toggleDiff2', "Show Inline Diff") }, + category: Categories.View, + toggled: { + condition: CTX_INLINE_CHAT_SHOWING_DIFF, + title: localize('toggleDiff2', "Show Inline Diff") + }, menu: { id: MENU_INLINE_CHAT_WIDGET_TOGGLE, - when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview), - group: '1_config', - order: 9 + when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview) } }); } - override runInlineChatCommand(_accessor: ServicesAccessor, ctrl: InlineChatController): void { - ctrl.toggleDiff(); + override runInlineChatCommand(accessor: ServicesAccessor, _ctrl: InlineChatController): void { + const configurationService = accessor.get(IConfigurationService); + const newValue = !configurationService.getValue('inlineChat.showDiff'); + configurationService.updateValue('inlineChat.showDiff', newValue); } } From 55cabc414bef2d0fa0611c2a43bccbd9a7790746 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 15:31:08 +0200 Subject: [PATCH 0037/1180] no longer need some of the toggle diff methods --- .../inlineChat/browser/inlineChatController.ts | 4 ---- .../inlineChat/browser/inlineChatStrategies.ts | 16 +++------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index d24cbbe0ab89a..a8b0056076813 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -713,10 +713,6 @@ export class InlineChatController implements IEditorContribution { } } - toggleDiff(): void { - this._strategy?.toggleDiff(); - } - focus(): void { this._zone.value.widget.focus(); } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index 31351a13c3d2c..c005e7d08b38b 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -43,8 +43,6 @@ export abstract class EditModeStrategy { abstract renderChanges(response: EditResponse): Promise; - abstract toggleDiff(): void; - abstract hasFocus(): boolean; abstract getWidgetPosition(): Position | undefined; @@ -137,10 +135,6 @@ export class PreviewStrategy extends EditModeStrategy { } } - toggleDiff(): void { - // nothing to do - } - getWidgetPosition(): Position | undefined { return; } @@ -253,7 +247,9 @@ export class LiveStrategy extends EditModeStrategy { this._store.add(configService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('inlineChat.showDiff')) { - this.toggleDiff(); + this._diffEnabled = !this._diffEnabled; + this._ctxShowingDiff.set(this._diffEnabled); + this._doToggleDiff(); } })); } @@ -264,12 +260,6 @@ export class LiveStrategy extends EditModeStrategy { this._store.dispose(); } - toggleDiff(): void { - this._diffEnabled = !this._diffEnabled; - this._ctxShowingDiff.set(this._diffEnabled); - this._doToggleDiff(); - } - protected _doToggleDiff(): void { this._inlineDiffDecorations.visible = this._diffEnabled; } From 5862acd27af7d5ee138403c463410a04f900e1f3 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 15:51:29 +0200 Subject: [PATCH 0038/1180] looks like now the toggling works as expected --- .../inlineChat/browser/inlineChatActions.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 62a20bff378f2..150b7980f3a8d 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -12,7 +12,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { InlineChatController, InlineChatRunOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_LAST_FEEDBACK, CTX_INLINE_CHAT_SHOWING_DIFF, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, InlineChatResponseType, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChateResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT, MENU_INLINE_CHAT_WIDGET_TOGGLE } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { localize } from 'vs/nls'; -import { IAction2Options, MenuRegistry } from 'vs/platform/actions/common/actions'; +import { IAction2Options, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -452,18 +452,21 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { constructor() { super({ id: 'inlineChat.toggleDiff', - title: localize('toggleDiff', 'Toggle Diff'), - icon: Codicon.diff, - precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE), + title: { + value: localize('toggleDiff', 'Toggle Diff'), + mnemonicTitle: localize({ key: 'miToggleDiff', comment: ['&& denotes a mnemonic'] }, "&&Toggle Diff"), + original: 'Toggle Diff', + }, category: Categories.View, toggled: { - condition: CTX_INLINE_CHAT_SHOWING_DIFF, - title: localize('toggleDiff2', "Show Inline Diff") + condition: ContextKeyExpr.equals('config.inlineChat.showDiff', true), + title: localize('toggleDiff2', "Toggle Diff"), + mnemonicTitle: localize({ key: 'miToggleDiff2', comment: ['&& denotes a mnemonic'] }, "&&Toggle Diff") }, - menu: { - id: MENU_INLINE_CHAT_WIDGET_TOGGLE, - when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview) - } + menu: [ + { id: MenuId.CommandPalette }, + { id: MENU_INLINE_CHAT_WIDGET_TOGGLE } + ] }); } @@ -471,6 +474,7 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { const configurationService = accessor.get(IConfigurationService); const newValue = !configurationService.getValue('inlineChat.showDiff'); configurationService.updateValue('inlineChat.showDiff', newValue); + console.log('newValue : ', newValue); } } From 2a65810af61cef88f0e12295e07709802b391c58 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 12 Jul 2023 16:09:07 +0200 Subject: [PATCH 0039/1180] cleaning up the code --- .../contrib/inlineChat/browser/inlineChatActions.ts | 3 +-- .../contrib/inlineChat/browser/inlineChatStrategies.ts | 7 +------ src/vs/workbench/contrib/inlineChat/common/inlineChat.ts | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 150b7980f3a8d..4db24fc6c501e 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -10,7 +10,7 @@ import { EditorAction2 } from 'vs/editor/browser/editorExtensions'; import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { InlineChatController, InlineChatRunOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; -import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_LAST_FEEDBACK, CTX_INLINE_CHAT_SHOWING_DIFF, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, InlineChatResponseType, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChateResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT, MENU_INLINE_CHAT_WIDGET_TOGGLE } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_LAST_FEEDBACK, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, InlineChatResponseType, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChateResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT, MENU_INLINE_CHAT_WIDGET_TOGGLE } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { localize } from 'vs/nls'; import { IAction2Options, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -474,7 +474,6 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { const configurationService = accessor.get(IConfigurationService); const newValue = !configurationService.getValue('inlineChat.showDiff'); configurationService.updateValue('inlineChat.showDiff', newValue); - console.log('newValue : ', newValue); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index c005e7d08b38b..341e4d497253b 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -24,7 +24,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { InlineChatFileCreatePreviewWidget, InlineChatLivePreviewWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget'; import { EditResponse, Session } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession'; import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatWidget'; -import { CTX_INLINE_CHAT_SHOWING_DIFF, CTX_INLINE_CHAT_DOCUMENT_CHANGED } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CTX_INLINE_CHAT_DOCUMENT_CHANGED } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; export abstract class EditModeStrategy { @@ -220,7 +220,6 @@ export class LiveStrategy extends EditModeStrategy { protected _diffEnabled: boolean = false; private readonly _inlineDiffDecorations: InlineDiffDecorations; - private readonly _ctxShowingDiff: IContextKey; private readonly _store: DisposableStore = new DisposableStore(); private _lastResponse?: EditResponse; @@ -241,14 +240,11 @@ export class LiveStrategy extends EditModeStrategy { this._diffEnabled = configService.getValue('inlineChat.showDiff'); this._inlineDiffDecorations = new InlineDiffDecorations(this._editor, this._diffEnabled); - this._ctxShowingDiff = CTX_INLINE_CHAT_SHOWING_DIFF.bindTo(contextKeyService); - this._ctxShowingDiff.set(this._diffEnabled); this._inlineDiffDecorations.visible = this._diffEnabled; this._store.add(configService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('inlineChat.showDiff')) { this._diffEnabled = !this._diffEnabled; - this._ctxShowingDiff.set(this._diffEnabled); this._doToggleDiff(); } })); @@ -256,7 +252,6 @@ export class LiveStrategy extends EditModeStrategy { override dispose(): void { this._inlineDiffDecorations.clear(); - this._ctxShowingDiff.reset(); this._store.dispose(); } diff --git a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts index 2c7d8c4a708d0..b9340aea96608 100644 --- a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts +++ b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts @@ -118,7 +118,6 @@ export const CTX_INLINE_CHAT_MESSAGE_CROP_STATE = new RawContextKey<'cropped' | export const CTX_INLINE_CHAT_OUTER_CURSOR_POSITION = new RawContextKey<'above' | 'below' | ''>('inlineChatOuterCursorPosition', '', localize('inlineChatOuterCursorPosition', "Whether the cursor of the outer editor is above or below the interactive editor input")); export const CTX_INLINE_CHAT_HAS_ACTIVE_REQUEST = new RawContextKey('inlineChatHasActiveRequest', false, localize('inlineChatHasActiveRequest', "Whether interactive editor has an active request")); export const CTX_INLINE_CHAT_HAS_STASHED_SESSION = new RawContextKey('inlineChatHasStashedSession', false, localize('inlineChatHasStashedSession', "Whether interactive editor has kept a session for quick restore")); -export const CTX_INLINE_CHAT_SHOWING_DIFF = new RawContextKey('inlineChatDiff', false, localize('inlineChatDiff', "Whether interactive editor show diffs for changes")); export const CTX_INLINE_CHAT_LAST_RESPONSE_TYPE = new RawContextKey('inlineChatLastResponseType', undefined, localize('inlineChatResponseType', "What type was the last response of the current interactive editor session")); export const CTX_INLINE_CHAT_RESPONSE_TYPES = new RawContextKey('inlineChatResponseTypes', undefined, localize('inlineChatResponseTypes', "What type was the responses have been receieved")); export const CTX_INLINE_CHAT_DID_EDIT = new RawContextKey('inlineChatDidEdit', undefined, localize('inlineChatDidEdit', "Whether interactive editor did change any code")); From 4c2df56f98d7e056077682326fec69d0fbfeacc0 Mon Sep 17 00:00:00 2001 From: aamunger Date: Wed, 12 Jul 2023 10:03:31 -0700 Subject: [PATCH 0040/1180] append html --- extensions/notebook-renderers/src/index.ts | 43 +++++++++++-------- .../notebook-renderers/src/textHelper.ts | 34 ++++++++++++++- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index 0450aa54f10a4..430b00301a740 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import type { ActivationFunction, OutputItem, RendererContext } from 'vscode-notebook-renderer'; -import { createOutputContent, scrollableClass } from './textHelper'; +import { appendOutput, createOutputContent, scrollableClass } from './textHelper'; import { HtmlRenderingHook, IDisposable, IRichRenderContext, JavaScriptRenderingHook, RenderOptions } from './rendererTypes'; import { ttPolicy } from './htmlHelper'; @@ -172,7 +172,7 @@ function renderError( outputElement.classList.add('traceback'); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const content = createOutputContent(outputInfo.id, [err.stack ?? ''], ctx.settings.lineLimit, outputScrolling, trustHTML); + const content = createOutputContent(outputInfo.id, err.stack ?? '', ctx.settings.lineLimit, outputScrolling, trustHTML); const contentParent = document.createElement('div'); contentParent.classList.toggle('word-wrap', ctx.settings.outputWordWrap); disposableStore.push(ctx.onDidChangeSettings(e => { @@ -276,26 +276,19 @@ interface OutputWithAppend extends OutputItem { // div output-item-id="{guid}" <-- content from outputItem parameter function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { const appendedText = outputInfo.appendedText?.(); - if (appendedText) { - console.log(`appending output version ${appendedText}`); - } const disposableStore = createDisposableStore(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); outputElement.classList.add('output-stream'); - const text = outputInfo.text(); - const newContent = createOutputContent(outputInfo.id, [text], ctx.settings.lineLimit, outputScrolling, false); - newContent.setAttribute('output-item-id', outputInfo.id); - if (error) { - newContent.classList.add('error'); - } + const scrollTop = outputScrolling ? findScrolledHeight(outputElement) : undefined; const previousOutputParent = getPreviousMatchingContentGroup(outputElement); // If the previous output item for the same cell was also a stream, append this output to the previous if (previousOutputParent) { + const newContent = createContent(outputInfo, ctx, outputScrolling, error); const existingContent = previousOutputParent.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; if (existingContent) { existingContent.replaceWith(newContent); @@ -309,15 +302,19 @@ function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, const existingContent = outputElement.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; let contentParent = existingContent?.parentElement; if (existingContent && contentParent) { - if (appendedText){ - existingContent + if (appendedText) { + appendOutput(existingContent, outputInfo.id, appendedText, ctx.settings.lineLimit, outputScrolling, false); } - existingContent.replaceWith(newContent); - while (newContent.nextSibling) { - // clear out any stale content if we had previously combined streaming outputs into this one - newContent.nextSibling.remove(); + else { + const newContent = createContent(outputInfo, ctx, outputScrolling, error); + existingContent.replaceWith(newContent); + while (newContent.nextSibling) { + // clear out any stale content if we had previously combined streaming outputs into this one + newContent.nextSibling.remove(); + } } } else { + const newContent = createContent(outputInfo, ctx, outputScrolling, error); contentParent = document.createElement('div'); contentParent.appendChild(newContent); while (outputElement.firstChild) { @@ -338,13 +335,23 @@ function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, return disposableStore; } +function createContent(outputInfo: OutputWithAppend, ctx: IRichRenderContext, outputScrolling: boolean, error: boolean) { + const text = outputInfo.text(); + const newContent = createOutputContent(outputInfo.id, text, ctx.settings.lineLimit, outputScrolling, false); + newContent.setAttribute('output-item-id', outputInfo.id); + if (error) { + newContent.classList.add('error'); + } + return newContent; +} + function renderText(outputInfo: OutputItem, outputElement: HTMLElement, ctx: IRichRenderContext): IDisposable { const disposableStore = createDisposableStore(); clearContainer(outputElement); const text = outputInfo.text(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const content = createOutputContent(outputInfo.id, [text], ctx.settings.lineLimit, outputScrolling, false); + const content = createOutputContent(outputInfo.id, text, ctx.settings.lineLimit, outputScrolling, false); content.classList.add('output-plaintext'); if (ctx.settings.outputWordWrap) { content.classList.add('word-wrap'); diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index 8cc03fd543e40..64d35eade8721 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -100,9 +100,9 @@ function scrollableArrayOfString(id: string, buffer: string[], trustHtml: boolea return element; } -export function createOutputContent(id: string, outputs: string[], linesLimit: number, scrollable: boolean, trustHtml: boolean): HTMLElement { +export function createOutputContent(id: string, outputText: string, linesLimit: number, scrollable: boolean, trustHtml: boolean): HTMLElement { - const buffer = outputs.join('\n').split(/\r\n|\r|\n/g); + const buffer = outputText.split(/\r\n|\r|\n/g); if (scrollable) { return scrollableArrayOfString(id, buffer, trustHtml); @@ -110,3 +110,33 @@ export function createOutputContent(id: string, outputs: string[], linesLimit: n return truncatedArrayOfString(id, buffer, linesLimit, trustHtml); } } + +export function appendOutput(element: HTMLElement, id: string, outputText: string, linesLimit: number, scrollable: boolean, trustHtml: boolean) { + const buffer = outputText.split(/\r\n|\r|\n/g); + let newContent: HTMLDivElement; + if (scrollable) { + newContent = scrollableArrayOfString(id, buffer, trustHtml); + element.appendChild(newContent); + // contains 1 span per line + // const innerContainer = element.childNodes[0].childNodes[0]; + // const linesToAdd = newContent.childNodes[0].childNodes[0].childNodes; + + // linesToAdd.forEach(span => { + // innerContainer.appendChild(span); + // while (innerContainer.childNodes.length > 5000) { + // innerContainer.firstChild?.remove(); + // } + // }); + } else { + newContent = truncatedArrayOfString(id, buffer, linesLimit, trustHtml); + + // contains 1 span per line + const innerContainer = element.childNodes[0].childNodes[0]; + const linesToAdd = newContent.childNodes[0].childNodes[0].childNodes; + + linesToAdd.forEach(span => { + innerContainer.appendChild(span); + + }); + } +} From 77a8acf71907a9f9dd261b394d96a58b6acfb576 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 12 Jul 2023 11:30:58 -0700 Subject: [PATCH 0041/1180] don't rerender the same output --- extensions/notebook-renderers/src/index.ts | 7 ++--- .../notebook-renderers/src/textHelper.ts | 30 ++----------------- .../view/renderers/backLayerWebView.ts | 6 ++++ 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index 430b00301a740..be59b011c12e3 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -281,8 +281,6 @@ function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, outputElement.classList.add('output-stream'); - - const scrollTop = outputScrolling ? findScrolledHeight(outputElement) : undefined; const previousOutputParent = getPreviousMatchingContentGroup(outputElement); @@ -302,8 +300,9 @@ function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, const existingContent = outputElement.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; let contentParent = existingContent?.parentElement; if (existingContent && contentParent) { - if (appendedText) { - appendOutput(existingContent, outputInfo.id, appendedText, ctx.settings.lineLimit, outputScrolling, false); + // appending output only in scrollable ouputs currently + if (appendedText && outputScrolling) { + appendOutput(existingContent, appendedText, false); } else { const newContent = createContent(outputInfo, ctx, outputScrolling, error); diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index 64d35eade8721..f335d2cfdda4e 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -111,32 +111,8 @@ export function createOutputContent(id: string, outputText: string, linesLimit: } } -export function appendOutput(element: HTMLElement, id: string, outputText: string, linesLimit: number, scrollable: boolean, trustHtml: boolean) { +export function appendOutput(element: HTMLElement, outputText: string, trustHtml: boolean) { const buffer = outputText.split(/\r\n|\r|\n/g); - let newContent: HTMLDivElement; - if (scrollable) { - newContent = scrollableArrayOfString(id, buffer, trustHtml); - element.appendChild(newContent); - // contains 1 span per line - // const innerContainer = element.childNodes[0].childNodes[0]; - // const linesToAdd = newContent.childNodes[0].childNodes[0].childNodes; - - // linesToAdd.forEach(span => { - // innerContainer.appendChild(span); - // while (innerContainer.childNodes.length > 5000) { - // innerContainer.firstChild?.remove(); - // } - // }); - } else { - newContent = truncatedArrayOfString(id, buffer, linesLimit, trustHtml); - - // contains 1 span per line - const innerContainer = element.childNodes[0].childNodes[0]; - const linesToAdd = newContent.childNodes[0].childNodes[0].childNodes; - - linesToAdd.forEach(span => { - innerContainer.appendChild(span); - - }); - } + const newContent = handleANSIOutput(buffer.join('\n'), trustHtml); + element.appendChild(newContent); } 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 4e3b2573ec390..eda0b16c645f6 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1499,6 +1499,12 @@ export class BackLayerWebView extends Themable { } const outputCache = this.insetMapping.get(content.source)!; + + if (outputCache.versionId === content.source.model.versionId) { + // already sent this output version to the renderer + return; + } + this.hiddenInsetMapping.delete(content.source); let updatedContent: ICreationContent | undefined = undefined; From cbb47129d378be07525588e4440f7f4e82f1d513 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 12 Jul 2023 11:58:09 -0700 Subject: [PATCH 0042/1180] cli: stop tunnel processes during update (#187738) * untested wip * make it work --- build/gulpfile.vscode.win32.js | 1 + build/win32/code.iss | 39 +++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js index 2d6f14551b33b..674eb41a5032c 100644 --- a/build/gulpfile.vscode.win32.js +++ b/build/gulpfile.vscode.win32.js @@ -98,6 +98,7 @@ function buildWin32Setup(arch, target) { AppMutex: product.win32MutexName, TunnelMutex: product.win32TunnelMutex, TunnelServiceMutex: product.win32TunnelServiceMutex, + TunnelApplicationName: product.tunnelApplicationName, ApplicationName: product.applicationName, Arch: arch, AppId: { 'ia32': ia32AppId, 'x64': x64AppId, 'arm64': arm64AppId }[arch], diff --git a/build/win32/code.iss b/build/win32/code.iss index 44c9f2f1f0b29..b7336831374b6 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -1362,12 +1362,6 @@ begin end; end; - if IsNotBackgroundUpdate() and CheckForMutexes('{#TunnelMutex}') then - begin - MsgBox('{#NameShort} is still running a tunnel. Please stop the tunnel before installing.', mbInformation, MB_OK); - Result := false - end; - end; function WizardNotSilent(): Boolean; @@ -1380,6 +1374,31 @@ end; var ShouldRestartTunnelService: Boolean; +function StopTunnelOtherProcesses(): Boolean; +var + WaitCounter: Integer; + TaskKilled: Integer; +begin + Log('Stopping all tunnel services (at ' + ExpandConstant('"{app}\bin\{#TunnelApplicationName}.exe"') + ')'); + ShellExec('', 'powershell.exe', '-Command "Get-WmiObject Win32_Process | Where-Object { $_.ExecutablePath -eq ' + ExpandConstant('''{app}\bin\{#TunnelApplicationName}.exe''') + ' } | Select @{Name=''Id''; Expression={$_.ProcessId}} | Stop-Process -Force"', '', SW_HIDE, ewWaitUntilTerminated, TaskKilled) + + WaitCounter := 10; + while (WaitCounter > 0) and CheckForMutexes('{#TunnelMutex}') do + begin + Log('Tunnel process is is still running, waiting'); + Sleep(500); + WaitCounter := WaitCounter - 1 + end; + + if CheckForMutexes('{#TunnelMutex}') then + begin + Log('Unable to stop tunnel processes'); + Result := False; + end + else + Result := True; +end; + procedure StopTunnelServiceIfNeeded(); var StopServiceResultCode: Integer; @@ -1413,7 +1432,11 @@ function PrepareToInstall(var NeedsRestart: Boolean): String; begin if IsNotBackgroundUpdate() then StopTunnelServiceIfNeeded(); - Result := '' + + if IsNotBackgroundUpdate() and not StopTunnelOtherProcesses() then + Result := '{#NameShort} is still running a tunnel process. Please stop the tunnel before installing.' + else + Result := ''; end; // VS Code will create a flag file before the update starts (/update=C:\foo\bar) @@ -1607,4 +1630,4 @@ begin #endif Exec(ExpandConstant('{sys}\icacls.exe'), ExpandConstant('"{app}" /inheritancelevel:r ') + Permissions, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); -end; \ No newline at end of file +end; From 588b36f058b422903b489d2b5f19185fe2fb8e8d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 12 Jul 2023 12:00:29 -0700 Subject: [PATCH 0043/1180] make changes --- .../workbench/contrib/inlineChat/browser/inlineChatWidget.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 57077181753fd..ef3951acd6569 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -179,6 +179,7 @@ export class InlineChatWidget { private _isLayouting: boolean = false; private _preferredExpansionState: ExpansionState | undefined; private _expansionState: ExpansionState = ExpansionState.NOT_CROPPED; + private _slashCommandDetails: { command: string; detail: string }[] = []; constructor( private readonly parentEditor: ICodeEditor, @@ -418,9 +419,12 @@ export class InlineChatWidget { } readPlaceholder(): void { + const slashCommand = this._slashCommandDetails.find(c => `${c.command} ` === this._inputModel.getValue().substring(1)); const hasText = this._inputModel.getValueLength() > 0; if (!hasText) { aria.status(this._elements.placeholder.innerText); + } else if (slashCommand) { + aria.status(slashCommand.detail); } } @@ -621,6 +625,7 @@ export class InlineChatWidget { if (commands.length === 0) { return; } + this._slashCommandDetails = commands.filter(c => c.command && c.detail).map(c => { return { command: c.command!, detail: c.detail! }; }); const selector: LanguageSelector = { scheme: this._inputModel.uri.scheme, pattern: this._inputModel.uri.path, language: this._inputModel.getLanguageId() }; this._slashCommands.add(this._languageFeaturesService.completionProvider.register(selector, new class implements CompletionItemProvider { From 9bca8bebfcafa5467cb7847f91c5dbfb38cd7a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 12 Jul 2023 21:15:48 +0200 Subject: [PATCH 0044/1180] switch update/release notes actions (#187740) --- .../contrib/update/browser/update.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/update/browser/update.ts b/src/vs/workbench/contrib/update/browser/update.ts index 39daccab96fd3..01fb0a759042e 100644 --- a/src/vs/workbench/contrib/update/browser/update.ts +++ b/src/vs/workbench/contrib/update/browser/update.ts @@ -451,16 +451,6 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Updating) }); - CommandsRegistry.registerCommand('update.restart', () => this.updateService.quitAndInstall()); - MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { - group: '7_update', - command: { - id: 'update.restart', - title: nls.localize('restartToUpdate', "Restart to Update (1)") - }, - when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready) - }); - CommandsRegistry.registerCommand('update.showUpdateReleaseNotes', () => { if (this.updateService.state.type !== StateType.Ready) { return; @@ -478,6 +468,16 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready) }); + CommandsRegistry.registerCommand('update.restart', () => this.updateService.quitAndInstall()); + MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { + group: '7_update', + command: { + id: 'update.restart', + title: nls.localize('restartToUpdate', "Restart to Update (1)") + }, + when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready) + }); + CommandsRegistry.registerCommand('_update.state', () => { return this.state; }); From cfaa152f707f30507a6ad877592946536c9c9eeb Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 12 Jul 2023 13:40:09 -0700 Subject: [PATCH 0045/1180] fix #187753 --- .../workbench/contrib/accessibility/browser/accessibleView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index c184c355c52aa..8754d601121b7 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -28,7 +28,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; const enum DEFAULT { WIDTH = 800, - TOP = 25 + TOP = 3 } export interface IAccessibleContentProvider { From e0e8ca87f3b5def0bc3ce960616a22408d88a681 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 12 Jul 2023 13:51:53 -0700 Subject: [PATCH 0046/1180] Pick up latest TS for building VS code (#187751) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9fba1bf8246b4..2c98e0a79bf2f 100644 --- a/package.json +++ b/package.json @@ -210,7 +210,7 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", - "typescript": "^5.2.0-dev.20230710", + "typescript": "^5.2.0-dev.20230712", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", diff --git a/yarn.lock b/yarn.lock index 65ca0297579ab..ac27990a8ae39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10036,10 +10036,10 @@ typescript@^4.7.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== -typescript@^5.2.0-dev.20230710: - version "5.2.0-dev.20230710" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.0-dev.20230710.tgz#6e42862d126c2c7b4ce14ce6124396561dd808c0" - integrity sha512-D4u4/pfdrIi94+F+iVzxzuzCk8bE/cbe4jng6Sce2Y1szj/QiBqN43X5lMrIbMR9Kb1G2AdWzYPrcNv/ButJGA== +typescript@^5.2.0-dev.20230712: + version "5.2.0-dev.20230712" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.0-dev.20230712.tgz#6da271394793fd1c1cba26800f43bb8c25825a87" + integrity sha512-F/VND6YrBGr8RvnmpFpTDC5sT0Hh5cuXFWurGEhSBjwXodW+POmfGU0uLn+s/Rl0+Yvffpd2WRrpYC7bSDQS/Q== typical@^4.0.0: version "4.0.0" From 8303f042cd537aab144ce2f0944300cdc02ea528 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 12 Jul 2023 13:56:17 -0700 Subject: [PATCH 0047/1180] focus last if input box is focused --- .../contrib/chat/browser/chat.contribution.ts | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 17eb7015f4e09..a4d715d9a75c9 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -40,8 +40,10 @@ import { registerClearActions } from 'vs/workbench/contrib/chat/browser/actions/ import { AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; -import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys'; +import { CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ICommandService } from 'vs/platform/commands/common/commands'; // Register configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -125,8 +127,18 @@ class ChatAccessibleViewContribution extends Disposable { this._register(AccessibleViewAction.addImplementation(100, 'panelChat', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const widgetService = accessor.get(IChatWidgetService); - const widget: IChatWidget | undefined = widgetService.lastFocusedWidget; - const focusedItem: ChatTreeItem | undefined = widget?.getFocus(); + const contextKeyService = accessor.get(IContextKeyService); + const commandService = accessor.get(ICommandService); + let widget: IChatWidget | undefined = widgetService.lastFocusedWidget; + let focusedItem: ChatTreeItem | undefined = widget?.getFocus(); + let focusedInput = false; + if (!contextKeyService.getContextKeyValue(CONTEXT_RESPONSE.key)) { + // focus is in the input box, so we need to focus the last widget first + commandService.executeCommand('chat.action.focus'); + widget = widgetService.lastFocusedWidget; + focusedItem = widget?.getFocus(); + focusedInput = true; + } if (!widget || !focusedItem || !isResponseVM(focusedItem)) { return false; } @@ -139,7 +151,11 @@ class ChatAccessibleViewContribution extends Disposable { verbositySettingKey: 'panelChat', provideContent(): string { return responseContent; }, onClose() { - widget.focus(focusedItem); + if (focusedInput) { + widget?.focusInput(); + } else { + widget!.focus(focusedItem!); + } }, options: { ariaLabel: nls.localize('chatAccessibleView', "Chat Accessible View"), language: 'typescript', type: AccessibleViewType.View } }); From a4fde6f2eb53a4961846df2f0ad7260778cbcc37 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 12 Jul 2023 14:09:01 -0700 Subject: [PATCH 0048/1180] Add more specific error for TS web server (#187752) This should help us better understand why the access failed --- .../typescript-language-features/web/webServer.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/web/webServer.ts b/extensions/typescript-language-features/web/webServer.ts index 6580a84995cfd..1688a93fcc023 100644 --- a/extensions/typescript-language-features/web/webServer.ts +++ b/extensions/typescript-language-features/web/webServer.ts @@ -76,6 +76,15 @@ function toTsWatcherKind(event: 'create' | 'change' | 'delete') { throw new Error(`Unknown event: ${event}`); } +class AccessOutsideOfRootError extends Error { + constructor( + public readonly filepath: string, + public readonly projectRootPaths: readonly string[] + ) { + super(`Could not read file outside of project root ${filepath}`); + } +} + type ServerHostWithImport = ts.server.ServerHost & { importPlugin(root: string, moduleName: string): Promise }; function createServerHost(extensionUri: URI, logger: ts.server.Logger, apiClient: ApiClient | undefined, args: string[], fsWatcher: MessagePort): ServerHostWithImport { @@ -455,7 +464,7 @@ function createServerHost(extensionUri: URI, logger: ts.server.Logger, apiClient } if (allowRead === 'block') { - throw new Error(`Could not read file outside of project root ${filepath}`); + throw new AccessOutsideOfRootError(filepath, Array.from(projectRootPaths.keys())); } return uri; From 6e0d58ef7eac2de244fa3eb9e67e8117c6904f73 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 12 Jul 2023 14:17:40 -0700 Subject: [PATCH 0049/1180] fix #186678 --- .../terminal.accessibility.contribution.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 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 bdf148b2ef202..55b008fbe2fab 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 @@ -129,8 +129,14 @@ registerTerminalAction({ keybinding: [ { primary: KeyMod.CtrlCmd | KeyCode.DownArrow, - weight: KeybindingWeight.WorkbenchContrib + 2, - when: TerminalContextKeys.accessibleBufferFocus + when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + weight: KeybindingWeight.WorkbenchContrib + 2 + }, + { + primary: KeyMod.CtrlCmd | KeyCode.DownArrow, + mac: { primary: KeyMod.Alt | KeyCode.DownArrow }, + when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), + weight: KeybindingWeight.WorkbenchContrib + 2 } ], run: async (c) => { @@ -151,8 +157,14 @@ registerTerminalAction({ keybinding: [ { primary: KeyMod.CtrlCmd | KeyCode.UpArrow, - weight: KeybindingWeight.WorkbenchContrib + 2, - when: TerminalContextKeys.accessibleBufferFocus + when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + weight: KeybindingWeight.WorkbenchContrib + 2 + }, + { + primary: KeyMod.CtrlCmd | KeyCode.UpArrow, + mac: { primary: KeyMod.Alt | KeyCode.UpArrow }, + when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), + weight: KeybindingWeight.WorkbenchContrib + 2 } ], run: async (c) => { From 600b5192e8b0d1d63f72e4548b05c961b220f729 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:28:05 -0700 Subject: [PATCH 0050/1180] Render the tree once rather than once per key (#187742) --- .../contrib/preferences/browser/settingsEditor2.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 3ce681d603319..b45e1856f2ae1 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -1356,9 +1356,11 @@ export class SettingsEditor2 extends EditorPane { keys.forEach(key => this.settingsTreeModel.updateElementsByName(key)); } - keys.forEach(key => this.renderTree(key)); + // Attempt to render the tree once rather than + // once for each key to avoid redundant calls to this.refreshTree() + this.renderTree(); } else { - return this.renderTree(); + this.renderTree(); } } From ae0d63d5a1d05f602d9620df427669c6e9835ea1 Mon Sep 17 00:00:00 2001 From: Anthony Stewart <150152+a-stewart@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:28:09 +0200 Subject: [PATCH 0051/1180] Increate the max width of action widgets to 80% of the browser width (#186157) --- src/vs/platform/actionWidget/browser/actionWidget.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/actionWidget/browser/actionWidget.css b/src/vs/platform/actionWidget/browser/actionWidget.css index c2ed9072d5816..ae7c6ce75fa6e 100644 --- a/src/vs/platform/actionWidget/browser/actionWidget.css +++ b/src/vs/platform/actionWidget/browser/actionWidget.css @@ -7,7 +7,7 @@ font-size: 13px; border-radius: 0; min-width: 160px; - max-width: 500px; + max-width: 80vw; z-index: 40; display: block; width: 100%; From 4529b4af392ba9b93a82557ae4c84015245242a1 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 12 Jul 2023 14:29:31 -0700 Subject: [PATCH 0052/1180] Fix Cloud Changes enablement placeholder (#187761) --- .../browser/editSessions.contribution.ts | 6 ++-- .../browser/editSessionsStorageService.ts | 28 +++++++++---------- .../editSessions/common/editSessions.ts | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 411241dbc6116..0f6e359a961b9 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -227,7 +227,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo ) { // store the fact that we prompted the user this.storageService.store(EditSessionsContribution.APPLICATION_LAUNCHED_VIA_CONTINUE_ON_STORAGE_KEY, true, StorageScope.APPLICATION, StorageTarget.MACHINE); - await this.editSessionsStorageService.initialize(); + await this.editSessionsStorageService.initialize('read'); if (this.editSessionsStorageService.isSignedIn) { await this.progressService.withProgress(resumeProgressOptions, async (progress) => await this.resumeEditSession(undefined, true, undefined, undefined, progress)); } else { @@ -491,7 +491,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo this.logService.info(ref !== undefined ? `Resuming changes from cloud with ref ${ref}...` : 'Checking for pending cloud changes...'); - if (silent && !(await this.editSessionsStorageService.initialize(true))) { + if (silent && !(await this.editSessionsStorageService.initialize('read', true))) { return; } @@ -838,7 +838,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo return continueWithCloudChanges; } - const initialized = await this.editSessionsStorageService.initialize(); + const initialized = await this.editSessionsStorageService.initialize('write'); if (!initialized) { this.telemetryService.publicLog2('continueOn.editSessions.canStore.outcome', { outcome: 'didNotEnableEditSessionsWhenPrompted' }); } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts index f394515c6e23e..fb44c17569990 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts @@ -106,7 +106,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes * @returns The ref of the stored state. */ async write(resource: SyncResource, content: string | EditSession): Promise { - await this.initialize(false); + await this.initialize('write', false); if (!this.initialized) { throw new Error('Please sign in to store your edit session.'); } @@ -131,7 +131,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes * @returns An object representing the requested or latest state, if any. */ async read(resource: SyncResource, ref: string | undefined): Promise<{ ref: string; content: string } | undefined> { - await this.initialize(false); + await this.initialize('read', false); if (!this.initialized) { throw new Error('Please sign in to apply your latest edit session.'); } @@ -159,7 +159,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes } async delete(resource: SyncResource, ref: string | null) { - await this.initialize(false); + await this.initialize('write', false); if (!this.initialized) { throw new Error(`Unable to delete edit session with ref ${ref}.`); } @@ -172,7 +172,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes } async list(resource: SyncResource): Promise { - await this.initialize(false); + await this.initialize('read', false); if (!this.initialized) { throw new Error(`Unable to list edit sessions.`); } @@ -186,11 +186,11 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes return []; } - public async initialize(silent: boolean = false) { + public async initialize(reason: 'read' | 'write', silent: boolean = false) { if (this.initialized) { return true; } - this.initialized = await this.doInitialize(silent); + this.initialized = await this.doInitialize(reason, silent); this.signedInContext.set(this.initialized); if (this.initialized) { this._didSignIn.fire(); @@ -205,7 +205,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes * meaning that authentication is configured and it * can be used to communicate with the remote storage service */ - private async doInitialize(silent: boolean): Promise { + private async doInitialize(reason: 'read' | 'write', silent: boolean): Promise { // Wait for authentication extensions to be registered await this.extensionService.whenInstalledExtensionsRegistered(); @@ -231,7 +231,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes return true; } - const authenticationSession = await this.getAuthenticationSession(silent); + const authenticationSession = await this.getAuthenticationSession(reason, silent); if (authenticationSession !== undefined) { this.authenticationInfo = authenticationSession; this.storeClient.setAuthToken(authenticationSession.token, authenticationSession.providerId); @@ -243,7 +243,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes private cachedMachines: Map | undefined; async getMachineById(machineId: string) { - await this.initialize(false); + await this.initialize('read', false); if (!this.cachedMachines) { const machines = await this.machineClient!.getMachines(); @@ -264,7 +264,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes return currentMachineId; } - private async getAuthenticationSession(silent: boolean) { + private async getAuthenticationSession(reason: 'read' | 'write', silent: boolean) { // If the user signed in previously and the session is still available, reuse that without prompting the user again if (this.existingSessionId) { this.logService.info(`Searching for existing authentication session with ID ${this.existingSessionId}`); @@ -295,7 +295,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes } // Ask the user to pick a preferred account - const authenticationSession = await this.getAccountPreference(); + const authenticationSession = await this.getAccountPreference(reason); if (authenticationSession !== undefined) { this.existingSessionId = authenticationSession.id; return { sessionId: authenticationSession.id, token: authenticationSession.idToken ?? authenticationSession.accessToken, providerId: authenticationSession.providerId }; @@ -312,10 +312,10 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes * * Prompts the user to pick an authentication option for storing and getting edit sessions. */ - private async getAccountPreference(): Promise { + private async getAccountPreference(reason: 'read' | 'write'): Promise { const quickpick = this.quickInputService.createQuickPick(); quickpick.ok = false; - quickpick.placeholder = localize('choose account placeholder', "Select an account to store your working changes in the cloud"); + quickpick.placeholder = reason === 'read' ? localize('choose account read placeholder', "Select an account to restore your working changes from the cloud") : localize('choose account placeholder', "Select an account to store your working changes in the cloud"); quickpick.ignoreFocusOut = true; quickpick.items = await this.createQuickpickItems(); @@ -482,7 +482,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes } async run() { - return await that.initialize(false); + return await that.initialize('write', false); } })); diff --git a/src/vs/workbench/contrib/editSessions/common/editSessions.ts b/src/vs/workbench/contrib/editSessions/common/editSessions.ts index 2c62c7f8ee245..53c3907641172 100644 --- a/src/vs/workbench/contrib/editSessions/common/editSessions.ts +++ b/src/vs/workbench/contrib/editSessions/common/editSessions.ts @@ -38,7 +38,7 @@ export interface IEditSessionsStorageService { lastReadResources: Map; lastWrittenResources: Map; - initialize(silent?: boolean): Promise; + initialize(reason: 'read' | 'write', silent?: boolean): Promise; read(resource: SyncResource, ref: string | undefined): Promise<{ ref: string; content: string } | undefined>; write(resource: SyncResource, content: string | EditSession): Promise; delete(resource: SyncResource, ref: string | null): Promise; From 6809b95ed034e798e23a8c7c7e548c64403aff59 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 12 Jul 2023 14:32:17 -0700 Subject: [PATCH 0053/1180] better approach --- .../contrib/chat/browser/chat.contribution.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index a4d715d9a75c9..defbcbd581d89 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -40,10 +40,9 @@ import { registerClearActions } from 'vs/workbench/contrib/chat/browser/actions/ import { AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; -import { CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; +import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; // Register configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -127,14 +126,19 @@ class ChatAccessibleViewContribution extends Disposable { this._register(AccessibleViewAction.addImplementation(100, 'panelChat', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const widgetService = accessor.get(IChatWidgetService); - const contextKeyService = accessor.get(IContextKeyService); - const commandService = accessor.get(ICommandService); + const codeEditorService = accessor.get(ICodeEditorService); + let widget: IChatWidget | undefined = widgetService.lastFocusedWidget; let focusedItem: ChatTreeItem | undefined = widget?.getFocus(); let focusedInput = false; - if (!contextKeyService.getContextKeyValue(CONTEXT_RESPONSE.key)) { + const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); + if (editor) { // focus is in the input box, so we need to focus the last widget first - commandService.executeCommand('chat.action.focus'); + const editorUri = editor.getModel()?.uri; + if (!editorUri) { + return false; + } + widgetService.getWidgetByInputUri(editorUri)?.focusLastMessage(); widget = widgetService.lastFocusedWidget; focusedItem = widget?.getFocus(); focusedInput = true; From 5b78562d6c5aca8928ce442968c1f07ca0c284f1 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 12 Jul 2023 15:03:49 -0700 Subject: [PATCH 0054/1180] truncate long outputs --- extensions/notebook-renderers/src/index.ts | 10 +-- .../notebook-renderers/src/rendererTypes.ts | 4 ++ .../src/test/notebookRenderer.test.ts | 66 +++++++++++++++++-- .../notebook-renderers/src/textHelper.ts | 34 ++++++++-- 4 files changed, 95 insertions(+), 19 deletions(-) diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index be59b011c12e3..4af59128a2cec 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import type { ActivationFunction, OutputItem, RendererContext } from 'vscode-notebook-renderer'; -import { appendOutput, createOutputContent, scrollableClass } from './textHelper'; -import { HtmlRenderingHook, IDisposable, IRichRenderContext, JavaScriptRenderingHook, RenderOptions } from './rendererTypes'; +import { appendScrollableOutput, createOutputContent, scrollableClass } from './textHelper'; +import { HtmlRenderingHook, IDisposable, IRichRenderContext, JavaScriptRenderingHook, OutputWithAppend, RenderOptions } from './rendererTypes'; import { ttPolicy } from './htmlHelper'; function clearContainer(container: HTMLElement) { @@ -265,10 +265,6 @@ function scrollingEnabled(output: OutputItem, options: RenderOptions) { metadata.scrollable : options.outputScrolling; } -interface OutputWithAppend extends OutputItem { - appendedText?(): string | undefined; -} - // div.cell_container // div.output_container // div.output.output-stream <-- outputElement parameter @@ -302,7 +298,7 @@ function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, if (existingContent && contentParent) { // appending output only in scrollable ouputs currently if (appendedText && outputScrolling) { - appendOutput(existingContent, appendedText, false); + appendScrollableOutput(existingContent, outputInfo.id, appendedText, outputInfo.text(), false); } else { const newContent = createContent(outputInfo, ctx, outputScrolling, error); diff --git a/extensions/notebook-renderers/src/rendererTypes.ts b/extensions/notebook-renderers/src/rendererTypes.ts index 9da94aeef5dcd..77f9ebac47201 100644 --- a/extensions/notebook-renderers/src/rendererTypes.ts +++ b/extensions/notebook-renderers/src/rendererTypes.ts @@ -35,3 +35,7 @@ export interface RenderOptions { } export type IRichRenderContext = RendererContext & { readonly settings: RenderOptions; readonly onDidChangeSettings: Event }; + +export interface OutputWithAppend extends OutputItem { + appendedText?(): string | undefined; +} diff --git a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts index e67d1d8ce260a..3c0c609140d4e 100644 --- a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts +++ b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts @@ -5,8 +5,8 @@ import * as assert from 'assert'; import { activate } from '..'; -import { OutputItem, RendererApi } from 'vscode-notebook-renderer'; -import { IDisposable, IRichRenderContext, RenderOptions } from '../rendererTypes'; +import { RendererApi } from 'vscode-notebook-renderer'; +import { IDisposable, IRichRenderContext, OutputWithAppend, RenderOptions } from '../rendererTypes'; import { JSDOM } from "jsdom"; const dom = new JSDOM(); @@ -116,10 +116,13 @@ suite('Notebook builtin output renderer', () => { } } - function createOutputItem(text: string, mime: string, id: string = '123'): OutputItem { + function createOutputItem(text: string, mime: string, id: string = '123', appendedText?: string): OutputWithAppend { return { id: id, mime: mime, + appendedText() { + return appendedText; + }, text() { return text; }, @@ -177,9 +180,9 @@ suite('Notebook builtin output renderer', () => { assert.ok(renderer, 'Renderer not created'); const outputElement = new OutputHtml().getFirstOuputElement(); - const outputItem = createOutputItem('content', 'text/plain'); + const outputItem = createOutputItem('content', mimeType); await renderer!.renderOutputItem(outputItem, outputElement); - const outputItem2 = createOutputItem('replaced content', 'text/plain'); + const outputItem2 = createOutputItem('replaced content', mimeType); await renderer!.renderOutputItem(outputItem2, outputElement); const inserted = outputElement.firstChild as HTMLElement; @@ -189,6 +192,59 @@ suite('Notebook builtin output renderer', () => { }); + test('Append streaming output', async () => { + const context = createContext({ outputWordWrap: false, outputScrolling: false }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('content', stdoutMimeType, '123', 'ignoredAppend'); + await renderer!.renderOutputItem(outputItem, outputElement); + const outputItem2 = createOutputItem('content\nappended', stdoutMimeType, '\nappended'); + await renderer!.renderOutputItem(outputItem2, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('>contentappendedcontentcontent { + const context = createContext({ outputWordWrap: false, outputScrolling: false }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const lotsOfLines = new Array(4998).fill('line').join('\n') + 'endOfInitialContent'; + const firstOuput = lotsOfLines + 'expected1'; + const outputItem = createOutputItem(firstOuput, stdoutMimeType, '123'); + await renderer!.renderOutputItem(outputItem, outputElement); + const appended = '\n' + lotsOfLines + 'expectedAppend'; + const outputItem2 = createOutputItem(firstOuput + appended, stdoutMimeType, appended); + await renderer!.renderOutputItem(outputItem2, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('>expected1expectedAppend { + const context = createContext({ outputWordWrap: false, outputScrolling: false }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const lotsOfLines = new Array(11000).fill('line').join('\n') + 'endOfInitialContent'; + const firstOuput = 'shouldBeTruncated' + lotsOfLines + 'expected1'; + const outputItem = createOutputItem(firstOuput, stdoutMimeType, '123'); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('>endOfInitialContentshouldBeTruncated { const context = createContext({ outputWordWrap: true, outputScrolling: true }); const renderer = await activate(context); diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index f335d2cfdda4e..97b3a1ba694de 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -4,9 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { handleANSIOutput } from './ansi'; - export const scrollableClass = 'scrollable'; +const softScrollableLineLimit = 5000; +const hardScrollableLineLimit = 8000; + /** * Output is Truncated. View as a [scrollable element] or open in a [text editor]. Adjust cell output [settings...] */ @@ -91,11 +93,11 @@ function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number function scrollableArrayOfString(id: string, buffer: string[], trustHtml: boolean) { const element = document.createElement('div'); - if (buffer.length > 5000) { + if (buffer.length > softScrollableLineLimit) { element.appendChild(generateNestedViewAllElement(id)); } - element.appendChild(handleANSIOutput(buffer.slice(-5000).join('\n'), trustHtml)); + element.appendChild(handleANSIOutput(buffer.slice(-1 * softScrollableLineLimit).join('\n'), trustHtml)); return element; } @@ -111,8 +113,26 @@ export function createOutputContent(id: string, outputText: string, linesLimit: } } -export function appendOutput(element: HTMLElement, outputText: string, trustHtml: boolean) { - const buffer = outputText.split(/\r\n|\r|\n/g); - const newContent = handleANSIOutput(buffer.join('\n'), trustHtml); - element.appendChild(newContent); +const outputLengths: Record = {}; + +export function appendScrollableOutput(element: HTMLElement, id: string, appended: string, fullText: string, trustHtml: boolean) { + if (!outputLengths[id]) { + outputLengths[id] = 0; + } + + const buffer = appended.split(/\r\n|\r|\n/g); + const appendedLength = buffer.length + outputLengths[id]; + // Allow the output to grow to the hard limit then replace it with the last softLimit number of lines if it grows too large + if (buffer.length + outputLengths[id] > hardScrollableLineLimit) { + const fullBuffer = fullText.split(/\r\n|\r|\n/g); + outputLengths[id] = Math.min(fullBuffer.length, softScrollableLineLimit); + const newElement = scrollableArrayOfString(id, fullBuffer.slice(-1 * softScrollableLineLimit), trustHtml); + newElement.setAttribute('output-item-id', id); + element.replaceWith(); + } + else { + element.appendChild(handleANSIOutput(buffer.join('\n'), trustHtml)); + outputLengths[id] = appendedLength; + } } + From e68a34f9bdc86a2933f079b1ac1436fab4bc4c3a Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 12 Jul 2023 15:20:43 -0700 Subject: [PATCH 0055/1180] append when stream outputs are concatenated --- extensions/notebook-renderers/src/index.ts | 11 ++++++++--- extensions/notebook-renderers/src/textHelper.ts | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index 4af59128a2cec..62c9fe7029586 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -282,12 +282,17 @@ function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, const previousOutputParent = getPreviousMatchingContentGroup(outputElement); // If the previous output item for the same cell was also a stream, append this output to the previous if (previousOutputParent) { - const newContent = createContent(outputInfo, ctx, outputScrolling, error); const existingContent = previousOutputParent.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; if (existingContent) { - existingContent.replaceWith(newContent); - + if (appendedText && outputScrolling) { + appendScrollableOutput(existingContent, outputInfo.id, appendedText, outputInfo.text(), false); + } + else { + const newContent = createContent(outputInfo, ctx, outputScrolling, error); + existingContent.replaceWith(newContent); + } } else { + const newContent = createContent(outputInfo, ctx, outputScrolling, error); previousOutputParent.appendChild(newContent); } previousOutputParent.classList.toggle('scrollbar-visible', previousOutputParent.scrollHeight > previousOutputParent.clientHeight); diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index 97b3a1ba694de..0c65e0f6d9353 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -128,7 +128,7 @@ export function appendScrollableOutput(element: HTMLElement, id: string, appende outputLengths[id] = Math.min(fullBuffer.length, softScrollableLineLimit); const newElement = scrollableArrayOfString(id, fullBuffer.slice(-1 * softScrollableLineLimit), trustHtml); newElement.setAttribute('output-item-id', id); - element.replaceWith(); + element.replaceWith(newElement); } else { element.appendChild(handleANSIOutput(buffer.join('\n'), trustHtml)); From 5b9cf3d53bad0f080318283e85aa580bcd2152f3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 00:40:53 +0200 Subject: [PATCH 0056/1180] Fix #176813 (#187750) * Fix #176813 * fix tests * fix tests * address feedback --- .../common/configurationModels.ts | 22 ++-- .../common/configurationService.ts | 2 +- .../test/common/configurationModels.test.ts | 48 ++++++++ .../test/common/configurations.test.ts | 8 +- .../browser/preferencesRenderers.ts | 25 ++-- .../settingsEditorSettingIndicators.ts | 17 ++- .../preferences/browser/settingsTree.ts | 76 +++++++++--- .../preferences/browser/settingsTreeModels.ts | 21 ++-- .../configuration/browser/configuration.ts | 50 ++++++-- .../browser/configurationService.ts | 113 +++++++++++++----- .../configuration/common/configuration.ts | 8 ++ .../common/configurationEditing.ts | 16 +-- .../test/browser/configurationService.test.ts | 104 +++++++++++++++- 13 files changed, 407 insertions(+), 103 deletions(-) diff --git a/src/vs/platform/configuration/common/configurationModels.ts b/src/vs/platform/configuration/common/configurationModels.ts index 9e171f9b6cb60..4055e5ae0b9a4 100644 --- a/src/vs/platform/configuration/common/configurationModels.ts +++ b/src/vs/platform/configuration/common/configurationModels.ts @@ -269,8 +269,10 @@ export class ConfigurationModel implements IConfigurationModel { } export interface ConfigurationParseOptions { - scopes: ConfigurationScope[] | undefined; + scopes?: ConfigurationScope[]; skipRestricted?: boolean; + include?: string[]; + exclude?: string[]; } export class ConfigurationModelParser { @@ -383,7 +385,7 @@ export class ConfigurationModelParser { private filter(properties: any, configurationProperties: { [qualifiedKey: string]: IConfigurationPropertySchema | undefined }, filterOverriddenProperties: boolean, options?: ConfigurationParseOptions): { raw: {}; restricted: string[]; hasExcludedProperties: boolean } { let hasExcludedProperties = false; - if (!options?.scopes && !options?.skipRestricted) { + if (!options?.scopes && !options?.skipRestricted && !options?.exclude?.length) { return { raw: properties, restricted: [], hasExcludedProperties }; } const raw: any = {}; @@ -400,9 +402,10 @@ export class ConfigurationModelParser { if (propertySchema?.restricted) { restricted.push(key); } - // Load unregistered configurations always. - if ((scope === undefined || options.scopes === undefined || options.scopes.includes(scope)) // Check scopes - && !(options.skipRestricted && propertySchema?.restricted)) { // Check restricted + if (!options.exclude?.includes(key) /* Check exclude */ + && (options.include?.includes(key) /* Check include */ + || ((scope === undefined || options.scopes === undefined || options.scopes.includes(scope)) /* Check scopes */ + && !(options.skipRestricted && propertySchema?.restricted)))) /* Check restricted */ { raw[key] = properties[key]; } else { hasExcludedProperties = true; @@ -435,19 +438,17 @@ export class ConfigurationModelParser { export class UserSettings extends Disposable { private readonly parser: ConfigurationModelParser; - private readonly parseOptions: ConfigurationParseOptions; protected readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; constructor( private readonly userSettingsResource: URI, - private readonly scopes: ConfigurationScope[] | undefined, + protected parseOptions: ConfigurationParseOptions, extUri: IExtUri, private readonly fileService: IFileService ) { super(); this.parser = new ConfigurationModelParser(this.userSettingsResource.toString()); - this.parseOptions = { scopes: this.scopes }; this._register(this.fileService.watch(extUri.dirname(this.userSettingsResource))); // Also listen to the resource incase the resource is a symlink - https://github.com/microsoft/vscode/issues/118134 this._register(this.fileService.watch(this.userSettingsResource)); @@ -467,7 +468,10 @@ export class UserSettings extends Disposable { } } - reparse(): ConfigurationModel { + reparse(parseOptions?: ConfigurationParseOptions): ConfigurationModel { + if (parseOptions) { + this.parseOptions = parseOptions; + } this.parser.reparse(this.parseOptions); return this.parser.configurationModel; } diff --git a/src/vs/platform/configuration/common/configurationService.ts b/src/vs/platform/configuration/common/configurationService.ts index 8a4ccfe329dcb..7eee99fd90e6c 100644 --- a/src/vs/platform/configuration/common/configurationService.ts +++ b/src/vs/platform/configuration/common/configurationService.ts @@ -37,7 +37,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe super(); this.defaultConfiguration = this._register(new DefaultConfiguration()); this.policyConfiguration = policyService instanceof NullPolicyService ? new NullPolicyConfiguration() : this._register(new PolicyConfiguration(this.defaultConfiguration, policyService, logService)); - this.userConfiguration = this._register(new UserSettings(this.settingsResource, undefined, extUriBiasedIgnorePathCase, fileService)); + this.userConfiguration = this._register(new UserSettings(this.settingsResource, {}, extUriBiasedIgnorePathCase, fileService)); this.configuration = new Configuration(this.defaultConfiguration.configurationModel, this.policyConfiguration.configurationModel, new ConfigurationModel(), new ConfigurationModel()); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reloadConfiguration(), 50)); diff --git a/src/vs/platform/configuration/test/common/configurationModels.test.ts b/src/vs/platform/configuration/test/common/configurationModels.test.ts index 1969669fb6214..db22861ee4a05 100644 --- a/src/vs/platform/configuration/test/common/configurationModels.test.ts +++ b/src/vs/platform/configuration/test/common/configurationModels.test.ts @@ -6,11 +6,26 @@ import * as assert from 'assert'; import { join } from 'vs/base/common/path'; import { URI } from 'vs/base/common/uri'; import { Configuration, ConfigurationChangeEvent, ConfigurationModel, ConfigurationModelParser, mergeChanges } from 'vs/platform/configuration/common/configurationModels'; +import { IConfigurationRegistry, Extensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; +import { Registry } from 'vs/platform/registry/common/platform'; import { WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Workspace } from 'vs/platform/workspace/test/common/testWorkspace'; suite('ConfigurationModelParser', () => { + suiteSetup(() => { + Registry.as(Extensions.Configuration).registerConfiguration({ + 'id': 'ConfigurationModelParserTest', + 'type': 'object', + 'properties': { + 'ConfigurationModelParserTest.windowSetting': { + 'type': 'string', + 'default': 'isSet', + } + } + }); + }); + test('parse configuration model with single override identifier', () => { const testObject = new ConfigurationModelParser(''); @@ -35,6 +50,39 @@ suite('ConfigurationModelParser', () => { assert.deepStrictEqual(JSON.stringify(testObject.configurationModel.overrides), JSON.stringify([{ identifiers: ['x', 'y', 'z'], keys: ['a'], contents: { 'a': 1 } }])); }); + test('parse configuration model with exclude option', () => { + const testObject = new ConfigurationModelParser(''); + + testObject.parse(JSON.stringify({ 'a': 1, 'b': 2 }), { exclude: ['a'] }); + + assert.strictEqual(testObject.configurationModel.getValue('a'), undefined); + assert.strictEqual(testObject.configurationModel.getValue('b'), 2); + }); + + test('parse configuration model with exclude option even included', () => { + const testObject = new ConfigurationModelParser(''); + + testObject.parse(JSON.stringify({ 'a': 1, 'b': 2 }), { exclude: ['a'], include: ['a'] }); + + assert.strictEqual(testObject.configurationModel.getValue('a'), undefined); + assert.strictEqual(testObject.configurationModel.getValue('b'), 2); + }); + + test('parse configuration model with scopes filter', () => { + const testObject = new ConfigurationModelParser(''); + + testObject.parse(JSON.stringify({ 'ConfigurationModelParserTest.windowSetting': '1' }), { scopes: [ConfigurationScope.APPLICATION] }); + + assert.strictEqual(testObject.configurationModel.getValue('ConfigurationModelParserTest.windowSetting'), undefined); + }); + + test('parse configuration model with include option', () => { + const testObject = new ConfigurationModelParser(''); + + testObject.parse(JSON.stringify({ 'ConfigurationModelParserTest.windowSetting': '1' }), { include: ['ConfigurationModelParserTest.windowSetting'], scopes: [ConfigurationScope.APPLICATION] }); + + assert.strictEqual(testObject.configurationModel.getValue('ConfigurationModelParserTest.windowSetting'), '1'); + }); }); diff --git a/src/vs/platform/configuration/test/common/configurations.test.ts b/src/vs/platform/configuration/test/common/configurations.test.ts index 02d0f4e889059..30cddfd214453 100644 --- a/src/vs/platform/configuration/test/common/configurations.test.ts +++ b/src/vs/platform/configuration/test/common/configurations.test.ts @@ -62,15 +62,15 @@ suite('DefaultConfiguration', () => { test('Test registering a property after initialize', async () => { const testObject = new DefaultConfiguration(); - const promise = Event.toPromise(testObject.onDidChangeConfiguration); await testObject.initialize(); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); configurationRegistry.registerConfiguration({ 'id': 'a', 'order': 1, 'title': 'a', 'type': 'object', 'properties': { - 'a': { + 'defaultConfiguration.testSetting1': { 'description': 'a', 'type': 'boolean', 'default': false, @@ -78,8 +78,8 @@ suite('DefaultConfiguration', () => { } }); const { defaults: actual, properties } = await promise; - assert.strictEqual(actual.getValue('a'), false); - assert.deepStrictEqual(properties, ['a']); + assert.strictEqual(actual.getValue('defaultConfiguration.testSetting1'), false); + assert.deepStrictEqual(properties, ['defaultConfiguration.testSetting1']); }); test('Test registering nested properties', async () => { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts index 76f3f201b1c49..c80d1d641c896 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts @@ -44,6 +44,7 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c import { isEqual } from 'vs/base/common/resources'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; +import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; export interface IPreferencesRenderer extends IDisposable { render(): void; @@ -481,7 +482,7 @@ class UnsupportedSettingsRenderer extends Disposable implements languages.CodeAc private readonly settingsEditorModel: SettingsEditorModel, @IMarkerService private readonly markerService: IMarkerService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IWorkbenchConfigurationService private readonly configurationService: IWorkbenchConfigurationService, @IWorkspaceTrustManagementService private readonly workspaceTrustManagementService: IWorkspaceTrustManagementService, @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, @@ -603,19 +604,27 @@ class UnsupportedSettingsRenderer extends Disposable implements languages.CodeAc private handleLocalUserConfiguration(setting: ISetting, configuration: IConfigurationPropertySchema, markerData: IMarkerData[]): void { if (!this.userDataProfileService.currentProfile.isDefault && !this.userDataProfileService.currentProfile.useDefaultFlags?.settings) { - if (isEqual(this.userDataProfilesService.defaultProfile.settingsResource, this.settingsEditorModel.uri) && configuration.scope !== ConfigurationScope.APPLICATION) { - // If we're in the default profile setting file, and the setting is not - // application-scoped, fade it out. + if (isEqual(this.userDataProfilesService.defaultProfile.settingsResource, this.settingsEditorModel.uri) && !this.configurationService.isSettingAppliedForAllProfiles(setting.key)) { + // If we're in the default profile setting file, and the setting cannot be applied in all profiles markerData.push({ severity: MarkerSeverity.Hint, tags: [MarkerTag.Unnecessary], ...setting.range, message: nls.localize('defaultProfileSettingWhileNonDefaultActive', "This setting cannot be applied while a non-default profile is active. It will be applied when the default profile is active.") }); - } else if (isEqual(this.userDataProfileService.currentProfile.settingsResource, this.settingsEditorModel.uri) && configuration.scope === ConfigurationScope.APPLICATION) { - // If we're in a profile setting file, and the setting is - // application-scoped, fade it out. - markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); + } else if (isEqual(this.userDataProfileService.currentProfile.settingsResource, this.settingsEditorModel.uri)) { + if (configuration.scope === ConfigurationScope.APPLICATION) { + // If we're in a profile setting file, and the setting is application-scoped, fade it out. + markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); + } else if (this.configurationService.isSettingAppliedForAllProfiles(setting.key)) { + // If we're in the non-default profile setting file, and the setting can be applied in all profiles, fade it out. + markerData.push({ + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + ...setting.range, + message: nls.localize('allProfileSettingWhileInNonDefaultProfileSetting', "This setting cannot be applied because it is configured to be applied in all profiles using setting {0}. Value from the default profile will be used instead.", APPLY_ALL_PROFILES_SETTING) + }); + } } } if (this.environmentService.remoteAuthority && (configuration.scope === ConfigurationScope.MACHINE || configuration.scope === ConfigurationScope.MACHINE_OVERRIDABLE)) { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts index 0482a32a1a400..645127cd81446 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts @@ -15,11 +15,12 @@ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { localize } from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; import { SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels'; import { POLICY_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IHoverOptions, IHoverService, IHoverWidget } from 'vs/workbench/services/hover/browser/hover'; const $ = DOM.$; @@ -75,7 +76,7 @@ export class SettingsTreeIndicatorsLabel implements IDisposable { constructor( container: HTMLElement, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IWorkbenchConfigurationService private readonly configurationService: IWorkbenchConfigurationService, @IHoverService private readonly hoverService: IHoverService, @IUserDataSyncEnablementService private readonly userDataSyncEnablementService: IUserDataSyncEnablementService, @ILanguageService private readonly languageService: ILanguageService, @@ -330,14 +331,11 @@ export class SettingsTreeIndicatorsLabel implements IDisposable { }, focus); }; this.addHoverDisposables(this.scopeOverridesIndicator.disposables, this.scopeOverridesIndicator.element, showHover); - } else if (this.profilesEnabled && element.matchesScope(ConfigurationTarget.APPLICATION, false)) { - // If the setting is an application-scoped setting, there are no overrides so we can use this - // indicator to display that information instead. + } else if (this.profilesEnabled && element.settingsTarget === ConfigurationTarget.USER_LOCAL && this.configurationService.isSettingAppliedForAllProfiles(element.setting.key)) { this.scopeOverridesIndicator.element.style.display = 'inline'; this.scopeOverridesIndicator.element.classList.add('setting-indicator'); - const applicationSettingText = localize('applicationSetting', "Applies to all profiles"); - this.scopeOverridesIndicator.label.text = applicationSettingText; + this.scopeOverridesIndicator.label.text = localize('applicationSetting', "Applies to all profiles"); const content = localize('applicationSettingDescription', "The setting is not specific to the current profile, and will retain its value when switching profiles."); const showHover = (focus: boolean) => { @@ -499,7 +497,7 @@ function getAccessibleScopeDisplayMidSentenceText(completeScope: string, languag return localizedScope; } -export function getIndicatorsLabelAriaLabel(element: SettingsTreeSettingElement, configurationService: IConfigurationService, userDataProfilesService: IUserDataProfilesService, languageService: ILanguageService): string { +export function getIndicatorsLabelAriaLabel(element: SettingsTreeSettingElement, configurationService: IWorkbenchConfigurationService, userDataProfilesService: IUserDataProfilesService, languageService: ILanguageService): string { const ariaLabelSections: string[] = []; // Add workspace trust text @@ -507,10 +505,9 @@ export function getIndicatorsLabelAriaLabel(element: SettingsTreeSettingElement, ariaLabelSections.push(localize('workspaceUntrustedAriaLabel', "Workspace untrusted; setting value not applied")); } - const profilesEnabled = userDataProfilesService.isEnabled(); if (element.hasPolicyValue) { ariaLabelSections.push(localize('policyDescriptionAccessible', "Managed by organization policy; setting value not applied")); - } else if (profilesEnabled && element.matchesScope(ConfigurationTarget.APPLICATION, false)) { + } else if (userDataProfilesService.isEnabled() && element.settingsTarget === ConfigurationTarget.USER_LOCAL && configurationService.isSettingAppliedForAllProfiles(element.setting.key)) { ariaLabelSections.push(localize('applicationSettingDescriptionAccessible', "Setting value retained when switching profiles")); } else { // Add other overrides text diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index eb63f256d47f1..ff00480a0ee12 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -23,6 +23,7 @@ import { IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree'; import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; import { Action, IAction, Separator } from 'vs/base/common/actions'; +import { distinct } from 'vs/base/common/arrays'; import { Codicon } from 'vs/base/common/codicons'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -63,7 +64,7 @@ import { ISettingsEditorViewState, SettingsTreeElement, SettingsTreeGroupChild, import { ExcludeSettingWidget, IListDataItem, IObjectDataItem, IObjectEnumOption, IObjectKeySuggester, IObjectValueSuggester, ISettingListChangeEvent, IncludeSettingWidget, ListSettingWidget, ObjectSettingCheckboxWidget, ObjectSettingDropdownWidget, ObjectValue } from 'vs/workbench/contrib/preferences/browser/settingsWidgets'; import { LANGUAGE_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences'; import { settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry'; -import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; @@ -758,7 +759,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre constructor( private readonly settingActions: IAction[], - private readonly disposableActionFactory: (setting: ISetting) => IAction[], + private readonly disposableActionFactory: (setting: ISetting, settingTarget: SettingsTarget) => IAction[], @IThemeService protected readonly _themeService: IThemeService, @IContextViewService protected readonly _contextViewService: IContextViewService, @IOpenerService protected readonly _openerService: IOpenerService, @@ -875,7 +876,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre const element = node.element; template.context = element; template.toolbar.context = element; - const actions = this.disposableActionFactory(element.setting); + const actions = this.disposableActionFactory(element.setting, element.settingsTarget); actions.forEach(a => isDisposable(a) && template.elementDisposables.add(a)); template.toolbar.setActions([], [...this.settingActions, ...actions]); @@ -901,6 +902,11 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre } template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter); + template.elementDisposables.add(this._configService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING)) { + template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter); + } + })); const onChange = (value: any) => this._onDidChangeSetting.fire({ key: element.setting.key, @@ -1959,6 +1965,7 @@ export class SettingTreeRenderers { @IInstantiationService private readonly _instantiationService: IInstantiationService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @IContextViewService private readonly _contextViewService: IContextViewService, + @IUserDataProfilesService private readonly _userDataProfilesService: IUserDataProfilesService, @IUserDataSyncEnablementService private readonly _userDataSyncEnablementService: IUserDataSyncEnablementService, ) { this.settingActions = [ @@ -1980,7 +1987,7 @@ export class SettingTreeRenderers { this._instantiationService.createInstance(CopySettingAsJSONAction), ]; - const actionFactory = (setting: ISetting) => this.getActionsForSetting(setting); + const actionFactory = (setting: ISetting, settingTarget: SettingsTarget) => this.getActionsForSetting(setting, settingTarget); const emptyActionFactory = (_: ISetting) => []; const settingRenderers = [ this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions, actionFactory), @@ -2015,14 +2022,18 @@ export class SettingTreeRenderers { ]; } - private getActionsForSetting(setting: ISetting): IAction[] { - const enableSync = this._userDataSyncEnablementService.isEnabled(); - return enableSync && !setting.disallowSyncIgnore ? - [ - new Separator(), - this._instantiationService.createInstance(SyncSettingAction, setting) - ] : - []; + private getActionsForSetting(setting: ISetting, settingTarget: SettingsTarget): IAction[] { + const actions: IAction[] = []; + if (this._userDataProfilesService.isEnabled() && setting.scope !== ConfigurationScope.APPLICATION && settingTarget === ConfigurationTarget.USER_LOCAL) { + actions.push(this._instantiationService.createInstance(ApplySettingToAllProfilesAction, setting)); + } + if (this._userDataSyncEnablementService.isEnabled() && !setting.disallowSyncIgnore) { + actions.push(this._instantiationService.createInstance(SyncSettingAction, setting)); + } + if (actions.length) { + actions.splice(0, 0, new Separator()); + } + return actions; } cancelSuggesters() { @@ -2295,7 +2306,7 @@ export class NonCollapsibleObjectTreeModel extends ObjectTreeModel { } class SettingsTreeAccessibilityProvider implements IListAccessibilityProvider { - constructor(private readonly configurationService: IConfigurationService, private readonly languageService: ILanguageService, private readonly userDataProfilesService: IUserDataProfilesService) { + constructor(private readonly configurationService: IWorkbenchConfigurationService, private readonly languageService: ILanguageService, private readonly userDataProfilesService: IUserDataProfilesService) { } getAriaLabel(element: SettingsTreeElement) { @@ -2337,7 +2348,7 @@ export class SettingsTree extends WorkbenchObjectTree { renderers: ITreeRenderer[], @IContextKeyService contextKeyService: IContextKeyService, @IListService listService: IListService, - @IConfigurationService configurationService: IConfigurationService, + @IWorkbenchConfigurationService configurationService: IWorkbenchConfigurationService, @IInstantiationService instantiationService: IInstantiationService, @ILanguageService languageService: ILanguageService, @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService @@ -2485,3 +2496,40 @@ class SyncSettingAction extends Action { } } + +class ApplySettingToAllProfilesAction extends Action { + static readonly ID = 'settings.applyToAllProfiles'; + static readonly LABEL = localize('applyToAllProfiles', "Apply Setting to all Profiles"); + + constructor( + private readonly setting: ISetting, + @IWorkbenchConfigurationService private readonly configService: IWorkbenchConfigurationService, + ) { + super(ApplySettingToAllProfilesAction.ID, ApplySettingToAllProfilesAction.LABEL); + this._register(Event.filter(configService.onDidChangeConfiguration, e => e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING))(() => this.update())); + this.update(); + } + + update() { + const allProfilesSettings = this.configService.getValue(APPLY_ALL_PROFILES_SETTING); + this.checked = allProfilesSettings.includes(this.setting.key); + } + + override async run(): Promise { + // first remove the current setting completely from ignored settings + const value = this.configService.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; + + if (this.checked) { + value.splice(value.indexOf(this.setting.key), 1); + } else { + value.push(this.setting.key); + } + + const newValue = distinct(value); + await this.configService.updateValue(APPLY_ALL_PROFILES_SETTING, newValue.length ? newValue : undefined, ConfigurationTarget.USER_LOCAL); + if (!this.checked) { + await this.configService.updateValue(this.setting.key, this.configService.inspect(this.setting.key).userLocal?.value, ConfigurationTarget.USER_LOCAL); + } + } + +} diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index 27d5d03efbd4e..e55eba8fa7754 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -169,6 +169,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { parent: SettingsTreeGroupElement, inspectResult: IInspectResult, isWorkspaceTrusted: boolean, + readonly settingsTarget: SettingsTarget, private readonly languageService: ILanguageService, private readonly productService: IProductService ) { @@ -544,17 +545,21 @@ export class SettingsTreeModel { this.updateSettings([...this._treeElementsBySettingName.values()].flat().filter(s => s.isUntrusted)); } - private getTargetToInspect(settingScope: ConfigurationScope | undefined): SettingsTarget { - if (!this._userDataProfileService.currentProfile.isDefault && settingScope === ConfigurationScope.APPLICATION) { - return ConfigurationTarget.APPLICATION; - } else { - return this._viewState.settingsTarget; + private getTargetToInspect(setting: ISetting): SettingsTarget { + if (!this._userDataProfileService.currentProfile.isDefault) { + if (setting.scope === ConfigurationScope.APPLICATION) { + return ConfigurationTarget.APPLICATION; + } + if (this._configurationService.isSettingAppliedForAllProfiles(setting.key) && this._viewState.settingsTarget === ConfigurationTarget.USER_LOCAL) { + return ConfigurationTarget.APPLICATION; + } } + return this._viewState.settingsTarget; } private updateSettings(settings: SettingsTreeSettingElement[]): void { for (const element of settings) { - const target = this.getTargetToInspect(element.setting.scope); + const target = this.getTargetToInspect(element.setting); const inspectResult = inspectSetting(element.setting.key, target, this._viewState.languageFilter, this._configurationService); element.update(inspectResult, this._isWorkspaceTrusted); } @@ -591,9 +596,9 @@ export class SettingsTreeModel { } private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement { - const target = this.getTargetToInspect(setting.scope); + const target = this.getTargetToInspect(setting); const inspectResult = inspectSetting(setting.key, target, this._viewState.languageFilter, this._configurationService); - const element = new SettingsTreeSettingElement(setting, parent, inspectResult, this._isWorkspaceTrusted, this._languageService, this._productService); + const element = new SettingsTreeSettingElement(setting, parent, inspectResult, this._isWorkspaceTrusted, this._viewState.settingsTarget, this._languageService, this._productService); const nameElements = this._treeElementsBySettingName.get(setting.key) || []; nameElements.push(element); diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 83e284a3df004..8f942efdd0ee9 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -11,7 +11,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FileChangeType, FileChangesEvent, IFileService, whenProviderRegistered, FileOperationError, FileOperationResult, FileOperation, FileOperationEvent } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser, ConfigurationParseOptions, UserSettings } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; import { WorkbenchState, IWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { ConfigurationScope, Extensions, IConfigurationRegistry, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry'; @@ -27,6 +27,7 @@ import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/envir import { isEmptyObject, isObject } from 'vs/base/common/types'; import { DefaultConfiguration as BaseDefaultConfiguration } from 'vs/platform/configuration/common/configurations'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; export class DefaultConfiguration extends BaseDefaultConfiguration { @@ -118,6 +119,37 @@ export class DefaultConfiguration extends BaseDefaultConfiguration { } +export class ApplicationConfiguration extends UserSettings { + + private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); + readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; + + private readonly reloadConfigurationScheduler: RunOnceScheduler; + + constructor( + userDataProfilesService: IUserDataProfilesService, + fileService: IFileService, + uriIdentityService: IUriIdentityService, + ) { + super(userDataProfilesService.defaultProfile.settingsResource, { scopes: [ConfigurationScope.APPLICATION] }, uriIdentityService.extUri, fileService); + this._register(this.onDidChange(() => this.reloadConfigurationScheduler.schedule())); + this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.loadConfiguration().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50)); + } + + async initialize(): Promise { + return this.loadConfiguration(); + } + + override async loadConfiguration(): Promise { + const model = await super.loadConfiguration(); + const value = model.getValue(APPLY_ALL_PROFILES_SETTING); + const allProfilesSettings = Array.isArray(value) ? value : []; + return this.parseOptions.include || allProfilesSettings.length + ? this.reparse({ ...this.parseOptions, include: allProfilesSettings }) + : model; + } +} + export class UserConfiguration extends Disposable { private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); @@ -127,29 +159,26 @@ export class UserConfiguration extends Disposable { private readonly userConfigurationChangeDisposable = this._register(new MutableDisposable()); private readonly reloadConfigurationScheduler: RunOnceScheduler; - private configurationParseOptions: ConfigurationParseOptions; - get hasTasksLoaded(): boolean { return this.userConfiguration.value instanceof FileServiceBasedConfiguration; } constructor( private settingsResource: URI, private tasksResource: URI | undefined, - scopes: ConfigurationScope[] | undefined, + private configurationParseOptions: ConfigurationParseOptions, private readonly fileService: IFileService, private readonly uriIdentityService: IUriIdentityService, private readonly logService: ILogService, ) { super(); - this.configurationParseOptions = { scopes, skipRestricted: false }; - this.userConfiguration.value = new UserSettings(settingsResource, scopes, uriIdentityService.extUri, this.fileService); + this.userConfiguration.value = new UserSettings(settingsResource, this.configurationParseOptions, uriIdentityService.extUri, this.fileService); this.userConfigurationChangeDisposable.value = this.userConfiguration.value.onDidChange(() => this.reloadConfigurationScheduler.schedule()); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.userConfiguration.value!.loadConfiguration().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50)); } - async reset(settingsResource: URI, tasksResource: URI | undefined, scopes: ConfigurationScope[] | undefined): Promise { + async reset(settingsResource: URI, tasksResource: URI | undefined, configurationParseOptions: ConfigurationParseOptions): Promise { this.settingsResource = settingsResource; this.tasksResource = tasksResource; - this.configurationParseOptions = { scopes, skipRestricted: false }; + this.configurationParseOptions = configurationParseOptions; const folder = this.uriIdentityService.extUri.dirname(this.settingsResource); const standAloneConfigurationResources: [string, URI][] = this.tasksResource ? [[TASKS_CONFIGURATION_KEY, this.tasksResource]] : []; const fileServiceBasedConfiguration = new FileServiceBasedConfiguration(folder.toString(), this.settingsResource, standAloneConfigurationResources, this.configurationParseOptions, this.fileService, this.uriIdentityService, this.logService); @@ -172,10 +201,11 @@ export class UserConfiguration extends Disposable { if (this.hasTasksLoaded) { return this.userConfiguration.value!.loadConfiguration(); } - return this.reset(this.settingsResource, this.tasksResource, this.configurationParseOptions.scopes); + return this.reset(this.settingsResource, this.tasksResource, this.configurationParseOptions); } - reparse(): ConfigurationModel { + reparse(parseOptions?: Partial): ConfigurationModel { + this.configurationParseOptions = { ...this.configurationParseOptions, ...parseOptions }; return this.userConfiguration.value!.reparse(this.configurationParseOptions); } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 7e68eba7dd704..9a920e59af042 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -15,13 +15,13 @@ import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from 'vs/p import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString, IConfigurationUpdateOverrides, isConfigurationUpdateOverrides, IConfigurationService, IConfigurationUpdateOptions } from 'vs/platform/configuration/common/configuration'; import { IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from 'vs/platform/configuration/common/configurations'; import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings, ConfigurationScope, IConfigurationPropertySchema, keyFromOverrideIdentifiers, OVERRIDE_PROPERTY_PATTERN, resourceLanguageSettingsSchemaId, configurationDefaultsSchemaId } from 'vs/platform/configuration/common/configurationRegistry'; import { IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, getStoredWorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ConfigurationEditing, EditableConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing'; -import { WorkspaceConfiguration, FolderConfiguration, RemoteUserConfiguration, UserConfiguration, DefaultConfiguration } from 'vs/workbench/services/configuration/browser/configuration'; +import { WorkspaceConfiguration, FolderConfiguration, RemoteUserConfiguration, UserConfiguration, DefaultConfiguration, ApplicationConfiguration } from 'vs/workbench/services/configuration/browser/configuration'; import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; @@ -44,6 +44,7 @@ import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/pol import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; +import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { return userDataProfile.isDefault @@ -67,7 +68,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat private initialized: boolean = false; private readonly defaultConfiguration: DefaultConfiguration; private readonly policyConfiguration: IPolicyConfiguration; - private applicationConfiguration: UserConfiguration | null = null; + private applicationConfiguration: ApplicationConfiguration | null = null; private readonly applicationConfigurationDisposables: DisposableStore; private readonly localUserConfiguration: UserConfiguration; private readonly remoteUserConfiguration: RemoteUserConfiguration | null = null; @@ -125,7 +126,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat this._configuration = new Configuration(this.defaultConfiguration.configurationModel, this.policyConfiguration.configurationModel, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), this.workspace); this.applicationConfigurationDisposables = this._register(new DisposableStore()); this.createApplicationConfiguration(); - this.localUserConfiguration = this._register(new UserConfiguration(userDataProfileService.currentProfile.settingsResource, userDataProfileService.currentProfile.tasksResource, getLocalUserConfigurationScopes(userDataProfileService.currentProfile, !!remoteAuthority), fileService, uriIdentityService, logService)); + this.localUserConfiguration = this._register(new UserConfiguration(userDataProfileService.currentProfile.settingsResource, userDataProfileService.currentProfile.tasksResource, { scopes: getLocalUserConfigurationScopes(userDataProfileService.currentProfile, !!remoteAuthority) }, fileService, uriIdentityService, logService)); this.cachedFolderConfigs = new ResourceMap(); this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); if (remoteAuthority) { @@ -159,7 +160,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat if (this.userDataProfileService.currentProfile.isDefault || this.userDataProfileService.currentProfile.useDefaultFlags?.settings) { this.applicationConfiguration = null; } else { - this.applicationConfiguration = this.applicationConfigurationDisposables.add(this._register(new UserConfiguration(this.userDataProfilesService.defaultProfile.settingsResource, undefined, [ConfigurationScope.APPLICATION], this.fileService, this.uriIdentityService, this.logService))); + this.applicationConfiguration = this.applicationConfigurationDisposables.add(this._register(new ApplicationConfiguration(this.userDataProfilesService, this.fileService, this.uriIdentityService))); this.applicationConfigurationDisposables.add(this.applicationConfiguration.onDidChangeConfiguration(configurationModel => this.onApplicationConfigurationChanged(configurationModel))); } } @@ -488,6 +489,14 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat this.instantiationService = instantiationService; } + isSettingAppliedForAllProfiles(key: string): boolean { + if (this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION) { + return true; + } + const allProfilesSettings = this.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; + return Array.isArray(allProfilesSettings) && allProfilesSettings.includes(key); + } + private async createWorkspace(arg: IAnyWorkspaceIdentifier): Promise { if (isWorkspaceIdentifier(arg)) { return this.createMultiFolderWorkspace(arg); @@ -592,31 +601,30 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat private async initializeConfiguration(trigger: boolean): Promise { await this.defaultConfiguration.initialize(); - const [, application, user] = await Promise.all([ - this.policyConfiguration.initialize(), - this.initializeApplicationConfiguration(), - (async () => { - mark('code/willInitUserConfiguration'); - const result = await this.initializeUserConfiguration(); - mark('code/didInitUserConfiguration'); - return result; - })() + const initPolicyConfigurationPromise = this.policyConfiguration.initialize(); + const initApplicationConfigurationPromise = this.applicationConfiguration ? this.applicationConfiguration.initialize() : Promise.resolve(new ConfigurationModel()); + const initUserConfiguration = async () => { + mark('code/willInitUserConfiguration'); + const result = await Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]); + if (this.applicationConfiguration) { + const applicationConfigurationModel = await initApplicationConfigurationPromise; + result[0] = this.localUserConfiguration.reparse({ exclude: applicationConfigurationModel.getValue(APPLY_ALL_PROFILES_SETTING) }); + } + mark('code/didInitUserConfiguration'); + return result; + }; + + const [, application, [local, remote]] = await Promise.all([ + initPolicyConfigurationPromise, + initApplicationConfigurationPromise, + initUserConfiguration() ]); mark('code/willInitWorkspaceConfiguration'); - await this.loadConfiguration(application, user.local, user.remote, trigger); + await this.loadConfiguration(application, local, remote, trigger); mark('code/didInitWorkspaceConfiguration'); } - private async initializeApplicationConfiguration(): Promise { - return this.applicationConfiguration ? this.applicationConfiguration.initialize() : Promise.resolve(new ConfigurationModel()); - } - - private async initializeUserConfiguration(): Promise<{ local: ConfigurationModel; remote: ConfigurationModel }> { - const [local, remote] = await Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]); - return { local, remote }; - } - private reloadDefaultConfiguration(): void { this.onDefaultConfigurationChanged(this.defaultConfiguration.reload()); } @@ -625,7 +633,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat if (!this.applicationConfiguration) { return new ConfigurationModel(); } - const model = await this.applicationConfiguration.reload(); + const model = await this.applicationConfiguration.loadConfiguration(); if (!donotTrigger) { this.onApplicationConfigurationChanged(model); } @@ -708,15 +716,19 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat private onUserDataProfileChanged(e: DidChangeUserDataProfileEvent): void { e.join((async () => { const promises: Promise[] = []; - promises.push(this.localUserConfiguration.reset(e.profile.settingsResource, e.profile.tasksResource, getLocalUserConfigurationScopes(e.profile, !!this.remoteUserConfiguration))); + promises.push(this.localUserConfiguration.reset(e.profile.settingsResource, e.profile.tasksResource, { scopes: getLocalUserConfigurationScopes(e.profile, !!this.remoteUserConfiguration) })); if (e.previous.isDefault !== e.profile.isDefault) { this.createApplicationConfiguration(); if (this.applicationConfiguration) { promises.push(this.reloadApplicationConfiguration(true)); } } - const [localUser, application] = await Promise.all(promises); - await this.loadConfiguration(application ?? this._configuration.applicationConfiguration, localUser, this._configuration.remoteUserConfiguration, true); + let [localUser, application] = await Promise.all(promises); + application = application ?? this._configuration.applicationConfiguration; + if (this.applicationConfiguration) { + localUser = this.localUserConfiguration.reparse({ exclude: application.getValue(APPLY_ALL_PROFILES_SETTING) }); + } + await this.loadConfiguration(application, localUser, this._configuration.remoteUserConfiguration, true); })()); } @@ -759,9 +771,35 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat private onApplicationConfigurationChanged(applicationConfiguration: ConfigurationModel): void { const previous = { data: this._configuration.toData(), workspace: this.workspace }; + const previousAllProfilesSettings = this._configuration.applicationConfiguration.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; const change = this._configuration.compareAndUpdateApplicationConfiguration(applicationConfiguration); + const currentAllProfilesSettings = this.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; const configurationProperties = this.configurationRegistry.getConfigurationProperties(); - change.keys = change.keys.filter(key => configurationProperties[key]?.scope === ConfigurationScope.APPLICATION); + const changedKeys: string[] = []; + for (const changedKey of change.keys) { + if (configurationProperties[changedKey]?.scope === ConfigurationScope.APPLICATION) { + changedKeys.push(changedKey); + if (changedKey === APPLY_ALL_PROFILES_SETTING) { + for (const previousAllProfileSetting of previousAllProfilesSettings) { + if (!currentAllProfilesSettings.includes(previousAllProfileSetting)) { + changedKeys.push(previousAllProfileSetting); + } + } + for (const currentAllProfileSetting of currentAllProfilesSettings) { + if (!previousAllProfilesSettings.includes(currentAllProfileSetting)) { + changedKeys.push(currentAllProfileSetting); + } + } + } + } + else if (currentAllProfilesSettings.includes(changedKey)) { + changedKeys.push(changedKey); + } + } + change.keys = changedKeys; + if (change.keys.includes(APPLY_ALL_PROFILES_SETTING)) { + this._configuration.updateLocalUserConfiguration(this.localUserConfiguration.reparse({ exclude: currentAllProfilesSettings })); + } this.triggerConfigurationChange(change, previous, ConfigurationTarget.USER); } @@ -981,7 +1019,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat await this.configurationEditing.writeConfiguration(editableConfigurationTarget, { key, value }, { scopes: overrides, ...options }); switch (editableConfigurationTarget) { case EditableConfigurationTarget.USER_LOCAL: - if (this.applicationConfiguration && this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION) { + if (this.applicationConfiguration && this.isSettingAppliedForAllProfiles(key)) { await this.reloadApplicationConfiguration(); } else { await this.reloadLocalUserConfiguration(); @@ -1313,3 +1351,18 @@ const workbenchContributionsRegistry = Registry.as(Extensions.Configuration); +configurationRegistry.registerConfiguration({ + ...workbenchConfigurationNodeBase, + properties: { + [APPLY_ALL_PROFILES_SETTING]: { + 'type': 'array', + description: localize('setting description', "Configure settings to be applied for all profiles."), + 'default': [], + 'scope': ConfigurationScope.APPLICATION, + additionalProperties: true, + uniqueItems: true, + } + } +}); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 95888019697bf..043add6bd72e1 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -84,6 +84,14 @@ export interface IWorkbenchConfigurationService extends IConfigurationService { * @param arg workspace Identifier */ initialize(arg: IAnyWorkspaceIdentifier): Promise; + + /** + * Returns true if the setting can be applied for all profiles otherwise false. + * @param setting + */ + isSettingAppliedForAllProfiles(setting: string): boolean; } export const TASKS_DEFAULT = '{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": []\n}'; + +export const APPLY_ALL_PROFILES_SETTING = 'workbench.settings.applyToAllProfiles'; diff --git a/src/vs/workbench/services/configuration/common/configurationEditing.ts b/src/vs/workbench/services/configuration/common/configurationEditing.ts index 04982ee66847e..adbf60a3ef6a9 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditing.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditing.ts @@ -12,8 +12,8 @@ import { Edit, FormattingOptions } from 'vs/base/common/jsonFormatter'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IConfigurationService, IConfigurationUpdateOptions, IConfigurationUpdateOverrides } from 'vs/platform/configuration/common/configuration'; -import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY, USER_STANDALONE_CONFIGURATIONS, TASKS_DEFAULT, FOLDER_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { IConfigurationUpdateOptions, IConfigurationUpdateOverrides } from 'vs/platform/configuration/common/configuration'; +import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY, USER_STANDALONE_CONFIGURATIONS, TASKS_DEFAULT, FOLDER_SCOPES, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, keyFromOverrideIdentifiers, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry'; @@ -144,7 +144,7 @@ export class ConfigurationEditing { constructor( private readonly remoteSettingsResource: URI | null, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IWorkbenchConfigurationService private readonly configurationService: IWorkbenchConfigurationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, @@ -586,10 +586,10 @@ export class ConfigurationEditing { const configurationScope = configurationProperties[key]?.scope; let jsonPath = overrides.overrideIdentifiers?.length ? [keyFromOverrideIdentifiers(overrides.overrideIdentifiers), key] : [key]; if (target === EditableConfigurationTarget.USER_LOCAL || target === EditableConfigurationTarget.USER_REMOTE) { - return { key, jsonPath, value: config.value, resource: withNullAsUndefined(this.getConfigurationFileResource(target, undefined, '', null, configurationScope)), target }; + return { key, jsonPath, value: config.value, resource: withNullAsUndefined(this.getConfigurationFileResource(target, key, '', null, configurationScope)), target }; } - const resource = this.getConfigurationFileResource(target, undefined, FOLDER_SETTINGS_PATH, overrides.resource, configurationScope); + const resource = this.getConfigurationFileResource(target, key, FOLDER_SETTINGS_PATH, overrides.resource, configurationScope); if (this.isWorkspaceConfigurationResource(resource)) { jsonPath = ['settings', ...jsonPath]; } @@ -601,12 +601,12 @@ export class ConfigurationEditing { return !!(workspace.configuration && resource && workspace.configuration.fsPath === resource.fsPath); } - private getConfigurationFileResource(target: EditableConfigurationTarget, standAloneConfigurationKey: string | undefined, relativePath: string, resource: URI | null | undefined, scope: ConfigurationScope | undefined): URI | null { + private getConfigurationFileResource(target: EditableConfigurationTarget, key: string, relativePath: string, resource: URI | null | undefined, scope: ConfigurationScope | undefined): URI | null { if (target === EditableConfigurationTarget.USER_LOCAL) { - if (standAloneConfigurationKey === TASKS_CONFIGURATION_KEY) { + if (key === TASKS_CONFIGURATION_KEY) { return this.userDataProfileService.currentProfile.tasksResource; } else { - if (scope === ConfigurationScope.APPLICATION && !this.userDataProfileService.currentProfile.isDefault) { + if (!this.userDataProfileService.currentProfile.isDefault && this.configurationService.isSettingAppliedForAllProfiles(key)) { return this.userDataProfilesService.defaultProfile.settingsResource; } return this.userDataProfileService.currentProfile.settingsResource; diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index 3ec31a2514773..e0613cac0c707 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -28,7 +28,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; +import { APPLY_ALL_PROFILES_SETTING, IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; import { SignService } from 'vs/platform/sign/browser/signService'; import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; import { IKeybindingEditingService, KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -1529,6 +1529,11 @@ suite('WorkspaceConfigurationService - Profiles', () => { 'id': '_test', 'type': 'object', 'properties': { + [APPLY_ALL_PROFILES_SETTING]: { + 'type': 'array', + 'default': [], + 'scope': ConfigurationScope.APPLICATION, + }, 'configurationService.profiles.applicationSetting': { 'type': 'string', 'default': 'isSet', @@ -1682,6 +1687,63 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting3'), 'defaultProfile'); })); + test('initialize with custom all profiles settings', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + await testObject.initialize(convertToWorkspacePayload(joinPath(ROOT, 'a'))); + + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + })); + + test('update all profiles settings', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], [APPLY_ALL_PROFILES_SETTING, 'configurationService.profiles.testSetting2']); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + })); + + test('setting applied to all profiles is registered later', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting4": "userValue" }')); + await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting4": "profileValue" }')); + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting4'], ConfigurationTarget.USER_LOCAL); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting4'), 'userValue'); + + configurationRegistry.registerConfiguration({ + 'id': '_test', + 'type': 'object', + 'properties': { + 'configurationService.profiles.testSetting4': { + 'type': 'string', + 'default': 'isSet', + } + } + }); + + await testObject.reloadConfiguration(); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting4'), 'userValue'); + })); + + test('update setting that is applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await testObject.updateValue('configurationService.profiles.testSetting2', 'updatedValue', ConfigurationTarget.USER_LOCAL); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting2']); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'updatedValue'); + })); + + test('test isSettingAppliedToAllProfiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.applicationSetting2'), true); + assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.testSetting2'), false); + + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.testSetting2'), true); + })); + test('switch to default profile', () => runWithFakedTimers({ useFakeTimers: true }, async () => { await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "applicationValue", "configurationService.profiles.testSetting": "userValue" }')); await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "profileValue", "configurationService.profiles.testSetting": "profileValue" }')); @@ -1725,6 +1787,46 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'isSet'); })); + test('switch to default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + await userDataProfileService.updateCurrentProfile(instantiationService.get(IUserDataProfilesService).defaultProfile); + + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + })); + + test('switch to non default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + const profile = toUserDataProfile('custom2', 'custom2', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache')); + await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting": "profileValue", "configurationService.profiles.testSetting2": "profileValue2" }')); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await userDataProfileService.updateCurrentProfile(profile); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting']); + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue'); + })); + + test('switch to non default from default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + await userDataProfileService.updateCurrentProfile(instantiationService.get(IUserDataProfilesService).defaultProfile); + + const profile = toUserDataProfile('custom2', 'custom2', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache')); + await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting": "profileValue", "configurationService.profiles.testSetting2": "profileValue2" }')); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await userDataProfileService.updateCurrentProfile(profile); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting']); + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue'); + })); + }); suite('WorkspaceConfigurationService-Multiroot', () => { From 3881831877aa72d90c3a9524c810e870594ea15c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 01:20:50 +0200 Subject: [PATCH 0057/1180] Apply extension to all profiles (#187767) Apply extension to all profiles #157492 --- .../browser/extensions.contribution.ts | 18 ++++++++++++++++++ .../extensions/browser/extensionsActions.ts | 6 +++++- .../browser/extensionsWorkbenchService.ts | 10 +++++++++- .../contrib/extensions/common/extensions.ts | 1 + .../common/extensionManagementService.ts | 4 ++-- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index f0f2c01fbbda5..a3859aab82254 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -1442,6 +1442,24 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi } }); + this.registerExtensionAction({ + id: 'workbench.extensions.action.toggleApplyToAllProfiles', + title: { value: localize('workbench.extensions.action.toggleApplyToAllProfiles', "Apply this Extension to all Profiles"), original: `Apply this Extension to all Profiles` }, + toggled: ContextKeyExpr.has('isApplicationScopedExtension'), + menu: { + id: MenuId.ExtensionContext, + group: '2_configure', + when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate()), + order: 4 + }, + run: async (accessor: ServicesAccessor, id: string) => { + const extension = this.extensionsWorkbenchService.local.find(e => areSameExtensions({ id }, e.identifier)); + if (extension) { + return this.extensionsWorkbenchService.toggleApplyExtensionToAllProfiles(extension); + } + } + }); + this.registerExtensionAction({ id: 'workbench.extensions.action.ignoreRecommendation', title: { value: localize('workbench.extensions.action.ignoreRecommendation', "Ignore Recommendation"), original: `Ignore Recommendation` }, diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 9f651b6eee280..ee6c57e9959d0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -18,7 +18,7 @@ import { IGalleryExtension, IExtensionGalleryService, ILocalExtension, InstallOp import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionRecommendationReason, IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { areSameExtensions, getExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension, getWorkspaceSupportTypeMessage, TargetPlatform } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension, getWorkspaceSupportTypeMessage, TargetPlatform, isApplicationScopedExtension } from 'vs/platform/extensions/common/extensions'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IFileService, IFileContent } from 'vs/platform/files/common/files'; import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -1010,6 +1010,8 @@ async function getContextMenuActionsGroups(extension: IExtension | undefined | n if (extension) { cksOverlay.push(['extension', extension.identifier.id]); cksOverlay.push(['isBuiltinExtension', extension.isBuiltin]); + cksOverlay.push(['isDefaultApplicationScopedExtension', extension.local && isApplicationScopedExtension(extension.local.manifest)]); + cksOverlay.push(['isApplicationScopedExtension', extension.local && extension.local.isApplicationScoped]); cksOverlay.push(['extensionHasConfiguration', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.configuration]); cksOverlay.push(['extensionHasKeybindings', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.keybindings]); cksOverlay.push(['extensionHasCommands', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes?.commands]); @@ -1179,6 +1181,8 @@ export class MenuItemExtensionAction extends ExtensionAction { } if (this.action.id === TOGGLE_IGNORE_EXTENSION_ACTION_ID) { this.checked = !this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension); + } else { + this.checked = this.action.checked; } } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index db1ded35930b0..b333b339afe7f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -34,7 +34,7 @@ import * as resources from 'vs/base/common/resources'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IFileService } from 'vs/platform/files/common/files'; -import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, TargetPlatform, ExtensionIdentifier, IExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, TargetPlatform, ExtensionIdentifier, IExtensionIdentifier, IExtensionDescription, isApplicationScopedExtension } from 'vs/platform/extensions/common/extensions'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { IProductService } from 'vs/platform/product/common/productService'; import { FileAccess } from 'vs/base/common/network'; @@ -50,6 +50,7 @@ import { getLocale } from 'vs/platform/languagePacks/common/languagePacks'; import { ILocaleService } from 'vs/workbench/services/localization/common/locale'; import { TelemetryTrustedValue } from 'vs/platform/telemetry/common/telemetryUtils'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; interface IExtensionStateProvider { (extension: Extension): T; @@ -774,6 +775,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension @ILocaleService private readonly localeService: ILocaleService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IFileService private readonly fileService: IFileService, + @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, ) { super(); const preferPreReleasesValue = configurationService.getValue('_extensions.preferPreReleases'); @@ -1619,6 +1621,12 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension await this.userDataAutoSyncService.triggerSync(['IgnoredExtensionsUpdated'], false, false); } + async toggleApplyExtensionToAllProfiles(extension: IExtension): Promise { + if (extension.local && !isApplicationScopedExtension(extension.local.manifest)) { + await this.extensionManagementService.updateMetadata(extension.local, { isApplicationScoped: !extension.local.isApplicationScoped }, this.userDataProfilesService.defaultProfile.extensionsResource); + } + } + private isInstalledExtensionSynced(extension: ILocalExtension): boolean { if (extension.isMachineScoped) { return false; diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index 4c34dc5ba0428..1ce6153fb8bde 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -120,6 +120,7 @@ export interface IExtensionsWorkbenchService { // Sync APIs isExtensionIgnoredToSync(extension: IExtension): boolean; toggleExtensionIgnoredToSync(extension: IExtension): Promise; + toggleApplyExtensionToAllProfiles(extension: IExtension): Promise; } export const enum ExtensionEditorTab { diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts index ab17bcf9f8b85..1b378e1b24a55 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts @@ -153,10 +153,10 @@ export class ExtensionManagementService extends Disposable implements IWorkbench return Promise.reject(`Invalid location ${extension.location.toString()}`); } - updateMetadata(extension: ILocalExtension, metadata: Partial): Promise { + updateMetadata(extension: ILocalExtension, metadata: Partial, profileLocation?: URI): Promise { const server = this.getServer(extension); if (server) { - return server.extensionManagementService.updateMetadata(extension, metadata); + return server.extensionManagementService.updateMetadata(extension, metadata, profileLocation); } return Promise.reject(`Invalid location ${extension.location.toString()}`); } From 3ffd570e52ac3a9f3c783c86cc77fe1d80c58e7c Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:41:30 -0700 Subject: [PATCH 0058/1180] Exclude node_modules from CodeQL (#187773) Exclude node_modules --- CodeQL.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CodeQL.yml b/CodeQL.yml index 9ef07560af34e..eecb813a96f9a 100644 --- a/CodeQL.yml +++ b/CodeQL.yml @@ -21,3 +21,9 @@ path_classifiers: - "out-build" - "out-vscode" - "**/out/**" + + # The default behavior is to tag library code as `library`. Results are hidden + # for library code. You can tag further files as being library code by adding them + # to the `library` section. + library: + - "**/node_modules/**" From 2f1013a310bbd74410e74fad99497841edad0eda Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 12 Jul 2023 17:00:32 -0700 Subject: [PATCH 0059/1180] Render slash commands as blocks (#187620) --- src/vs/workbench/contrib/chat/browser/chat.ts | 1 + .../contrib/chat/browser/chatWidget.ts | 4 + .../browser/contrib/chatInputEditorContrib.ts | 118 +++++++++++++++--- .../contrib/chat/common/chatService.ts | 1 + .../vscode.proposed.interactive.d.ts | 1 + 5 files changed, 108 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index b42cad92d7e00..8c51aaa217532 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -60,6 +60,7 @@ export interface IChatWidget { acceptInput(query?: string): void; focusLastMessage(): void; focusInput(): void; + getSlashCommandsSync(): ISlashCommand[] | undefined; getSlashCommands(): Promise; getCodeBlockInfoForEditor(uri: URI): IChatCodeBlockInfo | undefined; getCodeBlockInfosForResponse(response: IChatResponseViewModel): IChatCodeBlockInfo[]; diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index fa29aac02296b..9fe7dc958362d 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -219,6 +219,10 @@ export class ChatWidget extends Disposable implements IChatWidget { } } + getSlashCommandsSync(): ISlashCommand[] | undefined { + return this.lastSlashCommands; + } + async getSlashCommands(): Promise { if (!this.viewModel) { return; diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index 1bf461d1ae382..830d85d35b639 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -15,24 +15,34 @@ import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { localize } from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; -import { editorForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { editorForeground, textCodeBlockBackground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart'; import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; +import { ContentWidgetPositionPreference, IContentWidget } from 'vs/editor/browser/editorBrowser'; +import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { Selection } from 'vs/editor/common/core/selection'; const decorationDescription = 'chat'; const slashCommandPlaceholderDecorationType = 'chat-session-detail'; const slashCommandTextDecorationType = 'chat-session-text'; +const slashCommandContentWidgetId = 'chat-session-content-widget'; class InputEditorDecorations extends Disposable { + private _slashCommandDomNode = document.createElement('div'); + private _slashCommandContentWidget: IContentWidget | undefined; + private _previouslyUsedSlashCommands = new Set(); + constructor( private readonly widget: IChatWidget, @ICodeEditorService private readonly codeEditorService: ICodeEditorService, @IThemeService private readonly themeService: IThemeService, + @IChatService private readonly chatService: IChatService, ) { super(); @@ -43,14 +53,25 @@ class InputEditorDecorations extends Disposable { this.updateInputEditorDecorations(); this._register(this.widget.inputEditor.onDidChangeModelContent(() => this.updateInputEditorDecorations())); - this._register(this.widget.onDidChangeViewModel(() => this.updateInputEditorDecorations())); + this._register(this.widget.onDidChangeViewModel(() => { + this._previouslyUsedSlashCommands.clear(); + this.updateInputEditorDecorations(); + })); + this._register(this.chatService.onDidSubmitSlashCommand((e) => { + if (e.sessionId === this.widget.viewModel?.sessionId && !this._previouslyUsedSlashCommands.has(e.slashCommand)) { + this._previouslyUsedSlashCommands.add(e.slashCommand); + } + })); } private updateRegisteredDecorationTypes() { - const theme = this.themeService.getColorTheme(); this.codeEditorService.removeDecorationType(slashCommandTextDecorationType); + this.updateInputEditorContentWidgets({ hide: true }); this.codeEditorService.registerDecorationType(decorationDescription, slashCommandTextDecorationType, { - color: theme.getColor(textLinkForeground)?.toString() + opacity: '0', + after: { + contentText: ' ', + } }); this.updateInputEditorDecorations(); } @@ -62,10 +83,10 @@ class InputEditorDecorations extends Disposable { } private async updateInputEditorDecorations() { - const value = this.widget.inputEditor.getValue(); + const inputValue = this.widget.inputEditor.getValue(); const slashCommands = await this.widget.getSlashCommands(); // TODO this async call can lead to a flicker of the placeholder text when switching editor tabs - if (!value) { + if (!inputValue) { const extensionPlaceholder = this.widget.viewModel?.inputPlaceholder; const defaultPlaceholder = slashCommands?.length ? localize('interactive.input.placeholderWithCommands', "Ask a question or type '/' for topics") : @@ -88,32 +109,44 @@ class InputEditorDecorations extends Disposable { } ]; this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandPlaceholderDecorationType, decoration); + this.updateInputEditorContentWidgets({ hide: true }); return; } - const command = value && slashCommands?.find(c => value.startsWith(`/${c.command} `)); - if (command && command.detail && value === `/${command.command} `) { - const decoration: IDecorationOptions[] = [ - { + let slashCommandPlaceholderDecoration: IDecorationOptions[] | undefined; + const command = inputValue && slashCommands?.find(c => inputValue.startsWith(`/${c.command} `)); + if (command && inputValue === `/${command.command} `) { + const isFollowupSlashCommand = this._previouslyUsedSlashCommands.has(command.command); + const shouldRenderFollowupPlaceholder = command.followupPlaceholder && isFollowupSlashCommand; + if (shouldRenderFollowupPlaceholder || command.detail) { + slashCommandPlaceholderDecoration = [{ range: { startLineNumber: 1, endLineNumber: 1, - startColumn: command.command.length + 2, + startColumn: command && typeof command !== 'string' ? (command?.command.length + 2) : 1, endColumn: 1000 }, renderOptions: { after: { - contentText: command.detail, - color: this.getPlaceholderColor() + contentText: shouldRenderFollowupPlaceholder ? command.followupPlaceholder : command.detail, + color: this.getPlaceholderColor(), + padding: '0 0 0 5px' } } - } - ]; - this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandPlaceholderDecorationType, decoration); - } else { + }]; + this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandPlaceholderDecorationType, slashCommandPlaceholderDecoration); + } + } + if (!slashCommandPlaceholderDecoration) { this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandPlaceholderDecorationType, []); } + if (command && inputValue.startsWith(`/${command.command} `)) { + this.updateInputEditorContentWidgets({ command: command.command }); + } else { + this.updateInputEditorContentWidgets({ hide: true }); + } + if (command && command.detail) { const textDecoration: IDecorationOptions[] = [ { @@ -130,6 +163,40 @@ class InputEditorDecorations extends Disposable { this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandTextDecorationType, []); } } + + private async updateInputEditorContentWidgets(arg: { command: string } | { hide: true }) { + const domNode = this._slashCommandDomNode; + + if (this._slashCommandContentWidget && 'hide' in arg) { + domNode.toggleAttribute('hidden', true); + this.widget.inputEditor.removeContentWidget(this._slashCommandContentWidget); + return; + } else if ('command' in arg) { + const theme = this.themeService.getColorTheme(); + domNode.style.padding = '0 0.4em'; + domNode.style.borderRadius = '3px'; + domNode.style.backgroundColor = theme.getColor(textCodeBlockBackground)?.toString() ?? ''; + domNode.style.color = theme.getColor(textLinkForeground)?.toString() ?? ''; + domNode.innerText = `${arg.command} `; + domNode.toggleAttribute('hidden', false); + + this._slashCommandContentWidget = { + getId() { return slashCommandContentWidgetId; }, + getDomNode() { return domNode; }, + getPosition() { + return { + position: { + lineNumber: 1, + column: 1 + }, + preference: [ContentWidgetPositionPreference.EXACT] + }; + }, + }; + + this.widget.inputEditor.addContentWidget(this._slashCommandContentWidget); + } + } } class InputEditorSlashCommandFollowups extends Disposable { @@ -139,6 +206,7 @@ class InputEditorSlashCommandFollowups extends Disposable { ) { super(); this._register(this.chatService.onDidSubmitSlashCommand(({ slashCommand, sessionId }) => this.repopulateSlashCommand(slashCommand, sessionId))); + this._register(this.widget.inputEditor.onKeyUp((e) => this.handleKeyUp(e))); } private async repopulateSlashCommand(slashCommand: string, sessionId: string) { @@ -159,6 +227,22 @@ class InputEditorSlashCommandFollowups extends Disposable { } } + + private handleKeyUp(e: IKeyboardEvent) { + if (e.keyCode !== KeyCode.Backspace) { + return; + } + + const value = this.widget.inputEditor.getValue().split(' ')[0]; + const currentSelection = this.widget.inputEditor.getSelection(); + if (!value.startsWith('/') || !currentSelection?.isEmpty() || currentSelection?.startLineNumber !== 1 || currentSelection?.startColumn !== value.length + 1) { + return; + } + + if (this.widget.getSlashCommandsSync()?.find((command) => `/${command.command}` === value)) { + this.widget.inputEditor.executeEdits('chat-input-editor-slash-commands', [{ range: new Range(1, 1, 1, currentSelection.startColumn), text: null }], [new Selection(1, 1, 1, 1)]); + } + } } ChatWidget.CONTRIBS.push(InputEditorDecorations, InputEditorSlashCommandFollowups); diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 95ebca455027d..59f031eb12043 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -71,6 +71,7 @@ export interface ISlashCommand { provider?: ISlashCommandProvider; sortText?: string; detail?: string; + followupPlaceholder?: 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 e8fefb4ba74e2..91224906d1b32 100644 --- a/src/vscode-dts/vscode.proposed.interactive.d.ts +++ b/src/vscode-dts/vscode.proposed.interactive.d.ts @@ -133,6 +133,7 @@ declare module 'vscode' { shouldRepopulate?: boolean; kind: CompletionItemKind; detail?: string; + followupPlaceholder?: string; } export interface InteractiveSessionReplyFollowup { From 5f8f10b5111a71f1a5903b775edf5a20689accb0 Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Wed, 12 Jul 2023 19:53:36 -0500 Subject: [PATCH 0060/1180] Fix #186781 --- .../contrib/terminalContrib/find/browser/terminalFindWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts index 2a3587555c5a1..2dc2579d56e5a 100644 --- a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts @@ -84,7 +84,7 @@ export class TerminalFindWidget extends SimpleFindWidget { override hide() { super.hide(); this._findWidgetVisible.reset(); - this._instance.focus(); + this._instance.focus(true); this._instance.xterm?.clearSearchDecorations(); } From 6b3e4d31dbb73cd42000b0c233d3b679023bf14e Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Wed, 12 Jul 2023 20:25:38 -0500 Subject: [PATCH 0061/1180] Show terminal find input action shorcuts in label --- .../browser/find/simpleFindWidget.ts | 22 ++++++++++--------- .../find/browser/terminalFindWidget.ts | 15 ++++++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index c402fb22a42b9..e604a67e2c188 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -18,7 +18,6 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { ContextScopedFindInput } from 'vs/platform/history/browser/contextScopedHistoryWidget'; import { widgetClose } from 'vs/platform/theme/common/iconRegistry'; import * as strings from 'vs/base/common/strings'; -import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { showHistoryKeybindingHint } from 'vs/platform/history/browser/historyWidgetKeybindingHint'; import { status } from 'vs/base/browser/ui/aria/aria'; @@ -34,9 +33,12 @@ interface IFindOptions { showCommonFindToggles?: boolean; checkImeCompletionState?: boolean; showResultCount?: boolean; - appendCaseSensitiveLabel?: string; - appendRegexLabel?: string; - appendWholeWordsLabel?: string; + appendCaseSensitiveActionId?: string; + appendRegexActionId?: string; + appendWholeWordsActionId?: string; + previousMatchActionId?: string; + nextMatchActionId?: string; + closeWidgetActionId?: string; matchesLimit?: number; type?: 'Terminal' | 'Webview'; } @@ -89,9 +91,9 @@ export abstract class SimpleFindWidget extends Widget { } }, showCommonFindToggles: options.showCommonFindToggles, - appendCaseSensitiveLabel: options.appendCaseSensitiveLabel && options.type === 'Terminal' ? this._getKeybinding(TerminalCommandId.ToggleFindCaseSensitive) : undefined, - appendRegexLabel: options.appendRegexLabel && options.type === 'Terminal' ? this._getKeybinding(TerminalCommandId.ToggleFindRegex) : undefined, - appendWholeWordsLabel: options.appendWholeWordsLabel && options.type === 'Terminal' ? this._getKeybinding(TerminalCommandId.ToggleFindWholeWord) : undefined, + appendCaseSensitiveLabel: options.appendCaseSensitiveActionId ? this._getKeybinding(options.appendCaseSensitiveActionId) : undefined, + appendRegexLabel: options.appendRegexActionId ? this._getKeybinding(options.appendRegexActionId) : undefined, + appendWholeWordsLabel: options.appendWholeWordsActionId ? this._getKeybinding(options.appendWholeWordsActionId) : undefined, showHistoryHint: () => showHistoryKeybindingHint(_keybindingService), inputBoxStyles: defaultInputBoxStyles, toggleStyles: defaultToggleStyles @@ -131,7 +133,7 @@ export abstract class SimpleFindWidget extends Widget { })); this.prevBtn = this._register(new SimpleButton({ - label: NLS_PREVIOUS_MATCH_BTN_LABEL, + label: NLS_PREVIOUS_MATCH_BTN_LABEL + (options.previousMatchActionId ? this._getKeybinding(options.previousMatchActionId) : ''), icon: findPreviousMatchIcon, onTrigger: () => { this.find(true); @@ -139,7 +141,7 @@ export abstract class SimpleFindWidget extends Widget { })); this.nextBtn = this._register(new SimpleButton({ - label: NLS_NEXT_MATCH_BTN_LABEL, + label: NLS_NEXT_MATCH_BTN_LABEL + (options.nextMatchActionId ? this._getKeybinding(options.nextMatchActionId) : ''), icon: findNextMatchIcon, onTrigger: () => { this.find(false); @@ -147,7 +149,7 @@ export abstract class SimpleFindWidget extends Widget { })); const closeBtn = this._register(new SimpleButton({ - label: NLS_CLOSE_BTN_LABEL, + label: NLS_CLOSE_BTN_LABEL + (options.closeWidgetActionId ? this._getKeybinding(options.closeWidgetActionId) : ''), icon: widgetClose, onTrigger: () => { this.hide(); diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts index 2a3587555c5a1..126447dbef93d 100644 --- a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts @@ -13,6 +13,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Event } from 'vs/base/common/event'; import type { ISearchOptions } from 'xterm-addon-search'; +import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; export class TerminalFindWidget extends SimpleFindWidget { private _findInputFocused: IContextKey; @@ -27,7 +28,19 @@ export class TerminalFindWidget extends SimpleFindWidget { @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService ) { - super({ showCommonFindToggles: true, checkImeCompletionState: true, showResultCount: true, type: 'Terminal', matchesLimit: XtermTerminalConstants.SearchHighlightLimit }, _contextViewService, _contextKeyService, keybindingService); + super({ + showCommonFindToggles: true, + checkImeCompletionState: true, + showResultCount: true, + appendCaseSensitiveActionId: TerminalCommandId.ToggleFindCaseSensitive, + appendRegexActionId: TerminalCommandId.ToggleFindRegex, + appendWholeWordsActionId: TerminalCommandId.ToggleFindWholeWord, + previousMatchActionId: TerminalCommandId.FindPrevious, + nextMatchActionId: TerminalCommandId.FindNext, + closeWidgetActionId: TerminalCommandId.FindHide, + type: 'Terminal', + matchesLimit: XtermTerminalConstants.SearchHighlightLimit + }, _contextViewService, _contextKeyService, keybindingService); this._register(this.state.onFindReplaceStateChange(() => { this.show(); From c8fe3e58a9e40e75efaa0ee86d6f435079866793 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 13 Jul 2023 11:28:25 +0200 Subject: [PATCH 0062/1180] Fixes #162450 - Support Inner Diff Line Alignment --- .../diffEditorWidget2/diffEditorWidget2.ts | 19 ++--- .../widget/diffEditorWidget2/lineAlignment.ts | 73 +++++++++++++++---- 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 91f99d55c6b15..1dab8ec750ef5 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -136,15 +136,16 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(autorunWithStore2('DiffEditorDecorations', (reader, store) => { store.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options)); })); - - this._register(this._instantiationService.createInstance( - ViewZoneManager, - this._editors, - this._diffModel, - this._options, - this, - () => this.unchangedRangesFeature.isUpdatingViewZones, - )); + this._register(autorunWithStore2('ViewZoneManager', (reader, store) => { + store.add(this._instantiationService.createInstance( + readHotReloadableExport(ViewZoneManager, reader), + this._editors, + this._diffModel, + this._options, + this, + () => this.unchangedRangesFeature.isUpdatingViewZones, + )); + })); this._register(autorunWithStore2('OverviewRulerPart', (reader, store) => { store.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors, diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts index 12f0c9bafed67..507e6d2039c7a 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts @@ -7,7 +7,7 @@ import { $ } from 'vs/base/browser/dom'; import { ArrayQueue } from 'vs/base/common/arrays'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { IObservable, derived, observableFromEvent, observableValue } from 'vs/base/common/observable'; import { autorun, autorunWithStore2 } from 'vs/base/common/observableImpl/autorun'; import { ThemeIcon } from 'vs/base/common/themables'; @@ -340,6 +340,17 @@ export class ViewZoneManager extends Disposable { scrollState.restore(this._editors.modified); })); + this._register(toDisposable(() => { + this._editors.original.changeViewZones((a) => { + for (const id of alignmentViewZoneIdsOrig) { a.removeZone(id); } + alignmentViewZoneIdsOrig.clear(); + }); + this._editors.modified.changeViewZones((a) => { + for (const id of alignmentViewZoneIdsMod) { a.removeZone(id); } + alignmentViewZoneIdsMod.clear(); + }); + })); + let ignoreChange = false; this._register(this._editors.original.onDidScrollChange(e => { if (e.scrollLeftChanged && !ignoreChange) { @@ -504,20 +515,52 @@ function computeRangeAlignment( const c = m.lineRangeMapping; handleAlignmentsOutsideOfDiffs(c.originalRange.startLineNumber, c.modifiedRange.startLineNumber); - const originalAdditionalHeight = originalLineHeightOverrides - .takeWhile(v => v.lineNumber < c.originalRange.endLineNumberExclusive) - ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; - const modifiedAdditionalHeight = modifiedLineHeightOverrides - .takeWhile(v => v.lineNumber < c.modifiedRange.endLineNumberExclusive) - ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; - - result.push({ - originalRange: c.originalRange, - modifiedRange: c.modifiedRange, - originalHeightInPx: c.originalRange.length * origLineHeight + originalAdditionalHeight, - modifiedHeightInPx: c.modifiedRange.length * modLineHeight + modifiedAdditionalHeight, - diff: m.lineRangeMapping, - }); + let first = true; + let lastModLineNumber = c.modifiedRange.startLineNumber; + let lastOrigLineNumber = c.originalRange.startLineNumber; + + function emitAlignment(origLineNumberExclusive: number, modLineNumberExclusive: number) { + if (origLineNumberExclusive < lastOrigLineNumber || modLineNumberExclusive < lastModLineNumber) { + return; + } + if (first) { + first = false; + } else if (origLineNumberExclusive === lastOrigLineNumber || modLineNumberExclusive === lastModLineNumber) { + return; + } + const originalRange = new LineRange(lastOrigLineNumber, origLineNumberExclusive); + const modifiedRange = new LineRange(lastModLineNumber, modLineNumberExclusive); + if (originalRange.isEmpty && modifiedRange.isEmpty) { + return; + } + + const originalAdditionalHeight = originalLineHeightOverrides + .takeWhile(v => v.lineNumber < origLineNumberExclusive) + ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; + const modifiedAdditionalHeight = modifiedLineHeightOverrides + .takeWhile(v => v.lineNumber < modLineNumberExclusive) + ?.reduce((p, c) => p + c.heightInPx, 0) ?? 0; + + result.push({ + originalRange, + modifiedRange, + originalHeightInPx: originalRange.length * origLineHeight + originalAdditionalHeight, + modifiedHeightInPx: modifiedRange.length * modLineHeight + modifiedAdditionalHeight, + }); + + lastOrigLineNumber = origLineNumberExclusive; + lastModLineNumber = modLineNumberExclusive; + } + + for (const i of c.innerChanges || []) { + if (i.originalRange.startColumn > 1 && i.modifiedRange.startColumn > 1) { + // There is some unmodified text on this line + emitAlignment(i.originalRange.startLineNumber, i.modifiedRange.startLineNumber); + } + emitAlignment(i.originalRange.endLineNumber, i.modifiedRange.endLineNumber); + } + + emitAlignment(c.originalRange.endLineNumberExclusive, c.modifiedRange.endLineNumberExclusive); lastOriginalLineNumber = c.originalRange.endLineNumberExclusive; lastModifiedLineNumber = c.modifiedRange.endLineNumberExclusive; From 369585db99845a28851b0bcfde7a5e66aba43397 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 12:12:23 +0200 Subject: [PATCH 0063/1180] work in progress --- .../browser/inlineChatController.ts | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 05cb6b8e8df7c..4a5c801b3da91 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -217,16 +217,16 @@ export class InlineChatController implements IEditorContribution { private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { console.log('inside of CREATE_SESSION'); - console.log('this._activeSession : ', this._activeSession); + console.log('inside of CREATE_SESSION, this._activeSession : ', this._activeSession); if (this._activeSession) { - console.log('before clearing the session store'); + console.log('inside of CREATE_SESSION, before clearing the session store'); this._sessionStore.clear(); - console.log('before releasing teh session'); + console.log('inside of CREATE_SESSION, before releasing the session'); this._inlineChatSessionService.releaseSession(this._activeSession); - console.log('before calling pause'); + console.log('inside of CREATE_SESSION, before calling pause'); await this[State.PAUSE](); } - console.log('this._activeSession after the cleaning : ', this._activeSession); + console.log('inside of CREATE_SESSION, this._activeSession after the cleaning : ', this._activeSession); assertType(this._activeSession === undefined); assertType(this._editor.hasModel()); @@ -239,7 +239,7 @@ export class InlineChatController implements IEditorContribution { if (!session) { const createSessionCts = new CancellationTokenSource(); const msgListener = Event.once(this._messages.event)(m => { - console.log('inside of the msgListener code of CREATE_SESSION'); + console.log('inside of CREATE_SESSION, inside of the msgListener code of CREATE_SESSION'); this._log('state=_createSession) message received', m); if (m === Message.ACCEPT_INPUT) { // user accepted the input before having a session @@ -292,7 +292,7 @@ export class InlineChatController implements IEditorContribution { private async [State.INIT_UI](options: InlineChatRunOptions): Promise { console.log('inside of init ui'); - console.log('this._activeSession : ', this._activeSession); + console.log('inside of INIT_UI, this._activeSession : ', this._activeSession); assertType(this._activeSession); // hide/cancel inline completions when invoking IE @@ -353,20 +353,20 @@ export class InlineChatController implements IEditorContribution { if (editIsOutsideOfWholeRange) { this._log('text changed outside of whole range, FINISH session'); - console.log('before the third finish existing session'); + console.log('inside of INIT_UI, before the third finish existing session'); this.finishExistingSession(); } })); if (!this._activeSession.lastExchange) { - console.log('before waiting for input'); + console.log('inside of INIT_UI,before waiting for input'); return State.WAIT_FOR_INPUT; } else if (options.isUnstashed) { delete options.isUnstashed; - console.log('before apply response'); + console.log('inside of INIT_UI,before apply response'); return State.APPLY_RESPONSE; } else { - console.log('before show response'); + console.log('inside of INIT_UI,before show response'); return State.SHOW_RESPONSE; } } @@ -386,6 +386,8 @@ export class InlineChatController implements IEditorContribution { private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions): Promise { + console.log('inside of wait for input'); + assertType(this._activeSession); assertType(this._strategy); @@ -406,7 +408,7 @@ export class InlineChatController implements IEditorContribution { } else { const barrier = new Barrier(); const msgListener = Event.once(this._messages.event)(m => { - console.log('inside of msgListener of WAIT FOR INPUT'); + console.log('inside of WAIT_FOR_INPUT, inside of msgListener'); this._log('state=_waitForInput) message received', m); message = m; barrier.open(); @@ -418,16 +420,14 @@ export class InlineChatController implements IEditorContribution { this._zone.value.widget.selectAll(); if (message & (Message.CANCEL_INPUT | Message.CANCEL_SESSION)) { - console.log('inside of wait for input'); - console.log('entered into the case when message cancel session'); + console.log('inside of WAIT_FOR_INPUT,entered into the case when message cancel session'); await this[State.CANCEL](); return; // return State.CANCEL; } if (message & Message.ACCEPT_SESSION) { - console.log('inside of wait for input'); - console.log('entered into the case when message accept'); + console.log('inside of WAIT_FOR_INPUT,entered into the case when message accept'); await this[State.ACCEPT](); return; // return State.ACCEPT; @@ -681,7 +681,7 @@ export class InlineChatController implements IEditorContribution { } private async [State.ACCEPT]() { - console.log('inside of accept'); + console.log('inside of State.ACCEPT'); assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); @@ -835,12 +835,15 @@ export class InlineChatController implements IEditorContribution { if (this._activeSession) { if (this._activeSession.editMode === EditMode.Preview) { this._log('finishing existing session, using CANCEL', this._activeSession.editMode); + console.log('before cancelling inside of finish existing session'); this.cancelSession(); } else { this._log('finishing existing session, using APPLY', this._activeSession.editMode); + console.log('before accepting inside of finish existing session'); this.acceptSession(); } } + console.log('at the end of finish existing session'); } unstashLastSession(): Session | undefined { From f73d83fc52b548041ab457bda4e5dab0e3acba83 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 12:30:58 +0200 Subject: [PATCH 0064/1180] adding changes from review --- src/vs/editor/contrib/colorPicker/browser/colorPicker.css | 6 +++--- .../editor/contrib/colorPicker/browser/colorPickerWidget.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css index f84c7ba6f2b8f..f484517caba97 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPicker.css +++ b/src/vs/editor/contrib/colorPicker/browser/colorPicker.css @@ -48,19 +48,19 @@ cursor: pointer; color: white; flex: 1; + white-space: nowrap; + overflow: hidden; } .colorpicker-header .picked-color .picked-color-presentation { white-space: nowrap; - margin-left: 30px; + margin-left: 5px; margin-right: 5px; } .colorpicker-header .picked-color .codicon { color: inherit; font-size: 14px; - position: absolute; - left: 8px; } .colorpicker-header .picked-color.light { diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts index 6c8cc3ab4e00c..f5ed98581b522 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts @@ -38,9 +38,9 @@ export class ColorPickerHeader extends Disposable { dom.append(container, this._domNode); this._pickedColorNode = dom.append(this._domNode, $('.picked-color')); - this._pickedColorPresentation = dom.append(this._pickedColorNode, document.createElement('div')); + dom.append(this._pickedColorNode, $('span.codicon.codicon-color-mode')); + this._pickedColorPresentation = dom.append(this._pickedColorNode, document.createElement('span')); this._pickedColorPresentation.classList.add('picked-color-presentation'); - dom.append(this._pickedColorNode, $('.codicon.codicon-color-mode')); const tooltip = localize('clickToToggleColorOptions', "Click to toggle color options (rgb/hsl/hex)"); this._pickedColorNode.setAttribute('title', tooltip); From 01851f692ad8b890346f24187a4903697c14c702 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 12:47:09 +0200 Subject: [PATCH 0065/1180] placing instead the minimum size determination as the initial size of the content hover when it is instantiated --- .../contrib/hover/browser/contentHover.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 5cc8ab5028e18..e18fc352eb9b7 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -30,7 +30,7 @@ export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; - private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + private readonly _widget: ContentHoverWidget; getWidgetContent(): string | undefined { const node = this._widget.getDomNode(); @@ -52,6 +52,11 @@ export class ContentHoverController extends Disposable { ) { super(); + const initialHeight = this._editor.getOption(EditorOption.lineHeight) + 8; + const initialWidth = 4 / 3 * initialHeight; + const initialSize = new dom.Dimension(initialWidth, initialHeight); + this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor, initialSize)); + // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -481,9 +486,10 @@ export class ContentHoverWidget extends ResizableContentWidget { constructor( editor: ICodeEditor, + initialSize: dom.Dimension, @IContextKeyService contextKeyService: IContextKeyService ) { - super(editor); + super(editor, initialSize); this._hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(contextKeyService); this._hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(contextKeyService); @@ -504,7 +510,6 @@ export class ContentHoverWidget extends ResizableContentWidget { this._hoverFocusedKey.set(false); })); this._setHoverData(undefined); - this._setMinimumDimensions(); this._layout(); this._editor.addContentWidget(this); } @@ -519,15 +524,6 @@ export class ContentHoverWidget extends ResizableContentWidget { return ContentHoverWidget.ID; } - private _setMinimumDimensions(): void { - const width = 50; - const height = this._editor.getOption(EditorOption.lineHeight) + 8; - const contentsDomNode = this._hover.contentsDomNode; - contentsDomNode.style.minWidth = width + 'px'; - contentsDomNode.style.minHeight = height + 'px'; - this._resizableNode.minSize = new dom.Dimension(width, height); - } - private static _applyDimensions(container: HTMLElement, width: number | string, height: number | string): void { const transformedWidth = typeof width === 'number' ? `${width}px` : width; const transformedHeight = typeof height === 'number' ? `${height}px` : height; From bc4492981c3fc11012a11567f5b59bb7465e0c45 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 12:52:46 +0200 Subject: [PATCH 0066/1180] changing initial size to minimum size --- src/vs/editor/contrib/hover/browser/contentHover.ts | 12 ++++++------ .../contrib/hover/browser/resizableContentWidget.ts | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e18fc352eb9b7..8f33f317138a6 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -52,10 +52,10 @@ export class ContentHoverController extends Disposable { ) { super(); - const initialHeight = this._editor.getOption(EditorOption.lineHeight) + 8; - const initialWidth = 4 / 3 * initialHeight; - const initialSize = new dom.Dimension(initialWidth, initialHeight); - this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor, initialSize)); + const minimumHeight = this._editor.getOption(EditorOption.lineHeight) + 8; + const minimumWidth = 4 / 3 * minimumHeight; + const minimumSize = new dom.Dimension(minimumWidth, minimumHeight); + this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor, minimumSize)); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; @@ -486,10 +486,10 @@ export class ContentHoverWidget extends ResizableContentWidget { constructor( editor: ICodeEditor, - initialSize: dom.Dimension, + minimumSize: dom.Dimension, @IContextKeyService contextKeyService: IContextKeyService ) { - super(editor, initialSize); + super(editor, minimumSize); this._hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(contextKeyService); this._hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(contextKeyService); diff --git a/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts b/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts index 69b72483fb367..0243d9e88bf48 100644 --- a/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts +++ b/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts @@ -25,13 +25,13 @@ export abstract class ResizableContentWidget extends Disposable implements ICont constructor( protected readonly _editor: ICodeEditor, - initialSize: dom.IDimension = new dom.Dimension(10, 10) + minimumSize: dom.IDimension = new dom.Dimension(10, 10) ) { super(); this._resizableNode.domNode.style.position = 'absolute'; - this._resizableNode.minSize = new dom.Dimension(10, 10); + this._resizableNode.minSize = dom.Dimension.lift(minimumSize); + this._resizableNode.layout(minimumSize.height, minimumSize.width); this._resizableNode.enableSashes(true, true, true, true); - this._resizableNode.layout(initialSize.height, initialSize.width); this._register(this._resizableNode.onDidResize(e => { this._resize(new dom.Dimension(e.dimension.width, e.dimension.height)); if (e.done) { From 49e56b6e780af9b5cc374f6d16b0cb7879962940 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 13:00:25 +0200 Subject: [PATCH 0067/1180] removing the view category from toggle inline diff --- src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 4db24fc6c501e..aa5a36893213d 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -457,7 +457,6 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { mnemonicTitle: localize({ key: 'miToggleDiff', comment: ['&& denotes a mnemonic'] }, "&&Toggle Diff"), original: 'Toggle Diff', }, - category: Categories.View, toggled: { condition: ContextKeyExpr.equals('config.inlineChat.showDiff', true), title: localize('toggleDiff2', "Toggle Diff"), From 415aef325f3aac4ac4c46871661d9652bd6544f4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 13:04:15 +0200 Subject: [PATCH 0068/1180] changing the text toggle diff to show diff --- .../contrib/inlineChat/browser/inlineChatActions.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index aa5a36893213d..5673709af89bf 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -453,14 +453,14 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { super({ id: 'inlineChat.toggleDiff', title: { - value: localize('toggleDiff', 'Toggle Diff'), - mnemonicTitle: localize({ key: 'miToggleDiff', comment: ['&& denotes a mnemonic'] }, "&&Toggle Diff"), - original: 'Toggle Diff', + original: 'Show Diff', + value: localize('showDiff', 'Show Diff'), + mnemonicTitle: localize({ key: 'miShowDiff', comment: ['&& denotes a mnemonic'] }, "&&Show Diff"), }, toggled: { condition: ContextKeyExpr.equals('config.inlineChat.showDiff', true), - title: localize('toggleDiff2', "Toggle Diff"), - mnemonicTitle: localize({ key: 'miToggleDiff2', comment: ['&& denotes a mnemonic'] }, "&&Toggle Diff") + title: localize('showDiff2', "Show Diff"), + mnemonicTitle: localize({ key: 'miShowDiff2', comment: ['&& denotes a mnemonic'] }, "&&Show Diff") }, menu: [ { id: MenuId.CommandPalette }, From 1f0f32f1be19ca7b3b7f1f6fb604263f8a2dd54a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 13:09:34 +0200 Subject: [PATCH 0069/1180] adding text to specify that the showDiff only works when inlineChat.mode is live or livePreview --- src/vs/workbench/contrib/inlineChat/common/inlineChat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts index f38b88eccfa07..2f9a6665b42f8 100644 --- a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts +++ b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts @@ -201,7 +201,7 @@ Registry.as(Extensions.Configuration).registerConfigurat id: 'editor', properties: { 'inlineChat.showDiff': { - description: localize('showDiff', "Enable/disable showing the diff when edits are generated."), + description: localize('showDiff', "Enable/disable showing the diff when edits are generated. Works only with inlineChat.mode equal to live or livePreview."), default: true, type: 'boolean' } From 0a5437b9442f36ec4b4d120a15741586c91c1398 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 13:11:17 +0200 Subject: [PATCH 0070/1180] mergging several registered properties into one --- .../contrib/inlineChat/browser/inlineChatActions.ts | 1 - src/vs/workbench/contrib/inlineChat/common/inlineChat.ts | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 5673709af89bf..c9ae443901d8e 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -31,7 +31,6 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { Position } from 'vs/editor/common/core/position'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { Categories } from 'vs/platform/action/common/actionCommonCategories'; CommandsRegistry.registerCommandAlias('interactiveEditor.start', 'inlineChat.start'); diff --git a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts index 2f9a6665b42f8..61cf7d493a1a2 100644 --- a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts +++ b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts @@ -193,13 +193,7 @@ Registry.as(Extensions.Configuration).registerConfigurat localize('mode.preview', "Changes are previewed only and need to be accepted via the apply button. Ending a session will discard the changes."), localize('mode.live', "Changes are applied directly to the document but can be highlighted via inline diffs. Ending a session will keep the changes."), ] - } - } -}); - -Registry.as(Extensions.Configuration).registerConfiguration({ - id: 'editor', - properties: { + }, 'inlineChat.showDiff': { description: localize('showDiff', "Enable/disable showing the diff when edits are generated. Works only with inlineChat.mode equal to live or livePreview."), default: true, From 445ed8ecc3b11a8b48eeb518cff47edde8741fc7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 13:12:31 +0200 Subject: [PATCH 0071/1180] addinf an underscore in front of the onContextMenu call --- .../workbench/contrib/inlineChat/browser/inlineChatWidget.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index d5679287a370e..d1711bcb9110e 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -332,11 +332,11 @@ export class InlineChatWidget { this._store.add(markdownMessageToolbar); this._store.add(addDisposableListener(this._elements.root, EventType.CONTEXT_MENU, async (event: MouseEvent) => { - this.onContextMenu(event); + this._onContextMenu(event); })); } - private onContextMenu(event: MouseEvent) { + private _onContextMenu(event: MouseEvent) { this._contextMenuService.showContextMenu({ menuId: MENU_INLINE_CHAT_WIDGET_TOGGLE, getAnchor: () => event, From fe0645573ddf54267a5fdd66ddf20fa633f7e5c1 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 13 Jul 2023 14:08:06 +0200 Subject: [PATCH 0072/1180] Comments widget input box indistinguishable from rest of comments widget when it has content (#187819) Fixes #187745 --- src/vs/workbench/contrib/comments/browser/media/review.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/comments/browser/media/review.css b/src/vs/workbench/contrib/comments/browser/media/review.css index 13be5cf92fb9a..dc27b9a50ae0f 100644 --- a/src/vs/workbench/contrib/comments/browser/media/review.css +++ b/src/vs/workbench/contrib/comments/browser/media/review.css @@ -349,6 +349,12 @@ outline-width: 1px; } +.review-widget .body .comment-form .monaco-editor, +.review-widget .body .comment-form .monaco-editor .monaco-editor-background, +.review-widget .body .edit-container .monaco-editor .monaco-editor-background { + background-color: var(--vscode-peekViewTitle-background); +} + .review-widget .body .comment-form .monaco-editor, .review-widget .body .edit-container .monaco-editor { width: 100%; From 7895f9bc23f85ffe6db5e3d27cae984f9fffab1c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 14:08:47 +0200 Subject: [PATCH 0073/1180] revert the feature (#187816) #176813 revert the feature --- .../browser/preferencesRenderers.ts | 10 +- .../preferences/browser/settingsTree.ts | 49 +-------- .../configuration/browser/configuration.ts | 10 +- .../browser/configurationService.ts | 56 +---------- .../configuration/common/configuration.ts | 2 - .../test/browser/configurationService.test.ts | 99 +------------------ 6 files changed, 8 insertions(+), 218 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts index c80d1d641c896..3983b46e19186 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts @@ -44,7 +44,7 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c import { isEqual } from 'vs/base/common/resources'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; -import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; export interface IPreferencesRenderer extends IDisposable { render(): void; @@ -616,14 +616,6 @@ class UnsupportedSettingsRenderer extends Disposable implements languages.CodeAc if (configuration.scope === ConfigurationScope.APPLICATION) { // If we're in a profile setting file, and the setting is application-scoped, fade it out. markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); - } else if (this.configurationService.isSettingAppliedForAllProfiles(setting.key)) { - // If we're in the non-default profile setting file, and the setting can be applied in all profiles, fade it out. - markerData.push({ - severity: MarkerSeverity.Hint, - tags: [MarkerTag.Unnecessary], - ...setting.range, - message: nls.localize('allProfileSettingWhileInNonDefaultProfileSetting', "This setting cannot be applied because it is configured to be applied in all profiles using setting {0}. Value from the default profile will be used instead.", APPLY_ALL_PROFILES_SETTING) - }); } } } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index ff00480a0ee12..9124e87d359be 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -23,7 +23,6 @@ import { IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree'; import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; import { Action, IAction, Separator } from 'vs/base/common/actions'; -import { distinct } from 'vs/base/common/arrays'; import { Codicon } from 'vs/base/common/codicons'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -64,7 +63,7 @@ import { ISettingsEditorViewState, SettingsTreeElement, SettingsTreeGroupChild, import { ExcludeSettingWidget, IListDataItem, IObjectDataItem, IObjectEnumOption, IObjectKeySuggester, IObjectValueSuggester, ISettingListChangeEvent, IncludeSettingWidget, ListSettingWidget, ObjectSettingCheckboxWidget, ObjectSettingDropdownWidget, ObjectValue } from 'vs/workbench/contrib/preferences/browser/settingsWidgets'; import { LANGUAGE_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences'; import { settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry'; -import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; @@ -902,11 +901,6 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre } template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter); - template.elementDisposables.add(this._configService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING)) { - template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter); - } - })); const onChange = (value: any) => this._onDidChangeSetting.fire({ key: element.setting.key, @@ -1965,7 +1959,6 @@ export class SettingTreeRenderers { @IInstantiationService private readonly _instantiationService: IInstantiationService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @IContextViewService private readonly _contextViewService: IContextViewService, - @IUserDataProfilesService private readonly _userDataProfilesService: IUserDataProfilesService, @IUserDataSyncEnablementService private readonly _userDataSyncEnablementService: IUserDataSyncEnablementService, ) { this.settingActions = [ @@ -2024,9 +2017,6 @@ export class SettingTreeRenderers { private getActionsForSetting(setting: ISetting, settingTarget: SettingsTarget): IAction[] { const actions: IAction[] = []; - if (this._userDataProfilesService.isEnabled() && setting.scope !== ConfigurationScope.APPLICATION && settingTarget === ConfigurationTarget.USER_LOCAL) { - actions.push(this._instantiationService.createInstance(ApplySettingToAllProfilesAction, setting)); - } if (this._userDataSyncEnablementService.isEnabled() && !setting.disallowSyncIgnore) { actions.push(this._instantiationService.createInstance(SyncSettingAction, setting)); } @@ -2496,40 +2486,3 @@ class SyncSettingAction extends Action { } } - -class ApplySettingToAllProfilesAction extends Action { - static readonly ID = 'settings.applyToAllProfiles'; - static readonly LABEL = localize('applyToAllProfiles', "Apply Setting to all Profiles"); - - constructor( - private readonly setting: ISetting, - @IWorkbenchConfigurationService private readonly configService: IWorkbenchConfigurationService, - ) { - super(ApplySettingToAllProfilesAction.ID, ApplySettingToAllProfilesAction.LABEL); - this._register(Event.filter(configService.onDidChangeConfiguration, e => e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING))(() => this.update())); - this.update(); - } - - update() { - const allProfilesSettings = this.configService.getValue(APPLY_ALL_PROFILES_SETTING); - this.checked = allProfilesSettings.includes(this.setting.key); - } - - override async run(): Promise { - // first remove the current setting completely from ignored settings - const value = this.configService.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; - - if (this.checked) { - value.splice(value.indexOf(this.setting.key), 1); - } else { - value.push(this.setting.key); - } - - const newValue = distinct(value); - await this.configService.updateValue(APPLY_ALL_PROFILES_SETTING, newValue.length ? newValue : undefined, ConfigurationTarget.USER_LOCAL); - if (!this.checked) { - await this.configService.updateValue(this.setting.key, this.configService.inspect(this.setting.key).userLocal?.value, ConfigurationTarget.USER_LOCAL); - } - } - -} diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 8f942efdd0ee9..70f1fcd1e9359 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -11,7 +11,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FileChangeType, FileChangesEvent, IFileService, whenProviderRegistered, FileOperationError, FileOperationResult, FileOperation, FileOperationEvent } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser, ConfigurationParseOptions, UserSettings } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration'; +import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; import { WorkbenchState, IWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { ConfigurationScope, Extensions, IConfigurationRegistry, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry'; @@ -140,14 +140,6 @@ export class ApplicationConfiguration extends UserSettings { return this.loadConfiguration(); } - override async loadConfiguration(): Promise { - const model = await super.loadConfiguration(); - const value = model.getValue(APPLY_ALL_PROFILES_SETTING); - const allProfilesSettings = Array.isArray(value) ? value : []; - return this.parseOptions.include || allProfilesSettings.length - ? this.reparse({ ...this.parseOptions, include: allProfilesSettings }) - : model; - } } export class UserConfiguration extends Disposable { diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 9a920e59af042..b02fbc29e61cd 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -15,7 +15,7 @@ import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from 'vs/p import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString, IConfigurationUpdateOverrides, isConfigurationUpdateOverrides, IConfigurationService, IConfigurationUpdateOptions } from 'vs/platform/configuration/common/configuration'; import { IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from 'vs/platform/configuration/common/configurations'; import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings, ConfigurationScope, IConfigurationPropertySchema, keyFromOverrideIdentifiers, OVERRIDE_PROPERTY_PATTERN, resourceLanguageSettingsSchemaId, configurationDefaultsSchemaId } from 'vs/platform/configuration/common/configurationRegistry'; import { IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, getStoredWorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces'; @@ -44,7 +44,6 @@ import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/pol import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; -import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { return userDataProfile.isDefault @@ -490,11 +489,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat } isSettingAppliedForAllProfiles(key: string): boolean { - if (this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION) { - return true; - } - const allProfilesSettings = this.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; - return Array.isArray(allProfilesSettings) && allProfilesSettings.includes(key); + return this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION; } private async createWorkspace(arg: IAnyWorkspaceIdentifier): Promise { @@ -606,10 +601,6 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat const initUserConfiguration = async () => { mark('code/willInitUserConfiguration'); const result = await Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]); - if (this.applicationConfiguration) { - const applicationConfigurationModel = await initApplicationConfigurationPromise; - result[0] = this.localUserConfiguration.reparse({ exclude: applicationConfigurationModel.getValue(APPLY_ALL_PROFILES_SETTING) }); - } mark('code/didInitUserConfiguration'); return result; }; @@ -723,12 +714,8 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat promises.push(this.reloadApplicationConfiguration(true)); } } - let [localUser, application] = await Promise.all(promises); - application = application ?? this._configuration.applicationConfiguration; - if (this.applicationConfiguration) { - localUser = this.localUserConfiguration.reparse({ exclude: application.getValue(APPLY_ALL_PROFILES_SETTING) }); - } - await this.loadConfiguration(application, localUser, this._configuration.remoteUserConfiguration, true); + const [localUser, application] = await Promise.all(promises); + await this.loadConfiguration(application ?? this._configuration.applicationConfiguration, localUser, this._configuration.remoteUserConfiguration, true); })()); } @@ -771,35 +758,15 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat private onApplicationConfigurationChanged(applicationConfiguration: ConfigurationModel): void { const previous = { data: this._configuration.toData(), workspace: this.workspace }; - const previousAllProfilesSettings = this._configuration.applicationConfiguration.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; const change = this._configuration.compareAndUpdateApplicationConfiguration(applicationConfiguration); - const currentAllProfilesSettings = this.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; const configurationProperties = this.configurationRegistry.getConfigurationProperties(); const changedKeys: string[] = []; for (const changedKey of change.keys) { if (configurationProperties[changedKey]?.scope === ConfigurationScope.APPLICATION) { changedKeys.push(changedKey); - if (changedKey === APPLY_ALL_PROFILES_SETTING) { - for (const previousAllProfileSetting of previousAllProfilesSettings) { - if (!currentAllProfilesSettings.includes(previousAllProfileSetting)) { - changedKeys.push(previousAllProfileSetting); - } - } - for (const currentAllProfileSetting of currentAllProfilesSettings) { - if (!previousAllProfilesSettings.includes(currentAllProfileSetting)) { - changedKeys.push(currentAllProfileSetting); - } - } - } - } - else if (currentAllProfilesSettings.includes(changedKey)) { - changedKeys.push(changedKey); } } change.keys = changedKeys; - if (change.keys.includes(APPLY_ALL_PROFILES_SETTING)) { - this._configuration.updateLocalUserConfiguration(this.localUserConfiguration.reparse({ exclude: currentAllProfilesSettings })); - } this.triggerConfigurationChange(change, previous, ConfigurationTarget.USER); } @@ -1351,18 +1318,3 @@ const workbenchContributionsRegistry = Registry.as(Extensions.Configuration); -configurationRegistry.registerConfiguration({ - ...workbenchConfigurationNodeBase, - properties: { - [APPLY_ALL_PROFILES_SETTING]: { - 'type': 'array', - description: localize('setting description', "Configure settings to be applied for all profiles."), - 'default': [], - 'scope': ConfigurationScope.APPLICATION, - additionalProperties: true, - uniqueItems: true, - } - } -}); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 043add6bd72e1..227c827eb2a35 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -93,5 +93,3 @@ export interface IWorkbenchConfigurationService extends IConfigurationService { } export const TASKS_DEFAULT = '{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": []\n}'; - -export const APPLY_ALL_PROFILES_SETTING = 'workbench.settings.applyToAllProfiles'; diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index e0613cac0c707..b336cb2fec3fe 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -28,7 +28,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { APPLY_ALL_PROFILES_SETTING, IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; +import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; import { SignService } from 'vs/platform/sign/browser/signService'; import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; import { IKeybindingEditingService, KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -1529,11 +1529,6 @@ suite('WorkspaceConfigurationService - Profiles', () => { 'id': '_test', 'type': 'object', 'properties': { - [APPLY_ALL_PROFILES_SETTING]: { - 'type': 'array', - 'default': [], - 'scope': ConfigurationScope.APPLICATION, - }, 'configurationService.profiles.applicationSetting': { 'type': 'string', 'default': 'isSet', @@ -1687,61 +1682,9 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting3'), 'defaultProfile'); })); - test('initialize with custom all profiles settings', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - - await testObject.initialize(convertToWorkspacePayload(joinPath(ROOT, 'a'))); - - assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); - })); - - test('update all profiles settings', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - const promise = Event.toPromise(testObject.onDidChangeConfiguration); - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - - const changeEvent = await promise; - assert.deepStrictEqual([...changeEvent.affectedKeys], [APPLY_ALL_PROFILES_SETTING, 'configurationService.profiles.testSetting2']); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); - })); - - test('setting applied to all profiles is registered later', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting4": "userValue" }')); - await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting4": "profileValue" }')); - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting4'], ConfigurationTarget.USER_LOCAL); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting4'), 'userValue'); - - configurationRegistry.registerConfiguration({ - 'id': '_test', - 'type': 'object', - 'properties': { - 'configurationService.profiles.testSetting4': { - 'type': 'string', - 'default': 'isSet', - } - } - }); - - await testObject.reloadConfiguration(); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting4'), 'userValue'); - })); - - test('update setting that is applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - const promise = Event.toPromise(testObject.onDidChangeConfiguration); - await testObject.updateValue('configurationService.profiles.testSetting2', 'updatedValue', ConfigurationTarget.USER_LOCAL); - - const changeEvent = await promise; - assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting2']); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'updatedValue'); - })); - test('test isSettingAppliedToAllProfiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.applicationSetting2'), true); assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.testSetting2'), false); - - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.testSetting2'), true); })); test('switch to default profile', () => runWithFakedTimers({ useFakeTimers: true }, async () => { @@ -1787,46 +1730,6 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'isSet'); })); - test('switch to default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - - await userDataProfileService.updateCurrentProfile(instantiationService.get(IUserDataProfilesService).defaultProfile); - - assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); - })); - - test('switch to non default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - - const profile = toUserDataProfile('custom2', 'custom2', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache')); - await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting": "profileValue", "configurationService.profiles.testSetting2": "profileValue2" }')); - const promise = Event.toPromise(testObject.onDidChangeConfiguration); - await userDataProfileService.updateCurrentProfile(profile); - - const changeEvent = await promise; - assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting']); - assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue'); - })); - - test('switch to non default from default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); - await userDataProfileService.updateCurrentProfile(instantiationService.get(IUserDataProfilesService).defaultProfile); - - const profile = toUserDataProfile('custom2', 'custom2', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache')); - await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting": "profileValue", "configurationService.profiles.testSetting2": "profileValue2" }')); - const promise = Event.toPromise(testObject.onDidChangeConfiguration); - await userDataProfileService.updateCurrentProfile(profile); - - const changeEvent = await promise; - assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting']); - assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); - assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue'); - })); - }); suite('WorkspaceConfigurationService-Multiroot', () => { From 429d6d203af96da2edb38682ba8b9fd0ed173be2 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 14:09:05 +0200 Subject: [PATCH 0074/1180] remove the extension action to apply in all profiles #157492 (#187815) --- .../browser/extensions.contribution.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index a3859aab82254..f0f2c01fbbda5 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -1442,24 +1442,6 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi } }); - this.registerExtensionAction({ - id: 'workbench.extensions.action.toggleApplyToAllProfiles', - title: { value: localize('workbench.extensions.action.toggleApplyToAllProfiles', "Apply this Extension to all Profiles"), original: `Apply this Extension to all Profiles` }, - toggled: ContextKeyExpr.has('isApplicationScopedExtension'), - menu: { - id: MenuId.ExtensionContext, - group: '2_configure', - when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate()), - order: 4 - }, - run: async (accessor: ServicesAccessor, id: string) => { - const extension = this.extensionsWorkbenchService.local.find(e => areSameExtensions({ id }, e.identifier)); - if (extension) { - return this.extensionsWorkbenchService.toggleApplyExtensionToAllProfiles(extension); - } - } - }); - this.registerExtensionAction({ id: 'workbench.extensions.action.ignoreRecommendation', title: { value: localize('workbench.extensions.action.ignoreRecommendation', "Ignore Recommendation"), original: `Ignore Recommendation` }, From ca6ebd67d1edfa2d1f4ebe53211160106028496a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 13 Jul 2023 14:09:30 +0200 Subject: [PATCH 0075/1180] Update shellscript grammar (#187811) --- extensions/shellscript/cgmanifest.json | 4 ++-- .../syntaxes/shell-unix-bash.tmLanguage.json | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extensions/shellscript/cgmanifest.json b/extensions/shellscript/cgmanifest.json index 87be4976392e7..f246d45fe21b4 100644 --- a/extensions/shellscript/cgmanifest.json +++ b/extensions/shellscript/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/better-shell-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-shell-syntax", - "commitHash": "1bad17d8badf6283125aaa7c31be06ba64146a0f" + "commitHash": "ce62ea59e8e522f8a07d8d8a2d1f992c6c600b91" } }, "license": "MIT", - "version": "1.5.4" + "version": "1.6.2" } ], "version": 1 diff --git a/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json b/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json index e132b9e5699cb..68055eb7b29ef 100644 --- a/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json +++ b/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/better-shell-syntax/commit/1bad17d8badf6283125aaa7c31be06ba64146a0f", + "version": "https://github.com/jeff-hykin/better-shell-syntax/commit/ce62ea59e8e522f8a07d8d8a2d1f992c6c600b91", "name": "Shell Script", "scopeName": "source.shell", "patterns": [ @@ -14,7 +14,7 @@ ], "repository": { "alias_statement": { - "begin": "(alias)[ \\t]*+[ \\t]*+(?:((?<=^|;|&|[ \\t])(?:export|declare|typeset|local|readonly)(?=[ \\t]|;|&|$))[ \\t]*+)?((?|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?:((?<=^|;|&|[ \\t])(?:export|declare|typeset|local|readonly)(?=[ \\t]|;|&|$))|((?!\"|'|\\\\\\n?$)[^!'\" \\t\\n\\r]+?))(?:(?= |\\t)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(?|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?:((?<=^|;|&|[ \\t])(?:readonly|declare|typeset|export|local)(?=[ \\t]|;|&|$))|((?!\"|'|\\\\\\n?$)[^!'\" \\t\\n\\r]+?))(?:(?= |\\t)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(? Date: Thu, 13 Jul 2023 14:13:37 +0200 Subject: [PATCH 0076/1180] does not appear to work with when clauses inside of menu --- .../workbench/contrib/inlineChat/browser/inlineChatActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index c9ae443901d8e..03e8cf4238fac 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -462,8 +462,8 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { mnemonicTitle: localize({ key: 'miShowDiff2', comment: ['&& denotes a mnemonic'] }, "&&Show Diff") }, menu: [ - { id: MenuId.CommandPalette }, - { id: MENU_INLINE_CHAT_WIDGET_TOGGLE } + { id: MenuId.CommandPalette, when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview) }, + { id: MENU_INLINE_CHAT_WIDGET_TOGGLE, when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview) } ] }); } From a07bb86a618f10d43eb3b82d155b3408f37c4080 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 14:18:17 +0200 Subject: [PATCH 0077/1180] adding all the comments --- .../browser/inlineChatController.ts | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 4a5c801b3da91..58067e15c590d 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -482,7 +482,7 @@ export class InlineChatController implements IEditorContribution { let message = Message.NONE; const msgListener = Event.once(this._messages.event)(m => { - console.log('inside of msgListener of MAKE REQUEST'); + console.log('inside of MAKE_REQUEST, inside of msgListener of MAKE REQUEST'); this._log('state=_makeRequest) message received', m); message = m; requestCts.cancel(); @@ -537,14 +537,12 @@ export class InlineChatController implements IEditorContribution { this._activeSession.addExchange(new SessionExchange(this._activeSession.lastInput, response)); if (message & Message.CANCEL_SESSION) { - console.log('inside of make request'); - console.log('cancelling the session'); + console.log('inside of MAKE_REQUEST, cancelling the session'); return State.CANCEL; } else if (message & Message.PAUSE_SESSION) { return State.PAUSE; } else if (message & Message.ACCEPT_SESSION) { - console.log('inside of make request'); - console.log('accepting'); + console.log('inside of MAKE_REQUEST, accepting'); return State.ACCEPT; } else { return State.APPLY_RESPONSE; @@ -685,25 +683,25 @@ export class InlineChatController implements IEditorContribution { assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); - console.log('after assert type'); + console.log('inside of State.ACCEPT, after assert type'); try { - console.log('before strategy apply'); + console.log('inside of State.ACCEPT, before strategy apply'); await this._strategy.apply(); - console.log('after strategy apply'); + console.log('inside of State.ACCEPT, after strategy apply'); // TODO: ASK WHY DESPITE AWAIT AFTER STRATEFY NOT PRINTED BEFORE CREATE SESSION } catch (err) { - console.log('when error obtained'); + console.log('inside of State.ACCEPT, when error obtained'); this._dialogService.error(localize('err.apply', "Failed to apply changes.", toErrorMessage(err))); this._log('FAILED to apply changes'); this._log(err); } - console.log('before release session'); + console.log('inside of State.ACCEPT, before release session'); await this._inlineChatSessionService.releaseSession(this._activeSession); - console.log('before state pause'); + console.log('inside of State.ACCEPT, before state pause'); await this[State.PAUSE](); } From d80f78877bdd9f4228f2153d0502f3e964b736d4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 14:30:47 +0200 Subject: [PATCH 0078/1180] adding some more comments --- .../contrib/inlineChat/browser/inlineChatController.ts | 7 ++++++- .../contrib/inlineChat/browser/inlineChatSession.ts | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 58067e15c590d..6059b0c35a70f 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -144,6 +144,7 @@ export class InlineChatController implements IEditorContribution { dispose(): void { console.log('inside of dispose'); this._stashedSession.clear(); + console.log('inside of dispose before calling finishExistingSession'); this.finishExistingSession(); this._store.dispose(); this._log('controller disposed'); @@ -177,6 +178,7 @@ export class InlineChatController implements IEditorContribution { async run(options: InlineChatRunOptions | undefined = {}): Promise { this._log('session starting inside of run'); + console.log('before finishExistingSession inside of run'); await this.finishExistingSession(); this._stashedSession.clear(); console.log('before calling create session inside of run'); @@ -353,7 +355,7 @@ export class InlineChatController implements IEditorContribution { if (editIsOutsideOfWholeRange) { this._log('text changed outside of whole range, FINISH session'); - console.log('inside of INIT_UI, before the third finish existing session'); + console.log('inside of INIT_UI, before calling finish existing session'); this.finishExistingSession(); } })); @@ -729,6 +731,7 @@ export class InlineChatController implements IEditorContribution { // only stash sessions that had edits this._stashedSession.value = this._instaService.createInstance(StashedSession, this._editor, mySession); } else { + console.log('before releasing the session of cancel'); this._inlineChatSessionService.releaseSession(mySession); } } @@ -870,6 +873,7 @@ class StashedSession { this._ctxHasStashedSession.set(true); this._listener = Event.once(Event.any(editor.onDidChangeCursorSelection, editor.onDidChangeModelContent, editor.onDidChangeModel))(() => { this._session = undefined; + console.log('before release session of constructor'); this._sessionService.releaseSession(session); this._ctxHasStashedSession.reset(); }); @@ -879,6 +883,7 @@ class StashedSession { this._listener.dispose(); this._ctxHasStashedSession.reset(); if (this._session) { + console.log('before release session of dispose'); this._sessionService.releaseSession(this._session); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts index 83aa7b064ff7d..79ac5e76633a1 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts @@ -477,6 +477,7 @@ export class InlineChatSessionService implements IInlineChatSessionService { } releaseSession(session: Session): void { + console.log('at the beginning of the release session'); const { editor } = session; @@ -498,6 +499,7 @@ export class InlineChatSessionService implements IInlineChatSessionService { // send telemetry this._telemetryService.publicLog2('interactiveEditor/session', session.asTelemetryData()); + console.log('at the end of the release session'); } getSession(editor: ICodeEditor, uri: URI): Session | undefined { From 3c632446d5052f7e4f7c8b9b464efaf2a2d7a02e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 14:47:21 +0200 Subject: [PATCH 0079/1180] go over this and try to understand why it does not work --- .../browser/inlineChatController.ts | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 6059b0c35a70f..f15eff338cd8d 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -180,6 +180,7 @@ export class InlineChatController implements IEditorContribution { this._log('session starting inside of run'); console.log('before finishExistingSession inside of run'); await this.finishExistingSession(); + console.log('after finish existing session inside of run'); this._stashedSession.clear(); console.log('before calling create session inside of run'); await this._nextState(State.CREATE_SESSION, options); @@ -220,14 +221,15 @@ export class InlineChatController implements IEditorContribution { private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { console.log('inside of CREATE_SESSION'); console.log('inside of CREATE_SESSION, this._activeSession : ', this._activeSession); - if (this._activeSession) { - console.log('inside of CREATE_SESSION, before clearing the session store'); - this._sessionStore.clear(); - console.log('inside of CREATE_SESSION, before releasing the session'); - this._inlineChatSessionService.releaseSession(this._activeSession); - console.log('inside of CREATE_SESSION, before calling pause'); - await this[State.PAUSE](); - } + // if (this._activeSession) { + // console.log('inside of CREATE_SESSION, before clearing the session store'); + // this._sessionStore.clear(); + // console.log('inside of CREATE_SESSION, before releasing the session'); + // this._inlineChatSessionService.releaseSession(this._activeSession); + // console.log('inside of CREATE_SESSION, before calling pause'); + // // Doesn't appear to be properly awaited? + // await this[State.PAUSE](); + // } console.log('inside of CREATE_SESSION, this._activeSession after the cleaning : ', this._activeSession); assertType(this._activeSession === undefined); assertType(this._editor.hasModel()); @@ -691,7 +693,7 @@ export class InlineChatController implements IEditorContribution { console.log('inside of State.ACCEPT, before strategy apply'); await this._strategy.apply(); console.log('inside of State.ACCEPT, after strategy apply'); - // TODO: ASK WHY DESPITE AWAIT AFTER STRATEFY NOT PRINTED BEFORE CREATE SESSION + // TODO: ASK WHY DESPITE AWAIT, AFTER STRATEFY NOT PRINTED BEFORE CREATE SESSION } catch (err) { console.log('inside of State.ACCEPT, when error obtained'); this._dialogService.error(localize('err.apply', "Failed to apply changes.", toErrorMessage(err))); @@ -812,6 +814,7 @@ export class InlineChatController implements IEditorContribution { acceptSession(): void { console.log('inside of acceptSession method'); + // Will fire a message which will be picked up by the controller and some other code will be run this._messages.fire(Message.ACCEPT_SESSION); } From 930a745d60ebf5367e4e34a0e126ff609a7e6b1a Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Thu, 13 Jul 2023 06:18:12 -0700 Subject: [PATCH 0080/1180] Improve slash command rendering in inline chat (#187769) * Render inline chat slash commands as blocks * Allow backspace to delete slash command block * Remove unnecessary template string literal --- .../contrib/inlineChat/browser/inlineChat.css | 9 ++- .../inlineChat/browser/inlineChatWidget.ts | 72 ++++++++++++++++++- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css index 23073e494bade..5beab56e7f251 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css @@ -278,13 +278,20 @@ } .monaco-editor .inline-chat-slash-command { - color: var(--vscode-textLink-foreground) + opacity: 0; } .monaco-editor .inline-chat-slash-command-detail { opacity: 0.5; } +.monaco-editor .inline-chat-slash-command-content-widget { + padding: 0 0.4em; + border-radius: 3px; + background-color: var(--vscode-textCodeBlock-background); + color: var(--vscode-textLink-foreground); +} + /* diff zone */ .monaco-editor .inline-chat-diff-widget { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 57077181753fd..dc9490e8c4fa7 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./inlineChat'; -import { DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IActiveCodeEditor, ICodeEditor, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; +import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions'; import { IRange, Range } from 'vs/editor/common/core/range'; import { localize } from 'vs/nls'; @@ -49,6 +49,7 @@ import { ExpansionState } from 'vs/workbench/contrib/inlineChat/browser/inlineCh import { IdleValue } from 'vs/base/common/async'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IMenuWorkbenchButtonBarOptions, MenuWorkbenchButtonBar } from 'vs/platform/actions/browser/buttonbar'; +import { KeyCode } from 'vs/base/common/keyCodes'; const defaultAriaLabel = localize('aria-label', "Inline Chat Input"); @@ -180,6 +181,8 @@ export class InlineChatWidget { private _preferredExpansionState: ExpansionState | undefined; private _expansionState: ExpansionState = ExpansionState.NOT_CROPPED; + private _slashCommandContentWidget: SlashCommandContentWidget; + constructor( private readonly parentEditor: ICodeEditor, @IModelService private readonly _modelService: IModelService, @@ -278,6 +281,11 @@ export class InlineChatWidget { this._store.add(this._inputModel.onDidChangeContent(togglePlaceholder)); togglePlaceholder(); + // slash command content widget + + this._slashCommandContentWidget = new SlashCommandContentWidget(this._inputEditor); + this._store.add(this._slashCommandContentWidget); + // toolbars const toolbar = this._instantiationService.createInstance(MenuWorkbenchToolBar, this._elements.editorToolbar, MENU_INLINE_CHAT_WIDGET, { @@ -654,6 +662,8 @@ export class InlineChatWidget { const decorations = this._inputEditor.createDecorationsCollection(); const updateSlashDecorations = () => { + this._slashCommandContentWidget.hide(); + const newDecorations: IModelDeltaDecoration[] = []; for (const command of commands) { const withSlash = `/${command.command}`; @@ -664,9 +674,16 @@ export class InlineChatWidget { options: { description: 'inline-chat-slash-command', inlineClassName: 'inline-chat-slash-command', + after: { + // Force some space between slash command and placeholder + content: ' ' + } } }); + this._slashCommandContentWidget.setCommandText(command.command); + this._slashCommandContentWidget.show(); + // inject detail when otherwise empty if (firstLine === `/${command.command} `) { newDecorations.push({ @@ -691,6 +708,57 @@ export class InlineChatWidget { } } +class SlashCommandContentWidget extends Disposable implements IContentWidget { + private _domNode = document.createElement('div'); + private _lastSlashCommandText: string | undefined; + + constructor(private _editor: ICodeEditor) { + super(); + + this._domNode.toggleAttribute('hidden', true); + this._domNode.classList.add('inline-chat-slash-command-content-widget'); + + // If backspace at a slash command boundary, remove the slash command + this._register(this._editor.onKeyUp((e) => { + if (e.keyCode !== KeyCode.Backspace) { + return; + } + + const firstLine = this._editor.getModel()?.getLineContent(1); + const selection = this._editor.getSelection(); + const withSlash = `/${this._lastSlashCommandText}`; + if (!firstLine?.startsWith(withSlash) || !selection?.isEmpty() || selection?.startLineNumber !== 1 || selection?.startColumn !== withSlash.length + 1) { + return; + } + + // Allow to undo the backspace + this._editor.executeEdits('inline-chat-slash-command', [{ + range: new Range(1, 1, 1, selection.startColumn), + text: null + }]); + })); + } + + show() { + this._domNode.toggleAttribute('hidden', false); + this._editor.addContentWidget(this); + } + + hide() { + this._domNode.toggleAttribute('hidden', true); + this._editor.removeContentWidget(this); + } + + setCommandText(slashCommand: string) { + this._domNode.innerText = `${slashCommand} `; + this._lastSlashCommandText = slashCommand; + } + + getId() { return 'inline-chat-slash-command-content-widget'; } + getDomNode() { return this._domNode; } + getPosition() { return { position: { lineNumber: 1, column: 1 }, preference: [ContentWidgetPositionPreference.EXACT] }; } +} + export class InlineChatZoneWidget extends ZoneWidget { readonly widget: InlineChatWidget; From d40162dd41d14dfc23b3026edc0ff4b9a8eaeeb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 13 Jul 2023 15:36:14 +0200 Subject: [PATCH 0081/1180] update distro (#187830) --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2c98e0a79bf2f..a1961f94d9dd9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.81.0", - "distro": "bed7b201bc6ebbfc63268cb4c390d788a86b0192", + "distro": "97db68abc58fce4ef0a70cdaa6255836e6a8d085", "author": { "name": "Microsoft Corporation" }, @@ -231,4 +231,4 @@ "optionalDependencies": { "windows-foreground-love": "0.5.0" } -} +} \ No newline at end of file From 034fd0518396d1efbce5b99bcc6fd9c713597786 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 13 Jul 2023 16:00:16 +0200 Subject: [PATCH 0082/1180] inline chat - workaround not being able to hide all lines of an editor (#187836) --- .../browser/inlineChatLivePreviewWidget.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts index e39c8d6d6ab3d..afc0d55b3ce14 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts @@ -307,15 +307,22 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { } private _hideEditorRanges(editor: ICodeEditor, lineRanges: LineRange[]): void { + assertType(editor.hasModel()); + lineRanges = lineRanges.filter(range => !range.isEmpty); if (lineRanges.length === 0) { // todo? this._logService.debug(`[IE] diff NOTHING to hide for ${editor.getId()} with ${String(editor.getModel()?.uri)}`); return; } - const ranges = lineRanges.map(lineRangeAsRange); - editor.setHiddenAreas(ranges, InlineChatLivePreviewWidget._hideId); - this._logService.debug(`[IE] diff HIDING ${ranges} for ${editor.getId()} with ${String(editor.getModel()?.uri)}`); + + let hiddenRanges = lineRanges.map(lineRangeAsRange); + if (LineRange.fromRange(hiddenRanges.reduce(Range.plusRange)).equals(LineRange.ofLength(1, editor.getModel().getLineCount()))) { + // TODO not every line can be hidden, keep the first line around + hiddenRanges = [editor.getModel().getFullModelRange().delta(1)]; + } + editor.setHiddenAreas(hiddenRanges, InlineChatLivePreviewWidget._hideId); + this._logService.debug(`[IE] diff HIDING ${hiddenRanges} for ${editor.getId()} with ${String(editor.getModel()?.uri)}`); } protected override revealRange(range: Range, isLastLine: boolean): void { From b92a1b8e7433ff97154590183287336eb2973f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 13 Jul 2023 16:04:45 +0200 Subject: [PATCH 0083/1180] Do not show "Show Update Release Notes" for recovery releases (#187838) fixes #187828 --- src/vs/workbench/contrib/update/browser/update.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/update/browser/update.ts b/src/vs/workbench/contrib/update/browser/update.ts index 01fb0a759042e..538bbbd55782b 100644 --- a/src/vs/workbench/contrib/update/browser/update.ts +++ b/src/vs/workbench/contrib/update/browser/update.ts @@ -32,6 +32,7 @@ import { Event } from 'vs/base/common/event'; import { Action } from 'vs/base/common/actions'; export const CONTEXT_UPDATE_STATE = new RawContextKey('updateState', StateType.Uninitialized); +export const MAJOR_MINOR_UPDATE_AVAILABLE = new RawContextKey('majorMinorUpdateAvailable', false); export const RELEASE_NOTES_URL = new RawContextKey('releaseNotesUrl', ''); export const DOWNLOAD_URL = new RawContextKey('downloadUrl', ''); @@ -160,6 +161,7 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu private state: UpdateState; private readonly badgeDisposable = this._register(new MutableDisposable()); private updateStateContextKey: IContextKey; + private majorMinorUpdateAvailableContextKey: IContextKey; constructor( @IStorageService private readonly storageService: IStorageService, @@ -176,6 +178,7 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu super(); this.state = updateService.state; this.updateStateContextKey = CONTEXT_UPDATE_STATE.bindTo(this.contextKeyService); + this.majorMinorUpdateAvailableContextKey = MAJOR_MINOR_UPDATE_AVAILABLE.bindTo(this.contextKeyService); this._register(updateService.onStateChange(this.onUpdateStateChange, this)); this.onUpdateStateChange(this.updateService.state); @@ -237,9 +240,13 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu this.onUpdateDownloaded(state.update); break; - case StateType.Ready: + case StateType.Ready: { + const currentVersion = parseVersion(this.productService.version); + const nextVersion = parseVersion(state.update.productVersion); + this.majorMinorUpdateAvailableContextKey.set(Boolean(currentVersion && nextVersion && isMajorMinorUpdate(currentVersion, nextVersion))); this.onUpdateReady(state.update); break; + } } let badge: IBadge | undefined = undefined; @@ -461,16 +468,18 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu }); MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { group: '7_update', + order: 1, command: { id: 'update.showUpdateReleaseNotes', title: nls.localize('showUpdateReleaseNotes', "Show Update Release Notes") }, - when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready) + when: ContextKeyExpr.and(CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready), MAJOR_MINOR_UPDATE_AVAILABLE) }); CommandsRegistry.registerCommand('update.restart', () => this.updateService.quitAndInstall()); MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { group: '7_update', + order: 2, command: { id: 'update.restart', title: nls.localize('restartToUpdate', "Restart to Update (1)") From 201401dc6df97f0655a5efad34303a2d6b49b678 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 13 Jul 2023 16:08:48 +0200 Subject: [PATCH 0084/1180] Sends telemetry when a line is slow to tokenize. (#187835) Fixes https://github.com/microsoft/vscode-internalbacklog/issues/4454 --- .../browser/textMateTokenizationFeatureImpl.ts | 14 +++++++++----- .../textMateTokenizationSupport.ts | 14 +++++++++----- .../textMate/browser/worker/textMate.worker.ts | 4 ++-- .../textMate/browser/worker/textMateWorkerModel.ts | 8 ++++++-- .../browser/workerHost/textMateWorkerHost.ts | 6 +++--- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts index b36b7e5910ea9..dd19178ffe930 100644 --- a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts +++ b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts @@ -57,7 +57,7 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate private _currentTokenColorMap: string[] | null = null; private readonly _workerHost = this._instantiationService.createInstance( TextMateWorkerHost, - (timeMs, languageId, sourceExtensionId, lineLength) => this.reportTokenizationTime(timeMs, languageId, sourceExtensionId, lineLength, true) + (timeMs, languageId, sourceExtensionId, lineLength, isRandomSample) => this.reportTokenizationTime(timeMs, languageId, sourceExtensionId, lineLength, true, isRandomSample) ); constructor( @@ -291,9 +291,10 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate r.containsEmbeddedLanguages, (textModel, tokenStore) => this._workerHost.createBackgroundTokenizer(textModel, tokenStore, maxTokenizationLineLength), () => this._configurationService.getValue('editor.experimental.asyncTokenizationVerification'), - (timeMs, lineLength) => { - this.reportTokenizationTime(timeMs, languageId, r.sourceExtensionId, lineLength, false); - } + (timeMs, lineLength, isRandomSample) => { + this.reportTokenizationTime(timeMs, languageId, r.sourceExtensionId, lineLength, false, isRandomSample); + }, + true, ); tokenization.onDidEncounterLanguage((encodedLanguageId) => { if (!this._encounteredLanguages[encodedLanguageId]) { @@ -377,7 +378,7 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate } } - public reportTokenizationTime(timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number, fromWorker: boolean): void { + public reportTokenizationTime(timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number, fromWorker: boolean, isRandomSample: boolean): void { // 50 events per hour (one event has a low probability) if (TextMateTokenizationFeature.reportTokenizationTimeCounter > 50) { // Don't flood telemetry with too many events @@ -396,6 +397,7 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate lineLength: number; fromWorker: boolean; sourceExtensionId: string | undefined; + isRandomSample: boolean; }, { owner: 'hediet'; @@ -404,6 +406,7 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate lineLength: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To relate the performance to the line length' }; fromWorker: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To figure out if this line was tokenized sync or async' }; sourceExtensionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To figure out which extension contributed the grammar' }; + isRandomSample: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To figure out if this is a random sample or measured because of some other condition.' }; comment: 'This event gives insight about the performance certain grammars.'; }>('editor.tokenizedLine', { @@ -412,6 +415,7 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate lineLength, fromWorker, sourceExtensionId, + isRandomSample, }); } } diff --git a/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts b/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts index 8a643cedce161..6a7328d31cd37 100644 --- a/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts +++ b/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts @@ -20,9 +20,10 @@ export class TextMateTokenizationSupport extends Disposable implements ITokeniza private readonly _grammar: IGrammar, private readonly _initialState: StateStack, private readonly _containsEmbeddedLanguages: boolean, - private readonly _createBackgroundTokenizer?: (textModel: ITextModel, tokenStore: IBackgroundTokenizationStore) => IBackgroundTokenizer | undefined, - private readonly _backgroundTokenizerShouldOnlyVerifyTokens: () => boolean = () => false, - private readonly _reportTokenizationTime?: (timeMs: number, lineLength: number) => void, + private readonly _createBackgroundTokenizer: ((textModel: ITextModel, tokenStore: IBackgroundTokenizationStore) => IBackgroundTokenizer | undefined) | undefined, + private readonly _backgroundTokenizerShouldOnlyVerifyTokens: () => boolean, + private readonly _reportTokenizationTime: (timeMs: number, lineLength: number, isRandomSample: boolean) => void, + private readonly _reportSlowTokenization: boolean, ) { super(); } @@ -47,12 +48,15 @@ export class TextMateTokenizationSupport extends Disposable implements ITokeniza } public tokenizeEncoded(line: string, hasEOL: boolean, state: StateStack): EncodedTokenizationResult { - const shouldMeasure = this._reportTokenizationTime && (Math.random() * 10_000 < 1); + const isRandomSample = Math.random() * 10_000 < 1; + const shouldMeasure = this._reportSlowTokenization || isRandomSample; const sw = shouldMeasure ? new StopWatch(true) : undefined; const textMateResult = this._grammar.tokenizeLine2(line, state, 500); if (shouldMeasure) { const timeMS = sw!.elapsed(); - this._reportTokenizationTime!(timeMS, line.length); + if (isRandomSample || timeMS > 32) { + this._reportTokenizationTime!(timeMS, line.length, isRandomSample); + } } if (textMateResult.stoppedEarly) { diff --git a/src/vs/workbench/services/textMate/browser/worker/textMate.worker.ts b/src/vs/workbench/services/textMate/browser/worker/textMate.worker.ts index 9f4a7f42512d3..275db92323383 100644 --- a/src/vs/workbench/services/textMate/browser/worker/textMate.worker.ts +++ b/src/vs/workbench/services/textMate/browser/worker/textMate.worker.ts @@ -136,8 +136,8 @@ export class TextMateTokenizationWorker { this._host.setTokensAndStates(resource, versionId, tokens, stateDeltas); } - public reportTokenizationTime(timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number): void { - this._host.reportTokenizationTime(timeMs, languageId, sourceExtensionId, lineLength); + public reportTokenizationTime(timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number, isRandomSample: boolean): void { + this._host.reportTokenizationTime(timeMs, languageId, sourceExtensionId, lineLength, isRandomSample); } // #endregion diff --git a/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts b/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts index db68091ac5f80..c39793848673e 100644 --- a/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts +++ b/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts @@ -98,8 +98,12 @@ export class TextMateWorkerModel extends MirrorTextModel { if (r.grammar) { const tokenizationSupport = new TokenizationSupportWithLineLimit( this._encodedLanguageId, - new TextMateTokenizationSupport(r.grammar, r.initialState, false, undefined, undefined, - (timeMs, lineLength) => { this._worker.reportTokenizationTime(timeMs, languageId, r.sourceExtensionId, lineLength); }), + new TextMateTokenizationSupport(r.grammar, r.initialState, false, undefined, () => false, + (timeMs, lineLength, isRandomSample) => { + this._worker.reportTokenizationTime(timeMs, languageId, r.sourceExtensionId, lineLength, isRandomSample); + }, + false + ), this._maxTokenizationLineLength ); this._tokenizationStateStore = new TokenizerWithStateStore(this._lines.length, tokenizationSupport); diff --git a/src/vs/workbench/services/textMate/browser/workerHost/textMateWorkerHost.ts b/src/vs/workbench/services/textMate/browser/workerHost/textMateWorkerHost.ts index 71032a5943f71..723152d3d6b7e 100644 --- a/src/vs/workbench/services/textMate/browser/workerHost/textMateWorkerHost.ts +++ b/src/vs/workbench/services/textMate/browser/workerHost/textMateWorkerHost.ts @@ -38,7 +38,7 @@ export class TextMateWorkerHost implements IDisposable { private _grammarDefinitions: IValidGrammarDefinition[] = []; constructor( - private readonly _reportTokenizationTime: (timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number) => void, + private readonly _reportTokenizationTime: (timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number, isRandomSample: boolean) => void, @IExtensionResourceLoaderService private readonly _extensionResourceLoaderService: IExtensionResourceLoaderService, @IModelService private readonly _modelService: IModelService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, @@ -204,8 +204,8 @@ export class TextMateWorkerHost implements IDisposable { } } - public reportTokenizationTime(timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number): void { - this._reportTokenizationTime(timeMs, languageId, sourceExtensionId, lineLength); + public reportTokenizationTime(timeMs: number, languageId: string, sourceExtensionId: string | undefined, lineLength: number, isRandomSample: boolean): void { + this._reportTokenizationTime(timeMs, languageId, sourceExtensionId, lineLength, isRandomSample); } // #endregion From a015a64c25d2782c01c5d0cb7a11da1893ce1880 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 16:16:28 +0200 Subject: [PATCH 0085/1180] review change --- .../contrib/inlineChat/browser/inlineChatActions.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 03e8cf4238fac..95fef85528594 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -461,9 +461,10 @@ export class ToggleInlineDiff extends AbstractInlineChatAction { title: localize('showDiff2', "Show Diff"), mnemonicTitle: localize({ key: 'miShowDiff2', comment: ['&& denotes a mnemonic'] }, "&&Show Diff") }, + precondition: ContextKeyExpr.notEquals('config.inlineChat.mode', 'preview'), menu: [ - { id: MenuId.CommandPalette, when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview) }, - { id: MENU_INLINE_CHAT_WIDGET_TOGGLE, when: CTX_INLINE_CHAT_EDIT_MODE.notEqualsTo(EditMode.Preview) } + { id: MenuId.CommandPalette }, + { id: MENU_INLINE_CHAT_WIDGET_TOGGLE } ] }); } From 5284fb58407eb494befe1564691558d739798cfd Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 13 Jul 2023 16:18:33 +0200 Subject: [PATCH 0086/1180] make live preview always show a side-by-side diff (#187840) --- .../browser/inlineChatLivePreviewWidget.ts | 98 ++----------------- 1 file changed, 8 insertions(+), 90 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts index afc0d55b3ce14..9fd5b51465cd7 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts @@ -10,7 +10,7 @@ import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; -import { IModelDecorationOptions, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; +import { ITextModel } from 'vs/editor/common/model'; import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; @@ -21,7 +21,7 @@ import { LineRange } from 'vs/editor/common/core/lineRange'; import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { Position } from 'vs/editor/common/core/position'; import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions'; -import { IEditorDecorationsCollection, ScrollType } from 'vs/editor/common/editorCommon'; +import { ScrollType } from 'vs/editor/common/editorCommon'; import { ILogService } from 'vs/platform/log/common/log'; import { lineRangeAsRange, invertLineRange } from 'vs/workbench/contrib/inlineChat/browser/utils'; import { ResourceLabel } from 'vs/workbench/browser/labels'; @@ -43,7 +43,6 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { private readonly _sessionStore = this._disposables.add(new DisposableStore()); private readonly _diffEditor: IDiffEditor; - private readonly _inlineDiffDecorations: IEditorDecorationsCollection; private _dim: Dimension | undefined; private _isVisible: boolean = false; private _isDiffLocked: boolean = false; @@ -59,8 +58,6 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { super.create(); assertType(editor.hasModel()); - this._inlineDiffDecorations = editor.createDecorationsCollection(); - const diffContributions = EditorExtensionsRegistry .getEditorContributions() .filter(c => c.id !== INLINE_CHAT_ID && c.id !== FoldingController.ID); @@ -120,10 +117,6 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { this._disposables.add(themeService.onDidColorThemeChange(doStyle)); } - override dispose(): void { - this._inlineDiffDecorations.clear(); - super.dispose(); - } protected override _fillContainer(container: HTMLElement): void { container.appendChild(this._elements.domNode); @@ -137,7 +130,6 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { override hide(): void { this._cleanupFullDiff(); - this._cleanupInlineDiff(); this._sessionStore.clear(); super.hide(); this._isVisible = false; @@ -175,70 +167,9 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { return; } - if (changes.length === 0 || this._session.textModel0.getValueLength() === 0) { - // no change or changes to an empty file - this._logService.debug('[IE] livePreview-mode: no diff'); - this.hide(); - - } else if (changes.every(isInlineDiffFriendly)) { - // simple changes - this._logService.debug('[IE] livePreview-mode: inline diff'); - this._cleanupFullDiff(); - this._renderChangesWithInlineDiff(changes); - - } else { - // complex changes - this._logService.debug('[IE] livePreview-mode: full diff'); - this._cleanupInlineDiff(); - this._renderChangesWithFullDiff(changes, range); - } - } - - // --- inline diff - - private _renderChangesWithInlineDiff(changes: readonly LineRangeMapping[]) { - const original = this._session.textModel0; - - const decorations: IModelDeltaDecoration[] = []; - - for (const { innerChanges } of changes) { - if (!innerChanges) { - continue; - } - for (const { modifiedRange, originalRange } of innerChanges) { - - const options: IModelDecorationOptions = { - description: 'interactive-diff-inline', - showIfCollapsed: true, - }; - - if (!modifiedRange.isEmpty()) { - options.className = 'inline-chat-lines-inserted-range'; - } - - if (!originalRange.isEmpty()) { - let content = original.getValueInRange(originalRange); - if (content.length > 7) { - content = content.substring(0, 7) + '…'; - } - options.before = { - content, - inlineClassName: 'inline-chat-lines-deleted-range-inline' - }; - } - - decorations.push({ - range: modifiedRange, - options - }); - } - } - - this._inlineDiffDecorations.set(decorations); - } - - private _cleanupInlineDiff() { - this._inlineDiffDecorations.clear(); + // complex changes + this._logService.debug('[IE] livePreview-mode: full diff'); + this._renderChangesWithFullDiff(changes, range); } // --- full diff @@ -273,7 +204,9 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { } private _computeHiddenRanges(model: ITextModel, range: Range, changes: readonly LineRangeMapping[]) { - assertType(changes.length > 0); + if (changes.length === 0) { + changes = [new LineRangeMapping(LineRange.fromRange(range), LineRange.fromRange(range), undefined)]; + } let originalLineRange = changes[0].originalRange; let modifiedLineRange = changes[0].modifiedRange; @@ -347,21 +280,6 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { } } -function isInlineDiffFriendly(mapping: LineRangeMapping): boolean { - if (!mapping.modifiedRange.equals(mapping.originalRange)) { - return false; - } - if (!mapping.innerChanges) { - return false; - } - for (const { modifiedRange, originalRange } of mapping.innerChanges) { - if (Range.spansMultipleLines(modifiedRange) || Range.spansMultipleLines(originalRange)) { - return false; - } - } - return true; -} - export class InlineChatFileCreatePreviewWidget extends ZoneWidget { From 7a2d479ab9659b177a49135424c1a737f428e676 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 16:21:53 +0200 Subject: [PATCH 0087/1180] implement feedback (#187841) --- .../browser/userDataProfile.ts | 83 ++++++----------- .../browser/userDataProfilePreview.ts | 2 +- .../userDataProfileImportExportService.ts | 92 ++++++++----------- .../userDataProfile/common/userDataProfile.ts | 4 +- 4 files changed, 68 insertions(+), 113 deletions(-) diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index ec4a10c8f333f..ced5b63ed9bd3 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -31,10 +31,16 @@ import { IRequestService, asJson } from 'vs/platform/request/common/request'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ILogService } from 'vs/platform/log/common/log'; +const CREATE_EMPTY_PROFILE_ACTION_ID = 'workbench.profiles.actions.createEmptyProfile'; +const CREATE_EMPTY_PROFILE_ACTION_TITLE = { + value: localize('create empty profile', "Create an Empty Profile..."), + original: 'Create an Empty Profile...' +}; + const CREATE_FROM_CURRENT_PROFILE_ACTION_ID = 'workbench.profiles.actions.createFromCurrentProfile'; const CREATE_FROM_CURRENT_PROFILE_ACTION_TITLE = { - value: localize('save profile as', "Create from Current Profile..."), - original: 'Create from Current Profile...' + value: localize('save profile as', "Save Current Profile As..."), + original: 'Save Current Profile As...' }; const CREATE_NEW_PROFILE_ACTION_ID = 'workbench.profiles.actions.createNewProfile'; @@ -113,7 +119,6 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements this.registerCreateNewProfileAction(); this.registerCreateProfileAction(); this.registerDeleteProfileAction(); - this.registerCreateProfileFromTemplatesAction(); this.registerHelpAction(); } @@ -445,11 +450,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements this._register(registerAction2(class CreateEmptyProfileAction extends Action2 { constructor() { super({ - id: 'workbench.profiles.actions.createEmptyProfile', - title: { - value: localize('create empty profile', "Create an Empty Profile..."), - original: 'Create an Empty Profile...' - }, + id: CREATE_EMPTY_PROFILE_ACTION_ID, + title: CREATE_EMPTY_PROFILE_ACTION_TITLE, category: PROFILES_CATEGORY, f1: true, precondition: PROFILES_ENABLEMENT_CONTEXT @@ -480,7 +482,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements return; } try { - await this.userDataProfileImportExportService.createFromCurrentProfile(name); + await this.userDataProfileImportExportService.SaveCurrentProfileAs(name); } catch (error) { this.notificationService.error(error); } @@ -489,13 +491,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements private async createNewProfile(): Promise { const title = localize('create new profle', "Create New Profile..."); - const name = await this.getNameForProfile(title); - if (!name) { - return; - } - const settings: IQuickPickItem = { id: ProfileResourceType.Settings, label: localize('settings', "Settings"), picked: true }; - const keybindings: IQuickPickItem = { id: ProfileResourceType.Keybindings, label: localize('keybindings', "Keyboard Shortcuts"), picked: false }; + const keybindings: IQuickPickItem = { id: ProfileResourceType.Keybindings, label: localize('keybindings', "Keyboard Shortcuts"), picked: true }; const snippets: IQuickPickItem = { id: ProfileResourceType.Snippets, label: localize('snippets', "User Snippets"), picked: true }; const tasks: IQuickPickItem = { id: ProfileResourceType.Tasks, label: localize('tasks', "User Tasks"), picked: true }; const extensions: IQuickPickItem = { id: ProfileResourceType.Extensions, label: localize('extensions', "Extensions"), picked: true }; @@ -510,7 +507,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements quickPick.hideCheckAll = true; quickPick.ignoreFocusOut = true; quickPick.customLabel = localize('create', "Create Profile"); - quickPick.description = localize('customise the profile', "Choose the data that should be scoped to the new profile."); + quickPick.description = localize('customise the profile', "Unselect to link to the Default Profile"); const disposables = new DisposableStore(); const update = () => { @@ -523,7 +520,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements let needUpdate = false; for (const resource of resources) { resource.picked = items.includes(resource); - const description = resource.picked ? undefined : localize('use default profile', "From Default Profile"); + const description = resource.picked ? undefined : localize('use default profile', "Default Profile"); if (resource.description !== description) { resource.description = description; needUpdate = true; @@ -554,6 +551,11 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements return; } + const name = await this.getNameForProfile(title); + if (!name) { + return; + } + try { const useDefaultFlags: UseDefaultProfileFlags | undefined = result.length !== resources.length ? { settings: !result.includes(settings), @@ -609,11 +611,16 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements const commandService = accessor.get(ICommandService); const userDataProfileImportExportService = accessor.get(IUserDataProfileImportExportService); const quickPickItems: QuickPickItem[] = [{ + id: CREATE_EMPTY_PROFILE_ACTION_ID, + label: localize('empty profile', "Empty Profile..."), + }, { id: CREATE_NEW_PROFILE_ACTION_ID, label: localize('new profile', "New Profile..."), + }, { + type: 'separator', }, { id: CREATE_FROM_CURRENT_PROFILE_ACTION_ID, - label: localize('using current', "From Current Profile..."), + label: localize('using current', "Save Current Profile As..."), }]; const profileTemplateQuickPickItems = await that.getProfileTemplatesQuickPickItems(); if (profileTemplateQuickPickItems.length) { @@ -643,7 +650,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements }; that.telemetryService.publicLog2('profileCreationAction:builtinTemplate', { profileName: (pick).name }); const uri = URI.parse((pick).url); - return userDataProfileImportExportService.importProfile(uri); + return userDataProfileImportExportService.importProfile(uri, { mode: 'apply' }); } } } @@ -705,44 +712,6 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements }); } - private registerCreateProfileFromTemplatesAction(): void { - const that = this; - this._register(registerAction2(class CreateProfileFromTemplatesAction extends Action2 { - constructor() { - super({ - id: 'workbench.profiles.actions.createProfileFromTemplates', - title: { - value: localize('create profile from templates', "Create Profile from Templates..."), - original: 'Create Profile from Templates...' - }, - category: PROFILES_CATEGORY, - precondition: PROFILES_ENABLEMENT_CONTEXT, - }); - } - - async run(accessor: ServicesAccessor) { - const quickInputService = accessor.get(IQuickInputService); - const userDataProfileImportExportService = accessor.get(IUserDataProfileImportExportService); - const notificationService = accessor.get(INotificationService); - const profileTemplateQuickPickItems = await that.getProfileTemplatesQuickPickItems(); - if (profileTemplateQuickPickItems.length) { - const pick = await quickInputService.pick(profileTemplateQuickPickItems, - { - hideInput: true, - canPickMany: false, - title: localize('create profile from template title', "{0}: Create...", PROFILES_CATEGORY.value) - }); - if ((pick)?.url) { - const uri = URI.parse((pick).url); - return userDataProfileImportExportService.importProfile(uri); - } - } else { - notificationService.info(localize('no templates', "There are no templates to create from")); - } - } - })); - } - private registerHelpAction(): void { this._register(registerAction2(class HelpAction extends Action2 { constructor() { diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfilePreview.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfilePreview.ts index 63abe7798c6c0..095948fa26f55 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfilePreview.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfilePreview.ts @@ -20,7 +20,7 @@ export class UserDataProfilePreviewContribution extends Disposable implements IW ) { super(); if (environmentService.options?.profileToPreview) { - userDataProfileImportExportService.importProfile(URI.revive(environmentService.options.profileToPreview), { preview: true }) + userDataProfileImportExportService.importProfile(URI.revive(environmentService.options.profileToPreview), { mode: 'preview' }) .then(null, error => logService.error('Error while previewing the profile', getErrorMessage(error))); } } diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts index 18fc59d8551cf..3fe9085063c7d 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts @@ -199,18 +199,21 @@ export class UserDataProfileImportExportService extends Disposable implements IU disposables.add(toDisposable(() => this.isProfileImportInProgressContextKey.set(false))); try { + const mode = options?.mode ?? 'preview'; const profileTemplate = await this.progressService.withProgress({ location: ProgressLocation.Window, command: showWindowLogActionId, - title: localize('resolving uri', "{0}: Resolving profile content...", options?.preview ? localize('preview profile', "Preview Profile") : localize('import profile', "Create Profile")), + title: localize('resolving uri', "{0}: Resolving profile content...", options?.mode ? localize('preview profile', "Preview Profile") : localize('import profile', "Create Profile")), }, () => this.resolveProfileTemplate(uri)); if (!profileTemplate) { return; } - if (options?.preview) { - await this.previewProfile(uri, profileTemplate); - } else { - await this.doImportProfile(profileTemplate); + if (mode === 'preview') { + await this.previewProfile(profileTemplate); + } else if (mode === 'apply') { + await this.createAndSwitch(profileTemplate, false, true, localize('create profile', "Create Profile")); + } else if (mode === 'both') { + await this.importAndPreviewProfile(uri, profileTemplate); } } finally { disposables.dispose(); @@ -246,11 +249,11 @@ export class UserDataProfileImportExportService extends Disposable implements IU } } - async createFromCurrentProfile(name: string): Promise { + async SaveCurrentProfileAs(name: string): Promise { const userDataProfilesExportState = this.instantiationService.createInstance(UserDataProfileExportState, this.userDataProfileService.currentProfile); try { const profileTemplate = await userDataProfilesExportState.getProfileTemplate(name, undefined); - await this.doImportProfile(profileTemplate); + await this.createAndSwitch(profileTemplate, false, true, localize('save profile as', "Save Profile As")); } finally { userDataProfilesExportState.dispose(); } @@ -266,7 +269,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU sticky: true, }, async progress => { const reportProgress = (message: string) => progress.report({ message: localize('troubleshoot profile progress', "Setting up Troubleshoot Profile: {0}", message) }); - const profile = await this.importWithProgress(profileTemplate, true, false, reportProgress); + const profile = await this.createProfile(profileTemplate, true, false, reportProgress); if (profile) { reportProgress(localize('progress extensions', "Applying Extensions...")); await this.instantiationService.createInstance(ExtensionsResource).copy(this.userDataProfileService.currentProfile, profile, true); @@ -359,21 +362,21 @@ export class UserDataProfileImportExportService extends Disposable implements IU return profileTemplate; } - private async previewProfile(uri: URI, profileTemplate: IUserDataProfileTemplate): Promise { + private async importAndPreviewProfile(uri: URI, profileTemplate: IUserDataProfileTemplate): Promise { const disposables = new DisposableStore(); try { const userDataProfileImportState = disposables.add(this.instantiationService.createInstance(UserDataProfileImportState, profileTemplate)); profileTemplate = await userDataProfileImportState.getProfileTemplateToImport(); - const importedProfile = await this.importAndSwitch(profileTemplate, true, false, localize('preview profile', "Preview Profile")); + const importedProfile = await this.createAndSwitch(profileTemplate, true, false, localize('preview profile', "Preview Profile")); if (!importedProfile) { return; } const barrier = new Barrier(); - const importAction = this.getImportAction(barrier, userDataProfileImportState); + const importAction = this.getCreateAction(barrier, userDataProfileImportState); const primaryAction = isWeb ? new Action('importInDesktop', localize('import in desktop', "Create Profile in {0}", this.productService.nameLong), undefined, true, async () => this.openerService.open(uri, { openExternal: true })) : importAction; @@ -432,69 +435,52 @@ export class UserDataProfileImportExportService extends Disposable implements IU } } - private async doImportProfile(profileTemplate: IUserDataProfileTemplate): Promise { + private async previewProfile(profileTemplate: IUserDataProfileTemplate): Promise { const disposables = new DisposableStore(); try { const userDataProfileImportState = disposables.add(this.instantiationService.createInstance(UserDataProfileImportState, profileTemplate)); - const barrier = new Barrier(); - const importAction = this.getImportAction(barrier, userDataProfileImportState); if (userDataProfileImportState.isEmpty()) { - await importAction.run(); + await this.createAndSwitch(profileTemplate, false, true, localize('create profile', "Create Profile")); } else { + const barrier = new Barrier(); + const importAction = this.getCreateAction(barrier, userDataProfileImportState); await this.showProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW, profileTemplate.name, importAction, new BarrierAction(barrier, new Action('cancel', localize('cancel', "Cancel")), this.notificationService), false, userDataProfileImportState); + await barrier.wait(); + await this.hideProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW); } - await barrier.wait(); - await this.hideProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW); } finally { disposables.dispose(); } } - private getImportAction(barrier: Barrier, userDataProfileImportState: UserDataProfileImportState): IAction { - const title = localize('import', "Create Profile", userDataProfileImportState.profile.name); - const importAction = new BarrierAction(barrier, new Action('import', title, undefined, true, () => { - const importProfileFn = async () => { - importAction.enabled = false; - const profileTemplate = await userDataProfileImportState.getProfileTemplateToImport(); - const importedProfile = await this.importAndSwitch(profileTemplate, false, true, title); - if (!importedProfile) { - return; - } - }; - if (userDataProfileImportState.isEmpty()) { - return importProfileFn(); - } else { - return this.progressService.withProgress({ - location: IMPORT_PROFILE_PREVIEW_VIEW, - }, () => importProfileFn()); - } + private getCreateAction(barrier: Barrier, userDataProfileImportState: UserDataProfileImportState): IAction { + const importAction = new BarrierAction(barrier, new Action('title', localize('import', "Create Profile"), undefined, true, async () => { + importAction.enabled = false; + const profileTemplate = await userDataProfileImportState.getProfileTemplateToImport(); + return this.createAndSwitch(profileTemplate, false, true, localize('create profile', "Create Profile")); }), this.notificationService); return importAction; } - private async importAndSwitch(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, title: string): Promise { + private async createAndSwitch(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, title: string): Promise { return this.progressService.withProgress({ - location: ProgressLocation.Window, - command: showWindowLogActionId, + location: ProgressLocation.Notification, + delay: 500, + sticky: true, }, async (progress) => { - progress.report({ message: localize('Importing profile', "{0} ({1})...", title, profileTemplate.name) }); - return this.importAndSwitchWithProgress(profileTemplate, temporaryProfile, extensions, message => progress.report({ message: `${title} (${profileTemplate.name}): ${message}` })); + title = `${title} (${profileTemplate.name})`; + progress.report({ message: title }); + const reportProgress = (message: string) => progress.report({ message: `${title}: ${message}` }); + const profile = await this.createProfile(profileTemplate, temporaryProfile, extensions, reportProgress); + if (profile) { + reportProgress(localize('switching profile', "Switching Profile...")); + await this.userDataProfileManagementService.switchProfile(profile); + } + return profile; }); } - private async importAndSwitchWithProgress(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, progress: (message: string) => void): Promise { - const profile = await this.importWithProgress(profileTemplate, temporaryProfile, extensions, progress); - - if (!profile) { - return; - } - - progress(localize('switching profile', "Switching Profile...")); - await this.userDataProfileManagementService.switchProfile(profile); - return profile; - } - - private async importWithProgress(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, progress: (message: string) => void): Promise { + private async createProfile(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, progress: (message: string) => void): Promise { const profile = await this.getProfileToImport(profileTemplate, temporaryProfile); if (!profile) { return undefined; diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index 99b78b05bab8a..bd126081ab012 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -74,7 +74,7 @@ export function toUserDataProfileUri(path: string, productService: IProductServi } export interface IProfileImportOptions { - readonly preview?: boolean; + readonly mode?: 'preview' | 'apply' | 'both'; } export const IUserDataProfileImportExportService = createDecorator('IUserDataProfileImportExportService'); @@ -87,7 +87,7 @@ export interface IUserDataProfileImportExportService { exportProfile(): Promise; importProfile(uri: URI, options?: IProfileImportOptions): Promise; showProfileContents(): Promise; - createFromCurrentProfile(name: string): Promise; + SaveCurrentProfileAs(name: string): Promise; createTroubleshootProfile(): Promise; setProfile(profile: IUserDataProfileTemplate): Promise; } From 22bb4b95ccd2f128e4ab08e5b2099b58f51cbc9e Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 13 Jul 2023 07:50:43 -0700 Subject: [PATCH 0088/1180] build: exclude the cli third party notices from hygenie (#187843) This might get moved later on, but for now exclude them --- build/filters.js | 1 + 1 file changed, 1 insertion(+) diff --git a/build/filters.js b/build/filters.js index 095cf733f8ca7..d729582eb6ca2 100644 --- a/build/filters.js +++ b/build/filters.js @@ -32,6 +32,7 @@ module.exports.unicodeFilter = [ '**', '!**/ThirdPartyNotices.txt', + '!**/ThirdPartyNotices.cli.txt', '!**/LICENSE.{txt,rtf}', '!LICENSES.chromium.html', '!**/LICENSE', From d88605d5423555c91ec5876b4f20bc33884dbb38 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 17:13:14 +0200 Subject: [PATCH 0089/1180] cleaning the code --- .../inlineChat/browser/inlineChatActions.ts | 1 + .../browser/inlineChatController.ts | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 83b481739a1cc..b65aab455b63a 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -67,6 +67,7 @@ export class StartSessionAction extends EditorAction2 { options = arg; } InlineChatController.get(editor)?.run(options); + InlineChatController.get(editor)?.run(options); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index f15eff338cd8d..55b8744a5f885 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -176,15 +176,17 @@ export class InlineChatController implements IEditorContribution { return this._zone.value.position; } + private _currentRun?: Promise; + async run(options: InlineChatRunOptions | undefined = {}): Promise { - this._log('session starting inside of run'); - console.log('before finishExistingSession inside of run'); - await this.finishExistingSession(); - console.log('after finish existing session inside of run'); + this.finishExistingSession(); + if (this._currentRun) { + await this._currentRun; + } this._stashedSession.clear(); - console.log('before calling create session inside of run'); - await this._nextState(State.CREATE_SESSION, options); - this._log('session done or paused'); + this._currentRun = this._nextState(State.CREATE_SESSION, options); + await this._currentRun; + this._currentRun = undefined; } // ---- state machine @@ -833,7 +835,7 @@ export class InlineChatController implements IEditorContribution { return result; } - async finishExistingSession(): Promise { + finishExistingSession(): void { console.log('inside of finish existing session'); console.log(this._activeSession); if (this._activeSession) { @@ -846,6 +848,7 @@ export class InlineChatController implements IEditorContribution { console.log('before accepting inside of finish existing session'); this.acceptSession(); } + } console.log('at the end of finish existing session'); } From 26151020a859156fb692dd82c298915de618a5fa Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 17:16:14 +0200 Subject: [PATCH 0090/1180] cleaning the code --- .../workbench/contrib/inlineChat/browser/inlineChatSession.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts index 79ac5e76633a1..83aa7b064ff7d 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts @@ -477,7 +477,6 @@ export class InlineChatSessionService implements IInlineChatSessionService { } releaseSession(session: Session): void { - console.log('at the beginning of the release session'); const { editor } = session; @@ -499,7 +498,6 @@ export class InlineChatSessionService implements IInlineChatSessionService { // send telemetry this._telemetryService.publicLog2('interactiveEditor/session', session.asTelemetryData()); - console.log('at the end of the release session'); } getSession(editor: ICodeEditor, uri: URI): Session | undefined { From 15db6060dbea7e707191c96fb62f63dedfda335f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 13 Jul 2023 17:16:24 +0200 Subject: [PATCH 0091/1180] cleaning the code --- .../inlineChat/browser/inlineChatActions.ts | 1 - .../browser/inlineChatController.ts | 71 ++----------------- .../browser/inlineChatStrategies.ts | 5 +- 3 files changed, 7 insertions(+), 70 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index b65aab455b63a..83b481739a1cc 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -67,7 +67,6 @@ export class StartSessionAction extends EditorAction2 { options = arg; } InlineChatController.get(editor)?.run(options); - InlineChatController.get(editor)?.run(options); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 55b8744a5f885..39436818fa9aa 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -134,7 +134,6 @@ export class InlineChatController implements IEditorContribution { } this._log('session RESUMING', e); - console.log('before calling create session of the constructor'); await this._nextState(State.CREATE_SESSION, { existingSession }); this._log('session done or paused'); })); @@ -142,9 +141,7 @@ export class InlineChatController implements IEditorContribution { } dispose(): void { - console.log('inside of dispose'); this._stashedSession.clear(); - console.log('inside of dispose before calling finishExistingSession'); this.finishExistingSession(); this._store.dispose(); this._log('controller disposed'); @@ -221,18 +218,6 @@ export class InlineChatController implements IEditorContribution { } private async [State.CREATE_SESSION](options: InlineChatRunOptions): Promise { - console.log('inside of CREATE_SESSION'); - console.log('inside of CREATE_SESSION, this._activeSession : ', this._activeSession); - // if (this._activeSession) { - // console.log('inside of CREATE_SESSION, before clearing the session store'); - // this._sessionStore.clear(); - // console.log('inside of CREATE_SESSION, before releasing the session'); - // this._inlineChatSessionService.releaseSession(this._activeSession); - // console.log('inside of CREATE_SESSION, before calling pause'); - // // Doesn't appear to be properly awaited? - // await this[State.PAUSE](); - // } - console.log('inside of CREATE_SESSION, this._activeSession after the cleaning : ', this._activeSession); assertType(this._activeSession === undefined); assertType(this._editor.hasModel()); @@ -245,7 +230,6 @@ export class InlineChatController implements IEditorContribution { if (!session) { const createSessionCts = new CancellationTokenSource(); const msgListener = Event.once(this._messages.event)(m => { - console.log('inside of CREATE_SESSION, inside of the msgListener code of CREATE_SESSION'); this._log('state=_createSession) message received', m); if (m === Message.ACCEPT_INPUT) { // user accepted the input before having a session @@ -297,8 +281,6 @@ export class InlineChatController implements IEditorContribution { } private async [State.INIT_UI](options: InlineChatRunOptions): Promise { - console.log('inside of init ui'); - console.log('inside of INIT_UI, this._activeSession : ', this._activeSession); assertType(this._activeSession); // hide/cancel inline completions when invoking IE @@ -359,20 +341,16 @@ export class InlineChatController implements IEditorContribution { if (editIsOutsideOfWholeRange) { this._log('text changed outside of whole range, FINISH session'); - console.log('inside of INIT_UI, before calling finish existing session'); this.finishExistingSession(); } })); if (!this._activeSession.lastExchange) { - console.log('inside of INIT_UI,before waiting for input'); return State.WAIT_FOR_INPUT; } else if (options.isUnstashed) { delete options.isUnstashed; - console.log('inside of INIT_UI,before apply response'); return State.APPLY_RESPONSE; } else { - console.log('inside of INIT_UI,before show response'); return State.SHOW_RESPONSE; } } @@ -391,9 +369,7 @@ export class InlineChatController implements IEditorContribution { } - private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions): Promise { - console.log('inside of wait for input'); - + private async [State.WAIT_FOR_INPUT](options: InlineChatRunOptions): Promise { assertType(this._activeSession); assertType(this._strategy); @@ -414,7 +390,6 @@ export class InlineChatController implements IEditorContribution { } else { const barrier = new Barrier(); const msgListener = Event.once(this._messages.event)(m => { - console.log('inside of WAIT_FOR_INPUT, inside of msgListener'); this._log('state=_waitForInput) message received', m); message = m; barrier.open(); @@ -426,17 +401,11 @@ export class InlineChatController implements IEditorContribution { this._zone.value.widget.selectAll(); if (message & (Message.CANCEL_INPUT | Message.CANCEL_SESSION)) { - console.log('inside of WAIT_FOR_INPUT,entered into the case when message cancel session'); - await this[State.CANCEL](); - return; - // return State.CANCEL; + return State.CANCEL; } if (message & Message.ACCEPT_SESSION) { - console.log('inside of WAIT_FOR_INPUT,entered into the case when message accept'); - await this[State.ACCEPT](); - return; - // return State.ACCEPT; + return State.ACCEPT; } if (message & Message.PAUSE_SESSION) { @@ -488,7 +457,6 @@ export class InlineChatController implements IEditorContribution { let message = Message.NONE; const msgListener = Event.once(this._messages.event)(m => { - console.log('inside of MAKE_REQUEST, inside of msgListener of MAKE REQUEST'); this._log('state=_makeRequest) message received', m); message = m; requestCts.cancel(); @@ -543,12 +511,10 @@ export class InlineChatController implements IEditorContribution { this._activeSession.addExchange(new SessionExchange(this._activeSession.lastInput, response)); if (message & Message.CANCEL_SESSION) { - console.log('inside of MAKE_REQUEST, cancelling the session'); return State.CANCEL; } else if (message & Message.PAUSE_SESSION) { return State.PAUSE; } else if (message & Message.ACCEPT_SESSION) { - console.log('inside of MAKE_REQUEST, accepting'); return State.ACCEPT; } else { return State.APPLY_RESPONSE; @@ -664,8 +630,6 @@ export class InlineChatController implements IEditorContribution { private async [State.PAUSE]() { - console.log('entered into pause state'); - this._ctxDidEdit.reset(); this._ctxUserDidEdit.reset(); this._ctxLastResponseType.reset(); @@ -685,35 +649,24 @@ export class InlineChatController implements IEditorContribution { } private async [State.ACCEPT]() { - console.log('inside of State.ACCEPT'); assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); - console.log('inside of State.ACCEPT, after assert type'); try { - console.log('inside of State.ACCEPT, before strategy apply'); await this._strategy.apply(); - console.log('inside of State.ACCEPT, after strategy apply'); - // TODO: ASK WHY DESPITE AWAIT, AFTER STRATEFY NOT PRINTED BEFORE CREATE SESSION } catch (err) { - console.log('inside of State.ACCEPT, when error obtained'); this._dialogService.error(localize('err.apply', "Failed to apply changes.", toErrorMessage(err))); this._log('FAILED to apply changes'); this._log(err); } - console.log('inside of State.ACCEPT, before release session'); - - await this._inlineChatSessionService.releaseSession(this._activeSession); + this._inlineChatSessionService.releaseSession(this._activeSession); - console.log('inside of State.ACCEPT, before state pause'); - await this[State.PAUSE](); + this[State.PAUSE](); } private async [State.CANCEL]() { - console.log('inside of cancel the session'); - assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); @@ -728,14 +681,13 @@ export class InlineChatController implements IEditorContribution { this._log(err); } - await this[State.PAUSE](); + this[State.PAUSE](); this._stashedSession.clear(); if (!mySession.isUnstashed && mySession.lastExchange) { // only stash sessions that had edits this._stashedSession.value = this._instaService.createInstance(StashedSession, this._editor, mySession); } else { - console.log('before releasing the session of cancel'); this._inlineChatSessionService.releaseSession(mySession); } } @@ -815,13 +767,10 @@ export class InlineChatController implements IEditorContribution { } acceptSession(): void { - console.log('inside of acceptSession method'); - // Will fire a message which will be picked up by the controller and some other code will be run this._messages.fire(Message.ACCEPT_SESSION); } cancelSession() { - console.log('inside of cancelSession'); let result: string | undefined; if (this._strategy && this._activeSession) { const changedText = this._activeSession.asChangedText(); @@ -836,21 +785,15 @@ export class InlineChatController implements IEditorContribution { } finishExistingSession(): void { - console.log('inside of finish existing session'); - console.log(this._activeSession); if (this._activeSession) { if (this._activeSession.editMode === EditMode.Preview) { this._log('finishing existing session, using CANCEL', this._activeSession.editMode); - console.log('before cancelling inside of finish existing session'); this.cancelSession(); } else { this._log('finishing existing session, using APPLY', this._activeSession.editMode); - console.log('before accepting inside of finish existing session'); this.acceptSession(); } - } - console.log('at the end of finish existing session'); } unstashLastSession(): Session | undefined { @@ -879,7 +822,6 @@ class StashedSession { this._ctxHasStashedSession.set(true); this._listener = Event.once(Event.any(editor.onDidChangeCursorSelection, editor.onDidChangeModelContent, editor.onDidChangeModel))(() => { this._session = undefined; - console.log('before release session of constructor'); this._sessionService.releaseSession(session); this._ctxHasStashedSession.reset(); }); @@ -889,7 +831,6 @@ class StashedSession { this._listener.dispose(); this._ctxHasStashedSession.reset(); if (this._session) { - console.log('before release session of dispose'); this._sessionService.releaseSession(this._session); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index 019a4ecfd58d5..36e64ebf09af5 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -86,7 +86,7 @@ export class PreviewStrategy extends EditModeStrategy { } async apply() { - console.log('at the beginning of the apply method of preview strategy'); + if (!(this._session.lastExchange?.response instanceof EditResponse)) { return; } @@ -107,7 +107,6 @@ export class PreviewStrategy extends EditModeStrategy { modelN.pushStackElement(); } } - console.log('at the end of the apply method of preview strategy'); } async cancel(): Promise { @@ -280,7 +279,6 @@ export class LiveStrategy extends EditModeStrategy { } async apply() { - console.log('inside of apply of live strategy'); if (this._editCount > 0) { this._editor.pushUndoStop(); } @@ -288,7 +286,6 @@ export class LiveStrategy extends EditModeStrategy { await this._bulkEditService.apply(this._lastResponse.workspaceEdits); this._instaService.invokeFunction(showSingleCreateFile, this._lastResponse); } - console.log('at the end of apply for live strategy'); } async cancel() { From ae5d6a86630f4801aec3125cec08d7afc9c43f14 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 08:21:03 -0700 Subject: [PATCH 0092/1180] use widget that we have already --- .../workbench/contrib/chat/browser/chat.contribution.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index defbcbd581d89..8677a3e6ffd3d 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -132,13 +132,8 @@ class ChatAccessibleViewContribution extends Disposable { let focusedItem: ChatTreeItem | undefined = widget?.getFocus(); let focusedInput = false; const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); - if (editor) { - // focus is in the input box, so we need to focus the last widget first - const editorUri = editor.getModel()?.uri; - if (!editorUri) { - return false; - } - widgetService.getWidgetByInputUri(editorUri)?.focusLastMessage(); + if (editor && widget) { + widget.focusLastMessage(); widget = widgetService.lastFocusedWidget; focusedItem = widget?.getFocus(); focusedInput = true; From d7bdb0a08a3716a37ba958762be0091d519c01bc Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 08:55:59 -0700 Subject: [PATCH 0093/1180] clean up --- .../contrib/chat/browser/chat.contribution.ts | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 8677a3e6ffd3d..aef372dee9260 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -22,7 +22,7 @@ import { registerChatExecuteActions } from 'vs/workbench/contrib/chat/browser/ac import { registerChatQuickQuestionActions } from 'vs/workbench/contrib/chat/browser/actions/chatQuickInputActions'; import { registerChatTitleActions } from 'vs/workbench/contrib/chat/browser/actions/chatTitleActions'; import { registerChatExportActions } from 'vs/workbench/contrib/chat/browser/actions/chatImportExport'; -import { ChatTreeItem, IChatAccessibilityService, IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; +import { IChatAccessibilityService, IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; import { ChatContributionService } from 'vs/workbench/contrib/chat/browser/chatContributionServiceImpl'; import { ChatEditor, IChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatEditor'; import { ChatEditorInput, ChatEditorInputSerializer } from 'vs/workbench/contrib/chat/browser/chatEditorInput'; @@ -128,32 +128,42 @@ class ChatAccessibleViewContribution extends Disposable { const widgetService = accessor.get(IChatWidgetService); const codeEditorService = accessor.get(ICodeEditorService); - let widget: IChatWidget | undefined = widgetService.lastFocusedWidget; - let focusedItem: ChatTreeItem | undefined = widget?.getFocus(); - let focusedInput = false; - const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); - if (editor && widget) { + let widget = widgetService.lastFocusedWidget; + if (!widget) { + return false; + } + + const chatInputFocused = !!(codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor()); + + if (chatInputFocused) { widget.focusLastMessage(); widget = widgetService.lastFocusedWidget; - focusedItem = widget?.getFocus(); - focusedInput = true; } - if (!widget || !focusedItem || !isResponseVM(focusedItem)) { + + if (!widget) { + return false; + } + + const verifiedWidget: IChatWidget = widget; + const focusedItem = verifiedWidget.getFocus(); + + if (!focusedItem) { return false; } - const responseContent = focusedItem?.response.value; + const responseContent = isResponseVM(focusedItem) ? focusedItem.response.value : undefined; if (!responseContent) { return false; } + accessibleViewService.show({ verbositySettingKey: 'panelChat', provideContent(): string { return responseContent; }, onClose() { - if (focusedInput) { - widget?.focusInput(); + if (chatInputFocused) { + verifiedWidget.focusInput(); } else { - widget!.focus(focusedItem!); + verifiedWidget.focus(focusedItem); } }, options: { ariaLabel: nls.localize('chatAccessibleView', "Chat Accessible View"), language: 'typescript', type: AccessibleViewType.View } From 634a9ce37b77891d3c03045126ffb8c8e87c89b5 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Thu, 13 Jul 2023 08:56:49 -0700 Subject: [PATCH 0094/1180] Dispose of test instantiation service (#187848) * Dispose of test instantiation service * Feedback --- .../browser/parts/editor/editorGroupModel.test.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts b/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts index 4b790fac167cd..3467cdcd50789 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts @@ -28,8 +28,18 @@ import { isEqual } from 'vs/base/common/resources'; suite('EditorGroupModel', () => { + let testInstService: TestInstantiationService | undefined; + + suiteTeardown(() => { + testInstService?.dispose(); + testInstService = undefined; + }); + function inst(): IInstantiationService { - const inst = new TestInstantiationService(); + if (!testInstService) { + testInstService = new TestInstantiationService(); + } + const inst = testInstService; inst.stub(IStorageService, new TestStorageService()); inst.stub(ILifecycleService, new TestLifecycleService()); inst.stub(IWorkspaceContextService, new TestContextService()); From 68213224210f346ea86e87e60c4eac45896d45e6 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Thu, 13 Jul 2023 09:31:16 -0700 Subject: [PATCH 0095/1180] Share code for chat slash command blocks --- src/vs/workbench/contrib/chat/browser/chat.ts | 1 - .../browser/chatSlashCommandContentWidget.css | 11 +++ .../browser/chatSlashCommandContentWidget.ts | 69 +++++++++++++++++ .../contrib/chat/browser/chatWidget.ts | 4 - .../browser/contrib/chatInputEditorContrib.ts | 75 +++---------------- .../contrib/inlineChat/browser/inlineChat.css | 7 -- .../inlineChat/browser/inlineChatWidget.ts | 57 +------------- 7 files changed, 95 insertions(+), 129 deletions(-) create mode 100644 src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css create mode 100644 src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.ts diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index 8c51aaa217532..b42cad92d7e00 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -60,7 +60,6 @@ export interface IChatWidget { acceptInput(query?: string): void; focusLastMessage(): void; focusInput(): void; - getSlashCommandsSync(): ISlashCommand[] | undefined; getSlashCommands(): Promise; getCodeBlockInfoForEditor(uri: URI): IChatCodeBlockInfo | undefined; getCodeBlockInfosForResponse(response: IChatResponseViewModel): IChatCodeBlockInfo[]; diff --git a/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css b/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css new file mode 100644 index 0000000000000..33532a3ee8aed --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.chat-slash-command-content-widget { + padding: 0 0.4em; + border-radius: 3px; + background-color: var(--vscode-textCodeBlock-background); + color: var(--vscode-textLink-foreground); +} diff --git a/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.ts b/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.ts new file mode 100644 index 0000000000000..a2fa834d90551 --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./chatSlashCommandContentWidget'; +import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { Range } from 'vs/editor/common/core/range'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget } from 'vs/editor/browser/editorBrowser'; +import { KeyCode } from 'vs/base/common/keyCodes'; + +export class SlashCommandContentWidget extends Disposable implements IContentWidget { + private _domNode = document.createElement('div'); + private _lastSlashCommandText: string | undefined; + + constructor(private _editor: ICodeEditor) { + super(); + + this._domNode.toggleAttribute('hidden', true); + this._domNode.classList.add('chat-slash-command-content-widget'); + + // If backspace at a slash command boundary, remove the slash command + this._register(this._editor.onKeyUp((e) => this._handleKeyUp(e))); + } + + override dispose() { + this._editor.removeContentWidget(this); + super.dispose(); + } + + show() { + this._domNode.toggleAttribute('hidden', false); + this._editor.addContentWidget(this); + } + + hide() { + this._domNode.toggleAttribute('hidden', true); + this._editor.removeContentWidget(this); + } + + setCommandText(slashCommand: string) { + this._domNode.innerText = `${slashCommand} `; + this._lastSlashCommandText = slashCommand; + } + + getId() { return 'chat-slash-command-content-widget'; } + getDomNode() { return this._domNode; } + getPosition() { return { position: { lineNumber: 1, column: 1 }, preference: [ContentWidgetPositionPreference.EXACT] }; } + + private _handleKeyUp(e: IKeyboardEvent) { + if (e.keyCode !== KeyCode.Backspace) { + return; + } + + const firstLine = this._editor.getModel()?.getLineContent(1); + const selection = this._editor.getSelection(); + const withSlash = `/${this._lastSlashCommandText}`; + if (!firstLine?.startsWith(withSlash) || !selection?.isEmpty() || selection?.startLineNumber !== 1 || selection?.startColumn !== withSlash.length + 1) { + return; + } + + // Allow to undo the backspace + this._editor.executeEdits('inline-chat-slash-command', [{ + range: new Range(1, 1, 1, selection.startColumn), + text: null + }]); + } +} diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 9fe7dc958362d..fa29aac02296b 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -219,10 +219,6 @@ export class ChatWidget extends Disposable implements IChatWidget { } } - getSlashCommandsSync(): ISlashCommand[] | undefined { - return this.lastSlashCommands; - } - async getSlashCommands(): Promise { if (!this.viewModel) { return; diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index 830d85d35b639..46b61d5efa3e4 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -15,27 +15,22 @@ import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { localize } from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; -import { editorForeground, textCodeBlockBackground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { editorForeground } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart'; import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; -import { ContentWidgetPositionPreference, IContentWidget } from 'vs/editor/browser/editorBrowser'; -import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { KeyCode } from 'vs/base/common/keyCodes'; -import { Selection } from 'vs/editor/common/core/selection'; +import { SlashCommandContentWidget } from 'vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget'; const decorationDescription = 'chat'; const slashCommandPlaceholderDecorationType = 'chat-session-detail'; const slashCommandTextDecorationType = 'chat-session-text'; -const slashCommandContentWidgetId = 'chat-session-content-widget'; class InputEditorDecorations extends Disposable { - private _slashCommandDomNode = document.createElement('div'); - private _slashCommandContentWidget: IContentWidget | undefined; + private _slashCommandContentWidget: SlashCommandContentWidget | undefined; private _previouslyUsedSlashCommands = new Set(); constructor( @@ -66,7 +61,7 @@ class InputEditorDecorations extends Disposable { private updateRegisteredDecorationTypes() { this.codeEditorService.removeDecorationType(slashCommandTextDecorationType); - this.updateInputEditorContentWidgets({ hide: true }); + this._slashCommandContentWidget?.hide(); this.codeEditorService.registerDecorationType(decorationDescription, slashCommandTextDecorationType, { opacity: '0', after: { @@ -109,7 +104,7 @@ class InputEditorDecorations extends Disposable { } ]; this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandPlaceholderDecorationType, decoration); - this.updateInputEditorContentWidgets({ hide: true }); + this._slashCommandContentWidget?.hide(); return; } @@ -142,9 +137,14 @@ class InputEditorDecorations extends Disposable { } if (command && inputValue.startsWith(`/${command.command} `)) { - this.updateInputEditorContentWidgets({ command: command.command }); + if (!this._slashCommandContentWidget) { + this._slashCommandContentWidget = new SlashCommandContentWidget(this.widget.inputEditor); + this._store.add(this._slashCommandContentWidget); + } + this._slashCommandContentWidget.setCommandText(command.command); + this._slashCommandContentWidget.show(); } else { - this.updateInputEditorContentWidgets({ hide: true }); + this._slashCommandContentWidget?.hide(); } if (command && command.detail) { @@ -163,40 +163,6 @@ class InputEditorDecorations extends Disposable { this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandTextDecorationType, []); } } - - private async updateInputEditorContentWidgets(arg: { command: string } | { hide: true }) { - const domNode = this._slashCommandDomNode; - - if (this._slashCommandContentWidget && 'hide' in arg) { - domNode.toggleAttribute('hidden', true); - this.widget.inputEditor.removeContentWidget(this._slashCommandContentWidget); - return; - } else if ('command' in arg) { - const theme = this.themeService.getColorTheme(); - domNode.style.padding = '0 0.4em'; - domNode.style.borderRadius = '3px'; - domNode.style.backgroundColor = theme.getColor(textCodeBlockBackground)?.toString() ?? ''; - domNode.style.color = theme.getColor(textLinkForeground)?.toString() ?? ''; - domNode.innerText = `${arg.command} `; - domNode.toggleAttribute('hidden', false); - - this._slashCommandContentWidget = { - getId() { return slashCommandContentWidgetId; }, - getDomNode() { return domNode; }, - getPosition() { - return { - position: { - lineNumber: 1, - column: 1 - }, - preference: [ContentWidgetPositionPreference.EXACT] - }; - }, - }; - - this.widget.inputEditor.addContentWidget(this._slashCommandContentWidget); - } - } } class InputEditorSlashCommandFollowups extends Disposable { @@ -206,7 +172,6 @@ class InputEditorSlashCommandFollowups extends Disposable { ) { super(); this._register(this.chatService.onDidSubmitSlashCommand(({ slashCommand, sessionId }) => this.repopulateSlashCommand(slashCommand, sessionId))); - this._register(this.widget.inputEditor.onKeyUp((e) => this.handleKeyUp(e))); } private async repopulateSlashCommand(slashCommand: string, sessionId: string) { @@ -227,22 +192,6 @@ class InputEditorSlashCommandFollowups extends Disposable { } } - - private handleKeyUp(e: IKeyboardEvent) { - if (e.keyCode !== KeyCode.Backspace) { - return; - } - - const value = this.widget.inputEditor.getValue().split(' ')[0]; - const currentSelection = this.widget.inputEditor.getSelection(); - if (!value.startsWith('/') || !currentSelection?.isEmpty() || currentSelection?.startLineNumber !== 1 || currentSelection?.startColumn !== value.length + 1) { - return; - } - - if (this.widget.getSlashCommandsSync()?.find((command) => `/${command.command}` === value)) { - this.widget.inputEditor.executeEdits('chat-input-editor-slash-commands', [{ range: new Range(1, 1, 1, currentSelection.startColumn), text: null }], [new Selection(1, 1, 1, 1)]); - } - } } ChatWidget.CONTRIBS.push(InputEditorDecorations, InputEditorSlashCommandFollowups); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css index 5beab56e7f251..efdacad53e2cc 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css @@ -285,13 +285,6 @@ opacity: 0.5; } -.monaco-editor .inline-chat-slash-command-content-widget { - padding: 0 0.4em; - border-radius: 3px; - background-color: var(--vscode-textCodeBlock-background); - color: var(--vscode-textLink-foreground); -} - /* diff zone */ .monaco-editor .inline-chat-diff-widget { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index ac29d7cf5c195..66927d167229b 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./inlineChat'; -import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; +import { DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IActiveCodeEditor, ICodeEditor, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions'; import { IRange, Range } from 'vs/editor/common/core/range'; import { localize } from 'vs/nls'; @@ -49,7 +49,7 @@ import { ExpansionState } from 'vs/workbench/contrib/inlineChat/browser/inlineCh import { IdleValue } from 'vs/base/common/async'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IMenuWorkbenchButtonBarOptions, MenuWorkbenchButtonBar } from 'vs/platform/actions/browser/buttonbar'; -import { KeyCode } from 'vs/base/common/keyCodes'; +import { SlashCommandContentWidget } from 'vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget'; const defaultAriaLabel = localize('aria-label', "Inline Chat Input"); @@ -713,57 +713,6 @@ export class InlineChatWidget { } } -class SlashCommandContentWidget extends Disposable implements IContentWidget { - private _domNode = document.createElement('div'); - private _lastSlashCommandText: string | undefined; - - constructor(private _editor: ICodeEditor) { - super(); - - this._domNode.toggleAttribute('hidden', true); - this._domNode.classList.add('inline-chat-slash-command-content-widget'); - - // If backspace at a slash command boundary, remove the slash command - this._register(this._editor.onKeyUp((e) => { - if (e.keyCode !== KeyCode.Backspace) { - return; - } - - const firstLine = this._editor.getModel()?.getLineContent(1); - const selection = this._editor.getSelection(); - const withSlash = `/${this._lastSlashCommandText}`; - if (!firstLine?.startsWith(withSlash) || !selection?.isEmpty() || selection?.startLineNumber !== 1 || selection?.startColumn !== withSlash.length + 1) { - return; - } - - // Allow to undo the backspace - this._editor.executeEdits('inline-chat-slash-command', [{ - range: new Range(1, 1, 1, selection.startColumn), - text: null - }]); - })); - } - - show() { - this._domNode.toggleAttribute('hidden', false); - this._editor.addContentWidget(this); - } - - hide() { - this._domNode.toggleAttribute('hidden', true); - this._editor.removeContentWidget(this); - } - - setCommandText(slashCommand: string) { - this._domNode.innerText = `${slashCommand} `; - this._lastSlashCommandText = slashCommand; - } - - getId() { return 'inline-chat-slash-command-content-widget'; } - getDomNode() { return this._domNode; } - getPosition() { return { position: { lineNumber: 1, column: 1 }, preference: [ContentWidgetPositionPreference.EXACT] }; } -} - export class InlineChatZoneWidget extends ZoneWidget { readonly widget: InlineChatWidget; From fe22b24f8edb86fd50f6f87697718059a6703633 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 18:52:45 +0200 Subject: [PATCH 0096/1180] finetune message and fix quickpick styling (#187855) * finetune message and fix quickpick styling * update desc --- .../quickinput/browser/media/quickInput.css | 1 + .../platform/quickinput/browser/quickInput.ts | 9 ++++++--- .../browser/userDataProfile.ts | 19 +++---------------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/vs/platform/quickinput/browser/media/quickInput.css b/src/vs/platform/quickinput/browser/media/quickInput.css index f3fbd726e1074..de8df301e3c80 100644 --- a/src/vs/platform/quickinput/browser/media/quickInput.css +++ b/src/vs/platform/quickinput/browser/media/quickInput.css @@ -55,6 +55,7 @@ .quick-input-header .quick-input-description { margin: 4px 2px; + flex: 1; } .quick-input-header { diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index 213a80ca1900d..7992328ec1f74 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -98,6 +98,7 @@ interface QuickInputUI { widget: HTMLElement; rightActionBar: ActionBar; checkAll: HTMLInputElement; + inputContainer: HTMLElement; filterContainer: HTMLElement; inputBox: QuickInputBox; visibleCountContainer: HTMLElement; @@ -1331,8 +1332,8 @@ export class QuickInputController extends Disposable { })); const description2 = dom.append(headerContainer, $('.quick-input-description')); - const extraContainer = dom.append(headerContainer, $('.quick-input-and-message')); - const filterContainer = dom.append(extraContainer, $('.quick-input-filter')); + const inputContainer = dom.append(headerContainer, $('.quick-input-and-message')); + const filterContainer = dom.append(inputContainer, $('.quick-input-filter')); const inputBox = this._register(new QuickInputBox(filterContainer, this.styles.inputBox, this.styles.toggle)); inputBox.setAttribute('aria-describedby', `${this.idPrefix}message`); @@ -1360,7 +1361,7 @@ export class QuickInputController extends Disposable { this.onDidCustomEmitter.fire(); })); - const message = dom.append(extraContainer, $(`#${this.idPrefix}message.quick-input-message`)); + const message = dom.append(inputContainer, $(`#${this.idPrefix}message.quick-input-message`)); const progressBar = new ProgressBar(container, this.styles.progressBar); progressBar.getContainer().classList.add('quick-input-progress'); @@ -1481,6 +1482,7 @@ export class QuickInputController extends Disposable { widget, rightActionBar, checkAll, + inputContainer, filterContainer, inputBox, visibleCountContainer, @@ -1749,6 +1751,7 @@ export class QuickInputController extends Disposable { ui.description1.style.display = visibilities.description && (visibilities.inputBox || visibilities.checkAll) ? '' : 'none'; ui.description2.style.display = visibilities.description && !(visibilities.inputBox || visibilities.checkAll) ? '' : 'none'; ui.checkAll.style.display = visibilities.checkAll ? '' : 'none'; + ui.inputContainer.style.display = visibilities.inputBox ? '' : 'none'; ui.filterContainer.style.display = visibilities.inputBox ? '' : 'none'; ui.visibleCountContainer.style.display = visibilities.visibleCount ? '' : 'none'; ui.countContainer.style.display = visibilities.count ? '' : 'none'; diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index ced5b63ed9bd3..5ea18399b20eb 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -507,27 +507,14 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements quickPick.hideCheckAll = true; quickPick.ignoreFocusOut = true; quickPick.customLabel = localize('create', "Create Profile"); - quickPick.description = localize('customise the profile', "Unselect to link to the Default Profile"); + quickPick.description = localize('customise the profile', "Choose what you want to configure in the profile. Unselected items are shared from the default profile."); + quickPick.items = resources; + quickPick.selectedItems = resources.filter(item => item.picked); const disposables = new DisposableStore(); - const update = () => { - quickPick.items = resources; - quickPick.selectedItems = resources.filter(item => item.picked); - }; - update(); - disposables.add(quickPick.onDidChangeSelection(items => { - let needUpdate = false; for (const resource of resources) { resource.picked = items.includes(resource); - const description = resource.picked ? undefined : localize('use default profile', "Default Profile"); - if (resource.description !== description) { - resource.description = description; - needUpdate = true; - } - } - if (needUpdate) { - update(); } })); From c9d8ab642c47188aab5c954e968dffa46e86753b Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 13 Jul 2023 10:14:05 -0700 Subject: [PATCH 0097/1180] Add two alternative UX's for the Quick Question experience (#187780) * Add two alternative UX's for the Quick Question experience Main changes: * Changes to the chat to have an alterative rendering of the input on the top... needs polish but decent for now * The inclusion of a setting to choose which mode you would like to use for the UX * 2 new modes: `InputOnBottomChat` and `InputOnTopChat` which do what you expect. * Move where the enum is to hopefully fix tests --- .../browser/actions/chatQuickInputActions.ts | 280 +----------------- .../multipleByScrollQuickQuestionAction.ts | 267 +++++++++++++++++ .../quickQuestionAction.ts | 61 ++++ .../singleQuickQuestionAction.ts | 261 ++++++++++++++++ .../contrib/chat/browser/chat.contribution.ts | 8 + src/vs/workbench/contrib/chat/browser/chat.ts | 2 +- .../contrib/chat/browser/chatInputPart.ts | 11 +- .../contrib/chat/browser/chatWidget.ts | 19 +- .../contrib/chat/browser/media/chat.css | 2 + .../browser/commandsQuickAccess.ts | 2 +- 10 files changed, 627 insertions(+), 286 deletions(-) create mode 100644 src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/multipleByScrollQuickQuestionAction.ts create mode 100644 src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction.ts create mode 100644 src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/singleQuickQuestionAction.ts diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts index e982980b2e060..e03b39894f3a6 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts @@ -3,284 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as dom from 'vs/base/browser/dom'; -import { Toggle } from 'vs/base/browser/ui/toggle/toggle'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { Codicon } from 'vs/base/common/codicons'; -import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { localize } from 'vs/nls'; -import { Emitter, Event } from 'vs/base/common/event'; -import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { asCssVariable, editorBackground, foreground, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground } from 'vs/platform/theme/common/colorRegistry'; -import { ChatListItemRenderer } from 'vs/workbench/contrib/chat/browser/chatListRenderer'; -import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions'; -import { ChatModel } from 'vs/workbench/contrib/chat/common/chatModel'; -import { IChatReplyFollowup, IChatService } from 'vs/workbench/contrib/chat/common/chatService'; -import { ChatViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel'; -import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions'; -import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; -import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys'; +import { registerAction2 } from 'vs/platform/actions/common/actions'; +import { AskQuickQuestionAction } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; -export const ASK_QUICK_QUESTION_ACTION_ID = 'chat.action.askQuickQuestion'; +import 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/singleQuickQuestionAction'; +import 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/multipleByScrollQuickQuestionAction'; export function registerChatQuickQuestionActions() { registerAction2(AskQuickQuestionAction); } - -class AskQuickQuestionAction extends Action2 { - - private _currentSession: InteractiveQuickPickSession | undefined; - private _currentQuery: string | undefined; - private _lastAcceptedQuery: string | undefined; - private _currentTimer: any | undefined; - private _input: IQuickPick | undefined; - - constructor() { - super({ - id: ASK_QUICK_QUESTION_ACTION_ID, - title: { value: localize('askQuickQuestion', "Ask Quick Question"), original: 'Ask Quick Question' }, - precondition: CONTEXT_PROVIDER_EXISTS, - f1: false, - category: CHAT_CATEGORY, - keybinding: { - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI, - linux: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyI - } - } - }); - } - - run(accessor: ServicesAccessor, query: string): void { - const quickInputService = accessor.get(IQuickInputService); - const chatService = accessor.get(IChatService); - const instantiationService = accessor.get(IInstantiationService); - - // First things first, clear the existing timer that will dispose the session - clearTimeout(this._currentTimer); - this._currentTimer = undefined; - - // If the input is already shown, hide it. This provides a toggle behavior of the quick pick - if (this._input !== undefined) { - this._input.hide(); - return; - } - - // Check if any providers are available. If not, show nothing - const providerInfo = chatService.getProviderInfos()[0]; - if (!providerInfo) { - return; - } - - const disposableStore = new DisposableStore(); - - //#region Setup quick pick - - this._input = quickInputService.createQuickPick(); - disposableStore.add(this._input); - this._input.placeholder = localize('askabot', "Ask {0} a question...", providerInfo.displayName); - - // Setup toggle that will be used to open the chat view - const openInChat = new Toggle({ - title: 'Open in chat view', - icon: Codicon.commentDiscussion, - isChecked: false, - inputActiveOptionBorder: asCssVariable(inputActiveOptionBorder), - inputActiveOptionForeground: asCssVariable(inputActiveOptionForeground), - inputActiveOptionBackground: asCssVariable(inputActiveOptionBackground) - }); - disposableStore.add(openInChat); - disposableStore.add(openInChat.onChange(async () => { - await this._currentSession?.openInChat(this._lastAcceptedQuery ?? this._input!.value); - this._currentQuery = undefined; - this._lastAcceptedQuery = undefined; - this._currentSession?.dispose(); - this._currentSession = undefined; - })); - this._input.toggles = [openInChat]; - - // Setup the widget that will be used to render the chat response - const containerList = dom.$('.interactive-list'); - const containerSession = dom.$('.interactive-session', undefined, containerList); - containerList.style.position = 'relative'; - this._input.widget = containerSession; - - //#endregion - - //#region quick pick events - - disposableStore.add(this._input.onDidChangeValue((value) => { - if (value !== this._currentQuery) { - this._currentQuery = value; - } - })); - disposableStore.add(this._input.onDidHide(() => { - disposableStore.dispose(); - this._input = undefined; - this._currentTimer = setTimeout(() => { - this._currentQuery = undefined; - this._lastAcceptedQuery = undefined; - this._currentSession?.dispose(); - this._currentSession = undefined; - }, 1000 * 30); // 30 seconds - })); - disposableStore.add(this._input.onDidAccept(async () => { - await this._currentSession?.accept(this._input!.value); - this._lastAcceptedQuery = this._input!.value; - })); - - //#endregion - - // If we were given a query (via executeCommand), then clear past state - if (query) { - this._currentSession?.dispose(); - this._currentSession = undefined; - } - this._currentSession ??= instantiationService.createInstance(InteractiveQuickPickSession); - this._input.show(); - // This line must come after showing the input so the offsetWidth is correct - this._currentSession.createList(containerList, containerList.offsetWidth); - - disposableStore.add(this._currentSession.onDidClickFollowup(async e => { - this._input!.focusOnInput(); - this._input!.value = e.message; - await this._currentSession?.accept(e.message); - })); - - // If we were given a query (via executeCommand), then accept it - if (query) { - this._input.value = query; - this._input.valueSelection = [0, this._input.value.length]; - this._currentQuery = query; - this._currentSession.accept(query); - } else if (this._currentQuery) { - this._input.value = this._currentQuery; - this._input.valueSelection = [0, this._input.value.length]; - } - } -} - -class InteractiveQuickPickSession extends Disposable { - - private _model: ChatModel; - private _viewModel: ChatViewModel; - - private readonly _onDidClickFollowup: Emitter = this._register(new Emitter()); - onDidClickFollowup: Event = this._onDidClickFollowup.event; - - private _listDisposable: DisposableStore | undefined; - - constructor( - @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IChatService private readonly _chatService: IChatService, - @IChatWidgetService private readonly _chatWidgetService: IChatWidgetService - ) { - super(); - - const providerInfo = _chatService.getProviderInfos()[0]; - this._model = this._register(_chatService.startSession(providerInfo.id, CancellationToken.None)!); - this._viewModel = this._register(new ChatViewModel(this._model, _instantiationService)); - } - - createList(container: HTMLElement, offsetWidth: number) { - this._listDisposable?.dispose(); - this._listDisposable = new DisposableStore(); - const options = this._listDisposable.add(this._instantiationService.createInstance(ChatEditorOptions, 'quickpick-interactive', foreground, editorBackground, editorBackground)); - const list = this._listDisposable.add(this._instantiationService.createInstance( - ChatListItemRenderer, - options, - { - getListLength: () => { - return 1; - }, - getSlashCommands() { - return []; - }, - } - )); - - const template = list.renderTemplate(container); - list.layout(offsetWidth); - this._listDisposable.add(this._viewModel.onDidChange(() => { - const items = this._viewModel.getItems(); - const node = { - element: items[items.length - 1], - children: [], - collapsed: false, - collapsible: false, - depth: 0, - filterData: undefined, - visible: true, - visibleChildIndex: 0, - visibleChildrenCount: 1, - }; - list.disposeElement(node, 0, template); - list.renderElement(node, 0, template); - })); - - if (this._viewModel.getItems().length) { - const items = this._viewModel.getItems(); - const node = { - element: items[items.length - 1], - children: [], - collapsed: false, - collapsible: false, - depth: 0, - filterData: undefined, - visible: true, - visibleChildIndex: 0, - visibleChildrenCount: 1, - }; - list.disposeElement(node, 0, template); - list.renderElement(node, 0, template); - } - - this._listDisposable.add(list.onDidClickFollowup(e => { - this._onDidClickFollowup.fire(e); - })); - } - - get providerId() { - return this._model.providerId; - } - - get sessionId() { - return this._model.sessionId; - } - - async accept(query: string) { - await this._model.waitForInitialization(); - const requests = this._model.getRequests(); - const lastRequest = requests[requests.length - 1]; - if (lastRequest?.message && lastRequest?.message === query) { - return; - } - if (this._model.requestInProgress) { - this._chatService.cancelCurrentRequestForSession(this.sessionId); - } - await this._chatService.sendRequest(this.sessionId, query); - } - - async openInChat(value: string) { - const widget = await this._chatWidgetService.revealViewForProvider(this.providerId); - if (!widget?.viewModel) { - return; - } - - const requests = this._model.getRequests().reverse(); - const response = requests.find(r => r.response?.response.value !== undefined); - const message = response?.response?.response.value; - if (message) { - this._chatService.addCompleteRequest(widget.viewModel.sessionId, value, { message }); - } else if (value) { - this._chatService.sendRequest(widget.viewModel.sessionId, value); - } - widget.focusInput(); - } -} diff --git a/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/multipleByScrollQuickQuestionAction.ts b/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/multipleByScrollQuickQuestionAction.ts new file mode 100644 index 0000000000000..095b8c2df8f88 --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/multipleByScrollQuickQuestionAction.ts @@ -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. + *--------------------------------------------------------------------------------------------*/ + +import * as dom from 'vs/base/browser/dom'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { Codicon } from 'vs/base/common/codicons'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { ThemeIcon } from 'vs/base/common/themables'; +import { localize } from 'vs/nls'; +import { IContextKeyService, IScopedContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { editorForeground, editorBackground } from 'vs/platform/theme/common/colorRegistry'; +import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; +import { AskQuickQuestionAction, IQuickQuestionMode, QuickQuestionMode } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; +import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; +import { IChatViewOptions } from 'vs/workbench/contrib/chat/browser/chatViewPane'; +import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget'; +import { ChatModel } from 'vs/workbench/contrib/chat/common/chatModel'; +import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; + +class BaseChatQuickQuestionMode implements IQuickQuestionMode { + private _currentTimer: any | undefined; + private _input: IQuickPick | undefined; + private _currentChat: QuickChat | undefined; + + constructor( + private readonly renderInputOnTop: boolean + ) { } + + run(accessor: ServicesAccessor, query: string): void { + const quickInputService = accessor.get(IQuickInputService); + const chatService = accessor.get(IChatService); + const instantiationService = accessor.get(IInstantiationService); + + // First things first, clear the existing timer that will dispose the session + clearTimeout(this._currentTimer); + this._currentTimer = undefined; + + // If the input is already shown, hide it. This provides a toggle behavior of the quick pick + if (this._input !== undefined) { + this._input.hide(); + return; + } + + // Check if any providers are available. If not, show nothing + // This shouldn't be needed because of the precondition, but just in case + const providerInfo = chatService.getProviderInfos()[0]; + if (!providerInfo) { + return; + } + + const disposableStore = new DisposableStore(); + + //#region Setup quick pick + + this._input = quickInputService.createQuickPick(); + disposableStore.add(this._input); + this._input.hideInput = true; + + + const containerList = dom.$('.interactive-list'); + const containerSession = dom.$('.interactive-session', undefined, containerList); + containerSession.style.height = '500px'; + containerList.style.position = 'relative'; + this._input.widget = containerSession; + + const clearButton = { + iconClass: ThemeIcon.asClassName(Codicon.clearAll), + tooltip: localize('clear', "Clear"), + }; + this._input.buttons = [ + clearButton, + { + iconClass: ThemeIcon.asClassName(Codicon.commentDiscussion), + tooltip: localize('openInChat', "Open in chat view"), + } + ]; + this._input.title = providerInfo.displayName; + + disposableStore.add(this._input.onDidHide(() => { + disposableStore.dispose(); + this._input = undefined; + this._currentTimer = setTimeout(() => { + this._currentChat?.dispose(); + this._currentChat = undefined; + }, 1000 * 30); // 30 seconds + })); + + //#endregion + + this._currentChat ??= instantiationService.createInstance(QuickChat, { + providerId: providerInfo.id, + renderInputOnTop: this.renderInputOnTop, + }); + this._currentChat.render(containerSession); + + disposableStore.add(this._input.onDidAccept(() => { + this._currentChat?.acceptInput(); + })); + + disposableStore.add(this._input.onDidTriggerButton((e) => { + if (e === clearButton) { + this._currentChat?.clear(); + } else { + this._currentChat?.openChatView(); + } + })); + + this._input.show(); + this._currentChat.layout(); + this._currentChat.focus(); + + if (query) { + this._currentChat.setValue(query); + this._currentChat.acceptInput(); + } + } +} + +class QuickChat extends Disposable { + private widget!: ChatWidget; + private model: ChatModel | undefined; + private _currentQuery: string | undefined; + + private _scopedContextKeyService!: IScopedContextKeyService; + get scopedContextKeyService() { + return this._scopedContextKeyService; + } + + private _currentParentElement?: HTMLElement; + + constructor( + private readonly chatViewOptions: IChatViewOptions & { renderInputOnTop: boolean }, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IChatService private readonly chatService: IChatService, + @IChatWidgetService private readonly _chatWidgetService: IChatWidgetService + ) { + super(); + } + + clear() { + this.model?.dispose(); + this.model = undefined; + this.updateModel(); + this.widget.inputEditor.setValue(''); + } + + focus(): void { + if (this.widget) { + this.widget.focusInput(); + } + } + + render(parent: HTMLElement): void { + this.widget?.dispose(); + this._currentParentElement = parent; + this._scopedContextKeyService = this._register(this.contextKeyService.createScoped(parent)); + const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection([IContextKeyService, this.scopedContextKeyService])); + this.widget = this._register( + scopedInstantiationService.createInstance( + ChatWidget, + { resource: true, renderInputOnTop: this.chatViewOptions.renderInputOnTop }, + { + listForeground: editorForeground, + listBackground: editorBackground, + inputEditorBackground: SIDE_BAR_BACKGROUND, + resultEditorBackground: SIDE_BAR_BACKGROUND + })); + this.widget.render(parent); + this.widget.setVisible(true); + this.updateModel(); + if (this._currentQuery) { + this.widget.inputEditor.setSelection({ + startLineNumber: 1, + startColumn: 1, + endLineNumber: 1, + endColumn: this._currentQuery.length + 1 + }); + } + + this.registerListeners(); + } + + private registerListeners(): void { + this._register(dom.addDisposableListener(parent, dom.EventType.RESIZE, () => this.layout())); + this._register(this.widget.inputEditor.onDidChangeModelContent((e) => { + this._currentQuery = this.widget.inputEditor.getValue(); + })); + } + + async acceptInput(): Promise { + if (this.widget.inputEditor.getValue().trim() === '/clear') { + this.clear(); + } else { + await this.widget.acceptInput(); + } + this.layout(); + } + + async openChatView(): Promise { + const widget = await this._chatWidgetService.revealViewForProvider(this.chatViewOptions.providerId); + if (!widget?.viewModel || !this.model) { + return; + } + + for (const request of this.model.getRequests()) { + if (request.response?.response.value || request.response?.errorDetails) { + this.chatService.addCompleteRequest(widget.viewModel.sessionId, + request.message as string, + { + message: request.response.response.value, + errorDetails: request.response.errorDetails + }); + } else if (request.message) { + + } + } + + const value = this.widget.inputEditor.getValue(); + if (value) { + widget.inputEditor.setValue(value); + } + widget.focusInput(); + } + + setValue(value: string): void { + this.widget.inputEditor.setValue(value); + } + + layout(): void { + if (this._currentParentElement) { + this.widget.layout(500, this._currentParentElement.offsetWidth); + } + } + + private updateModel(): void { + this.model ??= this.chatService.startSession(this.chatViewOptions.providerId, CancellationToken.None); + if (!this.model) { + throw new Error('Could not start chat session'); + } + + this.widget.setModel(this.model, { inputValue: this._currentQuery }); + } +} + +AskQuickQuestionAction.registerMode( + QuickQuestionMode.InputOnTopChat, + class InputOnTopChatQuickQuestionMode extends BaseChatQuickQuestionMode { + constructor() { + super(true); + } + } +); + +AskQuickQuestionAction.registerMode( + QuickQuestionMode.InputOnBottomChat, + class InputOnBottomChatQuickQuestionMode extends BaseChatQuickQuestionMode { + constructor() { + super(false); + } + } +); diff --git a/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction.ts b/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction.ts new file mode 100644 index 0000000000000..55d1b8faab9f7 --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { Lazy } from 'vs/base/common/lazy'; +import { localize } from 'vs/nls'; +import { Action2 } from 'vs/platform/actions/common/actions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions'; +import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys'; + +export const ASK_QUICK_QUESTION_ACTION_ID = 'chat.action.askQuickQuestion'; + +export const enum QuickQuestionMode { + SingleQuestion = 'singleQuestion', + InputOnTopChat = 'inputOnTopChat', + InputOnBottomChat = 'inputOnBottomChat', +} + +export interface IQuickQuestionMode { + run(accessor: ServicesAccessor, query: string): void; +} + +export class AskQuickQuestionAction extends Action2 { + + private static readonly modeRegistry: Map> = new Map(); + static registerMode(mode: QuickQuestionMode, modeAction: { new(): IQuickQuestionMode }) { + AskQuickQuestionAction.modeRegistry.set(mode, new Lazy(() => new modeAction())); + } + + constructor() { + super({ + id: ASK_QUICK_QUESTION_ACTION_ID, + title: { value: localize('askQuickQuestion', "Ask Quick Question"), original: 'Ask Quick Question' }, + precondition: CONTEXT_PROVIDER_EXISTS, + f1: false, + category: CHAT_CATEGORY, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI, + linux: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyI + } + }, + }); + } + + override run(accessor: ServicesAccessor, query: string): void { + const configurationService = accessor.get(IConfigurationService); + + const mode = configurationService.getValue('chat.experimental.quickQuestion.mode'); + const modeAction = AskQuickQuestionAction.modeRegistry.get(mode); + if (modeAction) { + modeAction.value.run(accessor, query); + } + } +} diff --git a/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/singleQuickQuestionAction.ts b/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/singleQuickQuestionAction.ts new file mode 100644 index 0000000000000..b436449a51a0a --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/actions/quickQuestionActions/singleQuickQuestionAction.ts @@ -0,0 +1,261 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as dom from 'vs/base/browser/dom'; +import { Toggle } from 'vs/base/browser/ui/toggle/toggle'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { Codicon } from 'vs/base/common/codicons'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { localize } from 'vs/nls'; +import { Emitter, Event } from 'vs/base/common/event'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { asCssVariable, editorBackground, foreground, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground } from 'vs/platform/theme/common/colorRegistry'; +import { ChatListItemRenderer } from 'vs/workbench/contrib/chat/browser/chatListRenderer'; +import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions'; +import { ChatModel } from 'vs/workbench/contrib/chat/common/chatModel'; +import { IChatReplyFollowup, IChatService } from 'vs/workbench/contrib/chat/common/chatService'; +import { ChatViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel'; +import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; +import { AskQuickQuestionAction, IQuickQuestionMode, QuickQuestionMode } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; + +class AskSingleQuickQuestionMode implements IQuickQuestionMode { + + private _currentSession: InteractiveQuickPickSession | undefined; + private _currentQuery: string | undefined; + private _lastAcceptedQuery: string | undefined; + private _currentTimer: any | undefined; + private _input: IQuickPick | undefined; + + run(accessor: ServicesAccessor, query: string): void { + const quickInputService = accessor.get(IQuickInputService); + const chatService = accessor.get(IChatService); + const instantiationService = accessor.get(IInstantiationService); + + // First things first, clear the existing timer that will dispose the session + clearTimeout(this._currentTimer); + this._currentTimer = undefined; + + // If the input is already shown, hide it. This provides a toggle behavior of the quick pick + if (this._input !== undefined) { + this._input.hide(); + return; + } + + // Check if any providers are available. If not, show nothing + const providerInfo = chatService.getProviderInfos()[0]; + if (!providerInfo) { + return; + } + + const disposableStore = new DisposableStore(); + + //#region Setup quick pick + + this._input = quickInputService.createQuickPick(); + disposableStore.add(this._input); + this._input.placeholder = localize('askabot', "Ask {0} a question...", providerInfo.displayName); + + // Setup toggle that will be used to open the chat view + const openInChat = new Toggle({ + title: 'Open in chat view', + icon: Codicon.commentDiscussion, + isChecked: false, + inputActiveOptionBorder: asCssVariable(inputActiveOptionBorder), + inputActiveOptionForeground: asCssVariable(inputActiveOptionForeground), + inputActiveOptionBackground: asCssVariable(inputActiveOptionBackground) + }); + disposableStore.add(openInChat); + disposableStore.add(openInChat.onChange(async () => { + await this._currentSession?.openInChat(this._lastAcceptedQuery ?? this._input!.value); + this._currentQuery = undefined; + this._lastAcceptedQuery = undefined; + this._currentSession?.dispose(); + this._currentSession = undefined; + })); + this._input.toggles = [openInChat]; + + // Setup the widget that will be used to render the chat response + const containerList = dom.$('.interactive-list'); + const containerSession = dom.$('.interactive-session', undefined, containerList); + containerList.style.position = 'relative'; + this._input.widget = containerSession; + + //#endregion + + //#region quick pick events + + disposableStore.add(this._input.onDidChangeValue((value) => { + if (value !== this._currentQuery) { + this._currentQuery = value; + } + })); + disposableStore.add(this._input.onDidHide(() => { + disposableStore.dispose(); + this._input = undefined; + this._currentTimer = setTimeout(() => { + this._currentQuery = undefined; + this._lastAcceptedQuery = undefined; + this._currentSession?.dispose(); + this._currentSession = undefined; + }, 1000 * 30); // 30 seconds + })); + disposableStore.add(this._input.onDidAccept(async () => { + await this._currentSession?.accept(this._input!.value); + this._lastAcceptedQuery = this._input!.value; + })); + + //#endregion + + // If we were given a query (via executeCommand), then clear past state + if (query) { + this._currentSession?.dispose(); + this._currentSession = undefined; + } + this._currentSession ??= instantiationService.createInstance(InteractiveQuickPickSession); + this._input.show(); + // This line must come after showing the input so the offsetWidth is correct + this._currentSession.createList(containerList, containerList.offsetWidth); + + disposableStore.add(this._currentSession.onDidClickFollowup(async e => { + this._input!.focusOnInput(); + this._input!.value = e.message; + await this._currentSession?.accept(e.message); + })); + + // If we were given a query (via executeCommand), then accept it + if (query) { + this._input.value = query; + this._input.valueSelection = [0, this._input.value.length]; + this._currentQuery = query; + this._currentSession.accept(query); + } else if (this._currentQuery) { + this._input.value = this._currentQuery; + this._input.valueSelection = [0, this._input.value.length]; + } + } +} + +class InteractiveQuickPickSession extends Disposable { + + private _model: ChatModel; + private _viewModel: ChatViewModel; + + private readonly _onDidClickFollowup: Emitter = this._register(new Emitter()); + onDidClickFollowup: Event = this._onDidClickFollowup.event; + + private _listDisposable: DisposableStore | undefined; + + constructor( + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IChatService private readonly _chatService: IChatService, + @IChatWidgetService private readonly _chatWidgetService: IChatWidgetService + ) { + super(); + + const providerInfo = _chatService.getProviderInfos()[0]; + this._model = this._register(_chatService.startSession(providerInfo.id, CancellationToken.None)!); + this._viewModel = this._register(new ChatViewModel(this._model, _instantiationService)); + } + + createList(container: HTMLElement, offsetWidth: number) { + this._listDisposable?.dispose(); + this._listDisposable = new DisposableStore(); + const options = this._listDisposable.add(this._instantiationService.createInstance(ChatEditorOptions, 'quickpick-interactive', foreground, editorBackground, editorBackground)); + const list = this._listDisposable.add(this._instantiationService.createInstance( + ChatListItemRenderer, + options, + { + getListLength: () => { + return 1; + }, + getSlashCommands() { + return []; + }, + } + )); + + const template = list.renderTemplate(container); + list.layout(offsetWidth); + this._listDisposable.add(this._viewModel.onDidChange(() => { + const items = this._viewModel.getItems(); + const node = { + element: items[items.length - 1], + children: [], + collapsed: false, + collapsible: false, + depth: 0, + filterData: undefined, + visible: true, + visibleChildIndex: 0, + visibleChildrenCount: 1, + }; + list.disposeElement(node, 0, template); + list.renderElement(node, 0, template); + })); + + if (this._viewModel.getItems().length) { + const items = this._viewModel.getItems(); + const node = { + element: items[items.length - 1], + children: [], + collapsed: false, + collapsible: false, + depth: 0, + filterData: undefined, + visible: true, + visibleChildIndex: 0, + visibleChildrenCount: 1, + }; + list.disposeElement(node, 0, template); + list.renderElement(node, 0, template); + } + + this._listDisposable.add(list.onDidClickFollowup(e => { + this._onDidClickFollowup.fire(e); + })); + } + + get providerId() { + return this._model.providerId; + } + + get sessionId() { + return this._model.sessionId; + } + + async accept(query: string) { + await this._model.waitForInitialization(); + const requests = this._model.getRequests(); + const lastRequest = requests[requests.length - 1]; + if (lastRequest?.message && lastRequest?.message === query) { + return; + } + if (this._model.requestInProgress) { + this._chatService.cancelCurrentRequestForSession(this.sessionId); + } + await this._chatService.sendRequest(this.sessionId, query); + } + + async openInChat(value: string) { + const widget = await this._chatWidgetService.revealViewForProvider(this.providerId); + if (!widget?.viewModel) { + return; + } + + const requests = this._model.getRequests().reverse(); + const response = requests.find(r => r.response?.response.value !== undefined); + const message = response?.response?.response.value; + if (message) { + this._chatService.addCompleteRequest(widget.viewModel.sessionId, value, { message }); + } else if (value) { + this._chatService.sendRequest(widget.viewModel.sessionId, value); + } + widget.focusInput(); + } +} + +AskQuickQuestionAction.registerMode(QuickQuestionMode.SingleQuestion, AskSingleQuickQuestionMode); diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index aef372dee9260..656485ed70a90 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -43,6 +43,7 @@ import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { QuickQuestionMode } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; // Register configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -76,6 +77,13 @@ configurationRegistry.registerConfiguration({ type: 'number', description: nls.localize('interactiveSession.editor.lineHeight', "Controls the line height in pixels in chat codeblocks. Use 0 to compute the line height from the font size."), default: 0 + }, + 'chat.experimental.quickQuestion.mode': { + type: 'string', + tags: ['experimental'], + enum: [QuickQuestionMode.SingleQuestion, QuickQuestionMode.InputOnTopChat, QuickQuestionMode.InputOnBottomChat], + description: nls.localize('interactiveSession.quickQuestion.mode', "Controls the mode of quick question chat experience."), + default: QuickQuestionMode.SingleQuestion, } } }); diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index b42cad92d7e00..996a999286cce 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -45,7 +45,7 @@ export interface IChatCodeBlockInfo { export type ChatTreeItem = IChatRequestViewModel | IChatResponseViewModel | IChatWelcomeMessageViewModel; -export type IChatWidgetViewContext = { viewId: string } | { resource: boolean }; +export type IChatWidgetViewContext = { viewId: string; renderInputOnTop?: false } | { resource: boolean; renderInputOnTop?: boolean }; export interface IChatWidget { readonly onDidChangeViewModel: Event; diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index d41f490038d45..92af40f0f16b5 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -77,6 +77,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge constructor( // private readonly editorOptions: ChatEditorOptions, // TODO this should be used + private readonly options: { renderFollowupsBelow: boolean }, @IChatWidgetHistoryService private readonly historyService: IChatWidgetHistoryService, @IModelService private readonly modelService: IModelService, @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -176,9 +177,15 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge render(container: HTMLElement, initialValue: string, widget: IChatWidget) { this.container = dom.append(container, $('.interactive-input-part')); - this.followupsContainer = dom.append(this.container, $('.interactive-input-followups')); - const inputContainer = dom.append(this.container, $('.interactive-input-and-toolbar')); + let inputContainer: HTMLElement; + if (this.options.renderFollowupsBelow) { + inputContainer = dom.append(this.container, $('.interactive-input-and-toolbar')); + this.followupsContainer = dom.append(this.container, $('.interactive-input-followups')); + } else { + this.followupsContainer = dom.append(this.container, $('.interactive-input-followups')); + inputContainer = dom.append(this.container, $('.interactive-input-and-toolbar')); + } const inputScopedContextKeyService = this._register(this.contextKeyService.createScoped(inputContainer)); CONTEXT_IN_CHAT_INPUT.bindTo(inputScopedContextKeyService).set(true); diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index fa29aac02296b..c40f97ce4dc31 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -136,13 +136,20 @@ export class ChatWidget extends Disposable implements IChatWidget { } render(parent: HTMLElement): void { - this.container = dom.append(parent, $('.interactive-session')); - this.listContainer = dom.append(this.container, $(`.interactive-list`)); - const viewId = 'viewId' in this.viewContext ? this.viewContext.viewId : undefined; this.editorOptions = this._register(this.instantiationService.createInstance(ChatEditorOptions, viewId, this.styles.listForeground, this.styles.inputEditorBackground, this.styles.resultEditorBackground)); + const renderInputOnTop = this.viewContext.renderInputOnTop ?? false; + + this.container = dom.append(parent, $('.interactive-session')); + if (renderInputOnTop) { + this.createInput(this.container, { renderFollowupsBelow: true }); + this.listContainer = dom.append(this.container, $(`.interactive-list`)); + } else { + this.listContainer = dom.append(this.container, $(`.interactive-list`)); + this.createInput(this.container); + } + this.createList(this.listContainer); - this.createInput(this.container); this._register(this.editorOptions.onDidChange(() => this.onDidStyleChange())); this.onDidStyleChange(); @@ -327,8 +334,8 @@ export class ChatWidget extends Disposable implements IChatWidget { this.previousTreeScrollHeight = this.tree.scrollHeight; } - private createInput(container: HTMLElement): void { - this.inputPart = this.instantiationService.createInstance(ChatInputPart); + private createInput(container: HTMLElement, options?: { renderFollowupsBelow: boolean }): void { + this.inputPart = this.instantiationService.createInstance(ChatInputPart, { renderFollowupsBelow: options?.renderFollowupsBelow ?? false }); this.inputPart.render(container, '', this); this._register(this.inputPart.onDidFocus(() => this._onDidFocus.fire())); diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index 75a3d125a9892..e0ec10e9d5e5d 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -190,6 +190,7 @@ border-radius: 4px; position: relative; padding-left: 8px; + margin-bottom: 4px; } .interactive-session .interactive-input-and-toolbar.focused { @@ -298,6 +299,7 @@ display: flex; flex-direction: column; border-top: solid 1px var(--vscode-chat-requestBorder); + border-bottom: solid 1px var(--vscode-chat-requestBorder); } .interactive-session-followups { diff --git a/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts b/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts index dd837a29ec799..328d274502496 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts @@ -35,7 +35,7 @@ import { isFirefox } from 'vs/base/browser/browser'; import { IProductService } from 'vs/platform/product/common/productService'; import { ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService'; import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; -import { ASK_QUICK_QUESTION_ACTION_ID } from 'vs/workbench/contrib/chat/browser/actions/chatQuickInputActions'; +import { ASK_QUICK_QUESTION_ACTION_ID } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider { From 29f02712936e3edcec5f053d7361a9b88b2b8570 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 10:41:06 -0700 Subject: [PATCH 0098/1180] accessible view for notifications --- .../accessibility}/accessibleView.ts | 36 +++++++++++++++++-- .../parts/notifications/notificationsList.ts | 16 +++++++-- .../browser/accessibility.contribution.ts | 2 +- .../browser/actions/chatAccessibilityHelp.ts | 2 +- .../contrib/chat/browser/chat.contribution.ts | 2 +- .../browser/accessibility/accessibility.ts | 2 +- .../codeEditor/browser/diffEditorHelper.ts | 2 +- .../browser/notebookAccessibilityHelp.ts | 2 +- .../terminal.accessibility.contribution.ts | 2 +- .../browser/terminalAccessibilityHelp.ts | 2 +- 10 files changed, 55 insertions(+), 13 deletions(-) rename src/vs/workbench/{contrib/accessibility/browser => browser/accessibility}/accessibleView.ts (90%) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/browser/accessibility/accessibleView.ts similarity index 90% rename from src/vs/workbench/contrib/accessibility/browser/accessibleView.ts rename to src/vs/workbench/browser/accessibility/accessibleView.ts index 8754d601121b7..3be0b4add7515 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/browser/accessibility/accessibleView.ts @@ -22,9 +22,8 @@ import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/cont import { IContextViewDelegate, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard'; -import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; import { alert } from 'vs/base/browser/ui/aria/aria'; +import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; const enum DEFAULT { WIDTH = 800, @@ -80,7 +79,7 @@ class AccessibleView extends Disposable { this._editorContainer = document.createElement('div'); this._editorContainer.classList.add('accessible-view'); const codeEditorWidgetOptions: ICodeEditorWidgetOptions = { - contributions: EditorExtensionsRegistry.getSomeEditorContributions([LinkDetector.ID, SelectionClipboardContributionID, 'editor.contrib.selectionAnchorController']) + contributions: EditorExtensionsRegistry.getSomeEditorContributions([LinkDetector.ID, 'editor.contrib.selectionClipboard', 'editor.contrib.selectionAnchorController']) }; const editorOptions: IEditorConstructionOptions = { ...getSimpleEditorOptions(this._configurationService), @@ -226,3 +225,34 @@ export class AccessibleViewService extends Disposable implements IAccessibleView this._accessibleView.show(provider); } } +function getSimpleEditorOptions(configurationService: IConfigurationService): IEditorOptions { + return { + wordWrap: 'on', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden' + }, + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + dragAndDrop: false, + revealHorizontalRightPadding: 5, + minimap: { + enabled: false + }, + guides: { + indentation: false + }, + accessibilitySupport: configurationService.getValue<'auto' | 'off' | 'on'>('editor.accessibilitySupport'), + cursorBlinking: configurationService.getValue<'blink' | 'smooth' | 'phase' | 'expand' | 'solid'>('editor.cursorBlinking') + }; +} diff --git a/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/src/vs/workbench/browser/parts/notifications/notificationsList.ts index f54137e9371b9..48584abc52475 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsList.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsList.ts @@ -19,6 +19,7 @@ import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys'; import { Disposable } from 'vs/base/common/lifecycle'; import { AriaRole } from 'vs/base/browser/ui/aria/aria'; import { NotificationActionRunner } from 'vs/workbench/browser/parts/notifications/notificationsCommands'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; export interface INotificationsListOptions extends IListOptions { readonly widgetAriaLabel?: string; @@ -36,7 +37,8 @@ export class NotificationsList extends Disposable { private readonly container: HTMLElement, private readonly options: INotificationsListOptions, @IInstantiationService private readonly instantiationService: IInstantiationService, - @IContextMenuService private readonly contextMenuService: IContextMenuService + @IContextMenuService private readonly contextMenuService: IContextMenuService, + @IAccessibleViewService private readonly accessibleViewService: IAccessibleViewService ) { super(); } @@ -161,7 +163,17 @@ export class NotificationsList extends Disposable { // Remember focus and relative top of that item const focusedIndex = list.getFocus()[0]; const focusedItem = this.viewModel[focusedIndex]; - + this.accessibleViewService.show({ + provideContent: () => { return focusedItem.message.original.toString() || ''; }, + onClose(): void { + list.setFocus([focusedIndex]); + }, + verbositySettingKey: 'notifications', + options: { + ariaLabel: localize('notification', "Notification Accessible View"), + type: AccessibleViewType.View + } + }); let focusRelativeTop: number | null = null; if (typeof focusedIndex === 'number') { focusRelativeTop = list.getRelativeTop(focusedIndex); diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts index d391b388ac6c2..e4b747f5e02eb 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts @@ -13,7 +13,7 @@ import { localize } from 'vs/nls'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { AccessibilityHelpAction, AccessibleViewAction, registerAccessibilityConfiguration } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { AccessibleViewService, AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { AccessibleViewService, AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import * as strings from 'vs/base/common/strings'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts index 10a34e44a6a91..83892d5fb48b3 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts @@ -10,7 +10,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import { InlineChatController } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 656485ed70a90..4f362ccf834ad 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -38,7 +38,7 @@ import '../common/chatColors'; import { registerMoveActions } from 'vs/workbench/contrib/chat/browser/actions/chatMoveActions'; import { registerClearActions } from 'vs/workbench/contrib/chat/browser/actions/chatClearActions'; import { AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts index 903406a294778..b39ed1353f806 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts @@ -9,7 +9,7 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; -import { accessibilityHelpIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { accessibilityHelpIsShown } from 'vs/workbench/browser/accessibility/accessibleView'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { alert } from 'vs/base/browser/ui/aria/aria'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index 7414c5b26a5d6..5da8615c51cd4 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -20,7 +20,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; const enum WidgetState { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts b/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts index 717b6167614d7..5e45789ccb1f7 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts @@ -8,7 +8,7 @@ import { format } from 'vs/base/common/strings'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; export function getAccessibilityHelpText(accessor: ServicesAccessor): string { const keybindingService = accessor.get(IKeybindingService); 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 26042ec1cb190..baf38d2541b41 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 @@ -13,7 +13,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts index d5d73c308a1e2..318b912982d92 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts @@ -10,7 +10,7 @@ import { IAccessibilityService } from 'vs/platform/accessibility/common/accessib 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 { AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; +import { AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions } from 'vs/workbench/browser/accessibility/accessibleView'; import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import type { Terminal } from 'xterm'; From 092a43cfaa667e3739e06e5c52519d43ec658172 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 13 Jul 2023 19:54:37 +0200 Subject: [PATCH 0099/1180] Merge profile name and configuration pickers (#187862) --- .../quickinput/browser/media/quickInput.css | 2 +- .../platform/quickinput/browser/quickInput.ts | 14 +++++- .../platform/quickinput/common/quickInput.ts | 7 +++ .../browser/userDataProfile.ts | 49 +++++++++++++------ 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/quickinput/browser/media/quickInput.css b/src/vs/platform/quickinput/browser/media/quickInput.css index de8df301e3c80..9bb877f99914f 100644 --- a/src/vs/platform/quickinput/browser/media/quickInput.css +++ b/src/vs/platform/quickinput/browser/media/quickInput.css @@ -50,7 +50,7 @@ } .quick-input-description { - margin: 6px; + margin: 6px 6px 6px 11px; } .quick-input-header .quick-input-description { diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index 7992328ec1f74..f9829e3d98f77 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -537,6 +537,7 @@ class QuickPick extends QuickInput implements IQuickPi private _customButtonHover: string | undefined; private _quickNavigate: IQuickNavigateConfiguration | undefined; private _hideInput: boolean | undefined; + private _hideCountBadge: boolean | undefined; private _hideCheckAll: boolean | undefined; get quickNavigate() { @@ -796,6 +797,15 @@ class QuickPick extends QuickInput implements IQuickPi this.update(); } + get hideCountBadge() { + return !!this._hideCountBadge; + } + + set hideCountBadge(hideCountBadge: boolean) { + this._hideCountBadge = hideCountBadge; + this.update(); + } + get hideCheckAll() { return !!this._hideCheckAll; } @@ -1038,7 +1048,7 @@ class QuickPick extends QuickInput implements IQuickPi inputBox: !this._hideInput, progressBar: !this._hideInput || hasDescription, visibleCount: true, - count: this.canSelectMany, + count: this.canSelectMany && !this._hideCountBadge, ok: this.ok === 'default' ? this.canSelectMany : this.ok, list: true, message: !!this.validationMessage, @@ -1315,8 +1325,8 @@ export class QuickInputController extends Disposable { const rightActionBar = this._register(new ActionBar(titleBar)); rightActionBar.domNode.classList.add('quick-input-right-action-bar'); - const description1 = dom.append(container, $('.quick-input-description')); const headerContainer = dom.append(container, $('.quick-input-header')); + const description1 = dom.append(container, $('.quick-input-description')); const checkAll = dom.append(headerContainer, $('input.quick-input-check-all')); checkAll.type = 'checkbox'; diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 00c4a4d28b57b..8106d17087080 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -351,6 +351,8 @@ export interface IQuickPick extends IQuickInput { validationMessage: string | undefined; + severity: Severity; + inputHasFocus(): boolean; focusOnInput(): void; @@ -362,6 +364,11 @@ export interface IQuickPick extends IQuickInput { */ hideInput: boolean; + /** + * Allows to control if the count for the items should be shown + */ + hideCountBadge: boolean; + hideCheckAll: boolean; /** diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 5ea18399b20eb..9b2002bdfe2a4 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -30,6 +30,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IRequestService, asJson } from 'vs/platform/request/common/request'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ILogService } from 'vs/platform/log/common/log'; +import Severity from 'vs/base/common/severity'; const CREATE_EMPTY_PROFILE_ACTION_ID = 'workbench.profiles.actions.createEmptyProfile'; const CREATE_EMPTY_PROFILE_ACTION_TITLE = { @@ -500,14 +501,19 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements const quickPick = this.quickInputService.createQuickPick(); quickPick.title = title; - quickPick.hideInput = true; + quickPick.placeholder = localize('name placeholder', "Name the new profile"); quickPick.canSelectMany = true; + quickPick.matchOnDescription = false; + quickPick.matchOnDetail = false; + quickPick.matchOnLabel = false; + quickPick.sortByLabel = false; + quickPick.hideCountBadge = true; quickPick.ok = false; quickPick.customButton = true; quickPick.hideCheckAll = true; quickPick.ignoreFocusOut = true; quickPick.customLabel = localize('create', "Create Profile"); - quickPick.description = localize('customise the profile', "Choose what you want to configure in the profile. Unselected items are shared from the default profile."); + quickPick.description = localize('customise the profile', "Choose what to configure in the profile. Unselected items are shared from the default profile."); quickPick.items = resources; quickPick.selectedItems = resources.filter(item => item.picked); @@ -518,12 +524,29 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements } })); - let result: ReadonlyArray | undefined; + disposables.add(quickPick.onDidChangeValue(value => { + if (this.userDataProfilesService.profiles.some(p => p.name === value)) { + quickPick.validationMessage = localize('profileExists', "Profile with name {0} already exists.", value); + quickPick.severity = Severity.Error; + } else { + quickPick.severity = Severity.Ignore; + quickPick.validationMessage = undefined; + } + })); + + let result: { name: string; items: ReadonlyArray } | undefined; disposables.add(quickPick.onDidCustom(async () => { + if (!quickPick.value) { + quickPick.validationMessage = localize('name required', "Provide a name for the new profile"); + quickPick.severity = Severity.Error; + return; + } if (resources.some(resource => quickPick.selectedItems.includes(resource))) { - result = quickPick.selectedItems; + result = { name: quickPick.value, items: quickPick.selectedItems }; quickPick.hide(); } + quickPick.severity = Severity.Ignore; + quickPick.validationMessage = undefined; })); quickPick.show(); @@ -538,18 +561,14 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements return; } - const name = await this.getNameForProfile(title); - if (!name) { - return; - } - + const { name, items } = result; try { - const useDefaultFlags: UseDefaultProfileFlags | undefined = result.length !== resources.length ? { - settings: !result.includes(settings), - keybindings: !result.includes(keybindings), - snippets: !result.includes(snippets), - tasks: !result.includes(tasks), - extensions: !result.includes(extensions) + const useDefaultFlags: UseDefaultProfileFlags | undefined = items.length !== resources.length ? { + settings: !items.includes(settings), + keybindings: !items.includes(keybindings), + snippets: !items.includes(snippets), + tasks: !items.includes(tasks), + extensions: !items.includes(extensions) } : undefined; await this.userDataProfileManagementService.createAndEnterProfile(name, { useDefaultFlags }); } catch (error) { From 7b17343101821bd36e9939557e2200edc8122882 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:46:42 -0700 Subject: [PATCH 0100/1180] Always create terminal on empty terminal view show Part of #187772 --- .../contrib/terminal/browser/terminalView.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index c5b3308b7d490..f91f800c2ad0b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -127,9 +127,17 @@ export class TerminalViewPane extends ViewPane { return (decorationsEnabled === 'both' || decorationsEnabled === 'gutter') && this._configurationService.getValue(TerminalSettingId.ShellIntegrationEnabled); } - private _initializeTerminal() { - if (this.isBodyVisible() && this._terminalService.isProcessSupportRegistered && this._terminalService.connectionState === TerminalConnectionState.Connected && this._terminalService.restoredGroupCount === 0 && this._terminalGroupService.groups.length === 0) { - this._terminalService.createTerminal({ location: TerminalLocation.Panel }); + private _initializeTerminal(checkRestoredTerminals: boolean) { + if (this.isBodyVisible() && this._terminalService.isProcessSupportRegistered && this._terminalService.connectionState === TerminalConnectionState.Connected) { + let shouldCreate = this._terminalGroupService.groups.length === 0; + // When triggered just after reconnection, also check there are no groups that could be + // getting restored currently + if (checkRestoredTerminals) { + shouldCreate &&= this._terminalService.restoredGroupCount === 0; + } + if (shouldCreate) { + this._terminalService.createTerminal({ location: TerminalLocation.Panel }); + } } } @@ -169,7 +177,7 @@ export class TerminalViewPane extends ViewPane { if (!this._terminalService.isProcessSupportRegistered) { this._onDidChangeViewWelcomeState.fire(); } - this._initializeTerminal(); + this._initializeTerminal(false); // we don't know here whether or not it should be focused, so // defer focusing the panel to the focus() call // to prevent overriding preserveFocus for extensions @@ -181,7 +189,7 @@ export class TerminalViewPane extends ViewPane { } this._terminalGroupService.updateVisibility(); })); - this._register(this._terminalService.onDidChangeConnectionState(() => this._initializeTerminal())); + this._register(this._terminalService.onDidChangeConnectionState(() => this._initializeTerminal(true))); this.layoutBody(this._parentDomElement.offsetHeight, this._parentDomElement.offsetWidth); } From 02447a5b258275c43c6f72f70424f380a2a44837 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 14:19:15 -0700 Subject: [PATCH 0101/1180] fix #187114 --- .../browser/accessibility/accessibleView.ts | 13 +++--- .../notifications/notificationsCommands.ts | 26 +++++------ .../parts/notifications/notificationsList.ts | 16 +------ .../browser/accessibility.contribution.ts | 43 +++++++++++++++++++ 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/vs/workbench/browser/accessibility/accessibleView.ts b/src/vs/workbench/browser/accessibility/accessibleView.ts index 3be0b4add7515..14b3d401f80ff 100644 --- a/src/vs/workbench/browser/accessibility/accessibleView.ts +++ b/src/vs/workbench/browser/accessibility/accessibleView.ts @@ -170,11 +170,7 @@ class AccessibleView extends Disposable { }); const disposableStore = new DisposableStore(); disposableStore.add(this._editorWidget.onKeyUp((e) => { - if (e.keyCode === KeyCode.Escape) { - this._contextViewService.hideContextView(); - // Delay to allow the context view to hide #186514 - setTimeout(() => provider.onClose(), 100); - } else if (e.keyCode === KeyCode.KeyD && this._configurationService.getValue(settingKey)) { + if (e.keyCode === KeyCode.KeyD && this._configurationService.getValue(settingKey)) { alert(localize('disableAccessibilityHelp', '{0} accessibility verbosity is now disabled', provider.verbositySettingKey)); this._configurationService.updateValue(settingKey, false); } @@ -182,7 +178,12 @@ class AccessibleView extends Disposable { provider.onKeyDown?.(e); })); disposableStore.add(this._editorWidget.onKeyDown((e) => { - if (e.keyCode === KeyCode.KeyH && provider.options.readMoreUrl) { + if (e.keyCode === KeyCode.Escape) { + e.stopPropagation(); + this._contextViewService.hideContextView(); + // Delay to allow the context view to hide #186514 + setTimeout(() => provider.onClose(), 100); + } else if (e.keyCode === KeyCode.KeyH && provider.options.readMoreUrl) { const url: string = provider.options.readMoreUrl!; alert(AccessibilityHelpNLS.openingDocs); this._openerService.open(URI.parse(url)); diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts index ffe7592d9f1b0..71df63ebd3d92 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts @@ -61,23 +61,23 @@ export interface INotificationsToastController { hide(): void; } -export function registerNotificationCommands(center: INotificationsCenterController, toasts: INotificationsToastController, model: NotificationsModel): void { +export function getNotificationFromContext(listService: IListService, context?: unknown): INotificationViewItem | undefined { + if (isNotificationViewItem(context)) { + return context; + } - function getNotificationFromContext(listService: IListService, context?: unknown): INotificationViewItem | undefined { - if (isNotificationViewItem(context)) { - return context; + const list = listService.lastFocusedList; + if (list instanceof WorkbenchList) { + const focusedElement = list.getFocusedElements()[0]; + if (isNotificationViewItem(focusedElement)) { + return focusedElement; } + } - const list = listService.lastFocusedList; - if (list instanceof WorkbenchList) { - const focusedElement = list.getFocusedElements()[0]; - if (isNotificationViewItem(focusedElement)) { - return focusedElement; - } - } + return undefined; +} - return undefined; - } +export function registerNotificationCommands(center: INotificationsCenterController, toasts: INotificationsToastController, model: NotificationsModel): void { // Show Notifications Cneter CommandsRegistry.registerCommand(SHOW_NOTIFICATIONS_CENTER, () => { diff --git a/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/src/vs/workbench/browser/parts/notifications/notificationsList.ts index 48584abc52475..f54137e9371b9 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsList.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsList.ts @@ -19,7 +19,6 @@ import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys'; import { Disposable } from 'vs/base/common/lifecycle'; import { AriaRole } from 'vs/base/browser/ui/aria/aria'; import { NotificationActionRunner } from 'vs/workbench/browser/parts/notifications/notificationsCommands'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; export interface INotificationsListOptions extends IListOptions { readonly widgetAriaLabel?: string; @@ -37,8 +36,7 @@ export class NotificationsList extends Disposable { private readonly container: HTMLElement, private readonly options: INotificationsListOptions, @IInstantiationService private readonly instantiationService: IInstantiationService, - @IContextMenuService private readonly contextMenuService: IContextMenuService, - @IAccessibleViewService private readonly accessibleViewService: IAccessibleViewService + @IContextMenuService private readonly contextMenuService: IContextMenuService ) { super(); } @@ -163,17 +161,7 @@ export class NotificationsList extends Disposable { // Remember focus and relative top of that item const focusedIndex = list.getFocus()[0]; const focusedItem = this.viewModel[focusedIndex]; - this.accessibleViewService.show({ - provideContent: () => { return focusedItem.message.original.toString() || ''; }, - onClose(): void { - list.setFocus([focusedIndex]); - }, - verbositySettingKey: 'notifications', - options: { - ariaLabel: localize('notification', "Notification Accessible View"), - type: AccessibleViewType.View - } - }); + let focusRelativeTop: number | null = null; if (typeof focusedIndex === 'number') { focusRelativeTop = list.getRelativeTop(focusedIndex); diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts index e4b747f5e02eb..0ceff52d257fc 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts @@ -24,6 +24,9 @@ import { NEW_UNTITLED_FILE_COMMAND_ID } from 'vs/workbench/contrib/files/browser import { ModesHoverController } from 'vs/editor/contrib/hover/browser/hover'; import { withNullAsUndefined } from 'vs/base/common/types'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { getNotificationFromContext } from 'vs/workbench/browser/parts/notifications/notificationsCommands'; +import { IListService, WorkbenchList } from 'vs/platform/list/browser/listService'; +import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys'; registerAccessibilityConfiguration(); registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed); @@ -133,3 +136,43 @@ class HoverAccessibleViewContribution extends Disposable { const workbenchContributionsRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(HoverAccessibleViewContribution, LifecyclePhase.Eventually); + +class NotificationAccessibleViewContribution extends Disposable { + static ID: 'notificationAccessibleViewContribution'; + constructor() { + super(); + this._register(AccessibleViewAction.addImplementation(90, 'notifications', accessor => { + const accessibleViewService = accessor.get(IAccessibleViewService); + const listService = accessor.get(IListService); + const notification = getNotificationFromContext(listService); + if (!notification) { + return false; + } + let notificationIndex: number | undefined; + const list = listService.lastFocusedList; + if (list instanceof WorkbenchList) { + notificationIndex = list.indexOf(notification); + } + if (notificationIndex === undefined) { + return false; + } + accessibleViewService.show({ + provideContent: () => { return notification.message.original.toString() || ''; }, + onClose(): void { + if (list && notificationIndex !== undefined) { + list.domFocus(); + list.setFocus([notificationIndex]); + } + }, + verbositySettingKey: 'notifications', + options: { + ariaLabel: localize('notification', "Notification Accessible View"), + type: AccessibleViewType.View + } + }); + return true; + }, NotificationFocusedContext)); + } +} + +workbenchContributionsRegistry.registerWorkbenchContribution(NotificationAccessibleViewContribution, LifecyclePhase.Eventually); From 4284deab4203b23f2390641bc1596c2599635fbe Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 14:59:50 -0700 Subject: [PATCH 0102/1180] get it close to working to navigate bw them --- .../browser/accessibility/accessibleView.ts | 2 +- .../browser/accessibility.contribution.ts | 68 +++++++++++-------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/browser/accessibility/accessibleView.ts b/src/vs/workbench/browser/accessibility/accessibleView.ts index 14b3d401f80ff..deb54ed462864 100644 --- a/src/vs/workbench/browser/accessibility/accessibleView.ts +++ b/src/vs/workbench/browser/accessibility/accessibleView.ts @@ -174,8 +174,8 @@ class AccessibleView extends Disposable { alert(localize('disableAccessibilityHelp', '{0} accessibility verbosity is now disabled', provider.verbositySettingKey)); this._configurationService.updateValue(settingKey, false); } - e.stopPropagation(); provider.onKeyDown?.(e); + e.stopPropagation(); })); disposableStore.add(this._editorWidget.onKeyDown((e) => { if (e.keyCode === KeyCode.Escape) { diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts index 0ceff52d257fc..55244e09957d5 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts @@ -11,7 +11,7 @@ import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings'; import { ToggleTabFocusModeAction } from 'vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode'; import { localize } from 'vs/nls'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IKeybindingService, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; import { AccessibilityHelpAction, AccessibleViewAction, registerAccessibilityConfiguration } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; import { AccessibleViewService, AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import * as strings from 'vs/base/common/strings'; @@ -27,6 +27,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { getNotificationFromContext } from 'vs/workbench/browser/parts/notifications/notificationsCommands'; import { IListService, WorkbenchList } from 'vs/platform/list/browser/listService'; import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys'; +import { KeyCode } from 'vs/base/common/keyCodes'; registerAccessibilityConfiguration(); registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed); @@ -144,33 +145,46 @@ class NotificationAccessibleViewContribution extends Disposable { this._register(AccessibleViewAction.addImplementation(90, 'notifications', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const listService = accessor.get(IListService); - const notification = getNotificationFromContext(listService); - if (!notification) { - return false; - } - let notificationIndex: number | undefined; - const list = listService.lastFocusedList; - if (list instanceof WorkbenchList) { - notificationIndex = list.indexOf(notification); - } - if (notificationIndex === undefined) { - return false; - } - accessibleViewService.show({ - provideContent: () => { return notification.message.original.toString() || ''; }, - onClose(): void { - if (list && notificationIndex !== undefined) { - list.domFocus(); - list.setFocus([notificationIndex]); - } - }, - verbositySettingKey: 'notifications', - options: { - ariaLabel: localize('notification', "Notification Accessible View"), - type: AccessibleViewType.View + + function show(): boolean { + const notification = getNotificationFromContext(listService); + if (!notification) { + return false; } - }); - return true; + let notificationIndex: number | undefined; + const list = listService.lastFocusedList; + if (list instanceof WorkbenchList) { + notificationIndex = list.indexOf(notification); + } + if (notificationIndex === undefined) { + return false; + } + accessibleViewService.show({ + provideContent: () => { return notification.message.original.toString() || ''; }, + onClose(): void { + if (list && notificationIndex !== undefined) { + list.domFocus(); + list.setFocus([notificationIndex]); + } + }, + onKeyDown(e: IKeyboardEvent): void { + if (e.keyCode === KeyCode.DownArrow && e.altKey && e.ctrlKey) { + list?.focusNext(); + show(); + } else if (e.keyCode === KeyCode.UpArrow && e.altKey && e.ctrlKey) { + list?.focusPrevious(); + show(); + } + }, + verbositySettingKey: 'notifications', + options: { + ariaLabel: localize('notification', "Notification Accessible View"), + type: AccessibleViewType.View + } + }); + return true; + } + return show(); }, NotificationFocusedContext)); } } From 0a6f58c6bf576b85699a6316e8c7afa850d578b0 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 15:08:28 -0700 Subject: [PATCH 0103/1180] revert file move that did not help --- .../browser/accessibility.contribution.ts | 2 +- .../accessibility/browser}/accessibleView.ts | 36 ++----------------- 2 files changed, 4 insertions(+), 34 deletions(-) rename src/vs/workbench/{browser/accessibility => contrib/accessibility/browser}/accessibleView.ts (90%) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts index 55244e09957d5..14e0c135ccb87 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts @@ -13,7 +13,6 @@ import { localize } from 'vs/nls'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IKeybindingService, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; import { AccessibilityHelpAction, AccessibleViewAction, registerAccessibilityConfiguration } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { AccessibleViewService, AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import * as strings from 'vs/base/common/strings'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -28,6 +27,7 @@ import { getNotificationFromContext } from 'vs/workbench/browser/parts/notificat import { IListService, WorkbenchList } from 'vs/platform/list/browser/listService'; import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys'; import { KeyCode } from 'vs/base/common/keyCodes'; +import { IAccessibleViewService, AccessibleViewService, IAccessibleContentProvider, IAccessibleViewOptions, AccessibleViewType } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; registerAccessibilityConfiguration(); registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed); diff --git a/src/vs/workbench/browser/accessibility/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts similarity index 90% rename from src/vs/workbench/browser/accessibility/accessibleView.ts rename to src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index deb54ed462864..7f67ff99e9714 100644 --- a/src/vs/workbench/browser/accessibility/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -23,7 +23,8 @@ import { IContextViewDelegate, IContextViewService } from 'vs/platform/contextvi import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { alert } from 'vs/base/browser/ui/aria/aria'; -import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; +import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard'; const enum DEFAULT { WIDTH = 800, @@ -79,7 +80,7 @@ class AccessibleView extends Disposable { this._editorContainer = document.createElement('div'); this._editorContainer.classList.add('accessible-view'); const codeEditorWidgetOptions: ICodeEditorWidgetOptions = { - contributions: EditorExtensionsRegistry.getSomeEditorContributions([LinkDetector.ID, 'editor.contrib.selectionClipboard', 'editor.contrib.selectionAnchorController']) + contributions: EditorExtensionsRegistry.getSomeEditorContributions([LinkDetector.ID, SelectionClipboardContributionID, 'editor.contrib.selectionAnchorController']) }; const editorOptions: IEditorConstructionOptions = { ...getSimpleEditorOptions(this._configurationService), @@ -226,34 +227,3 @@ export class AccessibleViewService extends Disposable implements IAccessibleView this._accessibleView.show(provider); } } -function getSimpleEditorOptions(configurationService: IConfigurationService): IEditorOptions { - return { - wordWrap: 'on', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden' - }, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - dragAndDrop: false, - revealHorizontalRightPadding: 5, - minimap: { - enabled: false - }, - guides: { - indentation: false - }, - accessibilitySupport: configurationService.getValue<'auto' | 'off' | 'on'>('editor.accessibilitySupport'), - cursorBlinking: configurationService.getValue<'blink' | 'smooth' | 'phase' | 'expand' | 'solid'>('editor.cursorBlinking') - }; -} From 0dd3429cbd9d0ccc19715ad2582b9e557a6ec019 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 14 Jul 2023 00:58:58 +0200 Subject: [PATCH 0104/1180] Revert "revert the feature (#187816)" (#187871) This reverts commit 7895f9bc23f85ffe6db5e3d27cae984f9fffab1c. --- .../browser/preferencesRenderers.ts | 10 +- .../preferences/browser/settingsTree.ts | 49 ++++++++- .../configuration/browser/configuration.ts | 10 +- .../browser/configurationService.ts | 56 ++++++++++- .../configuration/common/configuration.ts | 2 + .../test/browser/configurationService.test.ts | 99 ++++++++++++++++++- 6 files changed, 218 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts index 3983b46e19186..c80d1d641c896 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts @@ -44,7 +44,7 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c import { isEqual } from 'vs/base/common/resources'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; -import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; export interface IPreferencesRenderer extends IDisposable { render(): void; @@ -616,6 +616,14 @@ class UnsupportedSettingsRenderer extends Disposable implements languages.CodeAc if (configuration.scope === ConfigurationScope.APPLICATION) { // If we're in a profile setting file, and the setting is application-scoped, fade it out. markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); + } else if (this.configurationService.isSettingAppliedForAllProfiles(setting.key)) { + // If we're in the non-default profile setting file, and the setting can be applied in all profiles, fade it out. + markerData.push({ + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + ...setting.range, + message: nls.localize('allProfileSettingWhileInNonDefaultProfileSetting', "This setting cannot be applied because it is configured to be applied in all profiles using setting {0}. Value from the default profile will be used instead.", APPLY_ALL_PROFILES_SETTING) + }); } } } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 9124e87d359be..ff00480a0ee12 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -23,6 +23,7 @@ import { IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree'; import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; import { Action, IAction, Separator } from 'vs/base/common/actions'; +import { distinct } from 'vs/base/common/arrays'; import { Codicon } from 'vs/base/common/codicons'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -63,7 +64,7 @@ import { ISettingsEditorViewState, SettingsTreeElement, SettingsTreeGroupChild, import { ExcludeSettingWidget, IListDataItem, IObjectDataItem, IObjectEnumOption, IObjectKeySuggester, IObjectValueSuggester, ISettingListChangeEvent, IncludeSettingWidget, ListSettingWidget, ObjectSettingCheckboxWidget, ObjectSettingDropdownWidget, ObjectValue } from 'vs/workbench/contrib/preferences/browser/settingsWidgets'; import { LANGUAGE_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences'; import { settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry'; -import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; @@ -901,6 +902,11 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre } template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter); + template.elementDisposables.add(this._configService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING)) { + template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter); + } + })); const onChange = (value: any) => this._onDidChangeSetting.fire({ key: element.setting.key, @@ -1959,6 +1965,7 @@ export class SettingTreeRenderers { @IInstantiationService private readonly _instantiationService: IInstantiationService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @IContextViewService private readonly _contextViewService: IContextViewService, + @IUserDataProfilesService private readonly _userDataProfilesService: IUserDataProfilesService, @IUserDataSyncEnablementService private readonly _userDataSyncEnablementService: IUserDataSyncEnablementService, ) { this.settingActions = [ @@ -2017,6 +2024,9 @@ export class SettingTreeRenderers { private getActionsForSetting(setting: ISetting, settingTarget: SettingsTarget): IAction[] { const actions: IAction[] = []; + if (this._userDataProfilesService.isEnabled() && setting.scope !== ConfigurationScope.APPLICATION && settingTarget === ConfigurationTarget.USER_LOCAL) { + actions.push(this._instantiationService.createInstance(ApplySettingToAllProfilesAction, setting)); + } if (this._userDataSyncEnablementService.isEnabled() && !setting.disallowSyncIgnore) { actions.push(this._instantiationService.createInstance(SyncSettingAction, setting)); } @@ -2486,3 +2496,40 @@ class SyncSettingAction extends Action { } } + +class ApplySettingToAllProfilesAction extends Action { + static readonly ID = 'settings.applyToAllProfiles'; + static readonly LABEL = localize('applyToAllProfiles', "Apply Setting to all Profiles"); + + constructor( + private readonly setting: ISetting, + @IWorkbenchConfigurationService private readonly configService: IWorkbenchConfigurationService, + ) { + super(ApplySettingToAllProfilesAction.ID, ApplySettingToAllProfilesAction.LABEL); + this._register(Event.filter(configService.onDidChangeConfiguration, e => e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING))(() => this.update())); + this.update(); + } + + update() { + const allProfilesSettings = this.configService.getValue(APPLY_ALL_PROFILES_SETTING); + this.checked = allProfilesSettings.includes(this.setting.key); + } + + override async run(): Promise { + // first remove the current setting completely from ignored settings + const value = this.configService.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; + + if (this.checked) { + value.splice(value.indexOf(this.setting.key), 1); + } else { + value.push(this.setting.key); + } + + const newValue = distinct(value); + await this.configService.updateValue(APPLY_ALL_PROFILES_SETTING, newValue.length ? newValue : undefined, ConfigurationTarget.USER_LOCAL); + if (!this.checked) { + await this.configService.updateValue(this.setting.key, this.configService.inspect(this.setting.key).userLocal?.value, ConfigurationTarget.USER_LOCAL); + } + } + +} diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 70f1fcd1e9359..8f942efdd0ee9 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -11,7 +11,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FileChangeType, FileChangesEvent, IFileService, whenProviderRegistered, FileOperationError, FileOperationResult, FileOperation, FileOperationEvent } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser, ConfigurationParseOptions, UserSettings } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; import { WorkbenchState, IWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { ConfigurationScope, Extensions, IConfigurationRegistry, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry'; @@ -140,6 +140,14 @@ export class ApplicationConfiguration extends UserSettings { return this.loadConfiguration(); } + override async loadConfiguration(): Promise { + const model = await super.loadConfiguration(); + const value = model.getValue(APPLY_ALL_PROFILES_SETTING); + const allProfilesSettings = Array.isArray(value) ? value : []; + return this.parseOptions.include || allProfilesSettings.length + ? this.reparse({ ...this.parseOptions, include: allProfilesSettings }) + : model; + } } export class UserConfiguration extends Disposable { diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index b02fbc29e61cd..9a920e59af042 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -15,7 +15,7 @@ import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from 'vs/p import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString, IConfigurationUpdateOverrides, isConfigurationUpdateOverrides, IConfigurationService, IConfigurationUpdateOptions } from 'vs/platform/configuration/common/configuration'; import { IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from 'vs/platform/configuration/common/configurations'; import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings, ConfigurationScope, IConfigurationPropertySchema, keyFromOverrideIdentifiers, OVERRIDE_PROPERTY_PATTERN, resourceLanguageSettingsSchemaId, configurationDefaultsSchemaId } from 'vs/platform/configuration/common/configurationRegistry'; import { IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, getStoredWorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces'; @@ -44,6 +44,7 @@ import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/pol import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; +import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { return userDataProfile.isDefault @@ -489,7 +490,11 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat } isSettingAppliedForAllProfiles(key: string): boolean { - return this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION; + if (this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION) { + return true; + } + const allProfilesSettings = this.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; + return Array.isArray(allProfilesSettings) && allProfilesSettings.includes(key); } private async createWorkspace(arg: IAnyWorkspaceIdentifier): Promise { @@ -601,6 +606,10 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat const initUserConfiguration = async () => { mark('code/willInitUserConfiguration'); const result = await Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]); + if (this.applicationConfiguration) { + const applicationConfigurationModel = await initApplicationConfigurationPromise; + result[0] = this.localUserConfiguration.reparse({ exclude: applicationConfigurationModel.getValue(APPLY_ALL_PROFILES_SETTING) }); + } mark('code/didInitUserConfiguration'); return result; }; @@ -714,8 +723,12 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat promises.push(this.reloadApplicationConfiguration(true)); } } - const [localUser, application] = await Promise.all(promises); - await this.loadConfiguration(application ?? this._configuration.applicationConfiguration, localUser, this._configuration.remoteUserConfiguration, true); + let [localUser, application] = await Promise.all(promises); + application = application ?? this._configuration.applicationConfiguration; + if (this.applicationConfiguration) { + localUser = this.localUserConfiguration.reparse({ exclude: application.getValue(APPLY_ALL_PROFILES_SETTING) }); + } + await this.loadConfiguration(application, localUser, this._configuration.remoteUserConfiguration, true); })()); } @@ -758,15 +771,35 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat private onApplicationConfigurationChanged(applicationConfiguration: ConfigurationModel): void { const previous = { data: this._configuration.toData(), workspace: this.workspace }; + const previousAllProfilesSettings = this._configuration.applicationConfiguration.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; const change = this._configuration.compareAndUpdateApplicationConfiguration(applicationConfiguration); + const currentAllProfilesSettings = this.getValue(APPLY_ALL_PROFILES_SETTING) ?? []; const configurationProperties = this.configurationRegistry.getConfigurationProperties(); const changedKeys: string[] = []; for (const changedKey of change.keys) { if (configurationProperties[changedKey]?.scope === ConfigurationScope.APPLICATION) { changedKeys.push(changedKey); + if (changedKey === APPLY_ALL_PROFILES_SETTING) { + for (const previousAllProfileSetting of previousAllProfilesSettings) { + if (!currentAllProfilesSettings.includes(previousAllProfileSetting)) { + changedKeys.push(previousAllProfileSetting); + } + } + for (const currentAllProfileSetting of currentAllProfilesSettings) { + if (!previousAllProfilesSettings.includes(currentAllProfileSetting)) { + changedKeys.push(currentAllProfileSetting); + } + } + } + } + else if (currentAllProfilesSettings.includes(changedKey)) { + changedKeys.push(changedKey); } } change.keys = changedKeys; + if (change.keys.includes(APPLY_ALL_PROFILES_SETTING)) { + this._configuration.updateLocalUserConfiguration(this.localUserConfiguration.reparse({ exclude: currentAllProfilesSettings })); + } this.triggerConfigurationChange(change, previous, ConfigurationTarget.USER); } @@ -1318,3 +1351,18 @@ const workbenchContributionsRegistry = Registry.as(Extensions.Configuration); +configurationRegistry.registerConfiguration({ + ...workbenchConfigurationNodeBase, + properties: { + [APPLY_ALL_PROFILES_SETTING]: { + 'type': 'array', + description: localize('setting description', "Configure settings to be applied for all profiles."), + 'default': [], + 'scope': ConfigurationScope.APPLICATION, + additionalProperties: true, + uniqueItems: true, + } + } +}); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 227c827eb2a35..043add6bd72e1 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -93,3 +93,5 @@ export interface IWorkbenchConfigurationService extends IConfigurationService { } export const TASKS_DEFAULT = '{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": []\n}'; + +export const APPLY_ALL_PROFILES_SETTING = 'workbench.settings.applyToAllProfiles'; diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index b336cb2fec3fe..e0613cac0c707 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -28,7 +28,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; +import { APPLY_ALL_PROFILES_SETTING, IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; import { SignService } from 'vs/platform/sign/browser/signService'; import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; import { IKeybindingEditingService, KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -1529,6 +1529,11 @@ suite('WorkspaceConfigurationService - Profiles', () => { 'id': '_test', 'type': 'object', 'properties': { + [APPLY_ALL_PROFILES_SETTING]: { + 'type': 'array', + 'default': [], + 'scope': ConfigurationScope.APPLICATION, + }, 'configurationService.profiles.applicationSetting': { 'type': 'string', 'default': 'isSet', @@ -1682,9 +1687,61 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting3'), 'defaultProfile'); })); + test('initialize with custom all profiles settings', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + await testObject.initialize(convertToWorkspacePayload(joinPath(ROOT, 'a'))); + + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + })); + + test('update all profiles settings', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], [APPLY_ALL_PROFILES_SETTING, 'configurationService.profiles.testSetting2']); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + })); + + test('setting applied to all profiles is registered later', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting4": "userValue" }')); + await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting4": "profileValue" }')); + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting4'], ConfigurationTarget.USER_LOCAL); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting4'), 'userValue'); + + configurationRegistry.registerConfiguration({ + 'id': '_test', + 'type': 'object', + 'properties': { + 'configurationService.profiles.testSetting4': { + 'type': 'string', + 'default': 'isSet', + } + } + }); + + await testObject.reloadConfiguration(); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting4'), 'userValue'); + })); + + test('update setting that is applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await testObject.updateValue('configurationService.profiles.testSetting2', 'updatedValue', ConfigurationTarget.USER_LOCAL); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting2']); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'updatedValue'); + })); + test('test isSettingAppliedToAllProfiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.applicationSetting2'), true); assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.testSetting2'), false); + + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + assert.strictEqual(testObject.isSettingAppliedForAllProfiles('configurationService.profiles.testSetting2'), true); })); test('switch to default profile', () => runWithFakedTimers({ useFakeTimers: true }, async () => { @@ -1730,6 +1787,46 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'isSet'); })); + test('switch to default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + await userDataProfileService.updateCurrentProfile(instantiationService.get(IUserDataProfilesService).defaultProfile); + + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + })); + + test('switch to non default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + + const profile = toUserDataProfile('custom2', 'custom2', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache')); + await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting": "profileValue", "configurationService.profiles.testSetting2": "profileValue2" }')); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await userDataProfileService.updateCurrentProfile(profile); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting']); + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue'); + })); + + test('switch to non default from default profile with settings applied to all profiles', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await testObject.updateValue(APPLY_ALL_PROFILES_SETTING, ['configurationService.profiles.testSetting2'], ConfigurationTarget.USER_LOCAL); + await userDataProfileService.updateCurrentProfile(instantiationService.get(IUserDataProfilesService).defaultProfile); + + const profile = toUserDataProfile('custom2', 'custom2', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache')); + await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.testSetting": "profileValue", "configurationService.profiles.testSetting2": "profileValue2" }')); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await userDataProfileService.updateCurrentProfile(profile); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.testSetting']); + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting2'), 'applicationValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting2'), 'userValue'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue'); + })); + }); suite('WorkspaceConfigurationService-Multiroot', () => { From 86bb5239ebc10d7cf9db835a5c1242e9c8207e96 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 14 Jul 2023 01:01:49 +0200 Subject: [PATCH 0105/1180] Fix #187487 (#187872) --- .../abstractExtensionManagementService.ts | 12 ++--- .../common/extensionManagement.ts | 1 - .../userDataSync/common/extensionsSync.ts | 2 +- .../browser/extensions.contribution.ts | 2 +- .../extensions/browser/extensionsActions.ts | 54 +++++++------------ .../remoteExtensionManagementService.ts | 6 +-- 6 files changed, 26 insertions(+), 51 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index b9449b9df7784..2ed53a4b0d7de 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -118,7 +118,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl await Promise.allSettled(extensions.map(async ({ extension, options }) => { try { - const compatible = await this.checkAndGetCompatibleVersion(extension, !!options?.installGivenVersion, !!options?.installPreReleaseVersion, false); + const compatible = await this.checkAndGetCompatibleVersion(extension, !!options?.installGivenVersion, !!options?.installPreReleaseVersion); installableExtensions.push({ ...compatible, options }); } catch (error) { results.push({ identifier: extension.identifier, operation: InstallOperation.Install, source: extension, error }); @@ -434,7 +434,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl const isDependency = dependecies.some(id => areSameExtensions({ id }, galleryExtension.identifier)); let compatible; try { - compatible = await this.checkAndGetCompatibleVersion(galleryExtension, false, installPreRelease, true); + compatible = await this.checkAndGetCompatibleVersion(galleryExtension, false, installPreRelease); } catch (error) { if (!isDependency) { this.logService.info('Skipping the packed extension as it cannot be installed', galleryExtension.identifier.id, getErrorMessage(error)); @@ -454,7 +454,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl return allDependenciesAndPacks; } - private async checkAndGetCompatibleVersion(extension: IGalleryExtension, sameVersion: boolean, installPreRelease: boolean, fallbackToRelease: boolean): Promise<{ extension: IGalleryExtension; manifest: IExtensionManifest }> { + private async checkAndGetCompatibleVersion(extension: IGalleryExtension, sameVersion: boolean, installPreRelease: boolean): Promise<{ extension: IGalleryExtension; manifest: IExtensionManifest }> { const extensionsControlManifest = await this.getExtensionsControlManifest(); if (extensionsControlManifest.malicious.some(identifier => areSameExtensions(extension.identifier, identifier))) { throw new ExtensionManagementError(nls.localize('malicious extension', "Can't install '{0}' extension since it was reported to be problematic.", extension.identifier.id), ExtensionManagementErrorCode.Malicious); @@ -466,11 +466,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } const compatibleExtension = await this.getCompatibleVersion(extension, sameVersion, installPreRelease); - if (compatibleExtension) { - if (!fallbackToRelease && installPreRelease && !sameVersion && extension.hasPreReleaseVersion && !compatibleExtension.properties.isPreReleaseVersion) { - throw new ExtensionManagementError(nls.localize('notFoundCompatiblePrereleaseDependency', "Can't install pre-release version of '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.IncompatiblePreRelease); - } - } else { + if (!compatibleExtension) { /** If no compatible release version is found, check if the extension has a release version or not and throw relevant error */ if (!installPreRelease && extension.properties.isPreReleaseVersion && (await this.galleryService.getExtensions([extension.identifier], CancellationToken.None))[0]) { throw new ExtensionManagementError(nls.localize('notFoundReleaseExtension', "Can't install release version of '{0}' extension because it has no release version.", extension.identifier.id), ExtensionManagementErrorCode.ReleaseVersionNotFound); diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 77f901579542f..23df3ac6abd94 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -407,7 +407,6 @@ export enum ExtensionManagementErrorCode { Deprecated = 'Deprecated', Malicious = 'Malicious', Incompatible = 'Incompatible', - IncompatiblePreRelease = 'IncompatiblePreRelease', IncompatibleTargetPlatform = 'IncompatibleTargetPlatform', ReleaseVersionNotFound = 'ReleaseVersionNotFound', Invalid = 'Invalid', diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index d898288a41e2d..aff6b64258522 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -527,7 +527,7 @@ export class LocalExtensionsProvider { addToSkipped.push(e); this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension`, gallery.displayName || gallery.identifier.id); } - if (error instanceof ExtensionManagementError && [ExtensionManagementErrorCode.Incompatible, ExtensionManagementErrorCode.IncompatiblePreRelease, ExtensionManagementErrorCode.IncompatibleTargetPlatform].includes(error.code)) { + if (error instanceof ExtensionManagementError && [ExtensionManagementErrorCode.Incompatible, ExtensionManagementErrorCode.IncompatibleTargetPlatform].includes(error.code)) { this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension because the compatible extension is not found.`, gallery.displayName || gallery.identifier.id); } else if (error) { this.logService.error(error); diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index f0f2c01fbbda5..bd7165c5d1246 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -678,7 +678,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi try { await this.extensionsWorkbenchService.install(extension, extension.local?.preRelease ? { installPreReleaseVersion: true } : undefined); } catch (err) { - runAction(this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, undefined, err)); + runAction(this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, err)); } })); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index ee6c57e9959d0..8ad613804b58c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -78,7 +78,6 @@ export class PromptExtensionInstallFailureAction extends Action { private readonly extension: IExtension, private readonly version: string, private readonly installOperation: InstallOperation, - private readonly installOptions: InstallOptions | undefined, private readonly error: Error, @IProductService private readonly productService: IProductService, @IOpenerService private readonly openerService: IOpenerService, @@ -138,44 +137,29 @@ export class PromptExtensionInstallFailureAction extends Action { return; } - let operationMessage = this.installOperation === InstallOperation.Update ? localize('update operation', "Error while updating '{0}' extension.", this.extension.displayName || this.extension.identifier.id) + const operationMessage = this.installOperation === InstallOperation.Update ? localize('update operation', "Error while updating '{0}' extension.", this.extension.displayName || this.extension.identifier.id) : localize('install operation', "Error while installing '{0}' extension.", this.extension.displayName || this.extension.identifier.id); let additionalMessage; const promptChoices: IPromptChoice[] = []; - if (ExtensionManagementErrorCode.IncompatiblePreRelease === (this.error.name)) { - operationMessage = getErrorMessage(this.error); - additionalMessage = localize('install release version message', "Would you like to install the release version?"); + const downloadUrl = await this.getDownloadUrl(); + if (downloadUrl) { + additionalMessage = localize('check logs', "Please check the [log]({0}) for more details.", `command:${showWindowLogActionId}`); promptChoices.push({ - label: localize('install release version', "Install Release Version"), - run: () => { - const installAction = this.instantiationService.createInstance(InstallAction, { installPreReleaseVersion: !!this.installOptions?.installPreReleaseVersion }); - installAction.extension = this.extension; - return installAction.run(); - } + label: localize('download', "Try Downloading Manually..."), + run: () => this.openerService.open(downloadUrl).then(() => { + this.notificationService.prompt( + Severity.Info, + localize('install vsix', 'Once downloaded, please manually install the downloaded VSIX of \'{0}\'.', this.extension.identifier.id), + [{ + label: localize('installVSIX', "Install from VSIX..."), + run: () => this.commandService.executeCommand(SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID) + }] + ); + }) }); } - else { - const downloadUrl = await this.getDownloadUrl(); - if (downloadUrl) { - additionalMessage = localize('check logs', "Please check the [log]({0}) for more details.", `command:${showWindowLogActionId}`); - promptChoices.push({ - label: localize('download', "Try Downloading Manually..."), - run: () => this.openerService.open(downloadUrl).then(() => { - this.notificationService.prompt( - Severity.Info, - localize('install vsix', 'Once downloaded, please manually install the downloaded VSIX of \'{0}\'.', this.extension.identifier.id), - [{ - label: localize('installVSIX', "Install from VSIX..."), - run: () => this.commandService.executeCommand(SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID) - }] - ); - }) - }); - } - } - const message = `${operationMessage}${additionalMessage ? ` ${additionalMessage}` : ''}`; this.notificationService.prompt(Severity.Error, message, promptChoices); } @@ -469,7 +453,7 @@ export class InstallAction extends ExtensionAction { try { return await this.extensionsWorkbenchService.install(extension, this.options); } catch (error) { - await this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, this.options, error).run(); + await this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, error).run(); return undefined; } } @@ -837,7 +821,7 @@ export class UpdateAction extends AbstractUpdateAction { await this.extensionsWorkbenchService.install(extension, extension.local?.preRelease ? { installPreReleaseVersion: true } : undefined); alert(localize('updateExtensionComplete', "Updating extension {0} to version {1} completed.", extension.displayName, extension.latestVersion)); } catch (err) { - this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, undefined, err).run(); + this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, err).run(); } } } @@ -1304,7 +1288,7 @@ export class InstallAnotherVersionAction extends ExtensionAction { await this.extensionsWorkbenchService.installVersion(this.extension!, pick.id, { installPreReleaseVersion: pick.isPreReleaseVersion }); } } catch (error) { - this.instantiationService.createInstance(PromptExtensionInstallFailureAction, this.extension!, pick.latest ? this.extension!.latestVersion : pick.id, InstallOperation.Install, undefined, error).run(); + this.instantiationService.createInstance(PromptExtensionInstallFailureAction, this.extension!, pick.latest ? this.extension!.latestVersion : pick.id, InstallOperation.Install, error).run(); } } return null; @@ -1811,7 +1795,7 @@ export class InstallRecommendedExtensionAction extends Action { try { await this.extensionWorkbenchService.install(extension); } catch (err) { - this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, undefined, err).run(); + this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, err).run(); } } } diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts index 112c8e95c5da2..30e29d6784dd1 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts @@ -129,11 +129,7 @@ export class NativeRemoteExtensionManagementService extends RemoteExtensionManag compatibleExtension = await this.galleryService.getCompatibleExtension(extension, includePreRelease, targetPlatform); } - if (compatibleExtension) { - if (includePreRelease && !compatibleExtension.properties.isPreReleaseVersion && extension.hasPreReleaseVersion) { - throw new ExtensionManagementError(localize('notFoundCompatiblePrereleaseDependency', "Can't install pre-release version of '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.IncompatiblePreRelease); - } - } else { + if (!compatibleExtension) { /** If no compatible release version is found, check if the extension has a release version or not and throw relevant error */ if (!includePreRelease && extension.properties.isPreReleaseVersion && (await this.galleryService.getExtensions([extension.identifier], CancellationToken.None))[0]) { throw new ExtensionManagementError(localize('notFoundReleaseExtension', "Can't install release version of '{0}' extension because it has no release version.", extension.identifier.id), ExtensionManagementErrorCode.ReleaseVersionNotFound); From c0d560ed49aee29ce51deb0cecfa99db2d6b0313 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 13 Jul 2023 16:02:57 -0700 Subject: [PATCH 0106/1180] Don't parse `@link` inside `@example` JSDoc tags (#187877) Fixes #187768 --- .../languageFeatures/util/textRendering.ts | 13 +++++- .../src/test/unit/textRendering.test.ts | 46 +++++++++++++++---- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts b/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts index bc4b7ad1b5f90..2918a7de54c06 100644 --- a/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts +++ b/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts @@ -49,9 +49,13 @@ function getTagBodyText( return '```\n' + text + '\n```'; } - const text = convertLinkTags(tag.text, filePathConverter); + let text = convertLinkTags(tag.text, filePathConverter); switch (tag.name) { case 'example': { + // Example text does not support `{@link}` as it is considered code. + // TODO: should we support it if it appears outside of an explicit code block? + text = asPlainText(tag.text); + // check for caption tags, fix for #79704 const captionTagMatches = text.match(/(.*?)<\/caption>\s*(\r\n|\n)/); if (captionTagMatches && captionTagMatches.index === 0) { @@ -132,6 +136,13 @@ function getTagBody(tag: Proto.JSDocTagInfo, filePathConverter: IFilePathToResou return (convertLinkTags(tag.text, filePathConverter)).split(/^(\S+)\s*-?\s*/); } +function asPlainText(parts: readonly Proto.SymbolDisplayPart[] | string): string { + if (typeof parts === 'string') { + return parts; + } + return parts.map(part => part.text).join(''); +} + export function asPlainTextWithLinks( parts: readonly Proto.SymbolDisplayPart[] | string, filePathConverter: IFilePathToResourceConverter, diff --git a/extensions/typescript-language-features/src/test/unit/textRendering.test.ts b/extensions/typescript-language-features/src/test/unit/textRendering.test.ts index 2354bb7f5892d..b13f682f71507 100644 --- a/extensions/typescript-language-features/src/test/unit/textRendering.test.ts +++ b/extensions/typescript-language-features/src/test/unit/textRendering.test.ts @@ -14,7 +14,7 @@ const noopToResource: IFilePathToResourceConverter = { }; suite('typescript.previewer', () => { - test('Should ignore hyphens after a param tag', async () => { + test('Should ignore hyphens after a param tag', () => { assert.strictEqual( tagsToMarkdown([ { @@ -25,7 +25,7 @@ suite('typescript.previewer', () => { '*@param* `a` — b'); }); - test('Should parse url jsdoc @link', async () => { + test('Should parse url jsdoc @link', () => { assert.strictEqual( documentationToMarkdown( 'x {@link http://www.example.com/foo} y {@link https://api.jquery.com/bind/#bind-eventType-eventData-handler} z', @@ -35,7 +35,7 @@ suite('typescript.previewer', () => { 'x [http://www.example.com/foo](http://www.example.com/foo) y [https://api.jquery.com/bind/#bind-eventType-eventData-handler](https://api.jquery.com/bind/#bind-eventType-eventData-handler) z'); }); - test('Should parse url jsdoc @link with text', async () => { + test('Should parse url jsdoc @link with text', () => { assert.strictEqual( documentationToMarkdown( 'x {@link http://www.example.com/foo abc xyz} y {@link http://www.example.com/bar|b a z} z', @@ -45,7 +45,7 @@ suite('typescript.previewer', () => { 'x [abc xyz](http://www.example.com/foo) y [b a z](http://www.example.com/bar) z'); }); - test('Should treat @linkcode jsdocs links as monospace', async () => { + test('Should treat @linkcode jsdocs links as monospace', () => { assert.strictEqual( documentationToMarkdown( 'x {@linkcode http://www.example.com/foo} y {@linkplain http://www.example.com/bar} z', @@ -55,7 +55,7 @@ suite('typescript.previewer', () => { 'x [`http://www.example.com/foo`](http://www.example.com/foo) y [http://www.example.com/bar](http://www.example.com/bar) z'); }); - test('Should parse url jsdoc @link in param tag', async () => { + test('Should parse url jsdoc @link in param tag', () => { assert.strictEqual( tagsToMarkdown([ { @@ -66,7 +66,7 @@ suite('typescript.previewer', () => { '*@param* `a` — x [abc xyz](http://www.example.com/foo) y [b a z](http://www.example.com/bar) z'); }); - test('Should ignore unclosed jsdocs @link', async () => { + test('Should ignore unclosed jsdocs @link', () => { assert.strictEqual( documentationToMarkdown( 'x {@link http://www.example.com/foo y {@link http://www.example.com/bar bar} z', @@ -76,7 +76,7 @@ suite('typescript.previewer', () => { 'x {@link http://www.example.com/foo y [bar](http://www.example.com/bar) z'); }); - test('Should support non-ascii characters in parameter name (#90108)', async () => { + test('Should support non-ascii characters in parameter name (#90108)', () => { assert.strictEqual( tagsToMarkdown([ { @@ -135,7 +135,35 @@ suite('typescript.previewer', () => { ); }); - test('Should render @linkcode symbol name as code', async () => { + test('Should not render @link inside of @example #187768', () => { + assert.strictEqual( + tagsToMarkdown([ + { + "name": "example", + "text": [ + { + "text": "1 + 1 ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "foo", + "kind": "linkName" + }, + { + "text": "}", + "kind": "link" + } + ] + } + ], noopToResource), + '*@example* \n```\n1 + 1 {@link foo}\n```'); + }); + + test('Should render @linkcode symbol name as code', () => { assert.strictEqual( asPlainTextWithLinks([ { "text": "a ", "kind": "text" }, @@ -155,7 +183,7 @@ suite('typescript.previewer', () => { 'a [`dog`](command:_typescript.openJsDocLink?%5B%7B%22file%22%3A%7B%22path%22%3A%22%2Fpath%2Ffile.ts%22%2C%22scheme%22%3A%22file%22%7D%2C%22position%22%3A%7B%22line%22%3A6%2C%22character%22%3A4%7D%7D%5D) b'); }); - test('Should render @linkcode text as code', async () => { + test('Should render @linkcode text as code', () => { assert.strictEqual( asPlainTextWithLinks([ { "text": "a ", "kind": "text" }, From 52d462293dba671b3d2417a299d3b61dfd4c8124 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Fri, 14 Jul 2023 01:04:15 +0200 Subject: [PATCH 0107/1180] Avoid creating services in APIs used by the monaco-editor repo itself (#187881) Fixes #169268: Avoid creating services in APIs used by the monaco-editor repo itself --- .../standalone/browser/standaloneLanguages.ts | 40 ++++++++++--------- .../standalone/browser/standaloneServices.ts | 22 ++++++++++ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 78d683d2fe5db..939d33910346a 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -54,16 +54,18 @@ export function getEncodedLanguageId(languageId: string): number { * @event */ export function onLanguage(languageId: string, callback: () => void): IDisposable { - const languageService = StandaloneServices.get(ILanguageService); - const disposable = languageService.onDidRequestRichLanguageFeatures((encounteredLanguageId) => { - if (encounteredLanguageId === languageId) { - // stop listening - disposable.dispose(); - // invoke actual listener - callback(); - } + return StandaloneServices.withServices(() => { + const languageService = StandaloneServices.get(ILanguageService); + const disposable = languageService.onDidRequestRichLanguageFeatures((encounteredLanguageId) => { + if (encounteredLanguageId === languageId) { + // stop listening + disposable.dispose(); + // invoke actual listener + callback(); + } + }); + return disposable; }); - return disposable; } /** @@ -72,16 +74,18 @@ export function onLanguage(languageId: string, callback: () => void): IDisposabl * @event */ export function onLanguageEncountered(languageId: string, callback: () => void): IDisposable { - const languageService = StandaloneServices.get(ILanguageService); - const disposable = languageService.onDidRequestBasicLanguageFeatures((encounteredLanguageId) => { - if (encounteredLanguageId === languageId) { - // stop listening - disposable.dispose(); - // invoke actual listener - callback(); - } + return StandaloneServices.withServices(() => { + const languageService = StandaloneServices.get(ILanguageService); + const disposable = languageService.onDidRequestBasicLanguageFeatures((encounteredLanguageId) => { + if (encounteredLanguageId === languageId) { + // stop listening + disposable.dispose(); + // invoke actual listener + callback(); + } + }); + return disposable; }); - return disposable; } /** diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index cc2ede5219cda..0546f5fc2821c 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -1128,6 +1128,7 @@ export module StandaloneServices { } let initialized = false; + const onDidInitialize = new Emitter(); export function initialize(overrides: IEditorOverrideServices): IInstantiationService { if (initialized) { return instantiationService; @@ -1163,6 +1164,27 @@ export module StandaloneServices { } } + onDidInitialize.fire(); + return instantiationService; } + + /** + * Executes callback once services are initialized. + */ + export function withServices(callback: () => IDisposable): IDisposable { + if (initialized) { + return callback(); + } + + const disposable = new DisposableStore(); + + const listener = disposable.add(onDidInitialize.event(() => { + listener.dispose(); + disposable.add(callback()); + })); + + return disposable; + } + } From 14a1c7e5e3465e737298e86336076d1d07f2944b Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Thu, 13 Jul 2023 16:29:26 -0700 Subject: [PATCH 0108/1180] allow multiple callers for decorating notebook webview (#187743) --- .../contrib/find/findMatchDecorationModel.ts | 11 +- .../browser/contrib/find/findModel.ts | 2 +- .../notebook/browser/notebookBrowser.ts | 8 +- .../notebook/browser/notebookEditorWidget.ts | 22 ++- .../view/renderers/backLayerWebView.ts | 23 +-- .../browser/view/renderers/webviewMessages.ts | 23 +-- .../browser/view/renderers/webviewPreloads.ts | 161 +++++++++++++----- .../test/browser/testNotebookEditor.ts | 1 + .../contrib/search/browser/notebookSearch.ts | 2 +- .../search/browser/notebookSearchService.ts | 8 +- .../contrib/search/browser/searchModel.ts | 50 +++--- .../search/test/browser/searchActions.test.ts | 2 +- .../search/test/browser/searchModel.test.ts | 2 +- .../browser/searchNotebookHelpers.test.ts | 2 +- .../search/test/browser/searchResult.test.ts | 28 +-- .../search/test/browser/searchTestCommon.ts | 8 +- .../search/test/browser/searchViewlet.test.ts | 4 +- 17 files changed, 226 insertions(+), 131 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/findMatchDecorationModel.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/findMatchDecorationModel.ts index 5e272f641c3d4..6fa5a4fea6ca5 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/findMatchDecorationModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/findMatchDecorationModel.ts @@ -17,7 +17,8 @@ export class FindMatchDecorationModel extends Disposable { private _currentMatchDecorations: { kind: 'input'; decorations: ICellModelDecorations[] } | { kind: 'output'; index: number } | null = null; constructor( - private readonly _notebookEditor: INotebookEditor + private readonly _notebookEditor: INotebookEditor, + private readonly ownerID: string, ) { super(); } @@ -26,7 +27,7 @@ export class FindMatchDecorationModel extends Disposable { return this._currentMatchDecorations; } - public clearDecorations() { + private clearDecorations() { this.clearCurrentFindMatchDecoration(); this.setAllFindMatchesDecorations([]); } @@ -75,7 +76,7 @@ export class FindMatchDecorationModel extends Disposable { this.clearCurrentFindMatchDecoration(); - const offset = await this._notebookEditor.highlightFind(index); + const offset = await this._notebookEditor.findHighlightCurrent(index, this.ownerID); this._currentMatchDecorations = { kind: 'output', index: index }; this._currentMatchCellDecorations = this._notebookEditor.deltaCellDecorations(this._currentMatchCellDecorations, [{ @@ -101,7 +102,7 @@ export class FindMatchDecorationModel extends Disposable { this._currentMatchDecorations = null; }); } else if (this._currentMatchDecorations?.kind === 'output') { - this._notebookEditor.unHighlightFind(this._currentMatchDecorations.index); + this._notebookEditor.findUnHighlightCurrent(this._currentMatchDecorations.index, this.ownerID); } this._currentMatchCellDecorations = this._notebookEditor.deltaCellDecorations(this._currentMatchCellDecorations, []); @@ -145,7 +146,7 @@ export class FindMatchDecorationModel extends Disposable { } stopWebviewFind() { - this._notebookEditor.findStop(); + this._notebookEditor.findStop(this.ownerID); } override dispose() { diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts index e08a00a42cb25..1d955dbbcdd94 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts @@ -111,7 +111,7 @@ export class FindModel extends Disposable { this._registerModelListener(this._notebookEditor.textModel); } - this._findMatchDecorationModel = new FindMatchDecorationModel(this._notebookEditor); + this._findMatchDecorationModel = new FindMatchDecorationModel(this._notebookEditor, this._notebookEditor.getId()); } private _updateCellStates(e: FindReplaceStateChangedEvent) { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts index 2959ca1b13ab4..5166e31799152 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts @@ -673,10 +673,10 @@ export interface INotebookEditor { getCellIndex(cell: ICellViewModel): number | undefined; getNextVisibleCellIndex(index: number): number | undefined; getPreviousVisibleCellIndex(index: number): number | undefined; - find(query: string, options: INotebookSearchOptions, token: CancellationToken): Promise; - highlightFind(matchIndex: number): Promise; - unHighlightFind(matchIndex: number): Promise; - findStop(): void; + find(query: string, options: INotebookSearchOptions, token: CancellationToken, skipWarmup?: boolean, shouldGetSearchPreviewInfo?: boolean, ownerID?: string): Promise; + findHighlightCurrent(matchIndex: number, ownerID?: string): Promise; + findUnHighlightCurrent(matchIndex: number, ownerID?: string): Promise; + findStop(ownerID?: string): void; showProgress(): void; hideProgress(): void; diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 801f7d93f6177..92fb5866d8b30 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -2430,15 +2430,19 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD return Promise.all(requests); } - async find(query: string, options: INotebookSearchOptions, token: CancellationToken, skipWarmup: boolean = false, shouldGetSearchPreviewInfo = false): Promise { + async find(query: string, options: INotebookSearchOptions, token: CancellationToken, skipWarmup: boolean = false, shouldGetSearchPreviewInfo = false, ownerID?: string): Promise { if (!this._notebookViewModel) { return []; } + if (!ownerID) { + ownerID = this.getId(); + } + const findMatches = this._notebookViewModel.find(query, options).filter(match => match.length > 0); if (!options.includeMarkupPreview && !options.includeOutput) { - this._webview?.findStop(); + this._webview?.findStop(ownerID); return findMatches; } @@ -2461,7 +2465,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD return []; } - const webviewMatches = await this._webview.find(query, { caseSensitive: options.caseSensitive, wholeWord: options.wholeWord, includeMarkup: !!options.includeMarkupPreview, includeOutput: !!options.includeOutput, shouldGetSearchPreviewInfo }); + const webviewMatches = await this._webview.find(query, { caseSensitive: options.caseSensitive, wholeWord: options.wholeWord, includeMarkup: !!options.includeMarkupPreview, includeOutput: !!options.includeOutput, shouldGetSearchPreviewInfo, ownerID }); if (token.isCancellationRequested) { return []; @@ -2517,24 +2521,24 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD return ret; } - async highlightFind(matchIndex: number): Promise { + async findHighlightCurrent(matchIndex: number, ownerID?: string): Promise { if (!this._webview) { return 0; } - return this._webview?.findHighlight(matchIndex); + return this._webview?.findHighlightCurrent(matchIndex, ownerID ?? this.getId()); } - async unHighlightFind(matchIndex: number): Promise { + async findUnHighlightCurrent(matchIndex: number, ownerID?: string): Promise { if (!this._webview) { return; } - return this._webview?.findUnHighlight(matchIndex); + return this._webview?.findUnHighlightCurrent(matchIndex, ownerID ?? this.getId()); } - findStop() { - this._webview?.findStop(); + findStop(ownerID?: string) { + this._webview?.findStop(ownerID ?? this.getId()); } //#endregion 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 06a4054a668d4..4a3c05451ea31 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1608,7 +1608,7 @@ export class BackLayerWebView extends Themable { }); } - async find(query: string, options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean }): Promise { + async find(query: string, options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean; ownerID: string }): Promise { if (query === '') { return []; } @@ -1632,16 +1632,17 @@ export class BackLayerWebView extends Themable { return ret; } - findStop() { + findStop(ownerID: string) { this._sendMessageToWebview({ - type: 'findStop' + type: 'findStop', + ownerID }); } - async findHighlight(index: number): Promise { + async findHighlightCurrent(index: number, ownerID: string): Promise { const p = new Promise(resolve => { const sub = this.webview?.onMessage(e => { - if (e.message.type === 'didFindHighlight') { + if (e.message.type === 'didFindHighlightCurrent') { resolve(e.message.offset); sub?.dispose(); } @@ -1649,18 +1650,20 @@ export class BackLayerWebView extends Themable { }); this._sendMessageToWebview({ - type: 'findHighlight', - index + type: 'findHighlightCurrent', + index, + ownerID }); const ret = await p; return ret; } - async findUnHighlight(index: number): Promise { + async findUnHighlightCurrent(index: number, ownerID: string): Promise { this._sendMessageToWebview({ - type: 'findUnHighlight', - index + type: 'findUnHighlightCurrent', + index, + ownerID }); } 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 15fc1f19790be..1b21208b7b477 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -397,22 +397,25 @@ export interface ITokenizedStylesChangedMessage { export interface IFindMessage { readonly type: 'find'; readonly query: string; - readonly options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean }; + readonly options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean; ownerID: string }; } -export interface IFindHighlightMessage { - readonly type: 'findHighlight'; +export interface IFindHighlightCurrentMessage { + readonly type: 'findHighlightCurrent'; readonly index: number; + readonly ownerID: string; } -export interface IFindUnHighlightMessage { - readonly type: 'findUnHighlight'; +export interface IFindUnHighlightCurrentMessage { + readonly type: 'findUnHighlightCurrent'; readonly index: number; + readonly ownerID: string; } export interface IFindStopMessage { readonly type: 'findStop'; + readonly ownerID: string; } export interface ISearchPreviewInfo { @@ -436,8 +439,8 @@ export interface IDidFindMessage extends BaseToWebviewMessage { readonly matches: IFindMatch[]; } -export interface IDidFindHighlightMessage extends BaseToWebviewMessage { - readonly type: 'didFindHighlight'; +export interface IDidFindHighlightCurrentMessage extends BaseToWebviewMessage { + readonly type: 'didFindHighlightCurrent'; readonly offset: number; } @@ -502,7 +505,7 @@ export type FromWebviewMessage = WebviewInitialized | IRenderedMarkupMessage | IRenderedCellOutputMessage | IDidFindMessage | - IDidFindHighlightMessage | + IDidFindHighlightCurrentMessage | IOutputResizedMessage | IGetOutputItemMessage | ILogRendererDebugMessage | @@ -534,8 +537,8 @@ export type ToWebviewMessage = IClearMessage | ITokenizedCodeBlockMessage | ITokenizedStylesChangedMessage | IFindMessage | - IFindHighlightMessage | - IFindUnHighlightMessage | + IFindHighlightCurrentMessage | + IFindUnHighlightCurrentMessage | IFindStopMessage | IReturnOutputItemMessage; 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 25dab44de718b..649d3421949e3 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -908,21 +908,30 @@ async function webviewPreloads(ctx: PreloadContext) { } interface IHighlighter { - highlightCurrentMatch(index: number): void; - unHighlightCurrentMatch(index: number): void; + addHighlights(matches: IFindMatch[], ownerID: string): void; + removeHighlights(ownerID: string): void; + highlightCurrentMatch(index: number, ownerID: string): void; + unHighlightCurrentMatch(index: number, ownerID: string): void; dispose(): void; } - let _highlighter: IHighlighter | null = null; + interface IHighlightInfo { + matches: IFindMatch[]; + currentMatchIndex: number; + } + const matchColor = window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).color; const currentMatchColor = window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).backgroundColor; class JSHighlighter implements IHighlighter { - private _findMatchIndex = -1; + private _activeHighlightInfo: Map; constructor( - readonly matches: IFindMatch[], ) { + this._activeHighlightInfo = new Map(); + } + + addHighlights(matches: IFindMatch[], ownerID: string): void { for (let i = matches.length - 1; i >= 0; i--) { const match = matches[i]; const ret = highlightRange(match.originalRange, true, 'mark', match.isShadow ? { @@ -932,14 +941,32 @@ async function webviewPreloads(ctx: PreloadContext) { }); match.highlightResult = ret; } + + const highlightInfo: IHighlightInfo = { + matches, + currentMatchIndex: -1 + }; + this._activeHighlightInfo.set(ownerID, highlightInfo); } - highlightCurrentMatch(index: number) { - const oldMatch = this.matches[this._findMatchIndex]; + removeHighlights(ownerID: string): void { + this._activeHighlightInfo.get(ownerID)?.matches.forEach(match => { + match.highlightResult?.dispose(); + }); + this._activeHighlightInfo.delete(ownerID); + } + + highlightCurrentMatch(index: number, ownerID: string) { + const highlightInfo = this._activeHighlightInfo.get(ownerID); + if (!highlightInfo) { + console.error('Modified current highlight match before adding highlight list.'); + return; + } + const oldMatch = highlightInfo.matches[highlightInfo.currentMatchIndex]; oldMatch?.highlightResult?.update(matchColor, oldMatch.isShadow ? undefined : 'find-match'); - const match = this.matches[index]; - this._findMatchIndex = index; + const match = highlightInfo.matches[index]; + highlightInfo.currentMatchIndex = index; const sel = window.getSelection(); if (!!match && !!sel && match.highlightResult) { let offset = 0; @@ -961,14 +988,18 @@ async function webviewPreloads(ctx: PreloadContext) { match.highlightResult?.update(currentMatchColor, match.isShadow ? undefined : 'current-find-match'); document.getSelection()?.removeAllRanges(); - postNotebookMessage('didFindHighlight', { + postNotebookMessage('didFindHighlightCurrent', { offset }); } } - unHighlightCurrentMatch(index: number) { - const oldMatch = this.matches[index]; + unHighlightCurrentMatch(index: number, ownerID: string) { + const highlightInfo = this._activeHighlightInfo.get(ownerID); + if (!highlightInfo) { + return; + } + const oldMatch = highlightInfo.matches[index]; if (oldMatch && oldMatch.highlightResult) { oldMatch.highlightResult.update(matchColor, oldMatch.isShadow ? undefined : 'find-match'); } @@ -976,37 +1007,76 @@ async function webviewPreloads(ctx: PreloadContext) { dispose() { document.getSelection()?.removeAllRanges(); - - this.matches.forEach(match => { - match.highlightResult?.dispose(); + this._activeHighlightInfo.forEach(highlightInfo => { + highlightInfo.matches.forEach(match => { + match.highlightResult?.dispose(); + }); }); } } class CSSHighlighter implements IHighlighter { + private _activeHighlightInfo: Map; private _matchesHighlight: Highlight; private _currentMatchesHighlight: Highlight; - private _findMatchIndex = -1; - constructor( - readonly matches: IFindMatch[], - ) { + constructor() { + this._activeHighlightInfo = new Map(); this._matchesHighlight = new Highlight(); this._matchesHighlight.priority = 1; this._currentMatchesHighlight = new Highlight(); this._currentMatchesHighlight.priority = 2; + CSS.highlights?.set(`find-highlight`, this._matchesHighlight); + CSS.highlights?.set(`current-find-highlight`, this._currentMatchesHighlight); + } + + _refreshRegistry(updateMatchesHighlight = true) { + // for performance reasons, only update the full list of highlights when we need to + if (updateMatchesHighlight) { + this._matchesHighlight.clear(); + } + + this._currentMatchesHighlight.clear(); + + this._activeHighlightInfo.forEach((highlightInfo) => { + + if (updateMatchesHighlight) { + for (let i = 0; i < highlightInfo.matches.length; i++) { + this._matchesHighlight.add(highlightInfo.matches[i].originalRange); + } + } + if (highlightInfo.currentMatchIndex < highlightInfo.matches.length && highlightInfo.currentMatchIndex >= 0) { + this._currentMatchesHighlight.add(highlightInfo.matches[highlightInfo.currentMatchIndex].originalRange); + } + }); + } + + addHighlights( + matches: IFindMatch[], + ownerID: string + ) { for (let i = 0; i < matches.length; i++) { this._matchesHighlight.add(matches[i].originalRange); } - CSS.highlights?.set('find-highlight', this._matchesHighlight); - CSS.highlights?.set('current-find-highlight', this._currentMatchesHighlight); + + const newEntry: IHighlightInfo = { + matches, + currentMatchIndex: -1, + }; + + this._activeHighlightInfo.set(ownerID, newEntry); } - highlightCurrentMatch(index: number): void { - this._findMatchIndex = index; - const match = this.matches[this._findMatchIndex]; - const range = match.originalRange; + highlightCurrentMatch(index: number, ownerID: string): void { + const highlightInfo = this._activeHighlightInfo.get(ownerID); + if (!highlightInfo) { + console.error('Modified current highlight match before adding highlight list.'); + return; + } + + highlightInfo.currentMatchIndex = index; + const match = highlightInfo.matches[index]; if (match) { let offset = 0; @@ -1015,20 +1085,28 @@ async function webviewPreloads(ctx: PreloadContext) { match.originalRange.startContainer.parentElement?.scrollIntoView({ behavior: 'auto', block: 'end', inline: 'nearest' }); const rangeOffset = match.originalRange.getBoundingClientRect().top; offset = rangeOffset - outputOffset; - postNotebookMessage('didFindHighlight', { + postNotebookMessage('didFindHighlightCurrent', { offset }); } catch (e) { console.error(e); } } + this._refreshRegistry(false); + } - this._currentMatchesHighlight.clear(); - this._currentMatchesHighlight.add(range); + unHighlightCurrentMatch(index: number, ownerID: string): void { + const highlightInfo = this._activeHighlightInfo.get(ownerID); + if (!highlightInfo) { + return; + } + + highlightInfo.currentMatchIndex = -1; } - unHighlightCurrentMatch(index: number): void { - this._currentMatchesHighlight.clear(); + removeHighlights(ownerID: string) { + this._activeHighlightInfo.delete(ownerID); + this._refreshRegistry(); } dispose(): void { @@ -1038,6 +1116,8 @@ async function webviewPreloads(ctx: PreloadContext) { } } + const _highlighter = (CSS.highlights) ? new CSSHighlighter() : new JSHighlighter(); + function extractSelectionLine(selection: Selection): ISearchPreviewInfo { const range = selection.getRangeAt(0); @@ -1126,7 +1206,7 @@ async function webviewPreloads(ctx: PreloadContext) { return offset + getSelectionOffsetRelativeTo(parentElement, currentNode.parentNode); } - const find = (query: string, options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean }) => { + const find = (query: string, options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean; ownerID: string }) => { let find = true; const matches: IFindMatch[] = []; @@ -1254,12 +1334,7 @@ async function webviewPreloads(ctx: PreloadContext) { console.log(e); } - if (matches.length && CSS.highlights) { - _highlighter = new CSSHighlighter(matches); - } else { - _highlighter = new JSHighlighter(matches); - } - + _highlighter.addHighlights(matches, options.ownerID); document.getSelection()?.removeAllRanges(); viewModel.toggleDragDropEnabled(currentOptions.dragAndDropEnabled); @@ -1448,20 +1523,20 @@ async function webviewPreloads(ctx: PreloadContext) { break; } case 'find': { - _highlighter?.dispose(); + _highlighter.removeHighlights(event.data.options.ownerID); find(event.data.query, event.data.options); break; } - case 'findHighlight': { - _highlighter?.highlightCurrentMatch(event.data.index); + case 'findHighlightCurrent': { + _highlighter?.highlightCurrentMatch(event.data.index, event.data.ownerID); break; } - case 'findUnHighlight': { - _highlighter?.unHighlightCurrentMatch(event.data.index); + case 'findUnHighlightCurrent': { + _highlighter?.unHighlightCurrentMatch(event.data.index, event.data.ownerID); break; } case 'findStop': { - _highlighter?.dispose(); + _highlighter.removeHighlights(event.data.ownerID); break; } case 'returnOutputItem': { diff --git a/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts b/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts index c8ac2befe3a2a..fd3cf5fdcb975 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts @@ -286,6 +286,7 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic override deltaCellDecorations() { return []; } override onDidChangeVisibleRanges = Event.None; override visibleRanges: ICellRange[] = [{ start: 0, end: 100 }]; + override getId(): string { return ''; } }; return { editor: notebookEditor, viewModel }; diff --git a/src/vs/workbench/contrib/search/browser/notebookSearch.ts b/src/vs/workbench/contrib/search/browser/notebookSearch.ts index 4a040c661a101..2fb526582198e 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearch.ts +++ b/src/vs/workbench/contrib/search/browser/notebookSearch.ts @@ -14,5 +14,5 @@ export interface INotebookSearchService { readonly _serviceBrand: undefined; - notebookSearch(query: ITextQuery, token: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }>; + notebookSearch(query: ITextQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }>; } diff --git a/src/vs/workbench/contrib/search/browser/notebookSearchService.ts b/src/vs/workbench/contrib/search/browser/notebookSearchService.ts index 711932ae636d7..b6209cf8de600 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearchService.ts +++ b/src/vs/workbench/contrib/search/browser/notebookSearchService.ts @@ -123,7 +123,7 @@ export class NotebookSearchService implements INotebookSearchService { return Array.from(uris.keys()); } - async notebookSearch(query: ITextQuery, token: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { + async notebookSearch(query: ITextQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { if (query.type !== QueryType.Text) { return { @@ -139,7 +139,7 @@ export class NotebookSearchService implements INotebookSearchService { const localNotebookWidgets = this.getLocalNotebookWidgets(); const localNotebookFiles = localNotebookWidgets.map(widget => widget.viewModel!.uri); - const localResultPromise = this.getLocalNotebookResults(query, token, localNotebookWidgets); + const localResultPromise = this.getLocalNotebookResults(query, token, localNotebookWidgets, searchInstanceID); const searchLocalEnd = Date.now(); const experimentalNotebooksEnabled = this.configurationService.getValue('search').experimental?.closedNotebookRichContentResults ?? false; @@ -248,7 +248,7 @@ export class NotebookSearchService implements INotebookSearchService { }; } - private async getLocalNotebookResults(query: ITextQuery, token: CancellationToken, widgets: Array): Promise { + private async getLocalNotebookResults(query: ITextQuery, token: CancellationToken, widgets: Array, searchID: string): Promise { const localResults = new ResourceMap(uri => this.uriIdentityService.extUri.getComparisonKey(uri)); let limitHit = false; @@ -266,7 +266,7 @@ export class NotebookSearchService implements INotebookSearchService { includeMarkupPreview: query.contentPattern.notebookInfo?.isInNotebookMarkdownPreview, includeCodeInput: query.contentPattern.notebookInfo?.isInNotebookCellInput, includeOutput: query.contentPattern.notebookInfo?.isInNotebookCellOutput, - }, token, false, true); + }, token, false, true, searchID); if (matches.length) { diff --git a/src/vs/workbench/contrib/search/browser/searchModel.ts b/src/vs/workbench/contrib/search/browser/searchModel.ts index 76b513ea17bd5..46c2d29079f3f 100644 --- a/src/vs/workbench/contrib/search/browser/searchModel.ts +++ b/src/vs/workbench/contrib/search/browser/searchModel.ts @@ -397,6 +397,7 @@ export class FileMatch extends Disposable implements IFileMatch { private _parent: FolderMatch, private rawMatch: IFileMatch, private _closestRoot: FolderMatchWorkspaceRoot | null, + private readonly searchInstanceID: string, @IModelService private readonly modelService: IModelService, @IReplaceService private readonly replaceService: IReplaceService, @ILabelService readonly labelService: ILabelService, @@ -763,7 +764,7 @@ export class FileMatch extends Disposable implements IFileMatch { } this._findMatchDecorationModel?.stopWebviewFind(); this._findMatchDecorationModel?.dispose(); - this._findMatchDecorationModel = new FindMatchDecorationModel(this._notebookEditorWidget); + this._findMatchDecorationModel = new FindMatchDecorationModel(this._notebookEditorWidget, this.searchInstanceID); } private _removeNotebookHighlights(): void { @@ -851,7 +852,7 @@ export class FileMatch extends Disposable implements IFileMatch { includeMarkupPreview: this._query.notebookInfo?.isInNotebookMarkdownPreview, includeCodeInput: this._query.notebookInfo?.isInNotebookCellInput, includeOutput: this._query.notebookInfo?.isInNotebookCellOutput, - }, CancellationToken.None, false, true); + }, CancellationToken.None, false, true, this.searchInstanceID); this.updateNotebookMatches(allMatches, true); } @@ -1117,7 +1118,7 @@ export class FolderMatch extends Disposable { return this._query; } - addFileMatch(raw: IFileMatch[], silent: boolean): void { + addFileMatch(raw: IFileMatch[], silent: boolean, searchInstanceID: string): void { // when adding a fileMatch that has intermediate directories const added: FileMatch[] = []; const updated: FileMatch[] = []; @@ -1151,7 +1152,7 @@ export class FolderMatch extends Disposable { existingFileMatch.addContext(rawFileMatch.results); } else { if (this instanceof FolderMatchWorkspaceRoot || this instanceof FolderMatchNoRoot) { - const fileMatch = this.createAndConfigureFileMatch(rawFileMatch); + const fileMatch = this.createAndConfigureFileMatch(rawFileMatch, searchInstanceID); added.push(fileMatch); } } @@ -1337,7 +1338,7 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource { return this.uriIdentityService.extUri.isEqual(uri1, ur2); } - private createFileMatch(query: IPatternInfo, previewOptions: ITextSearchPreviewOptions | undefined, maxResults: number | undefined, parent: FolderMatch, rawFileMatch: IFileMatch, closestRoot: FolderMatchWorkspaceRoot | null,): FileMatch { + private createFileMatch(query: IPatternInfo, previewOptions: ITextSearchPreviewOptions | undefined, maxResults: number | undefined, parent: FolderMatch, rawFileMatch: IFileMatch, closestRoot: FolderMatchWorkspaceRoot | null, searchInstanceID: string): FileMatch { const fileMatch = this.instantiationService.createInstance( FileMatch, @@ -1346,7 +1347,8 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource { maxResults, parent, rawFileMatch, - closestRoot + closestRoot, + searchInstanceID ); parent.doAddFile(fileMatch); const disposable = fileMatch.onChange(({ didRemove }) => parent.onFileChange(fileMatch, didRemove)); @@ -1354,7 +1356,7 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource { return fileMatch; } - createAndConfigureFileMatch(rawFileMatch: IFileMatch): FileMatch { + createAndConfigureFileMatch(rawFileMatch: IFileMatch, searchInstanceID: string): FileMatch { if (!this.uriHasParent(this.resource, rawFileMatch.resource)) { throw Error(`${rawFileMatch.resource} is not a descendant of ${this.resource}`); @@ -1382,7 +1384,7 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource { parent = folderMatch; } - return this.createFileMatch(this._query.contentPattern, this._query.previewOptions, this._query.maxResults, parent, rawFileMatch, root); + return this.createFileMatch(this._query.contentPattern, this._query.previewOptions, this._query.maxResults, parent, rawFileMatch, root, searchInstanceID); } } @@ -1401,14 +1403,15 @@ export class FolderMatchNoRoot extends FolderMatch { super(null, _id, _index, _query, _parent, _searchModel, null, replaceService, instantiationService, labelService, uriIdentityService); } - createAndConfigureFileMatch(rawFileMatch: IFileMatch): FileMatch { + createAndConfigureFileMatch(rawFileMatch: IFileMatch, searchInstanceID: string): FileMatch { const fileMatch = this.instantiationService.createInstance( FileMatch, this._query.contentPattern, this._query.previewOptions, this._query.maxResults, this, rawFileMatch, - null); + null, + searchInstanceID); this.doAddFile(fileMatch); const disposable = fileMatch.onChange(({ didRemove }) => this.onFileChange(fileMatch, didRemove)); fileMatch.onDispose(() => disposable.dispose()); @@ -1740,7 +1743,7 @@ export class SearchResult extends Disposable { return this._searchModel; } - add(allRaw: IFileMatch[], silent: boolean = false): void { + add(allRaw: IFileMatch[], searchInstanceID: string, silent: boolean = false): void { // Split up raw into a list per folder so we can do a batch add per folder. const { byFolder, other } = this.groupFilesByFolder(allRaw); @@ -1750,10 +1753,10 @@ export class SearchResult extends Disposable { } const folderMatch = this.getFolderMatch(raw[0].resource); - folderMatch?.addFileMatch(raw, silent); + folderMatch?.addFileMatch(raw, silent, searchInstanceID); }); - this._otherFilesMatch?.addFileMatch(other, silent); + this._otherFilesMatch?.addFileMatch(other, silent, searchInstanceID); this.disposePastResults(); } @@ -1991,16 +1994,16 @@ export class SearchModel extends Disposable { return this._searchResult; } - private async doSearch(query: ITextQuery, progressEmitter: Emitter, searchQuery: ITextQuery, onProgress?: (result: ISearchProgressItem) => void): Promise { + private async doSearch(query: ITextQuery, progressEmitter: Emitter, searchQuery: ITextQuery, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise { const searchStart = Date.now(); const tokenSource = this.currentCancelTokenSource = new CancellationTokenSource(); const onProgressCall = (p: ISearchProgressItem) => { progressEmitter.fire(); - this.onSearchProgress(p); + this.onSearchProgress(p, searchInstanceID); onProgress?.(p); }; - const notebookResult = await this.notebookSearchService.notebookSearch(query, this.currentCancelTokenSource.token, onProgressCall); + const notebookResult = await this.notebookSearchService.notebookSearch(query, this.currentCancelTokenSource.token, searchInstanceID, onProgressCall); const currentResult = await this.searchService.textSearch( searchQuery, this.currentCancelTokenSource.token, onProgressCall, @@ -2019,6 +2022,7 @@ export class SearchModel extends Disposable { if (!this.searchConfig.searchOnType) { this.searchResult.clear(); } + const searchInstanceID = Date.now().toString(); this._searchResult.query = this._searchQuery; @@ -2028,7 +2032,7 @@ export class SearchModel extends Disposable { // In search on type case, delay the streaming of results just a bit, so that we don't flash the only "local results" fast path this._startStreamDelay = new Promise(resolve => setTimeout(resolve, this.searchConfig.searchOnType ? 150 : 0)); - const currentRequest = this.doSearch(query, progressEmitter, this._searchQuery, onProgress); + const currentRequest = this.doSearch(query, progressEmitter, this._searchQuery, searchInstanceID, onProgress); const start = Date.now(); @@ -2043,7 +2047,7 @@ export class SearchModel extends Disposable { }); currentRequest.then( - value => this.onSearchCompleted(value, Date.now() - start), + value => this.onSearchCompleted(value, Date.now() - start, searchInstanceID), e => this.onSearchError(e, Date.now() - start)); try { @@ -2059,12 +2063,12 @@ export class SearchModel extends Disposable { } } - private onSearchCompleted(completed: ISearchComplete | null, duration: number): ISearchComplete | null { + private onSearchCompleted(completed: ISearchComplete | null, duration: number, searchInstanceID: string): ISearchComplete | null { if (!this._searchQuery) { throw new Error('onSearchCompleted must be called after a search is started'); } - this._searchResult.add(this._resultQueue); + this._searchResult.add(this._resultQueue, searchInstanceID); this._resultQueue.length = 0; const options: IPatternInfo = Object.assign({}, this._searchQuery.contentPattern); @@ -2108,17 +2112,17 @@ export class SearchModel extends Disposable { this.searchCancelledForNewSearch ? { exit: SearchCompletionExitCode.NewSearchStarted, results: [], messages: [] } : null, - duration); + duration, ''); this.searchCancelledForNewSearch = false; } } - private async onSearchProgress(p: ISearchProgressItem) { + private async onSearchProgress(p: ISearchProgressItem, searchInstanceID: string) { if ((p).resource) { this._resultQueue.push(p); await this._startStreamDelay; if (this._resultQueue.length) { - this._searchResult.add(this._resultQueue, true); + this._searchResult.add(this._resultQueue, searchInstanceID, true); this._resultQueue.length = 0; } } diff --git a/src/vs/workbench/contrib/search/test/browser/searchActions.test.ts b/src/vs/workbench/contrib/search/test/browser/searchActions.test.ts index fd518ce666c65..7d47ec0a8bfe5 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchActions.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchActions.test.ts @@ -120,7 +120,7 @@ suite('Search Actions', () => { }, searchModel.searchResult, searchModel, null); return instantiationService.createInstance(FileMatch, { pattern: '' - }, undefined, undefined, folderMatch, rawMatch, null); + }, undefined, undefined, folderMatch, rawMatch, null, ''); } function aMatch(fileMatch: FileMatch): Match { diff --git a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts index a3995b4ccc8b8..6a561cb325efb 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts @@ -160,7 +160,7 @@ suite('SearchModel', () => { function notebookSearchServiceWithInfo(results: IFileMatchWithCells[], tokenSource: CancellationTokenSource | undefined): INotebookSearchService { return { _serviceBrand: undefined, - notebookSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void, notebookURIs?: ResourceSet): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { + notebookSearch(query: ISearchQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void, notebookURIs?: ResourceSet): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { token?.onCancellationRequested(() => tokenSource?.cancel()); const localResults = new ResourceMap(uri => uri.path); diff --git a/src/vs/workbench/contrib/search/test/browser/searchNotebookHelpers.test.ts b/src/vs/workbench/contrib/search/test/browser/searchNotebookHelpers.test.ts index c8e419dd3735b..8f807a2a73947 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchNotebookHelpers.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchNotebookHelpers.test.ts @@ -208,7 +208,7 @@ suite('searchNotebookHelpers', () => { }, searchModel.searchResult, searchModel, null); return instantiationService.createInstance(FileMatch, { pattern: '' - }, undefined, undefined, folderMatch, rawMatch, null); + }, undefined, undefined, folderMatch, rawMatch, null, ''); } }); }); diff --git a/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts b/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts index 49a7afe9c0983..50500494d9a6b 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts @@ -31,7 +31,7 @@ import { NotebookEditorWidgetService } from 'vs/workbench/contrib/notebook/brows import { ICellMatch, IFileMatchWithCells } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { createFileUriFromPathFromRoot, getRootName } from 'vs/workbench/contrib/search/test/browser/searchTestCommon'; +import { addToSearchResult, createFileUriFromPathFromRoot, getRootName } from 'vs/workbench/contrib/search/test/browser/searchTestCommon'; const lineOneRange = new OneLineRange(1, 0, 1); @@ -176,7 +176,7 @@ suite('SearchResult', () => { new TextSearchMatch('preview 1', new OneLineRange(1, 4, 11)), new TextSearchMatch('preview 2', lineOneRange))]; - testObject.add(target); + addToSearchResult(testObject, target); assert.strictEqual(3, testObject.count()); @@ -206,7 +206,7 @@ suite('SearchResult', () => { aRawMatch('/2', new TextSearchMatch('preview 2', lineOneRange))]; - testObject.add(target); + addToSearchResult(testObject, target); assert.strictEqual(3, testObject.count()); @@ -261,7 +261,7 @@ suite('SearchResult', () => { }); const target = [fileMatch1, fileMatch2]; - testObject.add(target); + addToSearchResult(testObject, target); assert.strictEqual(6, testObject.count()); assert.deepStrictEqual(fileMatch1.cellResults[0].contentResults, (addFileMatch.getCall(0).args[0][0] as IFileMatchWithCells).cellResults[0].contentResults); assert.deepStrictEqual(fileMatch1.cellResults[0].webviewResults, (addFileMatch.getCall(0).args[0][0] as IFileMatchWithCells).cellResults[0].webviewResults); @@ -274,7 +274,7 @@ suite('SearchResult', () => { const target2 = sinon.spy(); const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange)), aRawMatch('/2', @@ -293,7 +293,7 @@ suite('SearchResult', () => { test('remove triggers change event', function () { const target = sinon.spy(); const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange))]); const objectToRemove = testObject.matches()[0]; @@ -308,7 +308,7 @@ suite('SearchResult', () => { test('remove array triggers change event', function () { const target = sinon.spy(); const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange)), aRawMatch('/2', @@ -324,7 +324,7 @@ suite('SearchResult', () => { test('Removing all line matches and adding back will add file back to result', function () { const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange))]); const target = testObject.matches()[0]; @@ -342,7 +342,7 @@ suite('SearchResult', () => { const voidPromise = Promise.resolve(null); instantiationService.stub(IReplaceService, 'replace', voidPromise); const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange))]); @@ -356,7 +356,7 @@ suite('SearchResult', () => { const voidPromise = Promise.resolve(null); instantiationService.stub(IReplaceService, 'replace', voidPromise); const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange))]); testObject.onChange(target); @@ -374,7 +374,7 @@ suite('SearchResult', () => { const voidPromise = Promise.resolve(null); instantiationService.stubPromise(IReplaceService, 'replace', voidPromise); const testObject = aSearchResult(); - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/1', new TextSearchMatch('preview 1', lineOneRange)), aRawMatch('/2', @@ -519,7 +519,7 @@ suite('SearchResult', () => { const root = searchResult?.folderMatches()[0]; return instantiationService.createInstance(FileMatch, { pattern: '' - }, undefined, undefined, root, rawMatch, null); + }, undefined, undefined, root, rawMatch, null, ''); } function aSearchResult(): SearchResult { @@ -569,7 +569,7 @@ suite('SearchResult', () => { ] }; - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/voo/foo.a', new TextSearchMatch('preview 1', lineOneRange), new TextSearchMatch('preview 2', lineOneRange)), aRawMatch('/with/path/bar.b', @@ -623,7 +623,7 @@ suite('SearchResult', () => { * |- eyy.y */ - testObject.add([ + addToSearchResult(testObject, [ aRawMatch('/voo/foo.a', new TextSearchMatch('preview 1', lineOneRange), new TextSearchMatch('preview 2', lineOneRange)), aRawMatch('/voo/beep/foo.c', diff --git a/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts b/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts index 0c2a6ce3eac3b..026df47ea9c19 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchTestCommon.ts @@ -14,7 +14,9 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { NotebookEditorWidgetService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl'; +import { SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IFileMatch } from 'vs/workbench/services/search/common/search'; import { TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; export function createFileUriFromPathFromRoot(path?: string): URI { @@ -38,8 +40,6 @@ export function getRootName(): string { } } - - export function stubModelService(instantiationService: TestInstantiationService): IModelService { instantiationService.stub(IThemeService, new TestThemeService()); const config = new TestConfigurationService(); @@ -52,3 +52,7 @@ export function stubNotebookEditorService(instantiationService: TestInstantiatio instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService()); return instantiationService.createInstance(NotebookEditorWidgetService); } + +export function addToSearchResult(searchResult: SearchResult, allRaw: IFileMatch[], searchInstanceID = '') { + searchResult.add(allRaw, searchInstanceID); +} diff --git a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts index 1624ba20a466b..014e7c143cc4b 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts @@ -78,7 +78,7 @@ suite('Search - Viewlet', () => { endColumn: 1 } }] - }]); + }], ''); const fileMatch = result.matches()[0]; const lineMatch = fileMatch.matches()[0]; @@ -181,7 +181,7 @@ suite('Search - Viewlet', () => { }; return instantiation.createInstance(FileMatch, { pattern: '' - }, undefined, undefined, parentFolder ?? aFolderMatch('', 0), rawMatch, null); + }, undefined, undefined, parentFolder ?? aFolderMatch('', 0), rawMatch, null, ''); } function aFolderMatch(path: string, index: number, parent?: SearchResult): FolderMatch { From d441153e31584a6e98322dae90933af7ca5b82b3 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 13 Jul 2023 17:14:37 -0700 Subject: [PATCH 0109/1180] Disable followup questions in the inputOnTop mode (#187884) For now, until we iron out what they should look like. --- .../contrib/chat/browser/chatInputPart.ts | 15 ++++++--------- .../workbench/contrib/chat/browser/chatWidget.ts | 6 +++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index 92af40f0f16b5..eeef6b5f5f4c7 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -77,7 +77,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge constructor( // private readonly editorOptions: ChatEditorOptions, // TODO this should be used - private readonly options: { renderFollowupsBelow: boolean }, + private readonly options: { renderFollowups: boolean }, @IChatWidgetHistoryService private readonly historyService: IChatWidgetHistoryService, @IModelService private readonly modelService: IModelService, @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -178,14 +178,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge render(container: HTMLElement, initialValue: string, widget: IChatWidget) { this.container = dom.append(container, $('.interactive-input-part')); - let inputContainer: HTMLElement; - if (this.options.renderFollowupsBelow) { - inputContainer = dom.append(this.container, $('.interactive-input-and-toolbar')); - this.followupsContainer = dom.append(this.container, $('.interactive-input-followups')); - } else { - this.followupsContainer = dom.append(this.container, $('.interactive-input-followups')); - inputContainer = dom.append(this.container, $('.interactive-input-and-toolbar')); - } + this.followupsContainer = dom.append(this.container, $('.interactive-input-followups')); + const inputContainer = dom.append(this.container, $('.interactive-input-and-toolbar')); const inputScopedContextKeyService = this._register(this.contextKeyService.createScoped(inputContainer)); CONTEXT_IN_CHAT_INPUT.bindTo(inputScopedContextKeyService).set(true); @@ -256,6 +250,9 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge } async renderFollowups(items?: IChatReplyFollowup[]): Promise { + if (!this.options.renderFollowups) { + return; + } this.followupsDisposables.clear(); dom.clearNode(this.followupsContainer); diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index c40f97ce4dc31..bea6bc2f7a925 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -142,7 +142,7 @@ export class ChatWidget extends Disposable implements IChatWidget { this.container = dom.append(parent, $('.interactive-session')); if (renderInputOnTop) { - this.createInput(this.container, { renderFollowupsBelow: true }); + this.createInput(this.container, { renderFollowups: false }); this.listContainer = dom.append(this.container, $(`.interactive-list`)); } else { this.listContainer = dom.append(this.container, $(`.interactive-list`)); @@ -334,8 +334,8 @@ export class ChatWidget extends Disposable implements IChatWidget { this.previousTreeScrollHeight = this.tree.scrollHeight; } - private createInput(container: HTMLElement, options?: { renderFollowupsBelow: boolean }): void { - this.inputPart = this.instantiationService.createInstance(ChatInputPart, { renderFollowupsBelow: options?.renderFollowupsBelow ?? false }); + private createInput(container: HTMLElement, options?: { renderFollowups: boolean }): void { + this.inputPart = this.instantiationService.createInstance(ChatInputPart, { renderFollowups: options?.renderFollowups ?? true }); this.inputPart.render(container, '', this); this._register(this.inputPart.onDidFocus(() => this._onDidFocus.fire())); From 7bd35446a584a38e41067a6c5b43ba1ddfbdc61e Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 13 Jul 2023 18:04:19 -0700 Subject: [PATCH 0110/1180] cli: fix windows service-mode not working (#187883) It seems like we need to run the server (a batch file) with cmd explicitly when the server itself is not run from a command prompt. --- cli/src/tunnels/code_server.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cli/src/tunnels/code_server.rs b/cli/src/tunnels/code_server.rs index 1246e1c944146..7c044fc70cb90 100644 --- a/cli/src/tunnels/code_server.rs +++ b/cli/src/tunnels/code_server.rs @@ -566,7 +566,17 @@ impl<'a> ServerBuilder<'a> { } fn get_base_command(&self) -> Command { + #[cfg(not(windows))] let mut cmd = Command::new(&self.server_paths.executable); + #[cfg(windows)] + let mut cmd = { + let mut cmd = Command::new("cmd"); + cmd.arg("/Q"); + cmd.arg("/C"); + cmd.arg(&self.server_paths.executable); + cmd + }; + cmd.stdin(std::process::Stdio::null()) .args(self.server_params.code_server_args.command_arguments()); cmd From e024a5c28063c64b3dd571bada6ec42d37c2f8a0 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 13 Jul 2023 19:51:11 -0700 Subject: [PATCH 0111/1180] fix compile errors --- .../contrib/chat/browser/actions/chatAccessibilityHelp.ts | 4 +--- src/vs/workbench/contrib/chat/browser/chat.contribution.ts | 2 +- .../contrib/codeEditor/browser/accessibility/accessibility.ts | 2 +- .../workbench/contrib/codeEditor/browser/diffEditorHelper.ts | 2 +- .../contrib/notebook/browser/notebookAccessibilityHelp.ts | 2 +- .../browser/terminal.accessibility.contribution.ts | 2 +- .../accessibility/browser/terminalAccessibilityHelp.ts | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts index 83892d5fb48b3..fd147f172eab9 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts @@ -10,10 +10,8 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import { InlineChatController } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; - - +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; export function getAccessibilityHelpText(accessor: ServicesAccessor, type: 'panelChat' | 'inlineChat'): string { const keybindingService = accessor.get(IKeybindingService); diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 4f362ccf834ad..656485ed70a90 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -38,7 +38,7 @@ import '../common/chatColors'; import { registerMoveActions } from 'vs/workbench/contrib/chat/browser/actions/chatMoveActions'; import { registerClearActions } from 'vs/workbench/contrib/chat/browser/actions/chatClearActions'; import { AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts index b39ed1353f806..903406a294778 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts @@ -9,7 +9,7 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; -import { accessibilityHelpIsShown } from 'vs/workbench/browser/accessibility/accessibleView'; +import { accessibilityHelpIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { alert } from 'vs/base/browser/ui/aria/aria'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index 5da8615c51cd4..174fbd3ac0091 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -20,8 +20,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; const enum WidgetState { Hidden, diff --git a/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts b/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts index 5e45789ccb1f7..717b6167614d7 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts @@ -8,7 +8,7 @@ import { format } from 'vs/base/common/strings'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; +import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; export function getAccessibilityHelpText(accessor: ServicesAccessor): string { const keybindingService = accessor.get(IKeybindingService); 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 baf38d2541b41..26042ec1cb190 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 @@ -13,7 +13,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { IAccessibleViewService } from 'vs/workbench/browser/accessibility/accessibleView'; +import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts index 318b912982d92..d5d73c308a1e2 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts @@ -10,7 +10,7 @@ import { IAccessibilityService } from 'vs/platform/accessibility/common/accessib 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 { AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions } from 'vs/workbench/browser/accessibility/accessibleView'; +import { AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import type { Terminal } from 'xterm'; From 12340da1f10186fee3aa4df448911b5bce99347d Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 13 Jul 2023 20:23:15 -0700 Subject: [PATCH 0112/1180] cli: allow installation as a service from the UI (#187869) - When turning on remote tunnel access, a quickpick is now shown asking users whether it should be installed as a service or just run in the session. - Picking the service install will install the tunnel as a service on the machine, and start it. - Turning off remote tunnel access will uninstall the service only if we were the ones to install it. - This involved some refactoring to add extra state to the RemoteTunnelService. There's now a "mode" that includes the previous "session" and reflects the desired end state. - I also did a cleanup with a `StreamSplitter` to ensure output of the CLI gets read line-by-line. This was depended upon by the remote tunnel service code, but it's not actually guaranteed. - Changes in the CLI: allow setting the tunnel name while installing the service, and make both service un/installation and renames idempotent. Closes https://github.com/microsoft/vscode/issues/184663 --- cli/src/commands/args.rs | 4 + cli/src/commands/tunnels.rs | 21 +- cli/src/rpc.rs | 14 +- cli/src/tunnels/dev_tunnels.rs | 40 ++-- cli/src/tunnels/service_windows.rs | 9 +- src/vs/base/common/buffer.ts | 82 +++---- src/vs/base/node/nodeStreams.ts | 62 ++++++ src/vs/base/test/node/nodeStreams.test.ts | 51 +++++ .../remoteTunnel/common/remoteTunnel.ts | 26 ++- .../remoteTunnel/node/remoteTunnelService.ts | 203 +++++++++++++----- .../remoteTunnel.contribution.ts | 154 ++++++++----- 11 files changed, 479 insertions(+), 187 deletions(-) create mode 100644 src/vs/base/node/nodeStreams.ts create mode 100644 src/vs/base/test/node/nodeStreams.test.ts diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index ad961496bcce1..a97e1fc387075 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -649,6 +649,10 @@ pub struct TunnelServiceInstallArgs { /// If set, the user accepts the server license terms and the server will be started without a user prompt. #[clap(long)] pub accept_server_license_terms: bool, + + /// Sets the machine name for port forwarding service + #[clap(long)] + pub name: Option, } #[derive(Args, Debug, Clone)] diff --git a/cli/src/commands/tunnels.rs b/cli/src/commands/tunnels.rs index d11c15ef1e336..24e349bb72047 100644 --- a/cli/src/commands/tunnels.rs +++ b/cli/src/commands/tunnels.rs @@ -135,10 +135,17 @@ pub async fn service( let manager = create_service_manager(ctx.log.clone(), &ctx.paths); match service_args { TunnelServiceSubCommands::Install(args) => { - // ensure logged in, otherwise subsequent serving will fail - Auth::new(&ctx.paths, ctx.log.clone()) - .get_credential() - .await?; + let auth = Auth::new(&ctx.paths, ctx.log.clone()); + + if let Some(name) = &args.name { + // ensure the name matches, and tunnel exists + dev_tunnels::DevTunnels::new(&ctx.log, auth, &ctx.paths) + .rename_tunnel(name) + .await?; + } else { + // still ensure they're logged in, otherwise subsequent serving will fail + auth.get_credential().await?; + } // likewise for license consent legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; @@ -203,20 +210,20 @@ pub async fn user(ctx: CommandContext, user_args: TunnelUserSubCommands) -> Resu Ok(0) } -/// Remove the tunnel used by this gateway, if any. +/// Remove the tunnel used by this tunnel, if any. pub async fn rename(ctx: CommandContext, rename_args: TunnelRenameArgs) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); let mut dt = dev_tunnels::DevTunnels::new(&ctx.log, auth, &ctx.paths); dt.rename_tunnel(&rename_args.name).await?; ctx.log.result(format!( - "Successfully renamed this gateway to {}", + "Successfully renamed this tunnel to {}", &rename_args.name )); Ok(0) } -/// Remove the tunnel used by this gateway, if any. +/// Remove the tunnel used by this tunnel, if any. pub async fn unregister(ctx: CommandContext) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); let mut dt = dev_tunnels::DevTunnels::new(&ctx.log, auth, &ctx.paths); diff --git a/cli/src/rpc.rs b/cli/src/rpc.rs index acd53dc38e077..a9a66153735dc 100644 --- a/cli/src/rpc.rs +++ b/cli/src/rpc.rs @@ -117,7 +117,7 @@ impl RpcMethodBuilder { Ok(p) => p, Err(err) => { return id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, @@ -131,7 +131,7 @@ impl RpcMethodBuilder { match callback(param.params, &context) { Ok(result) => id.map(|id| serial.serialize(&SuccessResponse { id, result })), Err(err) => id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, @@ -161,7 +161,7 @@ impl RpcMethodBuilder { Ok(p) => p, Err(err) => { return future::ready(id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, @@ -182,7 +182,7 @@ impl RpcMethodBuilder { id.map(|id| serial.serialize(&SuccessResponse { id, result })) } Err(err) => id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, @@ -222,7 +222,7 @@ impl RpcMethodBuilder { return ( None, future::ready(id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, @@ -255,7 +255,7 @@ impl RpcMethodBuilder { match callback(servers, param.params, context).await { Ok(r) => id.map(|id| serial.serialize(&SuccessResponse { id, result: r })), Err(err) => id.map(|id| { - serial.serialize(&ErrorResponse { + serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, @@ -427,7 +427,7 @@ impl RpcDispatcher { Some(Method::Async(callback)) => MaybeSync::Future(callback(id, body)), Some(Method::Duplex(callback)) => MaybeSync::Stream(callback(id, body)), None => MaybeSync::Sync(id.map(|id| { - self.serializer.serialize(&ErrorResponse { + self.serializer.serialize(ErrorResponse { id, error: ResponseError { code: -1, diff --git a/cli/src/tunnels/dev_tunnels.rs b/cli/src/tunnels/dev_tunnels.rs index 8476028a2f5fc..c4ca9741b8872 100644 --- a/cli/src/tunnels/dev_tunnels.rs +++ b/cli/src/tunnels/dev_tunnels.rs @@ -275,7 +275,9 @@ impl DevTunnels { /// Renames the current tunnel to the new name. pub async fn rename_tunnel(&mut self, name: &str) -> Result<(), AnyError> { - self.update_tunnel_name(None, name).await.map(|_| ()) + self.update_tunnel_name(self.launcher_tunnel.load(), name) + .await + .map(|_| ()) } /// Updates the name of the existing persisted tunnel to the new name. @@ -286,28 +288,34 @@ impl DevTunnels { name: &str, ) -> Result<(Tunnel, PersistedTunnel), AnyError> { let name = name.to_ascii_lowercase(); - self.check_is_name_free(&name).await?; - - debug!(self.log, "Tunnel name changed, applying updates..."); let (mut full_tunnel, mut persisted, is_new) = match persisted { Some(persisted) => { + debug!( + self.log, + "Found a persisted tunnel, seeing if the name matches..." + ); self.get_or_create_tunnel(persisted, Some(&name), NO_REQUEST_OPTIONS) .await } - None => self - .create_tunnel(&name, NO_REQUEST_OPTIONS) - .await - .map(|(pt, t)| (t, pt, true)), + None => { + debug!(self.log, "Creating a new tunnel with the requested name"); + self.create_tunnel(&name, NO_REQUEST_OPTIONS) + .await + .map(|(pt, t)| (t, pt, true)) + } }?; - if is_new { + let desired_tags = self.get_tags(&name); + if is_new || vec_eq_as_set(&full_tunnel.tags, &desired_tags) { return Ok((full_tunnel, persisted)); } - full_tunnel.tags = self.get_tags(&name); + debug!(self.log, "Tunnel name changed, applying updates..."); - let new_tunnel = spanf!( + full_tunnel.tags = desired_tags; + + let updated_tunnel = spanf!( self.log, self.log.span("dev-tunnel.tag.update"), self.client.update_tunnel(&full_tunnel, NO_REQUEST_OPTIONS) @@ -317,7 +325,7 @@ impl DevTunnels { persisted.name = name; self.launcher_tunnel.save(Some(persisted.clone()))?; - Ok((new_tunnel, persisted)) + Ok((updated_tunnel, persisted)) } /// Gets the persisted tunnel from the service, or creates a new one. @@ -443,6 +451,8 @@ impl DevTunnels { ) -> Result<(PersistedTunnel, Tunnel), AnyError> { info!(self.log, "Creating tunnel with the name: {}", name); + self.check_is_name_free(name).await?; + let mut tried_recycle = false; let new_tunnel = Tunnel { @@ -527,7 +537,7 @@ impl DevTunnels { options: &TunnelRequestOptions, ) -> Result { let new_tags = self.get_tags(name); - if vec_eq_unsorted(&tunnel.tags, &new_tags) { + if vec_eq_as_set(&tunnel.tags, &new_tags) { return Ok(tunnel); } @@ -610,7 +620,7 @@ impl DevTunnels { } async fn check_is_name_free(&mut self, name: &str) -> Result<(), AnyError> { - let existing = spanf!( + let existing: Vec = spanf!( self.log, self.log.span("dev-tunnel.rename.search"), self.client.list_all_tunnels(&TunnelRequestOptions { @@ -998,7 +1008,7 @@ fn clean_hostname_for_tunnel(hostname: &str) -> String { } } -fn vec_eq_unsorted(a: &[String], b: &[String]) -> bool { +fn vec_eq_as_set(a: &[String], b: &[String]) -> bool { if a.len() != b.len() { return false; } diff --git a/cli/src/tunnels/service_windows.rs b/cli/src/tunnels/service_windows.rs index 427eddd620d9e..3d2dc9f0c55b3 100644 --- a/cli/src/tunnels/service_windows.rs +++ b/cli/src/tunnels/service_windows.rs @@ -78,6 +78,7 @@ impl CliServiceManager for WindowsService { cmd.stderr(Stdio::null()); cmd.stdout(Stdio::null()); cmd.stdin(Stdio::null()); + cmd.creation_flags(CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); cmd.spawn() .map_err(|e| wrapdbg(e, "error starting service"))?; @@ -121,8 +122,12 @@ impl CliServiceManager for WindowsService { async fn unregister(&self) -> Result<(), AnyError> { let key = WindowsService::open_key()?; - key.delete_value(TUNNEL_ACTIVITY_NAME) - .map_err(|e| AnyError::from(wrap(e, "error deleting registry key")))?; + match key.delete_value(TUNNEL_ACTIVITY_NAME) { + Ok(_) => {} + Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} + Err(e) => return Err(wrap(e, "error deleting registry key").into()), + } + info!(self.log, "Tunnel service uninstalled"); let r = do_single_rpc_call::<_, ()>( diff --git a/src/vs/base/common/buffer.ts b/src/vs/base/common/buffer.ts index ff61eb5c9e253..08736ab8c0b71 100644 --- a/src/vs/base/common/buffer.ts +++ b/src/vs/base/common/buffer.ts @@ -172,51 +172,57 @@ export class VSBuffer { writeUInt8(this.buffer, value, offset); } - indexOf(subarray: VSBuffer | Uint8Array) { - const needle = subarray instanceof VSBuffer ? subarray.buffer : subarray; - const needleLen = needle.byteLength; - const haystack = this.buffer; - const haystackLen = haystack.byteLength; - - if (needleLen === 0) { - return 0; - } + indexOf(subarray: VSBuffer | Uint8Array, offset = 0) { + return binaryIndexOf(this.buffer, subarray instanceof VSBuffer ? subarray.buffer : subarray, offset); + } +} - if (needleLen === 1) { - return haystack.indexOf(needle[0]); - } +/** + * Like String.indexOf, but works on Uint8Arrays. + * Uses the boyer-moore-horspool algorithm to be reasonably speedy. + */ +export function binaryIndexOf(haystack: Uint8Array, needle: Uint8Array, offset = 0): number { + const needleLen = needle.byteLength; + const haystackLen = haystack.byteLength; - if (needleLen > haystackLen) { - return -1; - } + if (needleLen === 0) { + return 0; + } - // find index of the subarray using boyer-moore-horspool algorithm - const table = indexOfTable.value; - table.fill(needle.length); - for (let i = 0; i < needle.length; i++) { - table[needle[i]] = needle.length - i - 1; - } + if (needleLen === 1) { + return haystack.indexOf(needle[0]); + } + + if (needleLen > haystackLen - offset) { + return -1; + } + + // find index of the subarray using boyer-moore-horspool algorithm + const table = indexOfTable.value; + table.fill(needle.length); + for (let i = 0; i < needle.length; i++) { + table[needle[i]] = needle.length - i - 1; + } - let i = needle.length - 1; - let j = i; - let result = -1; - while (i < haystackLen) { - if (haystack[i] === needle[j]) { - if (j === 0) { - result = i; - break; - } - - i--; - j--; - } else { - i += Math.max(needle.length - j, table[haystack[i]]); - j = needle.length - 1; + let i = offset + needle.length - 1; + let j = i; + let result = -1; + while (i < haystackLen) { + if (haystack[i] === needle[j]) { + if (j === 0) { + result = i; + break; } - } - return result; + i--; + j--; + } else { + i += Math.max(needle.length - j, table[haystack[i]]); + j = needle.length - 1; + } } + + return result; } export function readUInt16LE(source: Uint8Array, offset: number): number { diff --git a/src/vs/base/node/nodeStreams.ts b/src/vs/base/node/nodeStreams.ts new file mode 100644 index 0000000000000..0719bb4678735 --- /dev/null +++ b/src/vs/base/node/nodeStreams.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { Transform } from 'stream'; +import { binaryIndexOf } from 'vs/base/common/buffer'; + +/** + * A Transform stream that splits the input on the "splitter" substring. + * The resulting chunks will contain (and trail with) the splitter match. + * The last chunk when the stream ends will be emitted even if a splitter + * is not encountered. + */ +export class StreamSplitter extends Transform { + private buffer: Buffer | undefined; + private readonly splitter: Buffer | number; + private readonly spitterLen: number; + + constructor(splitter: string | number | Buffer) { + super(); + if (typeof splitter === 'number') { + this.splitter = splitter; + this.spitterLen = 1; + } else { + const buf = Buffer.isBuffer(splitter) ? splitter : Buffer.from(splitter); + this.splitter = buf.length === 1 ? buf[0] : buf; + this.spitterLen = buf.length; + } + } + + override _transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null, data?: any) => void): void { + if (!this.buffer) { + this.buffer = chunk; + } else { + this.buffer = Buffer.concat([this.buffer, chunk]); + } + + let offset = 0; + while (offset < this.buffer.length) { + const index = typeof this.splitter === 'number' + ? this.buffer.indexOf(this.splitter, offset) + : binaryIndexOf(this.buffer, this.splitter, offset); + if (index === -1) { + break; + } + + this.push(this.buffer.slice(offset, index + this.spitterLen)); + offset = index + this.spitterLen; + } + + this.buffer = offset === this.buffer.length ? undefined : this.buffer.slice(offset); + callback(); + } + + override _flush(callback: (error?: Error | null, data?: any) => void): void { + if (this.buffer) { + this.push(this.buffer); + } + + callback(); + } +} diff --git a/src/vs/base/test/node/nodeStreams.test.ts b/src/vs/base/test/node/nodeStreams.test.ts new file mode 100644 index 0000000000000..620f817dfc9ef --- /dev/null +++ b/src/vs/base/test/node/nodeStreams.test.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +import { Writable } from 'stream'; +import * as assert from 'assert'; +import { StreamSplitter } from 'vs/base/node/nodeStreams'; + +suite('StreamSplitter', () => { + test('should split a stream on a single character splitter', (done) => { + const chunks: string[] = []; + const splitter = new StreamSplitter('\n'); + const writable = new Writable({ + write(chunk, _encoding, callback) { + chunks.push(chunk.toString()); + callback(); + }, + }); + + splitter.pipe(writable); + splitter.write('hello\nwor'); + splitter.write('ld\n'); + splitter.write('foo\nbar\nz'); + splitter.end(() => { + assert.deepStrictEqual(chunks, ['hello\n', 'world\n', 'foo\n', 'bar\n', 'z']); + done(); + }); + }); + + test('should split a stream on a multi-character splitter', (done) => { + const chunks: string[] = []; + const splitter = new StreamSplitter('---'); + const writable = new Writable({ + write(chunk, _encoding, callback) { + chunks.push(chunk.toString()); + callback(); + }, + }); + + splitter.pipe(writable); + splitter.write('hello---wor'); + splitter.write('ld---'); + splitter.write('foo---bar---z'); + splitter.end(() => { + assert.deepStrictEqual(chunks, ['hello---', 'world---', 'foo---', 'bar---', 'z']); + done(); + }); + }); +}); diff --git a/src/vs/platform/remoteTunnel/common/remoteTunnel.ts b/src/vs/platform/remoteTunnel/common/remoteTunnel.ts index 61654659195c1..d50077ee5082d 100644 --- a/src/vs/platform/remoteTunnel/common/remoteTunnel.ts +++ b/src/vs/platform/remoteTunnel/common/remoteTunnel.ts @@ -21,18 +21,33 @@ export interface IRemoteTunnelService { readonly onDidChangeTunnelStatus: Event; getTunnelStatus(): Promise; - getSession(): Promise; - readonly onDidChangeSession: Event; + getMode(): Promise; + readonly onDidChangeMode: Event; readonly onDidTokenFailed: Event; - initialize(session: IRemoteTunnelSession | undefined): Promise; + initialize(mode: TunnelMode): Promise; - startTunnel(session: IRemoteTunnelSession): Promise; + startTunnel(mode: ActiveTunnelMode): Promise; stopTunnel(): Promise; getTunnelName(): Promise; } +export interface ActiveTunnelMode { + readonly active: true; + readonly session: IRemoteTunnelSession; + readonly asService: boolean; +} + +export interface InactiveTunnelMode { + readonly active: false; +} + +export const INACTIVE_TUNNEL_MODE: InactiveTunnelMode = { active: false }; + +/** Saved mode for the tunnel. */ +export type TunnelMode = ActiveTunnelMode | InactiveTunnelMode; + export type TunnelStatus = TunnelStates.Connected | TunnelStates.Disconnected | TunnelStates.Connecting | TunnelStates.Uninitialized; export namespace TunnelStates { @@ -46,13 +61,14 @@ export namespace TunnelStates { export interface Connected { readonly type: 'connected'; readonly info: ConnectionInfo; + readonly serviceInstallFailed: boolean; } export interface Disconnected { readonly type: 'disconnected'; readonly onTokenFailed?: IRemoteTunnelSession; } export const disconnected = (onTokenFailed?: IRemoteTunnelSession): Disconnected => ({ type: 'disconnected', onTokenFailed }); - export const connected = (info: ConnectionInfo): Connected => ({ type: 'connected', info }); + export const connected = (info: ConnectionInfo, serviceInstallFailed: boolean): Connected => ({ type: 'connected', info, serviceInstallFailed }); export const connecting = (progress?: string): Connecting => ({ type: 'connecting', progress }); export const uninitialized: Uninitialized = { type: 'uninitialized' }; diff --git a/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts b/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts index 84ccef33653c9..08ba634bad057 100644 --- a/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts +++ b/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CONFIGURATION_KEY_HOST_NAME, CONFIGURATION_KEY_PREVENT_SLEEP, ConnectionInfo, IRemoteTunnelSession, IRemoteTunnelService, LOGGER_NAME, LOG_ID, TunnelStates, TunnelStatus } from 'vs/platform/remoteTunnel/common/remoteTunnel'; +import { CONFIGURATION_KEY_HOST_NAME, CONFIGURATION_KEY_PREVENT_SLEEP, ConnectionInfo, IRemoteTunnelSession, IRemoteTunnelService, LOGGER_NAME, LOG_ID, TunnelStates, TunnelStatus, TunnelMode, INACTIVE_TUNNEL_MODE, ActiveTunnelMode } from 'vs/platform/remoteTunnel/common/remoteTunnel'; import { Emitter } from 'vs/base/common/event'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -20,15 +20,18 @@ import { localize } from 'vs/nls'; import { hostname, homedir } from 'os'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { isString } from 'vs/base/common/types'; +import { StreamSplitter } from 'vs/base/node/nodeStreams'; type RemoteTunnelEnablementClassification = { owner: 'aeschli'; comment: 'Reporting when Remote Tunnel access is turned on or off'; enabled?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Flag indicating if Remote Tunnel Access is enabled or not' }; + service?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Flag indicating if Remote Tunnel Access is installed as a service' }; }; type RemoteTunnelEnablementEvent = { enabled: boolean; + service: boolean; }; const restartTunnelOnConfigurationChanges: readonly string[] = [ @@ -40,6 +43,8 @@ const restartTunnelOnConfigurationChanges: readonly string[] = [ // if set, the remote tunnel access is currently enabled. // if not set, the remote tunnel access is currently disabled. const TUNNEL_ACCESS_SESSION = 'remoteTunnelSession'; +// Boolean indicating whether the tunnel should be installed as a service. +const TUNNEL_ACCESS_IS_SERVICE = 'remoteTunnelIsService'; /** * This service runs on the shared service. It is running the `code-tunnel` command @@ -55,12 +60,19 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ private readonly _onDidChangeTunnelStatusEmitter = new Emitter(); public readonly onDidChangeTunnelStatus = this._onDidChangeTunnelStatusEmitter.event; - private readonly _onDidChangeSessionEmitter = new Emitter(); - public readonly onDidChangeSession = this._onDidChangeSessionEmitter.event; + private readonly _onDidChangeModeEmitter = new Emitter(); + public readonly onDidChangeMode = this._onDidChangeModeEmitter.event; private readonly _logger: ILogger; - private _session: IRemoteTunnelSession | undefined; + /** + * "Mode" in the terminal state we want to get to -- started, stopped, and + * the attributes associated with each. + * + * At any given time, work may be ongoing to get `_tunnelStatus` into a + * state that reflects the desired `mode`. + */ + private _mode: TunnelMode = INACTIVE_TUNNEL_MODE; private _tunnelProcess: CancelablePromise | undefined; @@ -98,7 +110,7 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ } })); - this._session = this._restoreSession(); + this._mode = this._restoreMode(); this._tunnelStatus = TunnelStates.uninitialized; } @@ -111,32 +123,34 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ this._onDidChangeTunnelStatusEmitter.fire(tunnelStatus); } - private setSession(session: IRemoteTunnelSession | undefined) { - if (!isSameSession(session, this._session)) { - this._session = session; - this._onDidChangeSessionEmitter.fire(session); - this._storeSession(session); - if (session) { - this._logger.info(`Session updated: ${session.accountLabel} (${session.providerId})`); - if (session.token) { - this._logger.info(`Session token updated: ${session.accountLabel} (${session.providerId})`); - } - } else { - this._logger.info(`Session reset`); + private setMode(mode: TunnelMode) { + if (isSameMode(this._mode, mode)) { + return; + } + + this._mode = mode; + this._storeMode(mode); + this._onDidChangeModeEmitter.fire(this._mode); + if (mode.active) { + this._logger.info(`Session updated: ${mode.session.accountLabel} (${mode.session.providerId}) (service=${mode.asService})`); + if (mode.session.token) { + this._logger.info(`Session token updated: ${mode.session.accountLabel} (${mode.session.providerId})`); } + } else { + this._logger.info(`Session reset`); } } - async getSession(): Promise { - return this._session; + getMode(): Promise { + return Promise.resolve(this._mode); } - async initialize(session: IRemoteTunnelSession | undefined): Promise { + async initialize(mode: TunnelMode): Promise { if (this._initialized) { return this._tunnelStatus; } this._initialized = true; - this.setSession(session); + this.setMode(mode); try { await this._startTunnelProcessDelayer.trigger(() => this.updateTunnelProcess()); } catch (e) { @@ -145,6 +159,14 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ return this._tunnelStatus; } + private readonly defaultOnOutput = (a: string, isErr: boolean) => { + if (isErr) { + this._logger.error(a); + } else { + this._logger.info(a); + } + }; + private getTunnelCommandLocation() { if (!this._tunnelCommand) { let binParentLocation; @@ -164,11 +186,12 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ return this._tunnelCommand; } - async startTunnel(session: IRemoteTunnelSession): Promise { - if (isSameSession(session, this._session) && this._tunnelStatus.type !== 'disconnected') { + async startTunnel(mode: ActiveTunnelMode): Promise { + if (isSameMode(this._mode, mode) && this._tunnelStatus.type !== 'disconnected') { return this._tunnelStatus; } - this.setSession(session); + + this.setMode(mode); try { await this._startTunnelProcessDelayer.trigger(() => this.updateTunnelProcess()); @@ -180,41 +203,49 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ async stopTunnel(): Promise { - this.setSession(undefined); - if (this._tunnelProcess) { this._tunnelProcess.cancel(); this._tunnelProcess = undefined; } - const onOutput = (a: string, isErr: boolean) => { - if (isErr) { - this._logger.error(a); - } else { - this._logger.info(a); + if (!this._mode.active) { + return; + } + + // Be careful to only uninstall the service if we're the ones who installed it: + const needsServiceUninstall = this._mode.asService; + this.setMode(INACTIVE_TUNNEL_MODE); + + try { + if (needsServiceUninstall) { + this.runCodeTunnelCommand('uninstallService', ['service', 'uninstall']); } - }; + } catch (e) { + this._logger.error(e); + } + try { - await this.runCodeTunnelCommand('stop', ['kill'], onOutput); + await this.runCodeTunnelCommand('stop', ['kill']); } catch (e) { this._logger.error(e); } - this.setTunnelStatus(TunnelStates.disconnected()); + this.setTunnelStatus(TunnelStates.disconnected()); } private async updateTunnelProcess(): Promise { - this.telemetryService.publicLog2('remoteTunnel.enablement', { enabled: !!this._session }); - + this.telemetryService.publicLog2('remoteTunnel.enablement', { + enabled: this._mode.active, + service: this._mode.active && this._mode.asService, + }); if (this._tunnelProcess) { this._tunnelProcess.cancel(); this._tunnelProcess = undefined; } - let isAttached = false; let output = ''; - + let isServiceInstalled = false; const onOutput = (a: string, isErr: boolean) => { if (isErr) { this._logger.error(a); @@ -241,22 +272,26 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ tunnel: object | null; } = JSON.parse(output.trim().split('\n').find(l => l.startsWith('{'))!); - isAttached = !!status.tunnel; - this._logger.info(isAttached ? 'Other tunnel running, attaching...' : 'No other tunnel running'); - if (!isAttached && !this._session) { - this._tunnelProcess = undefined; + isServiceInstalled = status.service_installed; + this._logger.info(status.tunnel ? 'Other tunnel running, attaching...' : 'No other tunnel running'); + + // If a tunnel is running but the mode isn't "active", we'll still attach + // to the tunnel to show its state in the UI. If neither are true, disconnect + if (!status.tunnel && !this._mode.active) { this.setTunnelStatus(TunnelStates.disconnected()); return; } } catch (e) { this._logger.error(e); - this._tunnelProcess = undefined; this.setTunnelStatus(TunnelStates.disconnected()); return; + } finally { + if (this._tunnelProcess === statusProcess) { + this._tunnelProcess = undefined; + } } - const session = this._session; - + const session = this._mode.active ? this._mode.session : undefined; if (session && session.token) { const token = session.token; this.setTunnelStatus(TunnelStates.connecting(localize({ key: 'remoteTunnelService.authorizing', comment: ['{0} is a user account name, {1} a provider name (e.g. Github)'] }, 'Connecting as {0} ({1})', session.accountLabel, session.providerId))); @@ -286,25 +321,67 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ } else { this.setTunnelStatus(TunnelStates.connecting(localize('remoteTunnelService.openTunnel', 'Opening tunnel'))); } - const args = ['--parent-process-id', String(process.pid), '--accept-server-license-terms', '--log', LogLevelToString(this._logger.getLevel())]; + const args = ['--accept-server-license-terms', '--log', LogLevelToString(this._logger.getLevel())]; if (hostName) { args.push('--name', hostName); } else { args.push('--random-name'); } + + let serviceInstallFailed = false; + if (this._mode.active && this._mode.asService && !isServiceInstalled) { + // I thought about calling `code tunnel kill` here, but having multiple + // tunnel processes running is pretty much idempotent. If there's + // another tunnel process running, the service process will + // take over when it exits, no hard feelings. + serviceInstallFailed = await this.installTunnelService(args) === false; + } + + return this.serverOrAttachTunnel(session, args, serviceInstallFailed); + } + + private async installTunnelService(args: readonly string[]) { + let status: number; + try { + status = await this.runCodeTunnelCommand('serviceInstall', ['service', 'install', ...args]); + } catch (e) { + this._logger.error(e); + status = 1; + } + + if (status !== 0) { + const msg = localize('remoteTunnelService.serviceInstallFailed', 'Failed to install tunnel as a service, starting in session...'); + this._logger.warn(msg); + this.setTunnelStatus(TunnelStates.connecting(msg)); + return false; + } + + return true; + } + + private async serverOrAttachTunnel(session: IRemoteTunnelSession | undefined, args: string[], serviceInstallFailed: boolean) { + args.push('--parent-process-id', String(process.pid)); + if (this._preventSleep()) { args.push('--no-sleep'); } + + let isAttached = false; const serveCommand = this.runCodeTunnelCommand('tunnel', args, (message: string, isErr: boolean) => { if (isErr) { this._logger.error(message); } else { this._logger.info(message); } + + if (message.includes('Connected to an existing tunnel process')) { + isAttached = true; + } + const m = message.match(/Open this link in your browser (https:\/\/([^\/\s]+)\/([^\/\s]+)\/([^\/\s]+))/); if (m) { const info: ConnectionInfo = { link: m[1], domain: m[2], tunnelName: m[4], isAttached }; - this.setTunnelStatus(TunnelStates.connected(info)); + this.setTunnelStatus(TunnelStates.connected(info, serviceInstallFailed)); } else if (message.match(/error refreshing token/)) { serveCommand.cancel(); this._onDidTokenFailedEmitter.fire(session); @@ -317,14 +394,14 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ // process exited unexpectedly this._logger.info(`tunnel process terminated`); this._tunnelProcess = undefined; - this._session = undefined; + this._mode = INACTIVE_TUNNEL_MODE; this.setTunnelStatus(TunnelStates.disconnected()); } }); } - private runCodeTunnelCommand(logLabel: string, commandArgs: string[], onOutput: (message: string, isError: boolean) => void = () => { }): CancelablePromise { + private runCodeTunnelCommand(logLabel: string, commandArgs: string[], onOutput: (message: string, isError: boolean) => void = this.defaultOnOutput): CancelablePromise { return createCancelablePromise(token => { return new Promise((resolve, reject) => { if (token.isCancellationRequested) { @@ -350,13 +427,13 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ tunnelProcess = spawn(tunnelCommand, ['tunnel', ...commandArgs], { cwd: homedir(), stdio }); } - tunnelProcess.stdout!.on('data', data => { + tunnelProcess.stdout!.pipe(new StreamSplitter('\n')).on('data', data => { if (tunnelProcess) { const message = data.toString(); onOutput(message, false); } }); - tunnelProcess.stderr!.on('data', data => { + tunnelProcess.stderr!.pipe(new StreamSplitter('\n')).on('data', data => { if (tunnelProcess) { const message = data.toString(); onOutput(message, true); @@ -394,30 +471,33 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ return name || undefined; } - private _restoreSession(): IRemoteTunnelSession | undefined { + private _restoreMode(): TunnelMode { try { const tunnelAccessSession = this.storageService.get(TUNNEL_ACCESS_SESSION, StorageScope.APPLICATION); + const asService = this.storageService.getBoolean(TUNNEL_ACCESS_IS_SERVICE, StorageScope.APPLICATION, false); if (tunnelAccessSession) { const session = JSON.parse(tunnelAccessSession) as IRemoteTunnelSession; if (session && isString(session.accountLabel) && isString(session.sessionId) && isString(session.providerId)) { - return session; + return { active: true, session, asService }; } this._logger.error('Problems restoring session from storage, invalid format', session); } } catch (e) { this._logger.error('Problems restoring session from storage', e); } - return undefined; + return INACTIVE_TUNNEL_MODE; } - private _storeSession(session: IRemoteTunnelSession | undefined): void { - if (session) { + private _storeMode(mode: TunnelMode): void { + if (mode.active) { const sessionWithoutToken = { - providerId: session.providerId, sessionId: session.sessionId, accountLabel: session.accountLabel + providerId: mode.session.providerId, sessionId: mode.session.sessionId, accountLabel: mode.session.accountLabel }; this.storageService.store(TUNNEL_ACCESS_SESSION, JSON.stringify(sessionWithoutToken), StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(TUNNEL_ACCESS_IS_SERVICE, mode.asService, StorageScope.APPLICATION, StorageTarget.MACHINE); } else { this.storageService.remove(TUNNEL_ACCESS_SESSION, StorageScope.APPLICATION); + this.storageService.remove(TUNNEL_ACCESS_IS_SERVICE, StorageScope.APPLICATION); } } } @@ -429,3 +509,12 @@ function isSameSession(a1: IRemoteTunnelSession | undefined, a2: IRemoteTunnelSe return a1 === a2; } +const isSameMode = (a: TunnelMode, b: TunnelMode) => { + if (a.active !== b.active) { + return false; + } else if (a.active && b.active) { + return a.asService === b.asService && isSameSession(a.session, b.session); + } else { + return true; + } +}; 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 7c6b0fe8cf5ed..5885e4005702a 100644 --- a/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts +++ b/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts @@ -3,40 +3,39 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Action } from 'vs/base/common/actions'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; -import { IProductService } from 'vs/platform/product/common/productService'; -import { CONFIGURATION_KEY_HOST_NAME, CONFIGURATION_KEY_PREFIX, CONFIGURATION_KEY_PREVENT_SLEEP, ConnectionInfo, IRemoteTunnelSession, IRemoteTunnelService, LOGGER_NAME, LOG_ID } from 'vs/platform/remoteTunnel/common/remoteTunnel'; -import { AuthenticationSession, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; +import { Schemas } from 'vs/base/common/network'; +import { ITunnelApplicationConfig } from 'vs/base/common/product'; +import { joinPath } from 'vs/base/common/resources'; +import { isNumber, isObject, isString } from 'vs/base/common/types'; +import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ILocalizedString } from 'vs/platform/action/common/action'; +import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { Extensions as ConfigurationExtensions, ConfigurationScope, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; +import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { ILogger, ILoggerService, ILogService } from 'vs/platform/log/common/log'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IQuickInputService, IQuickPickItem, IQuickPickSeparator, QuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { IOutputService } from 'vs/workbench/services/output/common/output'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; -import { IProgress, IProgressService, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ILogger, ILoggerService } from 'vs/platform/log/common/log'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { Action } from 'vs/base/common/actions'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IProgress, IProgressService, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator, QuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { CONFIGURATION_KEY_HOST_NAME, CONFIGURATION_KEY_PREFIX, CONFIGURATION_KEY_PREVENT_SLEEP, ConnectionInfo, INACTIVE_TUNNEL_MODE, IRemoteTunnelService, IRemoteTunnelSession, LOGGER_NAME, LOG_ID, TunnelStatus } from 'vs/platform/remoteTunnel/common/remoteTunnel'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IWorkspaceContextService, isUntitledWorkspace } from 'vs/platform/workspace/common/workspace'; -import { Schemas } from 'vs/base/common/network'; -import { URI } from 'vs/base/common/uri'; -import { joinPath } from 'vs/base/common/resources'; -import { ITunnelApplicationConfig } from 'vs/base/common/product'; -import { isNumber, isObject, isString } from 'vs/base/common/types'; +import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; +import { AuthenticationSession, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { IOutputService } from 'vs/workbench/services/output/common/output'; +import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; export const REMOTE_TUNNEL_CATEGORY: ILocalizedString = { original: 'Remote-Tunnels', @@ -103,10 +102,8 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo @IProductService productService: IProductService, @IStorageService private readonly storageService: IStorageService, @ILoggerService loggerService: ILoggerService, - @ILogService logService: ILogService, @IQuickInputService private readonly quickInputService: IQuickInputService, @INativeEnvironmentService private environmentService: INativeEnvironmentService, - @IFileService fileService: IFileService, @IRemoteTunnelService private remoteTunnelService: IRemoteTunnelService, @ICommandService private commandService: ICommandService, @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, @@ -127,20 +124,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo } this.serverConfiguration = serverConfiguration; - this._register(this.remoteTunnelService.onDidChangeTunnelStatus(status => { - this.connectionInfo = undefined; - if (status.type === 'disconnected') { - if (status.onTokenFailed) { - this.expiredSessions.add(status.onTokenFailed.sessionId); - } - this.connectionStateContext.set('disconnected'); - } else if (status.type === 'connecting') { - this.connectionStateContext.set('connecting'); - } else if (status.type === 'connected') { - this.connectionInfo = status.info; - this.connectionStateContext.set('connected'); - } - })); + this._register(this.remoteTunnelService.onDidChangeTunnelStatus(s => this.handleTunnelStatusUpdate(s))); this.registerCommands(); @@ -149,6 +133,21 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo this.recommendRemoteExtensionIfNeeded(); } + private handleTunnelStatusUpdate(status: TunnelStatus) { + this.connectionInfo = undefined; + if (status.type === 'disconnected') { + if (status.onTokenFailed) { + this.expiredSessions.add(status.onTokenFailed.sessionId); + } + this.connectionStateContext.set('disconnected'); + } else if (status.type === 'connecting') { + this.connectionStateContext.set('connecting'); + } else if (status.type === 'connected') { + this.connectionInfo = status.info; + this.connectionStateContext.set('connected'); + } + } + private async recommendRemoteExtensionIfNeeded() { await this.extensionService.whenInstalledExtensionsRegistered(); @@ -228,10 +227,17 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo } private async initialize(): Promise { - const session = await this.remoteTunnelService.getSession(); - if (session && session.token) { + const [mode, status] = await Promise.all([ + this.remoteTunnelService.getMode(), + this.remoteTunnelService.getTunnelStatus(), + ]); + + this.handleTunnelStatusUpdate(status); + + if (mode.active && mode.session.token) { return; // already initialized, token available } + return await this.progressService.withProgress( { location: ProgressLocation.Window, @@ -248,13 +254,13 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo } }); let newSession: IRemoteTunnelSession | undefined; - if (session) { - const token = await this.getSessionToken(session); + if (mode.active) { + const token = await this.getSessionToken(mode.session); if (token) { - newSession = { ...session, token }; + newSession = { ...mode.session, token }; } } - const status = await this.remoteTunnelService.initialize(newSession); + const status = await this.remoteTunnelService.initialize(mode.active && newSession ? { ...mode, session: newSession } : INACTIVE_TUNNEL_MODE); listener.dispose(); if (status.type === 'connected') { @@ -267,7 +273,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo } - private async startTunnel(): Promise { + private async startTunnel(asService: boolean): Promise { if (this.connectionInfo) { return this.connectionInfo; } @@ -301,6 +307,19 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo listener.dispose(); completed = true; s(status.info); + if (status.serviceInstallFailed) { + this.notificationService.notify({ + severity: Severity.Warning, + message: localize( + { + key: 'remoteTunnel.serviceInstallFailed', + comment: ['{Locked="](command:{0})"}'] + }, + "Installation as a service failed, and we fell back to running the tunnel for this session. See the [error log](command:{0}) for details.", + RemoteTunnelCommandIds.showLog, + ), + }); + } break; case 'disconnected': listener.dispose(); @@ -312,7 +331,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo }); const token = authenticationSession.session.idToken ?? authenticationSession.session.accessToken; const account: IRemoteTunnelSession = { sessionId: authenticationSession.session.id, token, providerId: authenticationSession.providerId, accountLabel: authenticationSession.session.account.label }; - this.remoteTunnelService.startTunnel(account).then(status => { + this.remoteTunnelService.startTunnel({ active: true, asService, session: account }).then(status => { if (!completed && (status.type === 'connected' || status.type === 'disconnected')) { listener.dispose(); if (status.type === 'connected') { @@ -403,7 +422,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo private async getAllSessions(): Promise { const authenticationProviders = await this.getAuthenticationProviders(); const accounts = new Map(); - const currentAccount = await this.remoteTunnelService.getSession(); + const currentAccount = await this.remoteTunnelService.getMode(); let currentSession: ExistingSessionItem | undefined; for (const provider of authenticationProviders) { @@ -413,7 +432,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo if (!this.expiredSessions.has(session.id)) { const item = this.createExistingSessionItem(session, provider.id); accounts.set(item.session.account.id, item); - if (currentAccount && currentAccount.sessionId === session.id) { + if (currentAccount.active && currentAccount.session.sessionId === session.id) { currentSession = item; } } @@ -483,6 +502,8 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo const commandService = accessor.get(ICommandService); const storageService = accessor.get(IStorageService); const dialogService = accessor.get(IDialogService); + const quickInputService = accessor.get(IQuickInputService); + const productService = accessor.get(IProductService); const didNotifyPreview = storageService.getBoolean(REMOTE_TUNNEL_PROMPTED_PREVIEW_STORAGE_KEY, StorageScope.APPLICATION, false); if (!didNotifyPreview) { @@ -497,12 +518,33 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo storageService.store(REMOTE_TUNNEL_PROMPTED_PREVIEW_STORAGE_KEY, true, StorageScope.APPLICATION, StorageTarget.USER); } - const connectionInfo = await that.startTunnel(); + const disposables = new DisposableStore(); + const quickPick = quickInputService.createQuickPick(); + quickPick.placeholder = localize('tunnel.enable.placeholder', 'Select how you want to enable access'); + quickPick.items = [ + { service: false, label: localize('tunnel.enable.session', 'Turn on for this session'), description: localize('tunnel.enable.session.description', 'Run whenever {0} is open', productService.nameShort) }, + { service: true, label: localize('tunnel.enable.service', 'Install as a service'), description: localize('tunnel.enable.service.description', 'Run whenever you\'re logged in') } + ]; + + const asService = await new Promise(resolve => { + disposables.add(quickPick.onDidAccept(() => resolve(quickPick.selectedItems[0]?.service))); + disposables.add(quickPick.onDidHide(() => resolve(undefined))); + quickPick.show(); + }); + + quickPick.dispose(); + + if (asService === undefined) { + return; // no-op + } + + const connectionInfo = await that.startTunnel(/* installAsService= */ asService); + if (connectionInfo) { const linkToOpen = that.getLinkToOpen(connectionInfo); const remoteExtension = that.serverConfiguration.extension; const linkToOpenForMarkdown = linkToOpen.toString(false).replace(/\)/g, '%29'); - await notificationService.notify({ + notificationService.notify({ severity: Severity.Info, message: localize( @@ -525,7 +567,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo const usedOnHostMessage: UsedOnHostMessage = { hostName: connectionInfo.tunnelName, timeStamp: new Date().getTime() }; storageService.store(REMOTE_TUNNEL_USED_STORAGE_KEY, JSON.stringify(usedOnHostMessage), StorageScope.APPLICATION, StorageTarget.USER); } else { - await notificationService.notify({ + notificationService.notify({ severity: Severity.Info, message: localize('progress.turnOn.failed', "Unable to turn on the remote tunnel access. Check the Remote Tunnel Service log for details."), @@ -699,7 +741,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo private async showManageOptions() { - const account = await this.remoteTunnelService.getSession(); + const account = await this.remoteTunnelService.getMode(); return new Promise((c, e) => { const disposables = new DisposableStore(); @@ -721,7 +763,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo items.push({ id: RemoteTunnelCommandIds.showLog, label: localize('manage.showLog', 'Show Log') }); items.push({ type: 'separator' }); items.push({ id: RemoteTunnelCommandIds.configure, label: localize('manage.tunnelName', 'Change Tunnel Name'), description: this.connectionInfo?.tunnelName }); - items.push({ id: RemoteTunnelCommandIds.turnOff, label: RemoteTunnelCommandLabels.turnOff, description: account ? `${account.accountLabel} (${account.providerId})` : undefined }); + items.push({ id: RemoteTunnelCommandIds.turnOff, label: RemoteTunnelCommandLabels.turnOff, description: account.active ? `${account.session.accountLabel} (${account.session.providerId})` : undefined }); quickPick.items = items; disposables.add(quickPick.onDidAccept(() => { From 43650e28b6700c43708084df436e769a6eb99426 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 13 Jul 2023 23:12:45 -0700 Subject: [PATCH 0113/1180] Re #187471. Dispose instantiationService on test finish. (#187900) --- .../browser/browserKeyboardMapper.test.ts | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/keybinding/test/browser/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/browser/browserKeyboardMapper.test.ts index 5b466a15fe102..3921c6f130e96 100644 --- a/src/vs/workbench/services/keybinding/test/browser/browserKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/browser/browserKeyboardMapper.test.ts @@ -35,13 +35,22 @@ class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { } suite('keyboard layout loader', () => { - const instantiationService: TestInstantiationService = new TestInstantiationService(); - const notitifcationService = instantiationService.stub(INotificationService, new TestNotificationService()); - const storageService = instantiationService.stub(IStorageService, new TestStorageService()); - const configurationService = instantiationService.stub(IConfigurationService, new TestConfigurationService()); + let instantiationService: TestInstantiationService; + let instance: TestKeyboardMapperFactory; - const commandService = instantiationService.stub(ICommandService, {}); - const instance = new TestKeyboardMapperFactory(configurationService, notitifcationService, storageService, commandService); + setup(() => { + instantiationService = new TestInstantiationService(); + const notitifcationService = instantiationService.stub(INotificationService, new TestNotificationService()); + const storageService = instantiationService.stub(IStorageService, new TestStorageService()); + const configurationService = instantiationService.stub(IConfigurationService, new TestConfigurationService()); + + const commandService = instantiationService.stub(ICommandService, {}); + instance = new TestKeyboardMapperFactory(configurationService, notitifcationService, storageService, commandService); + }); + + teardown(() => { + instantiationService.dispose(); + }); test('load default US keyboard layout', () => { assert.notStrictEqual(instance.activeKeyboardLayout, null); From 670b39eb0acb9d67789514ffd7a41072b4f07f75 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 10:04:05 +0200 Subject: [PATCH 0114/1180] adding console logs to understand where the error comes from --- src/vs/editor/browser/widget/diffEditorWidget.ts | 3 +++ .../contrib/inlineChat/browser/inlineChatStrategies.ts | 1 + .../contrib/inlineChat/browser/inlineChatWidget.ts | 7 +++++++ .../inlineChat/test/browser/inlineChatController.test.ts | 1 + 4 files changed, 12 insertions(+) diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index e21c1e9f3beb2..47afe24c19605 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -709,6 +709,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE } public override dispose(): void { + console.log('inside of the dispose method'); + this._codeEditorService.removeDiffEditor(this); if (this._beginUpdateDecorationsTimeout !== -1) { @@ -884,6 +886,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._onDidChangeModel.fire(); // Diff navigator + console.log('right before the final _register'); this._diffNavigator = this._register(this._instantiationService.createInstance(DiffNavigator, this, { alwaysRevealFirst: false, findResultLoop: this.getModifiedEditor().getOption(EditorOption.find).loop diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index 36e64ebf09af5..bbc2aabacb852 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -126,6 +126,7 @@ export class PreviewStrategy extends EditModeStrategy { const edits = response.localEdits.map(edit => EditOperation.replace(Range.lift(edit.range), edit.text)); this._widget.showEditsPreview(this._session.textModel0, edits, this._session.lastTextModelChanges); } else { + console.log('inside of render changes'); this._widget.hideEditsPreview(); } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index adb0b77635e8f..a7cc7801921c5 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -521,6 +521,7 @@ export class InlineChatWidget { this._elements.statusToolbar.classList.add('hidden'); this._elements.feedbackToolbar.classList.add('hidden'); this.hideCreatePreview(); + console.log('inside of reset'); this.hideEditsPreview(); this._onDidChangeHeight.fire(); } @@ -537,6 +538,7 @@ export class InlineChatWidget { showEditsPreview(textModelv0: ITextModel, edits: ISingleEditOperation[], changes: readonly LineRangeMapping[]) { if (changes.length === 0) { + console.log('inside of show edits preview'); this.hideEditsPreview(); return; } @@ -546,6 +548,7 @@ export class InlineChatWidget { const languageSelection: ILanguageSelection = { languageId: textModelv0.getLanguageId(), onDidChange: Event.None }; const modified = this._modelService.createModel(createTextBufferFactoryFromSnapshot(textModelv0.createSnapshot()), languageSelection, undefined, true); modified.applyEdits(edits, false); + console.log('inside of show edits preview'); this._previewDiffEditor.value.setModel({ original: textModelv0, modified }); // joined ranges @@ -577,7 +580,10 @@ export class InlineChatWidget { } hideEditsPreview() { + // Error happens because this is called after the diff editor widget is already disposed. + console.log('inside of hide edits preview'); this._elements.previewDiff.classList.add('hidden'); + // TODO: error is happening here this._previewDiffEditor.value.setModel(null); this._previewDiffModel.clear(); this._onDidChangeHeight.fire(); @@ -834,6 +840,7 @@ export class InlineChatZoneWidget extends ZoneWidget { } override hide(): void { + console.log('inside of hide'); this.container!.classList.remove('inside-selection'); this._ctxVisible.reset(); this._ctxCursorPosition.reset(); diff --git a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts index f4ba0f5b182ac..7733da149efea 100644 --- a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts +++ b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts @@ -156,6 +156,7 @@ suite('InteractiveChatController', function () { await run; + console.log('ctrl.getWidgetPosition() : ', ctrl.getWidgetPosition()); assert.ok(ctrl.getWidgetPosition() === undefined); }); From 42210746536554290fb35092495f4dfbef9bbb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 14 Jul 2023 10:14:19 +0200 Subject: [PATCH 0115/1180] fix windows servers, add top level folders (#187906) --- build/azure-pipelines/win32/product-build-win32.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 6356978d40bef..d733ec41efd45 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -263,7 +263,7 @@ steps: $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)\* -r } + exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) -r } echo "##vso[task.setvariable variable=SERVER_PATH]$ArchivePath" condition: and(succeededOrFailed(), eq(variables['BUILT_SERVER'], 'true')) displayName: Package server @@ -273,7 +273,7 @@ steps: $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web\* -r } + exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web -r } echo "##vso[task.setvariable variable=WEB_PATH]$ArchivePath" condition: and(succeededOrFailed(), eq(variables['BUILT_WEB'], 'true')) displayName: Package server (web) From a0f904dd54d04a87c3df08d42382a4d77075174a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 14 Jul 2023 10:28:51 +0200 Subject: [PATCH 0116/1180] only show update release notes in stable (#187908) --- .../contrib/update/browser/update.ts | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/contrib/update/browser/update.ts b/src/vs/workbench/contrib/update/browser/update.ts index 538bbbd55782b..bfba80a99dfe7 100644 --- a/src/vs/workbench/contrib/update/browser/update.ts +++ b/src/vs/workbench/contrib/update/browser/update.ts @@ -458,23 +458,25 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Updating) }); - CommandsRegistry.registerCommand('update.showUpdateReleaseNotes', () => { - if (this.updateService.state.type !== StateType.Ready) { - return; - } + if (this.productService.quality === 'stable') { + CommandsRegistry.registerCommand('update.showUpdateReleaseNotes', () => { + if (this.updateService.state.type !== StateType.Ready) { + return; + } - const version = this.updateService.state.update.version; - this.instantiationService.invokeFunction(accessor => showReleaseNotes(accessor, version)); - }); - MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { - group: '7_update', - order: 1, - command: { - id: 'update.showUpdateReleaseNotes', - title: nls.localize('showUpdateReleaseNotes', "Show Update Release Notes") - }, - when: ContextKeyExpr.and(CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready), MAJOR_MINOR_UPDATE_AVAILABLE) - }); + const version = this.updateService.state.update.version; + this.instantiationService.invokeFunction(accessor => showReleaseNotes(accessor, version)); + }); + MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { + group: '7_update', + order: 1, + command: { + id: 'update.showUpdateReleaseNotes', + title: nls.localize('showUpdateReleaseNotes', "Show Update Release Notes") + }, + when: ContextKeyExpr.and(CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready), MAJOR_MINOR_UPDATE_AVAILABLE) + }); + } CommandsRegistry.registerCommand('update.restart', () => this.updateService.quitAndInstall()); MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { From bd27bb08e5d3984ee288c4a9c4eba233625acd3c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 10:33:19 +0200 Subject: [PATCH 0117/1180] not sure what is causing the test errors --- .../browser/inlineChatController.ts | 4 +++ .../test/browser/inlineChatController.test.ts | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 39436818fa9aa..3306e796ce37e 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -176,6 +176,7 @@ export class InlineChatController implements IEditorContribution { private _currentRun?: Promise; async run(options: InlineChatRunOptions | undefined = {}): Promise { + console.log('inside of run'); this.finishExistingSession(); if (this._currentRun) { await this._currentRun; @@ -667,6 +668,7 @@ export class InlineChatController implements IEditorContribution { } private async [State.CANCEL]() { + console.log('inside of cancel function'); assertType(this._activeSession); assertType(this._strategy); this._sessionStore.clear(); @@ -771,6 +773,7 @@ export class InlineChatController implements IEditorContribution { } cancelSession() { + console.log('inside of the cancel session method'); let result: string | undefined; if (this._strategy && this._activeSession) { const changedText = this._activeSession.asChangedText(); @@ -785,6 +788,7 @@ export class InlineChatController implements IEditorContribution { } finishExistingSession(): void { + console.log('inside of finish existing session'); if (this._activeSession) { if (this._activeSession.editMode === EditMode.Preview) { this._log('finishing existing session, using CANCEL', this._activeSession.editMode); diff --git a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts index 7733da149efea..1ace231c30b32 100644 --- a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts +++ b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts @@ -141,27 +141,39 @@ suite('InteractiveChatController', function () { }); test('creation, not showing anything', function () { + console.log('*** at the begining of creation'); ctrl = instaService.createInstance(TestController, editor); assert.ok(ctrl); assert.strictEqual(ctrl.getWidgetPosition(), undefined); + console.log('*** at the end of creation'); }); test('run (show/hide)', async function () { + console.log('*** at the beginning of run (show/hide)'); + ctrl = instaService.createInstance(TestController, editor); + console.log('right before run'); const run = ctrl.run({ message: 'Hello', autoSend: true }); + console.log('right before waitFor INIT_SEQUENCE_AUTO_SEND'); await ctrl.waitFor(TestController.INIT_SEQUENCE_AUTO_SEND); assert.ok(ctrl.getWidgetPosition() !== undefined); + + console.log('right before cancel session'); ctrl.cancelSession(); + console.log('right before run'); await run; console.log('ctrl.getWidgetPosition() : ', ctrl.getWidgetPosition()); assert.ok(ctrl.getWidgetPosition() === undefined); + console.log('*** at the end of run (show/hide)'); }); test('wholeRange expands to whole lines, editor selection default', async function () { + console.log('*** at the beginning of wholeRange, editor selection default'); + editor.setSelection(new Range(1, 1, 1, 3)); ctrl = instaService.createInstance(TestController, editor); @@ -186,10 +198,14 @@ suite('InteractiveChatController', function () { ctrl.cancelSession(); d.dispose(); + + console.log('*** at the end of wholeRange, editor selection default'); }); test('wholeRange expands to whole lines, session provided', async function () { + console.log('*** at the beginning of wholeRange, editor selection provided'); + editor.setSelection(new Range(1, 1, 1, 1)); ctrl = instaService.createInstance(TestController, editor); @@ -215,9 +231,14 @@ suite('InteractiveChatController', function () { ctrl.cancelSession(); d.dispose(); + + console.log('*** at the end of wholeRange, editor selection provided'); }); test('typing outside of wholeRange finishes session', async function () { + + console.log('*** at the beginning of typing outside'); + ctrl = instaService.createInstance(TestController, editor); ctrl.run({ message: 'Hello', autoSend: true }); @@ -231,10 +252,14 @@ suite('InteractiveChatController', function () { editor.trigger('test', 'type', { text: 'a' }); await ctrl.waitFor([State.ACCEPT]); + + console.log('*** at the end of typing outside'); }); test('\'whole range\' isn\'t updated for edits outside whole range #4346', async function () { + console.log('*** at the beginning of whole range isnt updated'); + editor.setSelection(new Range(3, 1, 3, 1)); const d = inlineChatService.addProvider({ @@ -271,9 +296,14 @@ suite('InteractiveChatController', function () { await ctrl.waitFor([State.MAKE_REQUEST, State.APPLY_RESPONSE, State.SHOW_RESPONSE, State.WAIT_FOR_INPUT]); assert.deepStrictEqual(session.wholeRange.value, new Range(1, 1, 4, 12)); + + console.log('*** at the end of whole range isnt updated'); }); test('Stuck inline chat widget #211', async function () { + + console.log('*** at the beginning of stuck inline chat'); + const d = inlineChatService.addProvider({ debugName: 'Unit Test', prepareInlineChatSession() { @@ -306,5 +336,7 @@ suite('InteractiveChatController', function () { await p; assert.strictEqual(ctrl.getWidgetPosition(), undefined); + + console.log('*** at the end of stuck inline chat'); }); }); From 6a152ca5231c2035bc8718e41dc96047e33bed96 Mon Sep 17 00:00:00 2001 From: Ehab Younes Date: Fri, 14 Jul 2023 08:49:15 +0000 Subject: [PATCH 0118/1180] Expose the focused element and change event in the TreeView API (#184268) * Expose the focused element and event in the TreeView API * Exposed active TreeItem through extension proposal * Add proposal to test extension * Merge change selection and focus events * Finish selection+focus change in treeview * Clean up * Clean up * Add checkProposedApiEnabled back in --------- Co-authored-by: Ehab Younes Co-authored-by: Alex Ross --- extensions/vscode-api-tests/package.json | 1 + .../api/browser/mainThreadTreeViews.ts | 3 +- .../workbench/api/common/extHost.protocol.ts | 3 +- .../workbench/api/common/extHostTreeViews.ts | 41 +++++++++++-------- .../workbench/browser/parts/views/treeView.ts | 26 ++++++++---- src/vs/workbench/common/views.ts | 4 +- .../common/extensionsApiProposals.ts | 1 + .../vscode.proposed.treeViewActiveItem.d.ts | 30 ++++++++++++++ 8 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index b230a1a4897ff..369927c00f21d 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -44,6 +44,7 @@ "timeline", "tokenInformation", "treeItemCheckbox", + "treeViewActiveItem", "treeViewReveal", "testInvalidateResults", "workspaceTrust", diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index 6b6a75aaf60db..04170a3c9a06b 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -177,8 +177,7 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie private registerListeners(treeViewId: string, treeView: ITreeView): void { this._register(treeView.onDidExpandItem(item => this._proxy.$setExpanded(treeViewId, item.handle, true))); this._register(treeView.onDidCollapseItem(item => this._proxy.$setExpanded(treeViewId, item.handle, false))); - this._register(treeView.onDidChangeSelection(items => this._proxy.$setSelection(treeViewId, items.map(({ handle }) => handle)))); - this._register(treeView.onDidChangeFocus(item => this._proxy.$setFocus(treeViewId, item.handle))); + this._register(treeView.onDidChangeSelectionAndFocus(items => this._proxy.$setSelectionAndFocus(treeViewId, items.selection.map(({ handle }) => handle), items.focus.handle))); this._register(treeView.onDidChangeVisibility(isVisible => this._proxy.$setVisible(treeViewId, isVisible))); this._register(treeView.onDidChangeCheckboxState(items => { this._proxy.$changeCheckboxState(treeViewId, items.map(item => { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 3471b4cecaf70..5320cb4a8b0ea 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1563,8 +1563,7 @@ export interface ExtHostTreeViewsShape { $handleDrop(destinationViewId: string, requestId: number, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise; $handleDrag(sourceViewId: string, sourceTreeItemHandles: string[], operationUuid: string, token: CancellationToken): Promise; $setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void; - $setSelection(treeViewId: string, treeItemHandles: string[]): void; - $setFocus(treeViewId: string, treeItemHandle: string): void; + $setSelectionAndFocus(treeViewId: string, selectionHandles: string[], focusHandle: string): void; $setVisible(treeViewId: string, visible: boolean): void; $changeCheckboxState(treeViewId: string, checkboxUpdates: CheckboxUpdate[]): void; $hasResolve(treeViewId: string): Promise; diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index 2950a3b5894a6..3aaa6a38b29c0 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -24,6 +24,7 @@ import { IMarkdownString } from 'vs/base/common/htmlContent'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { ITreeViewsDnDService, TreeViewsDnDService } from 'vs/editor/common/services/treeViewsDnd'; import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility'; +import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; type TreeItemHandle = string; @@ -99,6 +100,14 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { get onDidExpandElement() { return treeView.onDidExpandElement; }, get selection() { return treeView.selectedElements; }, get onDidChangeSelection() { return treeView.onDidChangeSelection; }, + get activeItem() { + checkProposedApiEnabled(extension, 'treeViewActiveItem'); + return treeView.focusedElement; + }, + get onDidChangeActiveItem() { + checkProposedApiEnabled(extension, 'treeViewActiveItem'); + return treeView.onDidChangeActiveItem; + }, get visible() { return treeView.visible; }, get onDidChangeVisibility() { return treeView.onDidChangeVisibility; }, get onDidChangeCheckboxState() { @@ -222,20 +231,12 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { treeView.setExpanded(treeItemHandle, expanded); } - $setSelection(treeViewId: string, treeItemHandles: string[]): void { + $setSelectionAndFocus(treeViewId: string, selectedHandles: string[], focusedHandle: string) { const treeView = this.treeViews.get(treeViewId); if (!treeView) { throw new NoTreeViewError(treeViewId); } - treeView.setSelection(treeItemHandles); - } - - $setFocus(treeViewId: string, treeItemHandles: string) { - const treeView = this.treeViews.get(treeViewId); - if (!treeView) { - throw new NoTreeViewError(treeViewId); - } - treeView.setFocus(treeItemHandles); + treeView.setSelectionAndFocus(selectedHandles, focusedHandle); } $setVisible(treeViewId: string, isVisible: boolean): void { @@ -313,6 +314,9 @@ class ExtHostTreeView extends Disposable { private _onDidChangeSelection: Emitter> = this._register(new Emitter>()); readonly onDidChangeSelection: Event> = this._onDidChangeSelection.event; + private _onDidChangeActiveItem: Emitter> = this._register(new Emitter>()); + readonly onDidChangeActiveItem: Event> = this._onDidChangeActiveItem.event; + private _onDidChangeVisibility: Emitter = this._register(new Emitter()); readonly onDidChangeVisibility: Event = this._onDidChangeVisibility.event; @@ -479,15 +483,20 @@ class ExtHostTreeView extends Disposable { } } - setSelection(treeItemHandles: TreeItemHandle[]): void { - if (!equals(this._selectedHandles, treeItemHandles)) { - this._selectedHandles = treeItemHandles; + setSelectionAndFocus(selectedHandles: TreeItemHandle[], focusedHandle: string): void { + const changedSelection = !equals(this._selectedHandles, selectedHandles); + this._selectedHandles = selectedHandles; + + const changedFocus = this._focusedHandle !== focusedHandle; + this._focusedHandle = focusedHandle; + + if (changedSelection) { this._onDidChangeSelection.fire(Object.freeze({ selection: this.selectedElements })); } - } - setFocus(treeItemHandle: TreeItemHandle) { - this._focusedHandle = treeItemHandle; + if (changedFocus) { + this._onDidChangeActiveItem.fire(Object.freeze({ activeItem: this.focusedElement })); + } } setVisible(visible: boolean): void { diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 5cacc80e6baf6..77b9e62a7b73b 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -215,6 +215,8 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { private root: ITreeItem; private elementsToRefresh: ITreeItem[] = []; + private lastSelection: readonly ITreeItem[] = []; + private lastActive: ITreeItem; private readonly _onDidExpandItem: Emitter = this._register(new Emitter()); readonly onDidExpandItem: Event = this._onDidExpandItem.event; @@ -222,11 +224,8 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { private readonly _onDidCollapseItem: Emitter = this._register(new Emitter()); readonly onDidCollapseItem: Event = this._onDidCollapseItem.event; - private _onDidChangeSelection: Emitter = this._register(new Emitter()); - readonly onDidChangeSelection: Event = this._onDidChangeSelection.event; - - private _onDidChangeFocus: Emitter = this._register(new Emitter()); - readonly onDidChangeFocus: Event = this._onDidChangeFocus.event; + private _onDidChangeSelectionAndFocus: Emitter<{ selection: readonly ITreeItem[]; focus: ITreeItem }> = this._register(new Emitter<{ selection: readonly ITreeItem[]; focus: ITreeItem }>()); + readonly onDidChangeSelectionAndFocus: Event<{ selection: readonly ITreeItem[]; focus: ITreeItem }> = this._onDidChangeSelectionAndFocus.event; private readonly _onDidChangeVisibility: Emitter = this._register(new Emitter()); readonly onDidChangeVisibility: Event = this._onDidChangeVisibility.event; @@ -267,6 +266,7 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { ) { super(); this.root = new Root(); + this.lastActive = this.root; // Try not to add anything that could be costly to this constructor. It gets called once per tree view // during startup, and anything added here can affect performance. } @@ -702,10 +702,17 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { const customTreeKey = RawCustomTreeViewContextKey.bindTo(this.tree.contextKeyService); customTreeKey.set(true); this._register(this.tree.onContextMenu(e => this.onContextMenu(treeMenus, e, actionRunner))); - this._register(this.tree.onDidChangeSelection(e => this._onDidChangeSelection.fire(e.elements))); + + this._register(this.tree.onDidChangeSelection(e => { + this.lastSelection = e.elements; + this.lastActive = this.tree?.getFocus()[0] ?? this.lastActive; + this._onDidChangeSelectionAndFocus.fire({ selection: this.lastSelection, focus: this.lastActive }); + })); this._register(this.tree.onDidChangeFocus(e => { - if (e.elements.length) { - this._onDidChangeFocus.fire(e.elements[0]); + if (e.elements.length && (e.elements[0] !== this.lastActive)) { + this.lastActive = e.elements[0]; + this.lastSelection = this.tree?.getSelection() ?? this.lastSelection; + this._onDidChangeSelectionAndFocus.fire({ selection: this.lastSelection, focus: this.lastActive }); } })); this._register(this.tree.onDidChangeCollapseState(e => { @@ -957,7 +964,8 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { } const newSelection = tree.getSelection(); if (oldSelection.length !== newSelection.length || oldSelection.some((value, index) => value.handle !== newSelection[index].handle)) { - this._onDidChangeSelection.fire(newSelection); + this.lastSelection = newSelection; + this._onDidChangeSelectionAndFocus.fire({ selection: this.lastSelection, focus: this.lastActive }); } this.refreshing = false; this._onDidCompleteRefresh.fire(); diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 99efb9f3133f5..f86f9cb92bb8e 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -667,9 +667,7 @@ export interface ITreeView extends IDisposable { readonly onDidCollapseItem: Event; - readonly onDidChangeSelection: Event; - - readonly onDidChangeFocus: Event; + readonly onDidChangeSelectionAndFocus: Event<{ selection: readonly ITreeItem[]; focus: ITreeItem }>; readonly onDidChangeVisibility: Event; diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index ed18b53ce4f9d..98f89dca7086b 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -91,6 +91,7 @@ export const allApiProposals = Object.freeze({ textSearchProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts', timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts', tokenInformation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tokenInformation.d.ts', + treeViewActiveItem: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts', treeViewReveal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.treeViewReveal.d.ts', tunnels: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tunnels.d.ts', windowActivity: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.windowActivity.d.ts', diff --git a/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts b/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts new file mode 100644 index 0000000000000..27eab8603f60b --- /dev/null +++ b/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // https://github.com/microsoft/vscode/issues/170248 + + export interface TreeView extends Disposable { + /** + * Currently active item. + */ + readonly activeItem: T | undefined; + /** + * Event that is fired when the {@link TreeView.activeItem active item} has changed + */ + readonly onDidChangeActiveItem: Event>; + } + + /** + * The event that is fired when there is a change in {@link TreeView.activeItem tree view's active item} + */ + export interface TreeViewActiveItemChangeEvent { + /** + * Active item. + */ + readonly activeItem: T | undefined; + } +} From 4635c352d4a1d0a7452a39d76ba7f4e027b2813f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 11:18:41 +0200 Subject: [PATCH 0119/1180] refactoring the code --- src/vs/editor/contrib/hover/browser/hover.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 46c94e313df48..0058f9179dad8 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -216,6 +216,9 @@ export class ModesHoverController implements IEditorContribution { this._glyphWidget.startShowingAt(target.position.lineNumber); return; } + if (this._contentWidget?.isFocused()) { + return; + } if (!this._contentWidget?.widget.isResizing && !_sticky) { this._hideWidgets(); } From e86cdd8dfe168e5cff9152f7e2ef6058bd06a42b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 11:18:50 +0200 Subject: [PATCH 0120/1180] refactoring the code --- .../contrib/hover/browser/contentHover.ts | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index cb9e19bd00193..6ceb236f05767 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -195,9 +195,7 @@ export class ContentHoverController extends Disposable { private _setCurrentResult(hoverResult: HoverResult | null): void { if (this._currentResult === hoverResult) { - if (hoverResult === null && !this._widget.isFocused) { - this._widget.hide(); - } + // avoid updating the DOM to avoid resetting the user selection return; } if (hoverResult && hoverResult.messages.length === 0) { @@ -207,9 +205,6 @@ export class ContentHoverController extends Disposable { if (this._currentResult) { this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { - if (this._widget.isFocused) { - return; - } this._widget.hide(); } } @@ -232,6 +227,10 @@ export class ContentHoverController extends Disposable { return this._widget.isVisible; } + public isFocused(): boolean { + return this._widget.isFocused; + } + public containsNode(node: Node | null | undefined): boolean { return (node ? this._widget.getDomNode().contains(node) : false); } @@ -264,7 +263,9 @@ export class ContentHoverController extends Disposable { return; } } - + if (hoverResult.messages.length === 0 && this._widget.isFocused) { + return; + } this._setCurrentResult(hoverResult); } @@ -735,7 +736,10 @@ export class ContentHoverWidget extends ResizableContentWidget { } public hide(): void { - const stoleFocus = this._visibleData?.stoleFocus || this._hoverFocusedKey.get(); + if (!this._visibleData) { + return; + } + const stoleFocus = this._visibleData.stoleFocus || this._hoverFocusedKey.get(); this._setHoverData(undefined); this._resizableNode.maxSize = new dom.Dimension(Infinity, Infinity); this._resizableNode.clearSashHoverState(); From ede257b88938d0c5aec83d20ec0c3354e78ae65f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 11:22:12 +0200 Subject: [PATCH 0121/1180] cleaning the code --- src/vs/editor/contrib/hover/browser/hover.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 0058f9179dad8..5fff46b45b58b 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -216,12 +216,14 @@ export class ModesHoverController implements IEditorContribution { this._glyphWidget.startShowingAt(target.position.lineNumber); return; } - if (this._contentWidget?.isFocused()) { + if ( + this._contentWidget?.isFocused() + || this._contentWidget?.widget.isResizing + || _sticky + ) { return; } - if (!this._contentWidget?.widget.isResizing && !_sticky) { - this._hideWidgets(); - } + this._hideWidgets(); } private _onKeyDown(e: IKeyboardEvent): void { From dc142e4cd111b8f370d0549d8c207df7de55facd Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 14 Jul 2023 11:52:40 +0200 Subject: [PATCH 0122/1180] BUILD: Exclude third party notices from indentation filter (#187913) --- build/filters.js | 1 + 1 file changed, 1 insertion(+) diff --git a/build/filters.js b/build/filters.js index d729582eb6ca2..93cddb57ac794 100644 --- a/build/filters.js +++ b/build/filters.js @@ -66,6 +66,7 @@ module.exports.indentationFilter = [ // except specific files '!**/ThirdPartyNotices.txt', + '!**/ThirdPartyNotices.cli.txt', '!**/LICENSE.{txt,rtf}', '!LICENSES.chromium.html', '!**/LICENSE', From e2cc9c28e680170d452c0ee0e24eceb49a6a6ffd Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 14:13:39 +0200 Subject: [PATCH 0123/1180] change from review --- src/vs/editor/contrib/hover/browser/contentHover.ts | 3 --- src/vs/editor/contrib/hover/browser/hover.ts | 10 +++++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 6ceb236f05767..37cf599c4fe6c 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -263,9 +263,6 @@ export class ContentHoverController extends Disposable { return; } } - if (hoverResult.messages.length === 0 && this._widget.isFocused) { - return; - } this._setCurrentResult(hoverResult); } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 5fff46b45b58b..eba76ac91f867 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -155,6 +155,10 @@ export class ModesHoverController implements IEditorContribution { private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { const target = mouseEvent.target; + if (this._contentWidget?.isFocused() || this._contentWidget?.widget.isResizing) { + return; + } + if (this._isMouseDown && this._hoverClicked) { return; } @@ -216,11 +220,7 @@ export class ModesHoverController implements IEditorContribution { this._glyphWidget.startShowingAt(target.position.lineNumber); return; } - if ( - this._contentWidget?.isFocused() - || this._contentWidget?.widget.isResizing - || _sticky - ) { + if (_sticky) { return; } this._hideWidgets(); From d656306c7a72819d262dc84eb19c8c71330e2b8c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 14:14:26 +0200 Subject: [PATCH 0124/1180] cleaning the code more --- src/vs/editor/contrib/hover/browser/contentHover.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 37cf599c4fe6c..bb8c57d1307f7 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -263,6 +263,7 @@ export class ContentHoverController extends Disposable { return; } } + this._setCurrentResult(hoverResult); } From fb15f1df481e36aa8bf49aeeb197f7c4d0448328 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 14:20:16 +0200 Subject: [PATCH 0125/1180] Cleaning the code, using getters instead --- .../colorPicker/browser/colorContributions.ts | 2 +- .../contrib/hover/browser/contentHover.ts | 12 ++++++---- src/vs/editor/contrib/hover/browser/hover.ts | 24 +++++++++---------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts b/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts index 7ff5f54f24892..2c041f1c7490c 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorContributions.ts @@ -60,7 +60,7 @@ export class ColorContribution extends Disposable implements IEditorContribution if (!hoverController) { return; } - if (!hoverController.isColorPickerVisible()) { + if (!hoverController.isColorPickerVisible) { const range = new Range(target.range.startLineNumber, target.range.startColumn + 1, target.range.endLineNumber, target.range.endColumn + 1); hoverController.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Mouse, false, true); } diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index bb8c57d1307f7..e6467686589c7 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -215,22 +215,26 @@ export class ContentHoverController extends Disposable { this._setCurrentResult(null); } - public isColorPickerVisible(): boolean { + get isColorPickerVisible(): boolean { return this._widget.isColorPickerVisible; } - public isVisibleFromKeyboard(): boolean { + get isVisibleFromKeyboard(): boolean { return this._widget.isVisibleFromKeyboard; } - public isVisible(): boolean { + get isVisible(): boolean { return this._widget.isVisible; } - public isFocused(): boolean { + get isFocused(): boolean { return this._widget.isFocused; } + get isResizing(): boolean { + return this._widget.isResizing; + } + public containsNode(node: Node | null | undefined): boolean { return (node ? this._widget.getDomNode().contains(node) : false); } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index eba76ac91f867..0510a0bbc6f9d 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -155,7 +155,7 @@ export class ModesHoverController implements IEditorContribution { private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { const target = mouseEvent.target; - if (this._contentWidget?.isFocused() || this._contentWidget?.widget.isResizing) { + if (this._contentWidget?.isFocused || this._contentWidget?.isResizing) { return; } @@ -175,7 +175,7 @@ export class ModesHoverController implements IEditorContribution { if ( !this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID - && this._contentWidget?.isColorPickerVisible() + && this._contentWidget?.isColorPickerVisible ) { // though the hover is not sticky, the color picker needs to. return; @@ -186,7 +186,7 @@ export class ModesHoverController implements IEditorContribution { return; } - if (this._isHoverSticky && this._contentWidget?.isVisibleFromKeyboard()) { + if (this._isHoverSticky && this._contentWidget?.isVisibleFromKeyboard) { // Sticky mode is on and the hover has been shown via keyboard // so moving the mouse has no effect return; @@ -233,7 +233,7 @@ export class ModesHoverController implements IEditorContribution { const resolvedKeyboardEvent = this._keybindingService.softDispatch(e, this._editor.getDomNode()); // If the beginning of a multi-chord keybinding is pressed, or the command aims to focus the hover, set the variable to true, otherwise false - const mightTriggerFocus = (resolvedKeyboardEvent.kind === ResultKind.MoreChordsNeeded || (resolvedKeyboardEvent.kind === ResultKind.KbFound && resolvedKeyboardEvent.commandId === 'editor.action.showHover' && this._contentWidget?.isVisible())); + const mightTriggerFocus = (resolvedKeyboardEvent.kind === ResultKind.MoreChordsNeeded || (resolvedKeyboardEvent.kind === ResultKind.KbFound && resolvedKeyboardEvent.commandId === 'editor.action.showHover' && this._contentWidget?.isVisible)); if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift && !mightTriggerFocus) { @@ -246,7 +246,7 @@ export class ModesHoverController implements IEditorContribution { if (_sticky) { return; } - if ((this._isMouseDown && this._hoverClicked && this._contentWidget?.isColorPickerVisible()) || InlineSuggestionHintsContentWidget.dropDownVisible) { + if ((this._isMouseDown && this._hoverClicked && this._contentWidget?.isColorPickerVisible) || InlineSuggestionHintsContentWidget.dropDownVisible) { return; } this._hoverActivatedByColorDecoratorClick = false; @@ -262,10 +262,6 @@ export class ModesHoverController implements IEditorContribution { return this._contentWidget; } - public isColorPickerVisible(): boolean { - return this._contentWidget?.isColorPickerVisible() || false; - } - public showContentHover(range: Range, mode: HoverStartMode, source: HoverStartSource, focus: boolean, activatedByColorDecoratorClick: boolean = false): void { this._hoverActivatedByColorDecoratorClick = activatedByColorDecoratorClick; this._getOrCreateContentWidget().startShowingAtRange(range, mode, source, focus); @@ -307,8 +303,12 @@ export class ModesHoverController implements IEditorContribution { this._contentWidget?.goToBottom(); } - public isHoverVisible(): boolean | undefined { - return this._contentWidget?.isVisible(); + get isColorPickerVisible(): boolean | undefined { + return this._contentWidget?.isColorPickerVisible; + } + + get isHoverVisible(): boolean | undefined { + return this._contentWidget?.isVisible; } public dispose(): void { @@ -372,7 +372,7 @@ class ShowOrFocusHoverAction extends EditorAction { const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column); const focus = editor.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled || !!args?.focus; - if (controller.isHoverVisible()) { + if (controller.isHoverVisible) { controller.focus(); } else { controller.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Keyboard, focus); From 8df24c594697be28aa9b94396d3f21113ae83eb6 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 14:22:48 +0200 Subject: [PATCH 0126/1180] cleaning the code --- src/vs/editor/contrib/hover/browser/contentHover.ts | 10 +++++----- src/vs/editor/contrib/hover/browser/hover.ts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e6467686589c7..6989029fe4f92 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -215,23 +215,23 @@ export class ContentHoverController extends Disposable { this._setCurrentResult(null); } - get isColorPickerVisible(): boolean { + public get isColorPickerVisible(): boolean { return this._widget.isColorPickerVisible; } - get isVisibleFromKeyboard(): boolean { + public get isVisibleFromKeyboard(): boolean { return this._widget.isVisibleFromKeyboard; } - get isVisible(): boolean { + public get isVisible(): boolean { return this._widget.isVisible; } - get isFocused(): boolean { + public get isFocused(): boolean { return this._widget.isFocused; } - get isResizing(): boolean { + public get isResizing(): boolean { return this._widget.isResizing; } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 0510a0bbc6f9d..2c1e2b2611e7e 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -303,11 +303,11 @@ export class ModesHoverController implements IEditorContribution { this._contentWidget?.goToBottom(); } - get isColorPickerVisible(): boolean | undefined { + public get isColorPickerVisible(): boolean | undefined { return this._contentWidget?.isColorPickerVisible; } - get isHoverVisible(): boolean | undefined { + public get isHoverVisible(): boolean | undefined { return this._contentWidget?.isVisible; } From 8e1ae0da75850323611f6878a3449bee62d6250f Mon Sep 17 00:00:00 2001 From: Diego Colombo Date: Fri, 14 Jul 2023 14:19:13 +0100 Subject: [PATCH 0127/1180] Add proposed api to support auto closing pairs on langauge configuration (#186567) * adding support for auto closing pair --- .../api/browser/mainThreadLanguageFeatures.ts | 4 +++- src/vs/workbench/api/common/extHost.protocol.ts | 5 +++++ .../api/common/extHostLanguageFeatures.ts | 6 ++++++ .../extensions/common/extensionsApiProposals.ts | 1 + ...d.languageConfigurationAutoClosingPairs.d.ts | 17 +++++++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/vscode-dts/vscode.proposed.languageConfigurationAutoClosingPairs.d.ts diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 732637669fb37..548cc6b8517b2 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -852,7 +852,9 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread __electricCharacterSupport: undefined }; - if (_configuration.__characterPairSupport) { + if (_configuration.autoClosingPairs) { + configuration.autoClosingPairs = _configuration.autoClosingPairs; + } else if (_configuration.__characterPairSupport) { // backwards compatibility configuration.autoClosingPairs = _configuration.__characterPairSupport.autoClosingPairs; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5320cb4a8b0ea..0dc33e49a04ca 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -344,6 +344,11 @@ export interface ILanguageConfigurationDto { notIn?: string[]; }[]; }; + autoClosingPairs?: { + open: string; + close: string; + notIn?: string[]; + }[]; } export type GlobPattern = string | IRelativePattern; diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 78ecbea0a858d..442f8292b3e36 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -2533,6 +2533,10 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF `Do not use.`); } + if (configuration.autoClosingPairs) { + checkProposedApiEnabled(extension, 'languageConfigurationAutoClosingPairs'); + } + const handle = this._nextHandle(); const serializedConfiguration: extHostProtocol.ILanguageConfigurationDto = { comments: configuration.comments, @@ -2542,7 +2546,9 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF onEnterRules: configuration.onEnterRules ? ExtHostLanguageFeatures._serializeOnEnterRules(configuration.onEnterRules) : undefined, __electricCharacterSupport: configuration.__electricCharacterSupport, __characterPairSupport: configuration.__characterPairSupport, + autoClosingPairs: configuration.autoClosingPairs }; + this._proxy.$setLanguageConfiguration(handle, languageId, serializedConfiguration); return this._createDisposable(handle); } diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 98f89dca7086b..d42bf233a5c69 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -54,6 +54,7 @@ export const allApiProposals = Object.freeze({ interactiveUserActions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.interactiveUserActions.d.ts', interactiveWindow: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts', ipc: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.ipc.d.ts', + languageConfigurationAutoClosingPairs: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageConfigurationAutoClosingPairs.d.ts', notebookCellExecutionState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCellExecutionState.d.ts', notebookCodeActions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCodeActions.d.ts', notebookControllerAffinityHidden: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts', diff --git a/src/vscode-dts/vscode.proposed.languageConfigurationAutoClosingPairs.d.ts b/src/vscode-dts/vscode.proposed.languageConfigurationAutoClosingPairs.d.ts new file mode 100644 index 0000000000000..641e2f5f0d86c --- /dev/null +++ b/src/vscode-dts/vscode.proposed.languageConfigurationAutoClosingPairs.d.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // https://github.com/microsoft/vscode/issues/173738 + + export interface LanguageConfiguration { + autoClosingPairs?: { + open: string; + close: string; + notIn?: string[]; + }[]; + } +} From baabfe503d8477d7c11d0d5a9e08508353f7b496 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 14 Jul 2023 16:54:00 +0200 Subject: [PATCH 0128/1180] revert the code that was written for the set state optimization --- .../contrib/stickyScroll/browser/stickyScrollWidget.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 7c7260203bf93..7b4a946f5f358 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -6,7 +6,6 @@ import * as dom from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { createTrustedTypesPolicy } from 'vs/base/browser/trustedTypes'; -import { equals } from 'vs/base/common/arrays'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import 'vs/css!./stickyScroll'; import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser'; @@ -22,10 +21,6 @@ export class StickyScrollWidgetState { readonly lineNumbers: number[], readonly lastLineRelativePosition: number ) { } - - public equals(other: StickyScrollWidgetState | undefined): boolean { - return !!other && this.lastLineRelativePosition === other.lastLineRelativePosition && equals(this.lineNumbers, other.lineNumbers); - } } const _ttPolicy = createTrustedTypesPolicy('stickyScrollViewLayer', { createHTML: value => value }); @@ -40,7 +35,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { private _lastLineRelativePosition: number = 0; private _hoverOnLine: number = -1; private _hoverOnColumn: number = -1; - private _state: StickyScrollWidgetState | undefined; constructor( private readonly _editor: ICodeEditor @@ -74,10 +68,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } setState(state: StickyScrollWidgetState): void { - if (state.equals(this._state)) { - return; - } - this._state = state; dom.clearNode(this._rootDomNode); this._disposableStore.clear(); this._lineNumbers.length = 0; From f21001c1fecfd966a76ff02fd772dd823ed1d46f Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 14 Jul 2023 17:36:58 +0200 Subject: [PATCH 0129/1180] wip --- .../api/browser/extensionHost.contribution.ts | 2 + .../api/browser/mainThreadChatProvider.ts | 53 ++++ .../browser/mainThreadChatSlashCommands.ts | 51 ++++ .../workbench/api/common/extHost.api.impl.ts | 19 ++ .../workbench/api/common/extHost.protocol.ts | 26 ++ .../api/common/extHostChatProvider.ts | 69 +++++ .../api/common/extHostChatSlashCommand.ts | 70 ++++++ .../api/common/extHostTypeConverters.ts | 21 ++ src/vs/workbench/api/common/extHostTypes.ts | 19 ++ .../contrib/chat/browser/chat.contribution.ts | 5 +- .../contrib/chat/common/chatProvider.ts | 68 +++++ .../contrib/chat/common/chatSlashCommands.ts | 236 ++++++++++++++++++ .../common/extensionsApiProposals.ts | 2 + .../vscode.proposed.chatProvider.d.ts | 46 ++++ .../vscode.proposed.chatSlashCommands.d.ts | 45 ++++ 15 files changed, 731 insertions(+), 1 deletion(-) create mode 100644 src/vs/workbench/api/browser/mainThreadChatProvider.ts create mode 100644 src/vs/workbench/api/browser/mainThreadChatSlashCommands.ts create mode 100644 src/vs/workbench/api/common/extHostChatProvider.ts create mode 100644 src/vs/workbench/api/common/extHostChatSlashCommand.ts create mode 100644 src/vs/workbench/contrib/chat/common/chatProvider.ts create mode 100644 src/vs/workbench/contrib/chat/common/chatSlashCommands.ts create mode 100644 src/vscode-dts/vscode.proposed.chatProvider.d.ts create mode 100644 src/vscode-dts/vscode.proposed.chatSlashCommands.d.ts diff --git a/src/vs/workbench/api/browser/extensionHost.contribution.ts b/src/vs/workbench/api/browser/extensionHost.contribution.ts index d582b31b0b04a..6328cfd2df96e 100644 --- a/src/vs/workbench/api/browser/extensionHost.contribution.ts +++ b/src/vs/workbench/api/browser/extensionHost.contribution.ts @@ -19,6 +19,8 @@ import { StatusBarItemsExtensionPoint } from 'vs/workbench/api/browser/statusBar // --- mainThread participants import './mainThreadLocalization'; import './mainThreadBulkEdits'; +import './mainThreadChatProvider'; +import './mainThreadChatSlashCommands'; import './mainThreadCodeInsets'; import './mainThreadCLICommands'; import './mainThreadClipboard'; diff --git a/src/vs/workbench/api/browser/mainThreadChatProvider.ts b/src/vs/workbench/api/browser/mainThreadChatProvider.ts new file mode 100644 index 0000000000000..bdb067ec1d86c --- /dev/null +++ b/src/vs/workbench/api/browser/mainThreadChatProvider.ts @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DisposableMap } from 'vs/base/common/lifecycle'; +import { IProgress } from 'vs/platform/progress/common/progress'; +import { ExtHostChatProviderShape, ExtHostContext, MainContext, MainThreadChatProviderShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IChatResponseProviderMetadata, IChatResponseFragment, IChatProviderService } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; + +@extHostNamedCustomer(MainContext.MainThreadChatProvider) +export class MainThreadChatProvider implements MainThreadChatProviderShape { + + private readonly _proxy: ExtHostChatProviderShape; + private readonly _providerRegistrations = new DisposableMap(); + private readonly _pendingProgress = new Map>(); + + constructor( + extHostContext: IExtHostContext, + @IChatProviderService private readonly _chatProviderService: IChatProviderService, + ) { + this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostChatProvider); + } + + dispose(): void { + this._providerRegistrations.dispose(); + } + + $registerProvider(handle: number, metadata: IChatResponseProviderMetadata): void { + const registration = this._chatProviderService.registerChatResponseProvider({ + metadata, + provideChatResponse: async (messages, options, progress, token) => { + const requestId = (Math.random() * 1e6) | 0; + this._pendingProgress.set(requestId, progress); + try { + await this._proxy.$provideChatResponse(handle, requestId, messages, options, token); + } finally { + this._pendingProgress.delete(requestId); + } + } + }); + this._providerRegistrations.set(handle, registration); + } + + async $handleProgressChunk(requestId: number, chunk: IChatResponseFragment): Promise { + this._pendingProgress.get(requestId)?.report(chunk); + } + + $unregisterProvider(handle: number): void { + this._providerRegistrations.deleteAndDispose(handle); + } +} diff --git a/src/vs/workbench/api/browser/mainThreadChatSlashCommands.ts b/src/vs/workbench/api/browser/mainThreadChatSlashCommands.ts new file mode 100644 index 0000000000000..839885602edf6 --- /dev/null +++ b/src/vs/workbench/api/browser/mainThreadChatSlashCommands.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DisposableMap } from 'vs/base/common/lifecycle'; +import { IProgress } from 'vs/platform/progress/common/progress'; +import { ExtHostChatSlashCommandsShape, ExtHostContext, MainContext, MainThreadChatSlashCommandsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IChatSlashCommandService, IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; +import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; + + +@extHostNamedCustomer(MainContext.MainThreadChatSlashCommands) +export class MainThreadChatSlashCommands implements MainThreadChatSlashCommandsShape { + + private readonly _commands = new DisposableMap; + private readonly _pendingProgress = new Map>(); + private readonly _proxy: ExtHostChatSlashCommandsShape; + + constructor( + extHostContext: IExtHostContext, + @IChatSlashCommandService private readonly _chatSlashCommandService: IChatSlashCommandService + ) { + this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostChatSlashCommands); + } + + dispose(): void { + this._commands.clearAndDisposeAll(); + } + + $registerCommand(handle: number, name: string): void { + const d = this._chatSlashCommandService.registerSlashCallback(name, async (prompt, progress, history, token) => { + const requestId = Math.random(); + this._pendingProgress.set(requestId, progress); + try { + await this._proxy.$executeCommand(handle, requestId, prompt, { history }, token); + } finally { + this._pendingProgress.delete(requestId); + } + }); + this._commands.set(handle, d); + } + + async $handleProgressChunk(requestId: number, chunk: IChatSlashFragment): Promise { + this._pendingProgress.get(requestId)?.report(chunk); + } + + $unregisterCommand(handle: number): void { + this._commands.deleteAndDispose(handle); + } +} diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 1e585c0d3b01f..14a51200438b6 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -104,6 +104,8 @@ import { ExtHostSemanticSimilarity } from 'vs/workbench/api/common/extHostSemant import { ExtHostIssueReporter } from 'vs/workbench/api/common/extHostIssueReporter'; import { IExtHostManagedSockets } from 'vs/workbench/api/common/extHostManagedSockets'; import { ExtHostShare } from 'vs/workbench/api/common/extHostShare'; +import { ExtHostChatProvider } from 'vs/workbench/api/common/extHostChatProvider'; +import { ExtHostChatSlashCommands } from 'vs/workbench/api/common/extHostChatSlashCommand'; export interface IExtensionRegistries { mine: ExtensionDescriptionRegistry; @@ -203,6 +205,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostProfileContentHandlers = rpcProtocol.set(ExtHostContext.ExtHostProfileContentHandlers, new ExtHostProfileContentHandlers(rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostInteractive, new ExtHostInteractive(rpcProtocol, extHostNotebook, extHostDocumentsAndEditors, extHostCommands, extHostLogService)); const extHostInteractiveEditor = rpcProtocol.set(ExtHostContext.ExtHostInlineChat, new ExtHostInteractiveEditor(rpcProtocol, extHostCommands, extHostDocuments, extHostLogService)); + const extHostChatProvider = rpcProtocol.set(ExtHostContext.ExtHostChatProvider, new ExtHostChatProvider(rpcProtocol, extHostLogService)); + const extHostChatSlashCommands = rpcProtocol.set(ExtHostContext.ExtHostChatSlashCommands, new ExtHostChatSlashCommands(rpcProtocol, extHostChatProvider, extHostLogService)); const extHostChat = rpcProtocol.set(ExtHostContext.ExtHostChat, new ExtHostChat(rpcProtocol, extHostLogService)); const extHostSemanticSimilarity = rpcProtocol.set(ExtHostContext.ExtHostSemanticSimilarity, new ExtHostSemanticSimilarity(rpcProtocol)); const extHostIssueReporter = rpcProtocol.set(ExtHostContext.ExtHostIssueReporter, new ExtHostIssueReporter(rpcProtocol)); @@ -1324,6 +1328,18 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I } }; + // namespace: llm + const llm: typeof vscode.llm = { + registerChatResponseProvider(provider: vscode.ChatResponseProvider, metadata: vscode.ChatResponseProviderMetadata) { + checkProposedApiEnabled(extension, 'chatProvider'); + return extHostChatProvider.registerProvider(extension.identifier, provider, metadata); + }, + registerSlashCommand(name: string, command: vscode.SlashCommand) { + checkProposedApiEnabled(extension, 'chatSlashCommands'); + return extHostChatSlashCommands.registerCommand(extension.identifier, name, command); + } + }; + return { version: initData.version, // namespaces @@ -1337,6 +1353,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I interactive, interactiveSlashCommands, l10n, + llm, languages, notebooks, scm, @@ -1347,6 +1364,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I // types Breakpoint: extHostTypes.Breakpoint, TerminalOutputAnchor: extHostTypes.TerminalOutputAnchor, + ChatMessage: extHostTypes.ChatMessage, + ChatMessageRole: extHostTypes.ChatMessageRole, CallHierarchyIncomingCall: extHostTypes.CallHierarchyIncomingCall, CallHierarchyItem: extHostTypes.CallHierarchyItem, CallHierarchyOutgoingCall: extHostTypes.CallHierarchyOutgoingCall, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5320cb4a8b0ea..cf713f31a88fd 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -74,6 +74,8 @@ import { ITextQueryBuilderOptions } from 'vs/workbench/services/search/common/qu import * as search from 'vs/workbench/services/search/common/search'; import { ISaveProfileResult } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { TerminalCommandMatchResult, TerminalQuickFixCommand, TerminalQuickFixOpener } from 'vscode'; +import { IChatMessage, IChatResponseFragment, IChatResponseProviderMetadata } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; export type TerminalQuickFix = TerminalQuickFixCommand | TerminalQuickFixOpener; @@ -1119,6 +1121,26 @@ export interface MainThreadNotebookRenderersShape extends IDisposable { export interface MainThreadInteractiveShape extends IDisposable { } +export interface MainThreadChatProviderShape extends IDisposable { + $registerProvider(handle: number, metadata: IChatResponseProviderMetadata): void; + $unregisterProvider(handle: number): void; + $handleProgressChunk(requestId: number, chunk: IChatResponseFragment): Promise; +} + +export interface ExtHostChatProviderShape { + $provideChatResponse(handle: number, requestId: number, messages: IChatMessage[], options: { [name: string]: any }, token: CancellationToken): Promise; +} + +export interface MainThreadChatSlashCommandsShape extends IDisposable { + $registerCommand(handle: number, name: string): void; + $unregisterCommand(handle: number): void; + $handleProgressChunk(requestId: number, chunk: IChatSlashFragment): Promise; +} + +export interface ExtHostChatSlashCommandsShape { + $executeCommand(handle: number, requestId: number, prompt: string, context: { history: IChatMessage[] }, token: CancellationToken): Promise; +} + export interface MainThreadInlineChatShape extends IDisposable { $registerInteractiveEditorProvider(handle: number, debugName: string, supportsFeedback: boolean): Promise; $handleProgressChunk(requestId: string, chunk: { message?: string; edits?: languages.TextEdit[] }): Promise; @@ -2517,6 +2539,8 @@ export interface MainThreadTestingShape { export const MainContext = { MainThreadAuthentication: createProxyIdentifier('MainThreadAuthentication'), MainThreadBulkEdits: createProxyIdentifier('MainThreadBulkEdits'), + MainThreadChatProvider: createProxyIdentifier('MainThreadChatProvider'), + MainThreadChatSlashCommands: createProxyIdentifier('MainThreadChatSlashCommands'), MainThreadClipboard: createProxyIdentifier('MainThreadClipboard'), MainThreadCommands: createProxyIdentifier('MainThreadCommands'), MainThreadComments: createProxyIdentifier('MainThreadComments'), @@ -2635,6 +2659,8 @@ export const ExtHostContext = { ExtHostInteractive: createProxyIdentifier('ExtHostInteractive'), ExtHostInlineChat: createProxyIdentifier('ExtHostInlineChatShape'), ExtHostChat: createProxyIdentifier('ExtHostChat'), + ExtHostChatSlashCommands: createProxyIdentifier('ExtHostChatSlashCommands'), + ExtHostChatProvider: createProxyIdentifier('ExtHostChatProvider'), ExtHostSemanticSimilarity: createProxyIdentifier('ExtHostSemanticSimilarity'), ExtHostTheming: createProxyIdentifier('ExtHostTheming'), ExtHostTunnelService: createProxyIdentifier('ExtHostTunnelService'), diff --git a/src/vs/workbench/api/common/extHostChatProvider.ts b/src/vs/workbench/api/common/extHostChatProvider.ts new file mode 100644 index 0000000000000..067cba16aca6b --- /dev/null +++ b/src/vs/workbench/api/common/extHostChatProvider.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { ILogService } from 'vs/platform/log/common/log'; +import { ExtHostChatProviderShape, IMainContext, MainContext, MainThreadChatProviderShape } from 'vs/workbench/api/common/extHost.protocol'; +import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters'; +import type * as vscode from 'vscode'; +import { Progress } from 'vs/platform/progress/common/progress'; +import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; + + +type ProviderData = { + readonly extension: ExtensionIdentifier; + readonly provider: vscode.ChatResponseProvider; +}; + + +export class ExtHostChatProvider implements ExtHostChatProviderShape { + + private static _idPool = 1; + + private readonly _proxy: MainThreadChatProviderShape; + private readonly _providers = new Map(); + + constructor( + mainContext: IMainContext, + private readonly _logService: ILogService, + ) { + this._proxy = mainContext.getProxy(MainContext.MainThreadChatProvider); + } + + all() { + return Array.from(this._providers.values(), v => v.provider); + } + + registerProvider(extension: ExtensionIdentifier, provider: vscode.ChatResponseProvider, metadata: vscode.ChatResponseProviderMetadata): IDisposable { + + const handle = ExtHostChatProvider._idPool++; + this._providers.set(handle, { extension, provider }); + this._proxy.$registerProvider(handle, { extension, displayName: metadata.name ?? extension.value }); + + return toDisposable(() => { + this._proxy.$unregisterProvider(handle); + this._providers.delete(handle); + }); + } + + async $provideChatResponse(handle: number, requestId: number, messages: IChatMessage[], options: { [name: string]: any }, token: CancellationToken): Promise { + const data = this._providers.get(handle); + if (!data) { + return; + } + const progress = new Progress(async fragment => { + if (token.isCancellationRequested) { + this._logService.warn(`[CHAT](${data.extension.value}) CANNOT send progress because the REQUEST IS CANCELLED`); + return; + } + await this._proxy.$handleProgressChunk(requestId, { index: fragment.index, part: fragment.part }); + }, { async: true }); + + return data.provider.provideChatResponse(messages.map(typeConvert.ChatMessage.to), options, progress, token); + } + +} diff --git a/src/vs/workbench/api/common/extHostChatSlashCommand.ts b/src/vs/workbench/api/common/extHostChatSlashCommand.ts new file mode 100644 index 0000000000000..49f99bf8d70ad --- /dev/null +++ b/src/vs/workbench/api/common/extHostChatSlashCommand.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ILogService } from 'vs/platform/log/common/log'; +import { ExtHostChatSlashCommandsShape, IMainContext, MainContext, MainThreadChatSlashCommandsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostChatProvider } from 'vs/workbench/api/common/extHostChatProvider'; +import { ChatMessageRole } from 'vs/workbench/api/common/extHostTypes'; +import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters'; +import type * as vscode from 'vscode'; +import { Progress } from 'vs/platform/progress/common/progress'; +import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; + +export class ExtHostChatSlashCommands implements ExtHostChatSlashCommandsShape { + + private static _idPool = 0; + + private readonly _commands = new Map(); + private readonly _proxy: MainThreadChatSlashCommandsShape; + + constructor( + mainContext: IMainContext, + private readonly _extHostChatProvider: ExtHostChatProvider, + private readonly _logService: ILogService, + ) { + this._proxy = mainContext.getProxy(MainContext.MainThreadChatSlashCommands); + } + + registerCommand(extension: ExtensionIdentifier, name: string, command: vscode.SlashCommand): IDisposable { + + const handle = ExtHostChatSlashCommands._idPool++; + this._commands.set(handle, { extension, command }); + this._proxy.$registerCommand(handle, name); + + return toDisposable(() => { + this._proxy.$unregisterCommand(handle); + this._commands.delete(handle); + }); + } + + async $executeCommand(handle: number, requestId: number, prompt: string, context: { history: IChatMessage[] }, token: CancellationToken): Promise { + const data = this._commands.get(handle); + if (!data) { + this._logService.warn(`[CHAT](${handle}) CANNOT execute command because the command is not registered`); + return; + } + + // TODO@jrieken this isn't proper, instead the code should call to the renderer which + // coordinates and picks the right provider + const provider = this._extHostChatProvider.all()[0]; + if (!provider) { + this._logService.warn(`[CHAT](${handle}) CANNOT execute command because there is no provider`); + return; + } + + await data.command( + provider, + { role: ChatMessageRole.User, content: prompt }, + { history: context.history.map(typeConvert.ChatMessage.to) }, + new Progress(p => { + this._proxy.$handleProgressChunk(requestId, { value: p.message.value }); + }), + token + ); + } +} diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index a4fa2e9340b5e..6eeecf18669c9 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -44,6 +44,7 @@ import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGro import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import type * as vscode from 'vscode'; import * as types from './extHostTypes'; +import * as chatProvider from 'vs/workbench/contrib/chat/common/chatProvider'; export namespace Command { @@ -2155,3 +2156,23 @@ export namespace ChatFollowup { } } } + +export namespace ChatMessage { + export function to(message: chatProvider.IChatMessage): vscode.ChatMessage { + const res = new types.ChatMessage(ChatMessageRole.to(message.role), message.content); + res.name = message.name; + return res; + } +} + +export namespace ChatMessageRole { + + export function to(role: chatProvider.ChatMessageRole): vscode.ChatMessageRole { + switch (role) { + case chatProvider.ChatMessageRole.System: return types.ChatMessageRole.System; + case chatProvider.ChatMessageRole.User: return types.ChatMessageRole.User; + case chatProvider.ChatMessageRole.Assistant: return types.ChatMessageRole.Assistant; + case chatProvider.ChatMessageRole.Function: return types.ChatMessageRole.Function; + } + } +} diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 2647d41c5db3e..79eb3f08b260a 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -4095,4 +4095,23 @@ export enum InteractiveEditorResponseFeedbackKind { Undone = 2 } +export enum ChatMessageRole { + System = 0, + User = 1, + Assistant = 2, + Function = 3, +} + +export class ChatMessage implements vscode.ChatMessage { + + role: ChatMessageRole; + content: string; + name?: string; + + constructor(role: ChatMessageRole, content: string) { + this.role = role; + this.content = content; + } +} + //#endregion diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 656485ed70a90..6fe1558dcf553 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -44,6 +44,8 @@ import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatCo import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { QuickQuestionMode } from 'vs/workbench/contrib/chat/browser/actions/quickQuestionActions/quickQuestionAction'; +import { ChatProviderService, IChatProviderService } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { ChatSlashCommandService, IChatSlashCommandService } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; // Register configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -201,4 +203,5 @@ registerSingleton(IChatContributionService, ChatContributionService, Instantiati registerSingleton(IChatWidgetService, ChatWidgetService, InstantiationType.Delayed); registerSingleton(IChatAccessibilityService, ChatAccessibilityService, InstantiationType.Delayed); registerSingleton(IChatWidgetHistoryService, ChatWidgetHistoryService, InstantiationType.Delayed); - +registerSingleton(IChatProviderService, ChatProviderService, InstantiationType.Delayed); +registerSingleton(IChatSlashCommandService, ChatSlashCommandService, InstantiationType.Delayed); diff --git a/src/vs/workbench/contrib/chat/common/chatProvider.ts b/src/vs/workbench/contrib/chat/common/chatProvider.ts new file mode 100644 index 0000000000000..8ed47816d7e95 --- /dev/null +++ b/src/vs/workbench/contrib/chat/common/chatProvider.ts @@ -0,0 +1,68 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IProgress } from 'vs/platform/progress/common/progress'; + +export const enum ChatMessageRole { + System, + User, + Assistant, + Function, +} + +export interface IChatMessage { + readonly role: ChatMessageRole; + readonly content: string; + readonly name?: string; +} + +export interface IChatResponseFragment { + index: number; + part: string; +} + +export interface IChatResponseProviderMetadata { + readonly extension: ExtensionIdentifier; + readonly displayName: string; + readonly description?: string; +} + +export interface IChatResponseProvider { + metadata: IChatResponseProviderMetadata; + provideChatResponse(messages: IChatMessage[], options: { [name: string]: any }, progress: IProgress, token: CancellationToken): Thenable; +} + +export const IChatProviderService = createDecorator('chatProviderService'); + +export interface IChatProviderService { + + readonly _serviceBrand: undefined; + + registerChatResponseProvider(provider: IChatResponseProvider): IDisposable; + getAllProviders(): Iterable; +} + +export class ChatProviderService implements IChatProviderService { + readonly _serviceBrand: undefined; + + private readonly _providers: Set = new Set(); + + registerChatResponseProvider(provider: IChatResponseProvider): IDisposable { + this._providers.add(provider); + return { + dispose: () => { + this._providers.delete(provider); + } + }; + } + + getAllProviders(): Iterable { + return this._providers; + } +} diff --git a/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts b/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts new file mode 100644 index 0000000000000..651cf22126dc7 --- /dev/null +++ b/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts @@ -0,0 +1,236 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { Iterable } from 'vs/base/common/iterator'; +import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { localize } from 'vs/nls'; +import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { ServicesAccessor, createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IProgress, IProgressService, Progress, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { ChatMessageRole, IChatMessage, IChatProviderService, IChatResponseFragment } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { IExtensionService, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; + +//#region extension point + +const slashItem: IJSONSchema = { + type: 'object', + required: ['name', 'detail'], + properties: { + name: { + type: 'string', + markdownDescription: localize('name', "The name of the slash command which will be used as prefix.") + }, + detail: { + type: 'string', + markdownDescription: localize('details', "The details of the slash command.") + }, + } +}; + +const slashItems: IJSONSchema = { + description: localize('vscode.extension.contributes.slashes', "Contributes slash commands to chat"), + oneOf: [ + slashItem, + { + type: 'array', + items: slashItem + } + ] +}; + +export const slashesExtPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'slashes', + jsonSchema: slashItems +}); + +//#region slash service, commands etc + +export interface IChatSlashData { + id: string; + name: string; + detail: string; +} + +export interface IChatSlashFragment { + value: string; +} + +export type IChatSlashCallback = { (prompt: string, progress: IProgress, history: IChatMessage[], token: CancellationToken): Promise }; + +export const IChatSlashCommandService = createDecorator('chatSlashCommandService'); + +export interface IChatSlashCommandService { + _serviceBrand: undefined; + registerSlashData(data: IChatSlashData): IDisposable; + registerSlashCallback(id: string, command: IChatSlashCallback): IDisposable; + executeCommand(id: string, prompt: string, progress: IProgress, history: IChatMessage[], token: CancellationToken): Promise; + getCommands(): Array; +} + +type Tuple = { data: IChatSlashData; command?: IChatSlashCallback }; + +export class ChatSlashCommandService implements IChatSlashCommandService { + + declare _serviceBrand: undefined; + + private readonly _commands = new Map(); + + constructor(@IExtensionService private readonly _extensionService: IExtensionService) { + + const contributions = new DisposableStore(); + + slashesExtPoint.setHandler(extensions => { + contributions.clear(); + + for (const entry of extensions) { + if (!isProposedApiEnabled(entry.description, 'chatSlashCommands')) { + entry.collector.error(`The ${slashesExtPoint.name} is proposed API`); + continue; + } + + const { value } = entry; + + for (const candidate of Iterable.wrap(value)) { + contributions.add(this.registerSlashData({ ...candidate, id: candidate.name })); + } + } + }); + } + + dispose(): void { + this._commands.clear(); + } + + registerSlashData(data: IChatSlashData): IDisposable { + if (this._commands.has(data.id)) { + throw new Error(`Already registered a command with id ${data.id}}`); + } + this._commands.set(data.id, { data }); + return toDisposable(() => this._commands.delete(data.id)); + } + + registerSlashCallback(id: string, command: IChatSlashCallback): IDisposable { + const data = this._commands.get(id); + if (!data) { + throw new Error(`No command with id ${id} registered`); + } + data.command = command; + return toDisposable(() => data.command = undefined); + } + + getCommands(): Array { + return Array.from(this._commands.values(), v => v.data); + } + + async executeCommand(id: string, prompt: string, progress: IProgress, history: IChatMessage[], token: CancellationToken): Promise { + const data = this._commands.get(id); + if (!data) { + throw new Error('No command with id ${id} NOT registered'); + } + if (!data.command) { + await this._extensionService.activateByEvent(`onSlash:${id}`); + } + if (!data.command) { + throw new Error(`No command with id ${id} NOT resolved`); + } + + await data.command(prompt, progress, history, token); + } +} + + + + +// --- debug + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'chatbot.helloWorld', + title: 'Hello World', + category: 'Chatbot', + menu: { id: MenuId.CommandPalette } + }); + } + + override async run(accessor: ServicesAccessor, ...args: any[]): Promise { + const chatProvider = accessor.get(IChatProviderService); + + for (const provider of chatProvider.getAllProviders()) { + + const p = new Progress(value => { + console.log(provider.metadata.displayName, value); + }); + + await provider.provideChatResponse([{ role: ChatMessageRole.User, content: 'Hello.' }], { n: 2 }, p, CancellationToken.None); + } + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'chatbot.helloWorld', + title: 'Slashes for the Masses', + category: 'Chatbot', + menu: { id: MenuId.CommandPalette } + }); + } + + override async run(accessor: ServicesAccessor, ...args: any[]): Promise { + const quickPick = accessor.get(IQuickInputService); + const slashCommandService = accessor.get(IChatSlashCommandService); + const progress = accessor.get(IProgressService); + + const items: (IQuickPickItem & { cmd: IChatSlashData })[] = []; + for (const cmd of slashCommandService.getCommands()) { + items.push({ + cmd, + label: cmd.name, + detail: cmd.detail + }); + } + + const pick = await quickPick.pick(items, { placeHolder: 'Pick a command' }); + + if (!pick) { + return; + } + + const value = `/${pick.cmd.name} `; + const prompt = await quickPick.input({ value: value, valueSelection: [value.length, value.length], placeHolder: 'Enter a prompt' }); + + if (!prompt) { + return; + } + + const cts = new CancellationTokenSource(); + + progress.withProgress({ + location: ProgressLocation.Notification, + title: `${prompt}`, + cancellable: true, + }, async p => { + + const task = slashCommandService.executeCommand( + pick.cmd.id, + prompt, + new Progress(value => { + p.report({ message: value.value }); + console.log(value); + }), + [], + cts.token + ); + + await task; + }, () => cts.cancel()); + + } +}); diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 98f89dca7086b..448a524e212b9 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -9,6 +9,8 @@ export const allApiProposals = Object.freeze({ authGetSessions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authGetSessions.d.ts', authSession: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts', canonicalUriProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts', + chatProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatProvider.d.ts', + chatSlashCommands: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatSlashCommands.d.ts', codiconDecoration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts', commentsDraftState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts', contribCommentEditorActionsMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts', diff --git a/src/vscode-dts/vscode.proposed.chatProvider.d.ts b/src/vscode-dts/vscode.proposed.chatProvider.d.ts new file mode 100644 index 0000000000000..e5edcafe90df7 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.chatProvider.d.ts @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + export enum ChatMessageRole { + System = 0, + User = 1, + Assistant = 2, + Function = 3, + } + + export class ChatMessage { + role: ChatMessageRole; + content: string; + name?: string; + + constructor(role: ChatMessageRole, content: string); + } + + // TODO: chat response builder + export interface ChatResponse { + message: ChatMessage; + } + + export interface ChatResponseFragment { + index: number; + part: string; + } + + export interface ChatResponseProvider { + provideChatResponse(messages: ChatMessage[], options: { [name: string]: any }, progress: Progress, token: CancellationToken): Thenable; + } + + export interface ChatResponseProviderMetadata { + // TODO: add way to compute token count + name: string; + } + + export namespace llm { + export function registerChatResponseProvider(provider: ChatResponseProvider, metadata: ChatResponseProviderMetadata): Disposable; + } + +} diff --git a/src/vscode-dts/vscode.proposed.chatSlashCommands.d.ts b/src/vscode-dts/vscode.proposed.chatSlashCommands.d.ts new file mode 100644 index 0000000000000..487b458a5c7ba --- /dev/null +++ b/src/vscode-dts/vscode.proposed.chatSlashCommands.d.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + export interface SlashCommandContext { + + // messages so far + history: ChatMessage[]; + + // TODO: access to embeddings + // embeddings: {}; + + // TODO: access to "InputSourceId" + // DebugConsoleOutput + // Terminal + // CorrespondingTestFile + // CorrespondingImplementationFile + // ExtensionApi + // VSCode + // Workspace + } + + export interface SlashResponse { + message: MarkdownString; + // edits?: TextEdit[] | WorkspaceEdit; + } + + export interface SlashResult { + followUp?: InteractiveSessionFollowup[]; + } + + export interface SlashCommand { + + // TODO: Progress vs AsyncIterable + // CONSUMER of chat + (chat: ChatResponseProvider, prompt: ChatMessage, context: SlashCommandContext, progress: Progress, token: CancellationToken): Thenable; + } + + export namespace llm { + export function registerSlashCommand(name: string, command: SlashCommand): Disposable; + } +} From 6bff31c75f8d4ebebf384da9c2dcbabdec4bc4b1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 14 Jul 2023 17:50:20 +0200 Subject: [PATCH 0130/1180] More feedback (#187934) * #156144 More feedback * :lipstick: * add telemetry --- .../platform/quickinput/browser/quickInput.ts | 3 +- .../media/userDataProfileCreateWidget.css | 28 ++ .../browser/userDataProfile.ts | 349 ++++++++---------- .../userDataProfileImportExportService.ts | 46 +-- .../userDataProfile/common/userDataProfile.ts | 5 +- 5 files changed, 204 insertions(+), 227 deletions(-) create mode 100644 src/vs/workbench/contrib/userDataProfile/browser/media/userDataProfileCreateWidget.css diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index f9829e3d98f77..c8158ad9b50d7 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -1326,7 +1326,6 @@ export class QuickInputController extends Disposable { rightActionBar.domNode.classList.add('quick-input-right-action-bar'); const headerContainer = dom.append(container, $('.quick-input-header')); - const description1 = dom.append(container, $('.quick-input-description')); const checkAll = dom.append(headerContainer, $('input.quick-input-check-all')); checkAll.type = 'checkbox'; @@ -1379,6 +1378,8 @@ export class QuickInputController extends Disposable { const widget = dom.append(container, $('.quick-input-html-widget')); widget.tabIndex = -1; + const description1 = dom.append(container, $('.quick-input-description')); + const listId = this.idPrefix + 'list'; const list = this._register(new QuickInputList(container, listId, this.options)); inputBox.setAttribute('aria-controls', listId); diff --git a/src/vs/workbench/contrib/userDataProfile/browser/media/userDataProfileCreateWidget.css b/src/vs/workbench/contrib/userDataProfile/browser/media/userDataProfileCreateWidget.css new file mode 100644 index 0000000000000..899cf1a074a4c --- /dev/null +++ b/src/vs/workbench/contrib/userDataProfile/browser/media/userDataProfileCreateWidget.css @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.profile-type-widget { + display: flex; + margin: 0px 6px 8px 11px; + align-items: center; + justify-content: space-between; + font-size: 12px; +} + +.profile-type-widget>.profile-type-select-container { + overflow: hidden; + padding-left: 10px; + flex: 1; + display: flex; + align-items: center; + justify-content: center; +} + +.profile-type-widget>.profile-type-select-container>.monaco-select-box { + cursor: pointer; + line-height: 17px; + padding: 2px 23px 2px 8px; + border-radius: 2px; +} diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 9b2002bdfe2a4..3c8e7b62c303e 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -3,20 +3,19 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import 'vs/css!./media/userDataProfileCreateWidget'; import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; import { Action2, IMenuService, ISubmenuItem, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; -import { ICommandService } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IUserDataProfile, IUserDataProfilesService, ProfileResourceType, UseDefaultProfileFlags } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { RenameProfileAction } from 'vs/workbench/contrib/userDataProfile/browser/userDataProfileActions'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { CURRENT_PROFILE_CONTEXT, HAS_PROFILES_CONTEXT, IS_CURRENT_PROFILE_TRANSIENT_CONTEXT, IS_PROFILE_IMPORT_IN_PROGRESS_CONTEXT, IUserDataProfileImportExportService, IUserDataProfileManagementService, IUserDataProfileService, PROFILES_CATEGORY, PROFILE_FILTER, IS_PROFILE_EXPORT_IN_PROGRESS_CONTEXT, ProfilesMenu, PROFILES_ENABLEMENT_CONTEXT, PROFILES_TITLE } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; -import { IQuickInputService, IQuickPickItem, QuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { URI } from 'vs/base/common/uri'; @@ -31,32 +30,18 @@ import { IRequestService, asJson } from 'vs/platform/request/common/request'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ILogService } from 'vs/platform/log/common/log'; import Severity from 'vs/base/common/severity'; - -const CREATE_EMPTY_PROFILE_ACTION_ID = 'workbench.profiles.actions.createEmptyProfile'; -const CREATE_EMPTY_PROFILE_ACTION_TITLE = { - value: localize('create empty profile', "Create an Empty Profile..."), - original: 'Create an Empty Profile...' -}; - -const CREATE_FROM_CURRENT_PROFILE_ACTION_ID = 'workbench.profiles.actions.createFromCurrentProfile'; -const CREATE_FROM_CURRENT_PROFILE_ACTION_TITLE = { - value: localize('save profile as', "Save Current Profile As..."), - original: 'Save Current Profile As...' -}; - -const CREATE_NEW_PROFILE_ACTION_ID = 'workbench.profiles.actions.createNewProfile'; -const CREATE_NEW_PROFILE_ACTION_TITLE = { - value: localize('create new profile', "Create New Profile..."), - original: 'Create New Profile...' -}; +import { $, append } from 'vs/base/browser/dom'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { defaultSelectBoxStyles } from 'vs/platform/theme/browser/defaultStyles'; +import { isString } from 'vs/base/common/types'; interface IProfileTemplateInfo { readonly name: string; readonly url: string; } -type IProfileTemplateQuickPickItem = IQuickPickItem & IProfileTemplateInfo; - export class UserDataProfilesWorkbenchContribution extends Disposable implements IWorkbenchContribution { private readonly currentProfileContext: IContextKey; @@ -77,6 +62,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements @ILifecycleService private readonly lifecycleService: ILifecycleService, @IProductService private readonly productService: IProductService, @IRequestService private readonly requestService: IRequestService, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IContextViewService private readonly contextViewService: IContextViewService, @ILogService private readonly logService: ILogService, ) { super(); @@ -115,9 +102,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements this.registerCurrentProfilesActions(); this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => this.registerCurrentProfilesActions())); - this.registerCreateEmptyProfileAction(); this.registerCreateFromCurrentProfileAction(); - this.registerCreateNewProfileAction(); this.registerCreateProfileAction(); this.registerDeleteProfileAction(); @@ -214,21 +199,21 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements private readonly currentprofileActionsDisposable = this._register(new MutableDisposable()); private registerCurrentProfilesActions(): void { this.currentprofileActionsDisposable.value = new DisposableStore(); - this.currentprofileActionsDisposable.value.add(this.registerRenameCurrentProfileAction()); + this.currentprofileActionsDisposable.value.add(this.registerEditCurrentProfileAction()); this.currentprofileActionsDisposable.value.add(this.registerShowCurrentProfileContentsAction()); this.currentprofileActionsDisposable.value.add(this.registerExportCurrentProfileAction()); this.currentprofileActionsDisposable.value.add(this.registerImportProfileAction()); } - private registerRenameCurrentProfileAction(): IDisposable { + private registerEditCurrentProfileAction(): IDisposable { const that = this; return registerAction2(class RenameCurrentProfileAction extends Action2 { constructor() { super({ - id: `workbench.profiles.actions.renameCurrentProfile`, + id: `workbench.profiles.actions.editCurrentProfile`, title: { - value: localize('rename profile', "Rename..."), - original: `Rename...` + value: localize('edit profile', "Edit..."), + original: `Edit...` }, menu: [ { @@ -240,8 +225,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements ] }); } - async run(accessor: ServicesAccessor) { - accessor.get(ICommandService).executeCommand(RenameProfileAction.ID, that.userDataProfileService.currentProfile); + run() { + return that.saveProfile(that.userDataProfileService.currentProfile); } }); } @@ -413,46 +398,11 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements this._register(registerAction2(class CreateFromCurrentProfileAction extends Action2 { constructor() { super({ - id: CREATE_FROM_CURRENT_PROFILE_ACTION_ID, - title: CREATE_FROM_CURRENT_PROFILE_ACTION_TITLE, - category: PROFILES_CATEGORY, - f1: true, - precondition: PROFILES_ENABLEMENT_CONTEXT - }); - } - - run(accessor: ServicesAccessor) { - return that.createFromCurrentProfile(); - } - })); - } - - private registerCreateNewProfileAction(): void { - const that = this; - this._register(registerAction2(class CreateFromCurrentProfileAction extends Action2 { - constructor() { - super({ - id: CREATE_NEW_PROFILE_ACTION_ID, - title: CREATE_NEW_PROFILE_ACTION_TITLE, - category: PROFILES_CATEGORY, - f1: true, - precondition: PROFILES_ENABLEMENT_CONTEXT - }); - } - - run() { - return that.createNewProfile(); - } - })); - } - - private registerCreateEmptyProfileAction(): void { - const that = this; - this._register(registerAction2(class CreateEmptyProfileAction extends Action2 { - constructor() { - super({ - id: CREATE_EMPTY_PROFILE_ACTION_ID, - title: CREATE_EMPTY_PROFILE_ACTION_TITLE, + id: 'workbench.profiles.actions.createFromCurrentProfile', + title: { + value: localize('save profile as', "Save Current Profile As..."), + original: 'Save Current Profile As...' + }, category: PROFILES_CATEGORY, f1: true, precondition: PROFILES_ENABLEMENT_CONTEXT @@ -460,48 +410,35 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements } run(accessor: ServicesAccessor) { - return that.createEmptyProfile(); + return that.saveProfile(undefined, that.userDataProfileService.currentProfile); } })); } - private async createEmptyProfile(): Promise { - const name = await this.getNameForProfile(localize('create empty profile', "Create an Empty Profile...")); - if (!name) { - return; - } - try { - await this.userDataProfileManagementService.createAndEnterProfile(name, undefined); - } catch (error) { - this.notificationService.error(error); - } - } + private async saveProfile(profile: IUserDataProfile): Promise; + private async saveProfile(profile?: IUserDataProfile, source?: IUserDataProfile | string): Promise; + private async saveProfile(profile?: IUserDataProfile, source?: IUserDataProfile | string): Promise { - private async createFromCurrentProfile(): Promise { - const name = await this.getNameForProfile(localize('create from current profle', "Create from Current Profile...")); - if (!name) { - return; - } - try { - await this.userDataProfileImportExportService.SaveCurrentProfileAs(name); - } catch (error) { - this.notificationService.error(error); - } - } + type CreateProfileInfoClassification = { + owner: 'sandy081'; + comment: 'Report when profile is about to be created'; + }; + this.telemetryService.publicLog2<{}, CreateProfileInfoClassification>('userDataProfile.startCreate'); - private async createNewProfile(): Promise { - const title = localize('create new profle', "Create New Profile..."); + const disposables = new DisposableStore(); + const title = profile ? localize('save profile', "Edit Profile...") : localize('create new profle', "Create New Profile..."); - const settings: IQuickPickItem = { id: ProfileResourceType.Settings, label: localize('settings', "Settings"), picked: true }; - const keybindings: IQuickPickItem = { id: ProfileResourceType.Keybindings, label: localize('keybindings', "Keyboard Shortcuts"), picked: true }; - const snippets: IQuickPickItem = { id: ProfileResourceType.Snippets, label: localize('snippets', "User Snippets"), picked: true }; - const tasks: IQuickPickItem = { id: ProfileResourceType.Tasks, label: localize('tasks', "User Tasks"), picked: true }; - const extensions: IQuickPickItem = { id: ProfileResourceType.Extensions, label: localize('extensions', "Extensions"), picked: true }; + const settings: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Settings, label: localize('settings', "Settings"), picked: profile?.useDefaultFlags?.settings }; + const keybindings: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Keybindings, label: localize('keybindings', "Keyboard Shortcuts"), picked: profile?.useDefaultFlags?.keybindings }; + const snippets: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Snippets, label: localize('snippets', "User Snippets"), picked: profile?.useDefaultFlags?.snippets }; + const tasks: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Tasks, label: localize('tasks', "User Tasks"), picked: profile?.useDefaultFlags?.tasks }; + const extensions: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Extensions, label: localize('extensions', "Extensions"), picked: profile?.useDefaultFlags?.extensions }; const resources = [settings, keybindings, snippets, tasks, extensions]; const quickPick = this.quickInputService.createQuickPick(); quickPick.title = title; - quickPick.placeholder = localize('name placeholder', "Name the new profile"); + quickPick.placeholder = localize('name placeholder', "Profile name"); + quickPick.value = profile?.name ?? ''; quickPick.canSelectMany = true; quickPick.matchOnDescription = false; quickPick.matchOnDetail = false; @@ -512,42 +449,109 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements quickPick.customButton = true; quickPick.hideCheckAll = true; quickPick.ignoreFocusOut = true; - quickPick.customLabel = localize('create', "Create Profile"); - quickPick.description = localize('customise the profile', "Choose what to configure in the profile. Unselected items are shared from the default profile."); - quickPick.items = resources; - quickPick.selectedItems = resources.filter(item => item.picked); + quickPick.customLabel = profile ? localize('save', "Save") : localize('create', "Create"); + quickPick.description = localize('customise the profile', "Select configurations to share from the Default profile:"); + quickPick.items = [...resources]; + + const updateSelection = () => { + quickPick.selectedItems = resources.filter(item => item.picked); + }; + updateSelection(); + + const validate = () => { + if (!profile && this.userDataProfilesService.profiles.some(p => p.name === quickPick.value)) { + quickPick.validationMessage = localize('profileExists', "Profile with name {0} already exists.", quickPick.value); + quickPick.severity = Severity.Error; + return; + } + if (resources.every(resource => resource.picked)) { + quickPick.validationMessage = localize('cannot share all', "Cannot share all configurations from the Default Profile."); + quickPick.severity = Severity.Error; + return; + } + quickPick.severity = Severity.Ignore; + quickPick.validationMessage = undefined; + }; - const disposables = new DisposableStore(); disposables.add(quickPick.onDidChangeSelection(items => { for (const resource of resources) { resource.picked = items.includes(resource); } + validate(); })); - disposables.add(quickPick.onDidChangeValue(value => { - if (this.userDataProfilesService.profiles.some(p => p.name === value)) { - quickPick.validationMessage = localize('profileExists', "Profile with name {0} already exists.", value); - quickPick.severity = Severity.Error; - } else { - quickPick.severity = Severity.Ignore; - quickPick.validationMessage = undefined; - } - })); + disposables.add(quickPick.onDidChangeValue(validate)); let result: { name: string; items: ReadonlyArray } | undefined; - disposables.add(quickPick.onDidCustom(async () => { + disposables.add(Event.any(quickPick.onDidCustom, quickPick.onDidAccept)(() => { if (!quickPick.value) { quickPick.validationMessage = localize('name required', "Provide a name for the new profile"); quickPick.severity = Severity.Error; - return; } - if (resources.some(resource => quickPick.selectedItems.includes(resource))) { - result = { name: quickPick.value, items: quickPick.selectedItems }; - quickPick.hide(); + if (quickPick.validationMessage) { + return; } + result = { name: quickPick.value, items: quickPick.selectedItems }; + quickPick.hide(); quickPick.severity = Severity.Ignore; quickPick.validationMessage = undefined; })); + + if (!profile) { + const domNode = $('.profile-type-widget'); + append(domNode, $('.profile-type-create-label', undefined, localize('create from', "Copy from:"))); + const separator = { text: '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500', isDisabled: true }; + const profileOptions: (ISelectOptionItem & { id?: string; source?: IUserDataProfile | string })[] = []; + profileOptions.push({ text: localize('empty profile', "None") }); + const templates = await this.getProfileTemplatesFromProduct(); + if (templates.length) { + profileOptions.push({ ...separator, decoratorRight: localize('from templates', "Profile Templates") }); + for (const template of templates) { + profileOptions.push({ text: template.name, id: template.url, source: template.url }); + } + } + profileOptions.push({ ...separator, decoratorRight: localize('from existing profiles', "Existing Profiles") }); + for (const profile of this.userDataProfilesService.profiles) { + profileOptions.push({ text: profile.name, id: profile.id, source: profile }); + } + + const findOptionIndex = () => { + const index = profileOptions.findIndex(option => { + if (isString(source)) { + return option.id === source; + } else if (source) { + return option.id === source.id; + } + return false; + }); + return index > -1 ? index : 0; + }; + + const selectBox = disposables.add(this.instantiationService.createInstance(SelectBox, profileOptions, findOptionIndex(), this.contextViewService, defaultSelectBoxStyles, { useCustomDrawn: true })); + selectBox.render(append(domNode, $('.profile-type-select-container'))); + quickPick.widget = domNode; + + const updateOptions = () => { + const index = findOptionIndex(); + if (index <= 0) { + return; + } + const option = profileOptions[index]; + if (!isString(option.source)) { + for (const resource of resources) { + resource.picked = option.source?.useDefaultFlags?.[resource.id]; + } + updateSelection(); + } + }; + + updateOptions(); + disposables.add(selectBox.onDidSelect(({ index }) => { + source = profileOptions[index].source; + updateOptions(); + })); + } + quickPick.show(); await new Promise((c, e) => { @@ -558,37 +562,36 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements }); if (!result) { + this.telemetryService.publicLog2<{}, CreateProfileInfoClassification>('userDataProfile.cancelCreate'); return; } - const { name, items } = result; + this.telemetryService.publicLog2<{}, CreateProfileInfoClassification>('userDataProfile.successCreate'); + try { - const useDefaultFlags: UseDefaultProfileFlags | undefined = items.length !== resources.length ? { - settings: !items.includes(settings), - keybindings: !items.includes(keybindings), - snippets: !items.includes(snippets), - tasks: !items.includes(tasks), - extensions: !items.includes(extensions) + const useDefaultFlags: UseDefaultProfileFlags | undefined = result.items.length ? { + settings: result.items.includes(settings), + keybindings: result.items.includes(keybindings), + snippets: result.items.includes(snippets), + tasks: result.items.includes(tasks), + extensions: result.items.includes(extensions) } : undefined; - await this.userDataProfileManagementService.createAndEnterProfile(name, { useDefaultFlags }); + if (profile) { + await this.userDataProfileManagementService.updateProfile(profile, { name: result.name, useDefaultFlags }); + } else { + if (isString(source)) { + await this.userDataProfileImportExportService.importProfile(URI.parse(source), { mode: 'apply', name: result.name, useDefaultFlags }); + } else if (source) { + await this.userDataProfileImportExportService.createFromProfile(source, result.name, { useDefaultFlags }); + } else { + await this.userDataProfileManagementService.createAndEnterProfile(result.name, { useDefaultFlags }); + } + } } catch (error) { this.notificationService.error(error); } } - private async getNameForProfile(title: string): Promise { - return this.quickInputService.input({ - placeHolder: localize('name', "Profile name"), - title, - validateInput: async (value: string) => { - if (this.userDataProfilesService.profiles.some(p => p.name === value)) { - return localize('profileExists', "Profile with name {0} already exists.", value); - } - return undefined; - } - }); - } - private registerCreateProfileAction(): void { const that = this; this._register(registerAction2(class CreateProfileAction extends Action2 { @@ -601,6 +604,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements }, category: PROFILES_CATEGORY, precondition: PROFILES_ENABLEMENT_CONTEXT, + f1: true, menu: [ { id: ProfilesMenu, @@ -613,52 +617,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements } async run(accessor: ServicesAccessor) { - const quickInputService = accessor.get(IQuickInputService); - const commandService = accessor.get(ICommandService); - const userDataProfileImportExportService = accessor.get(IUserDataProfileImportExportService); - const quickPickItems: QuickPickItem[] = [{ - id: CREATE_EMPTY_PROFILE_ACTION_ID, - label: localize('empty profile', "Empty Profile..."), - }, { - id: CREATE_NEW_PROFILE_ACTION_ID, - label: localize('new profile', "New Profile..."), - }, { - type: 'separator', - }, { - id: CREATE_FROM_CURRENT_PROFILE_ACTION_ID, - label: localize('using current', "Save Current Profile As..."), - }]; - const profileTemplateQuickPickItems = await that.getProfileTemplatesQuickPickItems(); - if (profileTemplateQuickPickItems.length) { - quickPickItems.push({ - type: 'separator', - label: localize('templates', "Profile Templates") - }, ...profileTemplateQuickPickItems); - } - const pick = await quickInputService.pick(quickPickItems, - { - hideInput: true, - canPickMany: false, - title: localize('create profile title', "Create Profile...") - }); - if (pick) { - if (pick.id) { - return commandService.executeCommand(pick.id); - } - if ((pick).url) { - type ProfileCreationFromTemplateActionClassification = { - owner: 'sandy081'; - comment: 'Report profile creation from template action'; - profileName: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Name of the profile created from template' }; - }; - type ProfileCreationFromTemplateActionEvent = { - profileName: string; - }; - that.telemetryService.publicLog2('profileCreationAction:builtinTemplate', { profileName: (pick).name }); - const uri = URI.parse((pick).url); - return userDataProfileImportExportService.importProfile(uri, { mode: 'apply' }); - } - } + return that.saveProfile(); } })); } @@ -736,18 +695,6 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements })); } - private async getProfileTemplatesQuickPickItems(): Promise { - const quickPickItems: IProfileTemplateQuickPickItem[] = []; - const profileTemplates = await this.getProfileTemplatesFromProduct(); - for (const template of profileTemplates) { - quickPickItems.push({ - label: template.name, - ...template - }); - } - return quickPickItems; - } - private async getProfileTemplatesFromProduct(): Promise { if (this.productService.profileTemplatesUrl) { try { diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts index 3fe9085063c7d..dbfc7ae2f6e19 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts @@ -18,7 +18,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { IFileService } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { Extensions, ITreeItem, ITreeViewDataProvider, ITreeViewDescriptor, IViewContainersRegistry, IViewDescriptorService, IViewsRegistry, IViewsService, TreeItemCollapsibleState, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; -import { IUserDataProfile, IUserDataProfilesService, ProfileResourceType, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfile, IUserDataProfileOptions, IUserDataProfilesService, ProfileResourceType, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Registry } from 'vs/platform/registry/common/platform'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; @@ -209,11 +209,11 @@ export class UserDataProfileImportExportService extends Disposable implements IU return; } if (mode === 'preview') { - await this.previewProfile(profileTemplate); + await this.previewProfile(profileTemplate, options); } else if (mode === 'apply') { - await this.createAndSwitch(profileTemplate, false, true, localize('create profile', "Create Profile")); + await this.createAndSwitch(profileTemplate, false, true, options, localize('create profile', "Create Profile")); } else if (mode === 'both') { - await this.importAndPreviewProfile(uri, profileTemplate); + await this.importAndPreviewProfile(uri, profileTemplate, options); } } finally { disposables.dispose(); @@ -249,11 +249,11 @@ export class UserDataProfileImportExportService extends Disposable implements IU } } - async SaveCurrentProfileAs(name: string): Promise { - const userDataProfilesExportState = this.instantiationService.createInstance(UserDataProfileExportState, this.userDataProfileService.currentProfile); + async createFromProfile(profile: IUserDataProfile, name: string, options?: IUserDataProfileOptions): Promise { + const userDataProfilesExportState = this.instantiationService.createInstance(UserDataProfileExportState, profile); try { const profileTemplate = await userDataProfilesExportState.getProfileTemplate(name, undefined); - await this.createAndSwitch(profileTemplate, false, true, localize('save profile as', "Save Profile As")); + await this.createAndSwitch(profileTemplate, false, true, options, localize('create profile', "Create Profile")); } finally { userDataProfilesExportState.dispose(); } @@ -269,7 +269,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU sticky: true, }, async progress => { const reportProgress = (message: string) => progress.report({ message: localize('troubleshoot profile progress', "Setting up Troubleshoot Profile: {0}", message) }); - const profile = await this.createProfile(profileTemplate, true, false, reportProgress); + const profile = await this.createProfile(profileTemplate, true, false, { useDefaultFlags: this.userDataProfileService.currentProfile.useDefaultFlags }, reportProgress); if (profile) { reportProgress(localize('progress extensions', "Applying Extensions...")); await this.instantiationService.createInstance(ExtensionsResource).copy(this.userDataProfileService.currentProfile, profile, true); @@ -362,21 +362,21 @@ export class UserDataProfileImportExportService extends Disposable implements IU return profileTemplate; } - private async importAndPreviewProfile(uri: URI, profileTemplate: IUserDataProfileTemplate): Promise { + private async importAndPreviewProfile(uri: URI, profileTemplate: IUserDataProfileTemplate, options: IUserDataProfileOptions | undefined): Promise { const disposables = new DisposableStore(); try { const userDataProfileImportState = disposables.add(this.instantiationService.createInstance(UserDataProfileImportState, profileTemplate)); profileTemplate = await userDataProfileImportState.getProfileTemplateToImport(); - const importedProfile = await this.createAndSwitch(profileTemplate, true, false, localize('preview profile', "Preview Profile")); + const importedProfile = await this.createAndSwitch(profileTemplate, true, false, options, localize('preview profile', "Preview Profile")); if (!importedProfile) { return; } const barrier = new Barrier(); - const importAction = this.getCreateAction(barrier, userDataProfileImportState); + const importAction = this.getCreateAction(barrier, userDataProfileImportState, options); const primaryAction = isWeb ? new Action('importInDesktop', localize('import in desktop', "Create Profile in {0}", this.productService.nameLong), undefined, true, async () => this.openerService.open(uri, { openExternal: true })) : importAction; @@ -435,15 +435,15 @@ export class UserDataProfileImportExportService extends Disposable implements IU } } - private async previewProfile(profileTemplate: IUserDataProfileTemplate): Promise { + private async previewProfile(profileTemplate: IUserDataProfileTemplate, options: IUserDataProfileOptions | undefined): Promise { const disposables = new DisposableStore(); try { const userDataProfileImportState = disposables.add(this.instantiationService.createInstance(UserDataProfileImportState, profileTemplate)); if (userDataProfileImportState.isEmpty()) { - await this.createAndSwitch(profileTemplate, false, true, localize('create profile', "Create Profile")); + await this.createAndSwitch(profileTemplate, false, true, options, localize('create profile', "Create Profile")); } else { const barrier = new Barrier(); - const importAction = this.getCreateAction(barrier, userDataProfileImportState); + const importAction = this.getCreateAction(barrier, userDataProfileImportState, options); await this.showProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW, profileTemplate.name, importAction, new BarrierAction(barrier, new Action('cancel', localize('cancel', "Cancel")), this.notificationService), false, userDataProfileImportState); await barrier.wait(); await this.hideProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW); @@ -453,16 +453,16 @@ export class UserDataProfileImportExportService extends Disposable implements IU } } - private getCreateAction(barrier: Barrier, userDataProfileImportState: UserDataProfileImportState): IAction { + private getCreateAction(barrier: Barrier, userDataProfileImportState: UserDataProfileImportState, options: IUserDataProfileOptions | undefined): IAction { const importAction = new BarrierAction(barrier, new Action('title', localize('import', "Create Profile"), undefined, true, async () => { importAction.enabled = false; const profileTemplate = await userDataProfileImportState.getProfileTemplateToImport(); - return this.createAndSwitch(profileTemplate, false, true, localize('create profile', "Create Profile")); + return this.createAndSwitch(profileTemplate, false, true, options, localize('create profile', "Create Profile")); }), this.notificationService); return importAction; } - private async createAndSwitch(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, title: string): Promise { + private async createAndSwitch(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, options: IUserDataProfileOptions | undefined, title: string): Promise { return this.progressService.withProgress({ location: ProgressLocation.Notification, delay: 500, @@ -471,7 +471,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU title = `${title} (${profileTemplate.name})`; progress.report({ message: title }); const reportProgress = (message: string) => progress.report({ message: `${title}: ${message}` }); - const profile = await this.createProfile(profileTemplate, temporaryProfile, extensions, reportProgress); + const profile = await this.createProfile(profileTemplate, temporaryProfile, extensions, options, reportProgress); if (profile) { reportProgress(localize('switching profile', "Switching Profile...")); await this.userDataProfileManagementService.switchProfile(profile); @@ -480,8 +480,8 @@ export class UserDataProfileImportExportService extends Disposable implements IU }); } - private async createProfile(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, progress: (message: string) => void): Promise { - const profile = await this.getProfileToImport(profileTemplate, temporaryProfile); + private async createProfile(profileTemplate: IUserDataProfileTemplate, temporaryProfile: boolean, extensions: boolean, options: IUserDataProfileOptions | undefined, progress: (message: string) => void): Promise { + const profile = await this.getProfileToImport(profileTemplate, temporaryProfile, options); if (!profile) { return undefined; } @@ -569,12 +569,12 @@ export class UserDataProfileImportExportService extends Disposable implements IU return result?.id; } - private async getProfileToImport(profileTemplate: IUserDataProfileTemplate, temp: boolean): Promise { + private async getProfileToImport(profileTemplate: IUserDataProfileTemplate, temp: boolean, options: IUserDataProfileOptions | undefined): Promise { const profileName = profileTemplate.name; const profile = this.userDataProfilesService.profiles.find(p => p.name === profileName); if (profile) { if (temp) { - return this.userDataProfilesService.createNamedProfile(`${profileName} ${this.getProfileNameIndex(profileName)}`, { shortName: profileTemplate.shortName, transient: temp }); + return this.userDataProfilesService.createNamedProfile(`${profileName} ${this.getProfileNameIndex(profileName)}`, { ...options, shortName: profileTemplate.shortName, transient: temp }); } enum ImportProfileChoice { @@ -625,7 +625,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU } return this.userDataProfilesService.createNamedProfile(name); } else { - return this.userDataProfilesService.createNamedProfile(profileName, { shortName: profileTemplate.shortName, transient: temp }); + return this.userDataProfilesService.createNamedProfile(profileName, { ...options, shortName: profileTemplate.shortName, transient: temp }); } } diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index bd126081ab012..3c56ae564f290 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -73,7 +73,8 @@ export function toUserDataProfileUri(path: string, productService: IProductServi }); } -export interface IProfileImportOptions { +export interface IProfileImportOptions extends IUserDataProfileOptions { + readonly name?: string; readonly mode?: 'preview' | 'apply' | 'both'; } @@ -87,7 +88,7 @@ export interface IUserDataProfileImportExportService { exportProfile(): Promise; importProfile(uri: URI, options?: IProfileImportOptions): Promise; showProfileContents(): Promise; - SaveCurrentProfileAs(name: string): Promise; + createFromProfile(profile: IUserDataProfile, name: string, options?: IUserDataProfileOptions): Promise; createTroubleshootProfile(): Promise; setProfile(profile: IUserDataProfileTemplate): Promise; } From 80b3fcc08deccbbd4e4f844762f905ef78692a8c Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Fri, 14 Jul 2023 09:51:43 -0700 Subject: [PATCH 0131/1180] Notebook Find widget doesn't remove decorations on empty query (#187749) * Notebook Find widget doesn't remove decorations on empty query Fixes #187748 * send empty strings to find --- .../notebook/browser/contrib/find/findModel.ts | 12 +++++------- .../browser/view/renderers/backLayerWebView.ts | 4 ++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts index 1d955dbbcdd94..5c58ffda1bc1f 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts @@ -471,6 +471,9 @@ export class FindModel extends Disposable { } private async _compute(token: CancellationToken): Promise { + if (!this._notebookEditor.hasModel()) { + return null; + } let ret: CellFindMatchWithIndex[] | null = null; const val = this._state.searchString; const wordSeparators = this._configurationService.inspect('editor.wordSeparators').value; @@ -485,13 +488,8 @@ export class FindModel extends Disposable { includeMarkupPreview: !!this._state.filters?.markupPreview, includeOutput: !!this._state.filters?.codeOutput }; - if (!val) { - ret = null; - } else if (!this._notebookEditor.hasModel()) { - ret = null; - } else { - ret = await this._notebookEditor.find(val, options, token); - } + + ret = await this._notebookEditor.find(val, options, token); if (token.isCancellationRequested) { return null; 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 4a3c05451ea31..d45c567c32751 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1610,6 +1610,10 @@ export class BackLayerWebView extends Themable { async find(query: string, options: { wholeWord?: boolean; caseSensitive?: boolean; includeMarkup: boolean; includeOutput: boolean; shouldGetSearchPreviewInfo: boolean; ownerID: string }): Promise { if (query === '') { + this._sendMessageToWebview({ + type: 'findStop', + ownerID: options.ownerID + }); return []; } From b84241ef4cdec078fa22030ec340e4a20e022d1f Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 10:03:05 -0700 Subject: [PATCH 0132/1180] part of #163506 --- .../contrib/codeEditor/browser/outline/documentSymbolsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index 2974894d3ca7e..36d335f61cac6 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -49,7 +49,7 @@ export class DocumentSymbolAccessibilityProvider implements IListAccessibilityPr if (element instanceof OutlineGroup) { return element.label; } else { - return element.symbol.name; + return `${element.symbol.name} Symbol: ${SymbolKinds.toIcon(element.symbol.kind).id.replaceAll('symbol-', '')} `; } } } From bac433ac7b196f4980a9b192a944c9bab5d7477e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 10:12:35 -0700 Subject: [PATCH 0133/1180] make it a function --- src/vs/editor/common/languages.ts | 4 ++++ src/vs/monaco.d.ts | 2 ++ .../contrib/codeEditor/browser/outline/documentSymbolsTree.ts | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index d589e8aa27510..f42c695cc772c 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1189,6 +1189,10 @@ export namespace SymbolKinds { } return icon; } + + export function asAriaLabel(label: string, kind: SymbolKind): string { + return `${label} Symbol: ${SymbolKinds.toIcon(kind).id.replaceAll('symbol-', '')} `; + } } export interface DocumentSymbol { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 770c1268f3af8..4901b152ff25f 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7459,6 +7459,8 @@ declare namespace monaco.languages { Deprecated = 1 } + function asAriaLabel(label: string, kind: SymbolKind): string; + export interface DocumentSymbol { name: string; detail: string; diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index 36d335f61cac6..69680c0af9da8 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -49,7 +49,7 @@ export class DocumentSymbolAccessibilityProvider implements IListAccessibilityPr if (element instanceof OutlineGroup) { return element.label; } else { - return `${element.symbol.name} Symbol: ${SymbolKinds.toIcon(element.symbol.kind).id.replaceAll('symbol-', '')} `; + return SymbolKinds.asAriaLabel(element.symbol.name, element.symbol.kind); } } } From ed7c51f064d483554ea5df4fad253817cf90d0ca Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 10:15:54 -0700 Subject: [PATCH 0134/1180] localize --- .../contrib/codeEditor/browser/outline/documentSymbolsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index 69680c0af9da8..f5d9755eb385e 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -49,7 +49,7 @@ export class DocumentSymbolAccessibilityProvider implements IListAccessibilityPr if (element instanceof OutlineGroup) { return element.label; } else { - return SymbolKinds.asAriaLabel(element.symbol.name, element.symbol.kind); + return localize('document-symbol-aria-label', "{0}", SymbolKinds.asAriaLabel(element.symbol.name, element.symbol.kind)); } } } From 48d1ad43faa2f20a1f1b7693ea9bf1f1cfbb7a83 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 14 Jul 2023 19:18:29 +0200 Subject: [PATCH 0135/1180] Uses diff editor v2 in inline chat. (#187928) --- .../diffEditorWidget2/diffEditorWidget2.ts | 4 ++ .../widget/embeddedCodeEditorWidget.ts | 47 +++++++++++++++++++ .../browser/inlineChatLivePreviewWidget.ts | 4 +- .../inlineChat/browser/inlineChatWidget.ts | 8 ++-- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 1dab8ec750ef5..2e3980aac9292 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -220,6 +220,10 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { })); } + public getContentHeight() { + return this._editors.modified.getContentHeight(); + } + protected _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: Readonly, editorWidgetOptions: ICodeEditorWidgetOptions): CodeEditorWidget { const editor = instantiationService.createInstance(CodeEditorWidget, container, options, editorWidgetOptions); return editor; diff --git a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts index 553470a8494bc..06c449a33eaa0 100644 --- a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts +++ b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts @@ -20,6 +20,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2'; export class EmbeddedCodeEditorWidget extends CodeEditorWidget { @@ -67,6 +68,9 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget { } } +/** + * @deprecated Use EmbeddedDiffEditorWidget2 instead. + */ export class EmbeddedDiffEditorWidget extends DiffEditorWidget { private readonly _parentEditor: ICodeEditor; @@ -111,3 +115,46 @@ export class EmbeddedDiffEditorWidget extends DiffEditorWidget { super.updateOptions(this._overwriteOptions); } } + +/** + * TODO: Rename to EmbeddedDiffEditorWidget once EmbeddedDiffEditorWidget is removed. + */ +export class EmbeddedDiffEditorWidget2 extends DiffEditorWidget2 { + + private readonly _parentEditor: ICodeEditor; + private readonly _overwriteOptions: IDiffEditorOptions; + + constructor( + domElement: HTMLElement, + options: Readonly, + codeEditorWidgetOptions: IDiffCodeEditorWidgetOptions, + parentEditor: ICodeEditor, + @IContextKeyService contextKeyService: IContextKeyService, + @IInstantiationService instantiationService: IInstantiationService, + @ICodeEditorService codeEditorService: ICodeEditorService, + ) { + super(domElement, parentEditor.getRawOptions(), codeEditorWidgetOptions, contextKeyService, instantiationService, codeEditorService); + + this._parentEditor = parentEditor; + this._overwriteOptions = options; + + // Overwrite parent's options + super.updateOptions(this._overwriteOptions); + + this._register(parentEditor.onDidChangeConfiguration(e => this._onParentConfigurationChanged(e))); + } + + getParentEditor(): ICodeEditor { + return this._parentEditor; + } + + private _onParentConfigurationChanged(e: ConfigurationChangedEvent): void { + super.updateOptions(this._parentEditor.getRawOptions()); + super.updateOptions(this._overwriteOptions); + } + + override updateOptions(newOptions: IEditorOptions): void { + objects.mixin(this._overwriteOptions, newOptions, true); + super.updateOptions(this._overwriteOptions); + } +} diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts index 9fd5b51465cd7..3f38c66ae4ea3 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts @@ -7,7 +7,7 @@ import { Dimension, h } from 'vs/base/browser/dom'; import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { assertType } from 'vs/base/common/types'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; -import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; +import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget2 } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { ITextModel } from 'vs/editor/common/model'; @@ -62,7 +62,7 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { .getEditorContributions() .filter(c => c.id !== INLINE_CHAT_ID && c.id !== FoldingController.ID); - this._diffEditor = instantiationService.createInstance(EmbeddedDiffEditorWidget, this._elements.domNode, { + this._diffEditor = instantiationService.createInstance(EmbeddedDiffEditorWidget2, this._elements.domNode, { scrollbar: { useShadows: false, alwaysConsumeMouseWheel: false }, scrollBeyondLastLine: false, renderMarginRevertIcon: true, diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 48165a82036bd..e2c4e8a394e53 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -22,7 +22,7 @@ import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions'; import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2'; import { IModelService } from 'vs/editor/common/services/model'; import { URI } from 'vs/base/common/uri'; -import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; +import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget2 } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { HiddenItemStrategy, MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestController'; @@ -164,7 +164,7 @@ export class InlineChatWidget { private readonly _progressBar: ProgressBar; - private readonly _previewDiffEditor: IdleValue; + private readonly _previewDiffEditor: IdleValue; private readonly _previewDiffModel = this._store.add(new MutableDisposable()); private readonly _previewCreateTitle: ResourceLabel; @@ -329,7 +329,7 @@ export class InlineChatWidget { this._store.add(feedbackToolbar); // preview editors - this._previewDiffEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedDiffEditorWidget, this._elements.previewDiff, _previewEditorEditorOptions, { modifiedEditor: codeEditorWidgetOptions, originalEditor: codeEditorWidgetOptions }, parentEditor))); + this._previewDiffEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedDiffEditorWidget2, this._elements.previewDiff, _previewEditorEditorOptions, { modifiedEditor: codeEditorWidgetOptions, originalEditor: codeEditorWidgetOptions }, parentEditor))); this._previewCreateTitle = this._store.add(_instantiationService.createInstance(ResourceLabel, this._elements.previewCreateTitle, { supportIcons: true })); this._previewCreateEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedCodeEditorWidget, this._elements.previewCreate, _previewEditorEditorOptions, codeEditorWidgetOptions, parentEditor))); @@ -408,7 +408,7 @@ export class InlineChatWidget { const base = getTotalHeight(this._elements.progress) + getTotalHeight(this._elements.status); const editorHeight = this._inputEditor.getContentHeight() + 12 /* padding and border */; const markdownMessageHeight = getTotalHeight(this._elements.markdownMessage); - const previewDiffHeight = this._previewDiffEditor.value.getModel().modified ? 12 + Math.min(300, Math.max(0, this._previewDiffEditor.value.getContentHeight())) : 0; + const previewDiffHeight = this._previewDiffEditor.value.getModel() ? 12 + Math.min(300, Math.max(0, this._previewDiffEditor.value.getContentHeight())) : 0; const previewCreateTitleHeight = getTotalHeight(this._elements.previewCreateTitle); const previewCreateHeight = this._previewCreateEditor.value.getModel() ? 18 + Math.min(300, Math.max(0, this._previewCreateEditor.value.getContentHeight())) : 0; return base + editorHeight + markdownMessageHeight + previewDiffHeight + previewCreateTitleHeight + previewCreateHeight + 18 /* padding */ + 8 /*shadow*/; From 599c7e7639f7b00bbcb81b6c958fae993c3cff7e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 10:19:42 -0700 Subject: [PATCH 0136/1180] revert change --- src/vs/monaco.d.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 4901b152ff25f..770c1268f3af8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7459,8 +7459,6 @@ declare namespace monaco.languages { Deprecated = 1 } - function asAriaLabel(label: string, kind: SymbolKind): string; - export interface DocumentSymbol { name: string; detail: string; From 8dcddb412477dadd79a263805fec3a6616e0ab26 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Fri, 14 Jul 2023 10:39:24 -0700 Subject: [PATCH 0137/1180] Have auth proxy use application storage service (#187094) * Have auth proxy use application storage service Since this code is already using the encryption service, it already takes advantage of the better encryption provided by Electron so it can be stored in the normal storage service. With that said, we do need a migration path, so this handles that migration. * re-encrypt to force using the new electron algorithm * it should already be removed from the old location --- src/vs/code/electron-main/auth.ts | 55 +++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index 9e56bcfa902f0..6a18eba4eb550 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -8,11 +8,14 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; import { hash } from 'vs/base/common/hash'; import { Disposable } from 'vs/base/common/lifecycle'; +import { withNullAsUndefined } from 'vs/base/common/types'; import { generateUuid } from 'vs/base/common/uuid'; import { ICredentialsMainService } from 'vs/platform/credentials/common/credentials'; import { IEncryptionMainService } from 'vs/platform/encryption/common/encryptionService'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; +import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IApplicationStorageMainService } from 'vs/platform/storage/electron-main/storageMainService'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; interface ElectronAuthenticationResponseDetails extends AuthenticationResponseDetails { @@ -56,7 +59,8 @@ enum ProxyAuthState { export class ProxyAuthHandler extends Disposable { - private readonly PROXY_CREDENTIALS_SERVICE_KEY = `${this.productService.urlProtocol}.proxy-credentials`; + private readonly OLD_PROXY_CREDENTIALS_SERVICE_KEY = `${this.productService.urlProtocol}.proxy-credentials`; + private readonly PROXY_CREDENTIALS_SERVICE_KEY = 'proxy-credentials://'; private pendingProxyResolve: Promise | undefined = undefined; @@ -69,6 +73,7 @@ export class ProxyAuthHandler extends Disposable { @IWindowsMainService private readonly windowsMainService: IWindowsMainService, @ICredentialsMainService private readonly credentialsService: ICredentialsMainService, @IEncryptionMainService private readonly encryptionMainService: IEncryptionMainService, + @IApplicationStorageMainService private readonly applicationStorageMainService: IApplicationStorageMainService, @IProductService private readonly productService: IProductService ) { super(); @@ -141,29 +146,43 @@ export class ProxyAuthHandler extends Disposable { return undefined; } - private async doResolveProxyCredentials(authInfo: AuthInfo): Promise { - this.logService.trace('auth#doResolveProxyCredentials - enter', authInfo); - - // Compute a hash over the authentication info to be used - // with the credentials store to return the right credentials - // given the properties of the auth request - // (see https://github.com/microsoft/vscode/issues/109497) - const authInfoHash = String(hash({ scheme: authInfo.scheme, host: authInfo.host, port: authInfo.port })); - + // TODO: remove this migration in a release or two. + private async getAndMigrateProxyCredentials(authInfoHash: string): Promise<{ storedUsername: string | undefined; storedPassword: string | undefined }> { // Find any previously stored credentials - let storedUsername: string | undefined = undefined; - let storedPassword: string | undefined = undefined; try { - const encryptedSerializedProxyCredentials = await this.credentialsService.getPassword(this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + let encryptedSerializedProxyCredentials = this.applicationStorageMainService.get(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, StorageScope.APPLICATION); + let decryptedSerializedProxyCredentials: string | undefined; + if (!encryptedSerializedProxyCredentials) { + encryptedSerializedProxyCredentials = withNullAsUndefined(await this.credentialsService.getPassword(this.OLD_PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash)); + if (encryptedSerializedProxyCredentials) { + // re-encrypt to force new encryption algorithm to apply + decryptedSerializedProxyCredentials = await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials); + encryptedSerializedProxyCredentials = await this.encryptionMainService.encrypt(decryptedSerializedProxyCredentials); + this.applicationStorageMainService.store(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, encryptedSerializedProxyCredentials, StorageScope.APPLICATION, StorageTarget.MACHINE); + // Remove it from the old location since it's in the new location. + await this.credentialsService.deletePassword(this.OLD_PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + } + } if (encryptedSerializedProxyCredentials) { - const credentials: Credentials = JSON.parse(await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials)); + const credentials: Credentials = JSON.parse(decryptedSerializedProxyCredentials ?? await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials)); - storedUsername = credentials.username; - storedPassword = credentials.password; + return { storedUsername: credentials.username, storedPassword: credentials.password }; } } catch (error) { this.logService.error(error); // handle errors by asking user for login via dialog } + return { storedUsername: undefined, storedPassword: undefined }; + } + + private async doResolveProxyCredentials(authInfo: AuthInfo): Promise { + this.logService.trace('auth#doResolveProxyCredentials - enter', authInfo); + + // Compute a hash over the authentication info to be used + // with the credentials store to return the right credentials + // given the properties of the auth request + // (see https://github.com/microsoft/vscode/issues/109497) + const authInfoHash = String(hash({ scheme: authInfo.scheme, host: authInfo.host, port: authInfo.port })); + const { storedUsername, storedPassword } = await this.getAndMigrateProxyCredentials(authInfoHash); // Reply with stored credentials unless we used them already. // In that case we need to show a login dialog again because @@ -212,9 +231,9 @@ export class ProxyAuthHandler extends Disposable { try { if (reply.remember) { const encryptedSerializedCredentials = await this.encryptionMainService.encrypt(JSON.stringify(credentials)); - await this.credentialsService.setPassword(this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash, encryptedSerializedCredentials); + this.applicationStorageMainService.store(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, encryptedSerializedCredentials, StorageScope.APPLICATION, StorageTarget.MACHINE); } else { - await this.credentialsService.deletePassword(this.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + this.applicationStorageMainService.remove(this.PROXY_CREDENTIALS_SERVICE_KEY + authInfoHash, StorageScope.APPLICATION); } } catch (error) { this.logService.error(error); // handle gracefully From 88b4c049d0d09003fbe5efb5da46c1aa5bfe7ef8 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 11:10:11 -0700 Subject: [PATCH 0138/1180] localize --- src/vs/editor/common/languages.ts | 3 ++- src/vs/monaco.d.ts | 2 ++ .../contrib/codeEditor/browser/outline/documentSymbolsTree.ts | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index f42c695cc772c..0e2c97189d580 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -21,6 +21,7 @@ import { LanguageId } from 'vs/editor/common/encodedTokenAttributes'; import * as model from 'vs/editor/common/model'; import { TokenizationRegistry as TokenizationRegistryImpl } from 'vs/editor/common/tokenizationRegistry'; import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMultilineTokens'; +import { localize } from 'vs/nls'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IMarkerData } from 'vs/platform/markers/common/markers'; @@ -1191,7 +1192,7 @@ export namespace SymbolKinds { } export function asAriaLabel(label: string, kind: SymbolKind): string { - return `${label} Symbol: ${SymbolKinds.toIcon(kind).id.replaceAll('symbol-', '')} `; + return localize('symbolAriaLabel', "{0} Symbol: {1}", label, SymbolKinds.toIcon(kind).id.replaceAll('symbol-', '')); } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 770c1268f3af8..4901b152ff25f 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7459,6 +7459,8 @@ declare namespace monaco.languages { Deprecated = 1 } + function asAriaLabel(label: string, kind: SymbolKind): string; + export interface DocumentSymbol { name: string; detail: string; diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index f5d9755eb385e..ada95c86308c1 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -49,7 +49,7 @@ export class DocumentSymbolAccessibilityProvider implements IListAccessibilityPr if (element instanceof OutlineGroup) { return element.label; } else { - return localize('document-symbol-aria-label', "{0}", SymbolKinds.asAriaLabel(element.symbol.name, element.symbol.kind)); + return SymbolKinds.asAriaLabel(element.symbol.name, element.symbol.kind); } } } @@ -195,7 +195,7 @@ export class DocumentSymbolRenderer implements ITreeRenderer Date: Fri, 14 Jul 2023 11:13:11 -0700 Subject: [PATCH 0139/1180] revert a change --- .../contrib/codeEditor/browser/outline/documentSymbolsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index ada95c86308c1..69680c0af9da8 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -195,7 +195,7 @@ export class DocumentSymbolRenderer implements ITreeRenderer Date: Fri, 14 Jul 2023 11:19:24 -0700 Subject: [PATCH 0140/1180] fix: refresh tests button causing error (#187948) Fixes #187770 --- src/vs/workbench/contrib/testing/browser/testExplorerActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts index a5bce0dab7e7a..e17df8e852d31 100644 --- a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts +++ b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts @@ -1421,7 +1421,7 @@ export class RefreshTestsAction extends Action2 { const testService = accessor.get(ITestService); const progressService = accessor.get(IProgressService); - const controllerIds = distinct(elements.map(e => e.test.controllerId)); + const controllerIds = distinct(elements.filter(isDefined).map(e => e.test.controllerId)); return progressService.withProgress({ location: Testing.ViewletId }, async () => { if (controllerIds.length) { await Promise.all(controllerIds.map(id => testService.refreshTests(id))); From bbed4d12951990a7a6fe402e5f2c451637288678 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 11:24:02 -0700 Subject: [PATCH 0141/1180] add internal --- src/vs/editor/common/languages.ts | 3 +++ src/vs/monaco.d.ts | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 0e2c97189d580..c445cb52ea694 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1191,6 +1191,9 @@ export namespace SymbolKinds { return icon; } + /** + * @internal + */ export function asAriaLabel(label: string, kind: SymbolKind): string { return localize('symbolAriaLabel', "{0} Symbol: {1}", label, SymbolKinds.toIcon(kind).id.replaceAll('symbol-', '')); } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 4901b152ff25f..770c1268f3af8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7459,8 +7459,6 @@ declare namespace monaco.languages { Deprecated = 1 } - function asAriaLabel(label: string, kind: SymbolKind): string; - export interface DocumentSymbol { name: string; detail: string; From 0729d2c1a9d618795026cc6848faa865d4d874ac Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 14 Jul 2023 11:33:42 -0700 Subject: [PATCH 0142/1180] Remove unused eslint private error suppression (#187522) For #186737 --- .../editor/contrib/codeAction/browser/codeActionController.ts | 2 -- src/vs/editor/contrib/codeAction/browser/codeActionModel.ts | 2 -- .../contrib/webviewPanel/browser/webviewWorkbenchService.ts | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts index 5b8d6576b14e1..14307f031e5fd 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/* eslint-disable local/code-no-native-private */ - import { getDomNodePagePosition } from 'vs/base/browser/dom'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IAction } from 'vs/base/common/actions'; diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index 19963bfe57f62..b21d5f2dc5d2e 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/* eslint-disable local/code-no-native-private */ - import { CancelablePromise, createCancelablePromise, TimeoutTimer } from 'vs/base/common/async'; import { isCancellationError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts index 39750b798b27f..1bb57c73a74af 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/* eslint-disable local/code-no-native-private */ - import { CancelablePromise, createCancelablePromise, DeferredPromise } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { memoize } from 'vs/base/common/decorators'; From 6c94c8e08883eaa344d727344c1cd8429cceeace Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 14 Jul 2023 13:36:38 -0500 Subject: [PATCH 0143/1180] [typescript-language-features] Update autoImportFileExcludePatterns description (#186528) Update autoImportFileExcludePatterns description --- extensions/typescript-language-features/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index bd4dd6366ad6b..81260c405e103 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -152,7 +152,7 @@ "typescript.preferences.includePackageJsonAutoImports.auto": "Search dependencies based on estimated performance impact.", "typescript.preferences.includePackageJsonAutoImports.on": "Always search dependencies.", "typescript.preferences.includePackageJsonAutoImports.off": "Never search dependencies.", - "typescript.preferences.autoImportFileExcludePatterns": "Specify glob patterns of files to exclude from auto imports. Requires using TypeScript 4.8 or newer in the workspace.", + "typescript.preferences.autoImportFileExcludePatterns": "Specify glob patterns of files to exclude from auto imports. Relative paths are resolved relative to the workspace root. Patterns are evaluated using tsconfig.json [`exclude`](https://www.typescriptlang.org/tsconfig#exclude) semantics. Requires using TypeScript 4.8 or newer in the workspace.", "typescript.updateImportsOnFileMove.enabled": "Enable/disable automatic updating of import paths when you rename or move a file in VS Code.", "typescript.updateImportsOnFileMove.enabled.prompt": "Prompt on each rename.", "typescript.updateImportsOnFileMove.enabled.always": "Always update paths automatically.", From d7b089d5e3b5a56f131ace79b10b26ea0982da34 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 14 Jul 2023 20:38:25 +0200 Subject: [PATCH 0144/1180] proper request making, ensure fetcher cannot be used after command is done --- .../api/browser/mainThreadChatProvider.ts | 11 +++++-- .../workbench/api/common/extHost.protocol.ts | 3 ++ .../api/common/extHostChatProvider.ts | 25 +++++++++++----- .../api/common/extHostChatSlashCommand.ts | 29 ++++++++++++++----- .../api/common/extHostTypeConverters.ts | 21 ++++++++++++++ .../contrib/chat/common/chatProvider.ts | 14 ++++++--- .../contrib/chat/common/chatSlashCommands.ts | 13 +++------ 7 files changed, 87 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadChatProvider.ts b/src/vs/workbench/api/browser/mainThreadChatProvider.ts index bdb067ec1d86c..082c0b417d950 100644 --- a/src/vs/workbench/api/browser/mainThreadChatProvider.ts +++ b/src/vs/workbench/api/browser/mainThreadChatProvider.ts @@ -3,10 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { DisposableMap } from 'vs/base/common/lifecycle'; -import { IProgress } from 'vs/platform/progress/common/progress'; +import { IProgress, Progress } from 'vs/platform/progress/common/progress'; import { ExtHostChatProviderShape, ExtHostContext, MainContext, MainThreadChatProviderShape } from 'vs/workbench/api/common/extHost.protocol'; -import { IChatResponseProviderMetadata, IChatResponseFragment, IChatProviderService } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { IChatResponseProviderMetadata, IChatResponseFragment, IChatProviderService, IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; @extHostNamedCustomer(MainContext.MainThreadChatProvider) @@ -50,4 +51,10 @@ export class MainThreadChatProvider implements MainThreadChatProviderShape { $unregisterProvider(handle: number): void { this._providerRegistrations.deleteAndDispose(handle); } + + async $fetchResponse(requestId: number, messages: IChatMessage[], options: {}, token: CancellationToken): Promise { + return this._chatProviderService.fetchChatResponse(messages, options, new Progress(value => { + this._proxy.$handleResponseFragment(requestId, value); + }), token); + } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index cf713f31a88fd..a209eb6a7e4d8 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1125,10 +1125,13 @@ export interface MainThreadChatProviderShape extends IDisposable { $registerProvider(handle: number, metadata: IChatResponseProviderMetadata): void; $unregisterProvider(handle: number): void; $handleProgressChunk(requestId: number, chunk: IChatResponseFragment): Promise; + + $fetchResponse(requestId: number, messages: IChatMessage[], options: {}, token: CancellationToken): Promise; } export interface ExtHostChatProviderShape { $provideChatResponse(handle: number, requestId: number, messages: IChatMessage[], options: { [name: string]: any }, token: CancellationToken): Promise; + $handleResponseFragment(requestId: number, chunk: IChatResponseFragment): Promise; } export interface MainThreadChatSlashCommandsShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostChatProvider.ts b/src/vs/workbench/api/common/extHostChatProvider.ts index 067cba16aca6b..99b55b9cb32e2 100644 --- a/src/vs/workbench/api/common/extHostChatProvider.ts +++ b/src/vs/workbench/api/common/extHostChatProvider.ts @@ -10,16 +10,14 @@ import { ExtHostChatProviderShape, IMainContext, MainContext, MainThreadChatProv import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters'; import type * as vscode from 'vscode'; import { Progress } from 'vs/platform/progress/common/progress'; -import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { IChatMessage, IChatResponseFragment } from 'vs/workbench/contrib/chat/common/chatProvider'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; - type ProviderData = { readonly extension: ExtensionIdentifier; readonly provider: vscode.ChatResponseProvider; }; - export class ExtHostChatProvider implements ExtHostChatProviderShape { private static _idPool = 1; @@ -34,10 +32,6 @@ export class ExtHostChatProvider implements ExtHostChatProviderShape { this._proxy = mainContext.getProxy(MainContext.MainThreadChatProvider); } - all() { - return Array.from(this._providers.values(), v => v.provider); - } - registerProvider(extension: ExtensionIdentifier, provider: vscode.ChatResponseProvider, metadata: vscode.ChatResponseProviderMetadata): IDisposable { const handle = ExtHostChatProvider._idPool++; @@ -66,4 +60,21 @@ export class ExtHostChatProvider implements ExtHostChatProviderShape { return data.provider.provideChatResponse(messages.map(typeConvert.ChatMessage.to), options, progress, token); } + //#region --- making request + + private readonly _pendingRequest = new Map>(); + + async makeChatRequest(messages: vscode.ChatMessage[], options: { [name: string]: any }, progress: vscode.Progress, token: CancellationToken) { + const requestId = (Math.random() * 1e6) | 0; + this._pendingRequest.set(requestId, progress); + try { + await this._proxy.$fetchResponse(requestId, messages.map(typeConvert.ChatMessage.from), options, token); + } finally { + this._pendingRequest.delete(requestId); + } + } + + async $handleResponseFragment(requestId: number, chunk: IChatResponseFragment): Promise { + this._pendingRequest.get(requestId)?.report(chunk); + } } diff --git a/src/vs/workbench/api/common/extHostChatSlashCommand.ts b/src/vs/workbench/api/common/extHostChatSlashCommand.ts index 49f99bf8d70ad..1a0375199c46d 100644 --- a/src/vs/workbench/api/common/extHostChatSlashCommand.ts +++ b/src/vs/workbench/api/common/extHostChatSlashCommand.ts @@ -14,6 +14,7 @@ import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters'; import type * as vscode from 'vscode'; import { Progress } from 'vs/platform/progress/common/progress'; import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { raceCancellation } from 'vs/base/common/async'; export class ExtHostChatSlashCommands implements ExtHostChatSlashCommandsShape { @@ -49,22 +50,36 @@ export class ExtHostChatSlashCommands implements ExtHostChatSlashCommandsShape { return; } - // TODO@jrieken this isn't proper, instead the code should call to the renderer which - // coordinates and picks the right provider - const provider = this._extHostChatProvider.all()[0]; - if (!provider) { - this._logService.warn(`[CHAT](${handle}) CANNOT execute command because there is no provider`); - return; + let done = false; + const that = this; + function throwIfDone() { + if (done) { + throw new Error('Only valid while executing the command'); + } } - await data.command( + const provider: vscode.ChatResponseProvider = { + provideChatResponse(messages, options, progress, token) { + throwIfDone(); + return that._extHostChatProvider.makeChatRequest(messages, options, progress, token); + } + }; + + const task = data.command( provider, { role: ChatMessageRole.User, content: prompt }, { history: context.history.map(typeConvert.ChatMessage.to) }, new Progress(p => { + throwIfDone(); this._proxy.$handleProgressChunk(requestId, { value: p.message.value }); }), token ); + + try { + await raceCancellation(Promise.resolve(task), token); + } finally { + done = true; + } } } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 6eeecf18669c9..a039002324111 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -2163,8 +2163,18 @@ export namespace ChatMessage { res.name = message.name; return res; } + + + export function from(message: vscode.ChatMessage): chatProvider.IChatMessage { + return { + role: ChatMessageRole.from(message.role), + content: message.content, + name: message.name + }; + } } + export namespace ChatMessageRole { export function to(role: chatProvider.ChatMessageRole): vscode.ChatMessageRole { @@ -2175,4 +2185,15 @@ export namespace ChatMessageRole { case chatProvider.ChatMessageRole.Function: return types.ChatMessageRole.Function; } } + + export function from(role: vscode.ChatMessageRole): chatProvider.ChatMessageRole { + switch (role) { + case types.ChatMessageRole.System: return chatProvider.ChatMessageRole.System; + case types.ChatMessageRole.Assistant: return chatProvider.ChatMessageRole.Assistant; + case types.ChatMessageRole.Function: return chatProvider.ChatMessageRole.Function; + case types.ChatMessageRole.User: + default: + return chatProvider.ChatMessageRole.User; + } + } } diff --git a/src/vs/workbench/contrib/chat/common/chatProvider.ts b/src/vs/workbench/contrib/chat/common/chatProvider.ts index 8ed47816d7e95..a905a6e267a6c 100644 --- a/src/vs/workbench/contrib/chat/common/chatProvider.ts +++ b/src/vs/workbench/contrib/chat/common/chatProvider.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { CancellationToken } from 'vs/base/common/cancellation'; +import { Iterable } from 'vs/base/common/iterator'; import { IDisposable } from 'vs/base/common/lifecycle'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -35,7 +36,7 @@ export interface IChatResponseProviderMetadata { export interface IChatResponseProvider { metadata: IChatResponseProviderMetadata; - provideChatResponse(messages: IChatMessage[], options: { [name: string]: any }, progress: IProgress, token: CancellationToken): Thenable; + provideChatResponse(messages: IChatMessage[], options: { [name: string]: any }, progress: IProgress, token: CancellationToken): Promise; } export const IChatProviderService = createDecorator('chatProviderService'); @@ -45,7 +46,8 @@ export interface IChatProviderService { readonly _serviceBrand: undefined; registerChatResponseProvider(provider: IChatResponseProvider): IDisposable; - getAllProviders(): Iterable; + + fetchChatResponse(messages: IChatMessage[], options: { [name: string]: any }, progress: IProgress, token: CancellationToken): Promise; } export class ChatProviderService implements IChatProviderService { @@ -62,7 +64,11 @@ export class ChatProviderService implements IChatProviderService { }; } - getAllProviders(): Iterable { - return this._providers; + fetchChatResponse(messages: IChatMessage[], options: { [name: string]: any }, progress: IProgress, token: CancellationToken): Promise { + const provider = Iterable.first(this._providers); // TODO@jrieken have plan how N providers are handled + if (!provider) { + throw new Error('NO chat provider registered'); + } + return provider.provideChatResponse(messages, options, progress, token); } } diff --git a/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts b/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts index 651cf22126dc7..1b4cbcc31e6c9 100644 --- a/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts +++ b/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts @@ -145,8 +145,6 @@ export class ChatSlashCommandService implements IChatSlashCommandService { } - - // --- debug registerAction2(class extends Action2 { @@ -162,14 +160,11 @@ registerAction2(class extends Action2 { override async run(accessor: ServicesAccessor, ...args: any[]): Promise { const chatProvider = accessor.get(IChatProviderService); - for (const provider of chatProvider.getAllProviders()) { - - const p = new Progress(value => { - console.log(provider.metadata.displayName, value); - }); + const p = new Progress(value => { + console.log(value); + }); + await chatProvider.fetchChatResponse([{ role: ChatMessageRole.User, content: 'Hello.' }], { n: 2 }, p, CancellationToken.None); - await provider.provideChatResponse([{ role: ChatMessageRole.User, content: 'Hello.' }], { n: 2 }, p, CancellationToken.None); - } } }); From 5eb82ae6c400e8ff5eb3ab89809a4669c6b05bd5 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 14 Jul 2023 11:41:23 -0700 Subject: [PATCH 0145/1180] debug: better copying of eval expression results (#187951) For #187784. Needs DAP methods for a complete solution. --- .../workbench/contrib/debug/browser/repl.ts | 35 +++++++++++++++---- .../contrib/debug/browser/replViewer.ts | 4 +-- .../contrib/debug/common/replModel.ts | 12 +++---- .../contrib/debug/test/browser/repl.test.ts | 4 +-- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index a65674a80f96a..b12c97f0b8f54 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -19,13 +19,14 @@ import { HistoryNavigator } from 'vs/base/common/history'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { removeAnsiEscapeCodes } from 'vs/base/common/strings'; +import { ThemeIcon } from 'vs/base/common/themables'; import { URI as uri } from 'vs/base/common/uri'; import 'vs/css!./media/repl'; import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, registerEditorAction } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { EditorOption, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; +import { EDITOR_FONT_DEFAULTS, EditorOption } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IDecorationOptions } from 'vs/editor/common/editorCommon'; @@ -55,7 +56,6 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { editorForeground, resolveColorValue } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ThemeIcon } from 'vs/base/common/themables'; import { FilterViewPane, IViewPaneOptions, ViewAction } from 'vs/workbench/browser/parts/views/viewPane'; import { IViewDescriptorService, IViewsService } from 'vs/workbench/common/views'; import { getSimpleCodeEditorWidgetOptions, getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; @@ -63,10 +63,10 @@ import { FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/d import { debugConsoleClearAll, debugConsoleEvaluationPrompt } from 'vs/workbench/contrib/debug/browser/debugIcons'; import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector'; import { ReplFilter } from 'vs/workbench/contrib/debug/browser/replFilter'; -import { ReplAccessibilityProvider, ReplDataSource, ReplDelegate, ReplEvaluationInputsRenderer, ReplEvaluationResultsRenderer, ReplGroupRenderer, ReplRawObjectsRenderer, ReplOutputElementRenderer, ReplVariablesRenderer } from 'vs/workbench/contrib/debug/browser/replViewer'; -import { CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_REPL, CONTEXT_MULTI_SESSION_REPL, DEBUG_SCHEME, getStateLabel, IDebugConfiguration, IDebugService, IDebugSession, IReplConfiguration, IReplElement, IReplOptions, REPL_VIEW_ID, State } from 'vs/workbench/contrib/debug/common/debug'; +import { ReplAccessibilityProvider, ReplDataSource, ReplDelegate, ReplEvaluationInputsRenderer, ReplEvaluationResultsRenderer, ReplGroupRenderer, ReplOutputElementRenderer, ReplRawObjectsRenderer, ReplVariablesRenderer } from 'vs/workbench/contrib/debug/browser/replViewer'; +import { CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_REPL, CONTEXT_MULTI_SESSION_REPL, DEBUG_SCHEME, IDebugConfiguration, IDebugService, IDebugSession, IReplConfiguration, IReplElement, IReplOptions, REPL_VIEW_ID, State, getStateLabel } from 'vs/workbench/contrib/debug/common/debug'; import { Variable } from 'vs/workbench/contrib/debug/common/debugModel'; -import { ReplGroup } from 'vs/workbench/contrib/debug/common/replModel'; +import { ReplEvaluationResult, ReplGroup } from 'vs/workbench/contrib/debug/common/replModel'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; const $ = dom.$; @@ -1045,12 +1045,33 @@ registerAction2(class extends Action2 { async run(accessor: ServicesAccessor, element: IReplElement): Promise { const clipboardService = accessor.get(IClipboardService); + const debugService = accessor.get(IDebugService); const nativeSelection = window.getSelection(); const selectedText = nativeSelection?.toString(); if (selectedText && selectedText.length > 0) { - await clipboardService.writeText(selectedText); + return clipboardService.writeText(selectedText); } else if (element) { - await clipboardService.writeText(element.toString()); + return clipboardService.writeText(await this.tryEvaluateAndCopy(debugService, element) || element.toString()); + } + } + + private async tryEvaluateAndCopy(debugService: IDebugService, element: IReplElement): Promise { + // todo: we should expand DAP to allow copying more types here (#187784) + if (!(element instanceof ReplEvaluationResult)) { + return; + } + + const stackFrame = debugService.getViewModel().focusedStackFrame; + const session = debugService.getViewModel().focusedSession; + if (!stackFrame || !session || !session.capabilities.supportsClipboardContext) { + return; + } + + try { + const evaluation = await session.evaluate(element.originalExpression, stackFrame.frameId, 'clipboard'); + return evaluation?.body.result; + } catch (e) { + return; } } }); diff --git a/src/vs/workbench/contrib/debug/browser/replViewer.ts b/src/vs/workbench/contrib/debug/browser/replViewer.ts index 4193677ab1ec9..1ba443a95f18a 100644 --- a/src/vs/workbench/contrib/debug/browser/replViewer.ts +++ b/src/vs/workbench/contrib/debug/browser/replViewer.ts @@ -239,14 +239,14 @@ export class ReplVariablesRenderer extends AbstractExpressionsRenderer, _index: number, data: IExpressionTemplateData): void { const element = node.element; - super.renderExpressionElement(element instanceof ReplVariableElement ? element.expr : element, node, data); + super.renderExpressionElement(element instanceof ReplVariableElement ? element.expression : element, node, data); } protected renderExpression(expression: IExpression | ReplVariableElement, data: IExpressionTemplateData, highlights: IHighlight[]): void { const isReplVariable = expression instanceof ReplVariableElement; if (isReplVariable || !expression.name) { data.label.set(''); - renderExpressionValue(isReplVariable ? expression.expr : expression, data.value, { showHover: false, colorize: true, linkDetector: this.linkDetector }); + renderExpressionValue(isReplVariable ? expression.expression : expression, data.value, { showHover: false, colorize: true, linkDetector: this.linkDetector }); data.expression.classList.remove('nested-variable'); } else { renderVariable(expression as Variable, data, true, highlights, this.linkDetector); diff --git a/src/vs/workbench/contrib/debug/common/replModel.ts b/src/vs/workbench/contrib/debug/common/replModel.ts index 9e28f1d66d18d..4402ed3f3b5c9 100644 --- a/src/vs/workbench/contrib/debug/common/replModel.ts +++ b/src/vs/workbench/contrib/debug/common/replModel.ts @@ -76,19 +76,19 @@ export class ReplVariableElement implements INestingReplElement { private readonly id = generateUuid(); constructor( - public readonly expr: IExpression, + public readonly expression: IExpression, public readonly severity: severity, public readonly sourceData?: IReplElementSource, ) { - this.hasChildren = expr.hasChildren; + this.hasChildren = expression.hasChildren; } getChildren(): IReplElement[] | Promise { - return this.expr.getChildren(); + return this.expression.getChildren(); } toString(): string { - return this.expr.toString(); + return this.expression.toString(); } getId(): string { @@ -169,7 +169,7 @@ export class ReplEvaluationResult extends ExpressionContainer implements IReplEl return this._available; } - constructor() { + constructor(public readonly originalExpression: string) { super(undefined, undefined, 0, generateUuid()); } @@ -271,7 +271,7 @@ export class ReplModel { async addReplExpression(session: IDebugSession, stackFrame: IStackFrame | undefined, name: string): Promise { this.addReplElement(new ReplEvaluationInput(name)); - const result = new ReplEvaluationResult(); + const result = new ReplEvaluationResult(name); await result.evaluateExpression(name, session, stackFrame, 'repl'); this.addReplElement(result); } diff --git a/src/vs/workbench/contrib/debug/test/browser/repl.test.ts b/src/vs/workbench/contrib/debug/test/browser/repl.test.ts index 276f3e74aecfc..a04f2ed196330 100644 --- a/src/vs/workbench/contrib/debug/test/browser/repl.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/repl.test.ts @@ -51,8 +51,8 @@ suite('Debug - REPL', () => { const keyValueObject = { 'key1': 2, 'key2': 'value' }; repl.appendToRepl(session, { output: '', expression: new RawObjectReplElement('fakeid', 'fake', keyValueObject), sev: severity.Info }); const element = repl.getReplElements()[3]; - assert.strictEqual(element.expr.value, 'Object'); - assert.deepStrictEqual((element.expr as RawObjectReplElement).valueObj, keyValueObject); + assert.strictEqual(element.expression.value, 'Object'); + assert.deepStrictEqual((element.expression as RawObjectReplElement).valueObj, keyValueObject); repl.removeReplExpressions(); assert.strictEqual(repl.getReplElements().length, 0); From ef42b49e806b4a4f1202ec2e31f441465a7047de Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Fri, 14 Jul 2023 11:53:47 -0700 Subject: [PATCH 0146/1180] Support proxies in the telemetry service (#187952) --- src/vs/code/node/cliProcessMain.ts | 5 +- .../node/sharedProcess/sharedProcessMain.ts | 5 +- src/vs/platform/telemetry/node/1dsAppender.ts | 89 +++++++++++++++---- src/vs/server/node/serverServices.ts | 5 +- .../contrib/debug/node/telemetryApp.ts | 2 +- 5 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 0065a8da62e6f..a003267c0434a 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -192,7 +192,8 @@ class CliMain extends Disposable { services.set(IUriIdentityService, new UriIdentityService(fileService)); // Request - services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true)); + const requestService = new RequestService(configurationService, environmentService, logService, loggerService); + services.set(IRequestService, requestService); // Download Service services.set(IDownloadService, new SyncDescriptor(DownloadService, undefined, true)); @@ -212,7 +213,7 @@ class CliMain extends Disposable { const isInternal = isInternalTelemetry(productService, configurationService); if (supportsTelemetry(productService, environmentService)) { if (productService.aiConfig && productService.aiConfig.ariaKey) { - appenders.push(new OneDataSystemAppender(isInternal, 'monacoworkbench', null, productService.aiConfig.ariaKey)); + appenders.push(new OneDataSystemAppender(requestService, isInternal, 'monacoworkbench', null, productService.aiConfig.ariaKey)); } const config: ITelemetryServiceConfig = { diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts index d8b6d791e74b2..f911b0da431c2 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -251,7 +251,8 @@ class SharedProcessMain extends Disposable { services.set(IUriIdentityService, uriIdentityService); // Request - services.set(IRequestService, new RequestChannelClient(mainProcessService.getChannel('request'))); + const requestService = new RequestChannelClient(mainProcessService.getChannel('request')); + services.set(IRequestService, requestService); // Checksum services.set(IChecksumService, new SyncDescriptor(ChecksumService, undefined, false /* proxied to other processes */)); @@ -279,7 +280,7 @@ class SharedProcessMain extends Disposable { const logAppender = new TelemetryLogAppender(logService, loggerService, environmentService, productService); appenders.push(logAppender); if (productService.aiConfig?.ariaKey) { - const collectorAppender = new OneDataSystemAppender(internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); + const collectorAppender = new OneDataSystemAppender(requestService, internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data appenders.push(collectorAppender); } diff --git a/src/vs/platform/telemetry/node/1dsAppender.ts b/src/vs/platform/telemetry/node/1dsAppender.ts index 8d3d82ca50cab..94f0dc30692ac 100644 --- a/src/vs/platform/telemetry/node/1dsAppender.ts +++ b/src/vs/platform/telemetry/node/1dsAppender.ts @@ -4,41 +4,100 @@ *--------------------------------------------------------------------------------------------*/ import type { IPayloadData, IXHROverride } from '@microsoft/1ds-post-js'; -import * as https from 'https'; +import { streamToBuffer } from 'vs/base/common/buffer'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IRequestOptions } from 'vs/base/parts/request/common/request'; +import { IRequestService } from 'vs/platform/request/common/request'; import { AbstractOneDataSystemAppender, IAppInsightsCore } from 'vs/platform/telemetry/common/1dsAppender'; +/** + * Completes a request to submit telemetry to the server utilizing the request service + * @param options The options which will be used to make the request + * @param requestService The request service + * @returns An object containing the headers, statusCode, and responseData + */ +async function makeTelemetryRequest(options: IRequestOptions, requestService: IRequestService) { + const response = await requestService.request(options, CancellationToken.None); + const responseData = (await streamToBuffer(response.stream)).toString(); + const statusCode = response.res.statusCode ?? 200; + const headers = response.res.headers as Record; + return { + headers, + statusCode, + responseData + }; +} + +/** + * Complete a request to submit telemetry to the server utilizing the https module. Only used when the request service is not available + * @param options The options which will be used to make the request + * @param httpsModule The https node module + * @returns An object containing the headers, statusCode, and responseData + */ +function makeLegacyTelemetryRequest(options: IRequestOptions, httpsModule: typeof import('https')) { + const httpsOptions = { + method: options.type, + headers: options.headers + }; + const req = httpsModule.request(options.url ?? '', httpsOptions, res => { + res.on('data', function (responseData) { + return { + headers: res.headers as Record, + statusCode: res.statusCode ?? 200, + responseData: responseData.toString() + }; + }); + // On response with error send status of 0 and a blank response to oncomplete so we can retry events + res.on('error', function (err) { + throw err; + }); + }); + req.write(options.data); + req.end(); + return; +} + export class OneDataSystemAppender extends AbstractOneDataSystemAppender { constructor( + requestService: IRequestService | undefined, isInternalTelemetry: boolean, eventPrefix: string, defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => IAppInsightsCore), // allow factory function for testing ) { + let httpsModule: typeof import('https') | undefined; + if (!requestService) { + httpsModule = require('https'); + } // Override the way events get sent since node doesn't have XHTMLRequest const customHttpXHROverride: IXHROverride = { sendPOST: (payload: IPayloadData, oncomplete) => { - const options = { - method: 'POST', + + const telemetryRequestData = typeof payload.data === 'string' ? payload.data : new TextDecoder().decode(payload.data); + const requestOptions: IRequestOptions = { + type: 'POST', headers: { ...payload.headers, 'Content-Type': 'application/json', - 'Content-Length': Buffer.byteLength(payload.data) - } + 'Content-Length': Buffer.byteLength(payload.data).toString() + }, + url: payload.urlString, + data: telemetryRequestData }; + try { - const req = https.request(payload.urlString, options, res => { - res.on('data', function (responseData) { - oncomplete(res.statusCode ?? 200, res.headers as Record, responseData.toString()); + if (requestService) { + makeTelemetryRequest(requestOptions, requestService).then(({ statusCode, headers, responseData }) => { + oncomplete(statusCode, headers, responseData); }); - // On response with error send status of 0 and a blank response to oncomplete so we can retry events - res.on('error', function (err) { - oncomplete(0, {}); - }); - }); - req.write(payload.data); - req.end(); + } else { + if (!httpsModule) { + throw new Error('https module is undefined'); + } + makeLegacyTelemetryRequest(requestOptions, httpsModule); + } } catch { // If it errors out, send status of 0 and a blank response to oncomplete so we can retry events oncomplete(0, {}); diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index 910bbe0e5d100..d291af5dd1c1e 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -144,13 +144,14 @@ export async function setupServerServices(connectionToken: ServerConnectionToken services.set(IExtensionHostStatusService, extensionHostStatusService); // Request - services.set(IRequestService, new SyncDescriptor(RequestService)); + const requestService = new RequestService(configurationService, environmentService, logService, loggerService); + services.set(IRequestService, requestService); let oneDsAppender: ITelemetryAppender = NullAppender; const isInternal = isInternalTelemetry(productService, configurationService); if (supportsTelemetry(productService, environmentService)) { if (productService.aiConfig && productService.aiConfig.ariaKey) { - oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey); + oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, productService.aiConfig.ariaKey); disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data } diff --git a/src/vs/workbench/contrib/debug/node/telemetryApp.ts b/src/vs/workbench/contrib/debug/node/telemetryApp.ts index 6296aeb862eea..802a806486fef 100644 --- a/src/vs/workbench/contrib/debug/node/telemetryApp.ts +++ b/src/vs/workbench/contrib/debug/node/telemetryApp.ts @@ -7,7 +7,7 @@ import { Server } from 'vs/base/parts/ipc/node/ipc.cp'; import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; -const appender = new OneDataSystemAppender(false, process.argv[2], JSON.parse(process.argv[3]), process.argv[4]); +const appender = new OneDataSystemAppender(undefined, false, process.argv[2], JSON.parse(process.argv[3]), process.argv[4]); process.once('exit', () => appender.flush()); const channel = new TelemetryAppenderChannel([appender]); From b607d75611e29cb5c5846d1425c3415d0c7d1319 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 12:03:42 -0700 Subject: [PATCH 0147/1180] move things around --- src/vs/base/common/iconLabels.ts | 3 +- src/vs/editor/common/languages.ts | 40 +++++++++++++++---- .../browser/gotoSymbolQuickAccess.ts | 4 +- .../standalone/browser/standaloneLanguages.ts | 1 + src/vs/monaco.d.ts | 2 + .../browser/outline/documentSymbolsTree.ts | 35 ++-------------- 6 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/vs/base/common/iconLabels.ts b/src/vs/base/common/iconLabels.ts index 089afb9455c0f..eb657f5d15b3e 100644 --- a/src/vs/base/common/iconLabels.ts +++ b/src/vs/base/common/iconLabels.ts @@ -6,7 +6,6 @@ import { IMatch, matchesFuzzy } from 'vs/base/common/filters'; import { ltrim } from 'vs/base/common/strings'; import { ThemeIcon } from 'vs/base/common/themables'; - const iconStartMarker = '$('; const iconsRegex = new RegExp(`\\$\\(${ThemeIcon.iconNameExpression}(?:${ThemeIcon.iconModifierExpression})?\\)`, 'g'); // no capturing groups @@ -48,6 +47,8 @@ export function getCodiconAriaLabel(text: string | undefined) { } + + export interface IParsedLabelWithIcons { readonly text: string; readonly iconOffsets?: readonly number[]; diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index c445cb52ea694..17b1c5e3448d4 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1143,6 +1143,39 @@ export const enum SymbolKind { TypeParameter = 25 } +export const symbolKindNames: { [symbol: number]: string } = { + [SymbolKind.Array]: localize('Array', "array"), + [SymbolKind.Boolean]: localize('Boolean', "boolean"), + [SymbolKind.Class]: localize('Class', "class"), + [SymbolKind.Constant]: localize('Constant', "constant"), + [SymbolKind.Constructor]: localize('Constructor', "constructor"), + [SymbolKind.Enum]: localize('Enum', "enumeration"), + [SymbolKind.EnumMember]: localize('EnumMember', "enumeration member"), + [SymbolKind.Event]: localize('Event', "event"), + [SymbolKind.Field]: localize('Field', "field"), + [SymbolKind.File]: localize('File', "file"), + [SymbolKind.Function]: localize('Function', "function"), + [SymbolKind.Interface]: localize('Interface', "interface"), + [SymbolKind.Key]: localize('Key', "key"), + [SymbolKind.Method]: localize('Method', "method"), + [SymbolKind.Module]: localize('Module', "module"), + [SymbolKind.Namespace]: localize('Namespace', "namespace"), + [SymbolKind.Null]: localize('Null', "null"), + [SymbolKind.Number]: localize('Number', "number"), + [SymbolKind.Object]: localize('Object', "object"), + [SymbolKind.Operator]: localize('Operator', "operator"), + [SymbolKind.Package]: localize('Package', "package"), + [SymbolKind.Property]: localize('Property', "property"), + [SymbolKind.String]: localize('String', "string"), + [SymbolKind.Struct]: localize('Struct', "struct"), + [SymbolKind.TypeParameter]: localize('TypeParameter', "type parameter"), + [SymbolKind.Variable]: localize('Variable', "variable"), +}; + +export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string { + return localize('symbolAriaLabel', '{0} Symbol: {1}', symbolName, symbolKindNames[kind]); +} + export const enum SymbolTag { Deprecated = 1, } @@ -1190,13 +1223,6 @@ export namespace SymbolKinds { } return icon; } - - /** - * @internal - */ - export function asAriaLabel(label: string, kind: SymbolKind): string { - return localize('symbolAriaLabel', "{0} Symbol: {1}", label, SymbolKinds.toIcon(kind).id.replaceAll('symbol-', '')); - } } export interface DocumentSymbol { diff --git a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts index d6c3feb2a3187..77197c2f9d4fe 100644 --- a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts @@ -14,7 +14,7 @@ import { format, trim } from 'vs/base/common/strings'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; -import { DocumentSymbol, SymbolKind, SymbolKinds, SymbolTag } from 'vs/editor/common/languages'; +import { DocumentSymbol, SymbolKind, SymbolKinds, SymbolTag, getAriaLabelForSymbol } from 'vs/editor/common/languages'; import { IOutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { AbstractEditorNavigationQuickAccessProvider, IEditorNavigationQuickAccessOptions, IQuickAccessTextEditorContext } from 'vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess'; import { localize } from 'vs/nls'; @@ -316,7 +316,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit kind: symbol.kind, score: symbolScore, label: symbolLabelWithIcon, - ariaLabel: symbolLabel, + ariaLabel: getAriaLabelForSymbol(symbol.name, symbol.kind), description: containerLabel, highlights: deprecated ? undefined : { label: symbolMatches, diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 939d33910346a..031bc170bd7bf 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -778,6 +778,7 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { registerDocumentRangeSemanticTokensProvider: registerDocumentRangeSemanticTokensProvider, registerInlineCompletionsProvider: registerInlineCompletionsProvider, registerInlayHintsProvider: registerInlayHintsProvider, + getAriaLabelForSymbol: languages.getAriaLabelForSymbol, // enums DocumentHighlightKind: standaloneEnums.DocumentHighlightKind, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 770c1268f3af8..6bfb3fb8f6236 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7455,6 +7455,8 @@ declare namespace monaco.languages { TypeParameter = 25 } + export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string; + export enum SymbolTag { Deprecated = 1 } diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index 69680c0af9da8..3e7bdeec9c064 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -11,7 +11,7 @@ import { IIdentityProvider, IKeyboardNavigationLabelProvider, IListVirtualDelega import { ITreeNode, ITreeRenderer, ITreeFilter } from 'vs/base/browser/ui/tree/tree'; import { createMatches, FuzzyScore } from 'vs/base/common/filters'; import { Range } from 'vs/editor/common/core/range'; -import { SymbolKind, SymbolKinds, SymbolTag } from 'vs/editor/common/languages'; +import { SymbolKind, SymbolKinds, SymbolTag, getAriaLabelForSymbol, symbolKindNames } from 'vs/editor/common/languages'; import { OutlineElement, OutlineGroup, OutlineModel } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { localize } from 'vs/nls'; import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel'; @@ -49,7 +49,7 @@ export class DocumentSymbolAccessibilityProvider implements IListAccessibilityPr if (element instanceof OutlineGroup) { return element.label; } else { - return SymbolKinds.asAriaLabel(element.symbol.name, element.symbol.kind); + return getAriaLabelForSymbol(element.symbol.name, element.symbol.kind); } } } @@ -138,7 +138,7 @@ export class DocumentSymbolRenderer implements ITreeRenderer Date: Fri, 14 Jul 2023 12:10:04 -0700 Subject: [PATCH 0148/1180] clean up --- src/vs/base/common/iconLabels.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/base/common/iconLabels.ts b/src/vs/base/common/iconLabels.ts index eb657f5d15b3e..089afb9455c0f 100644 --- a/src/vs/base/common/iconLabels.ts +++ b/src/vs/base/common/iconLabels.ts @@ -6,6 +6,7 @@ import { IMatch, matchesFuzzy } from 'vs/base/common/filters'; import { ltrim } from 'vs/base/common/strings'; import { ThemeIcon } from 'vs/base/common/themables'; + const iconStartMarker = '$('; const iconsRegex = new RegExp(`\\$\\(${ThemeIcon.iconNameExpression}(?:${ThemeIcon.iconModifierExpression})?\\)`, 'g'); // no capturing groups @@ -47,8 +48,6 @@ export function getCodiconAriaLabel(text: string | undefined) { } - - export interface IParsedLabelWithIcons { readonly text: string; readonly iconOffsets?: readonly number[]; From 76f9fca873d4877968745dc78336fc5e6be5a019 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 17:16:55 -0700 Subject: [PATCH 0149/1180] fix error --- src/vs/monaco.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 6bfb3fb8f6236..e87de797b6a9c 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7455,6 +7455,10 @@ declare namespace monaco.languages { TypeParameter = 25 } + export const symbolKindNames: { + [symbol: number]: string; + }; + export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string; export enum SymbolTag { From a06ece3136b11030e2033cd2651c102eee30dcb4 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 17:20:04 -0700 Subject: [PATCH 0150/1180] fix issue --- src/vs/editor/standalone/browser/standaloneLanguages.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 031bc170bd7bf..03da1d4e3be9b 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -779,6 +779,7 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { registerInlineCompletionsProvider: registerInlineCompletionsProvider, registerInlayHintsProvider: registerInlayHintsProvider, getAriaLabelForSymbol: languages.getAriaLabelForSymbol, + symbolKindNames: languages.symbolKindNames, // enums DocumentHighlightKind: standaloneEnums.DocumentHighlightKind, From 247fab678c9858ff977f4e5ed51eb509bd9ed33e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 14 Jul 2023 18:43:33 -0700 Subject: [PATCH 0151/1180] mark with internal --- src/vs/editor/common/languages.ts | 6 ++++++ src/vs/editor/standalone/browser/standaloneLanguages.ts | 2 -- src/vs/monaco.d.ts | 6 ------ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 17b1c5e3448d4..3a08292c8d62c 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1143,6 +1143,9 @@ export const enum SymbolKind { TypeParameter = 25 } +/** + * @internal + */ export const symbolKindNames: { [symbol: number]: string } = { [SymbolKind.Array]: localize('Array', "array"), [SymbolKind.Boolean]: localize('Boolean', "boolean"), @@ -1172,6 +1175,9 @@ export const symbolKindNames: { [symbol: number]: string } = { [SymbolKind.Variable]: localize('Variable', "variable"), }; +/** + * @internal + */ export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string { return localize('symbolAriaLabel', '{0} Symbol: {1}', symbolName, symbolKindNames[kind]); } diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 03da1d4e3be9b..939d33910346a 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -778,8 +778,6 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { registerDocumentRangeSemanticTokensProvider: registerDocumentRangeSemanticTokensProvider, registerInlineCompletionsProvider: registerInlineCompletionsProvider, registerInlayHintsProvider: registerInlayHintsProvider, - getAriaLabelForSymbol: languages.getAriaLabelForSymbol, - symbolKindNames: languages.symbolKindNames, // enums DocumentHighlightKind: standaloneEnums.DocumentHighlightKind, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e87de797b6a9c..770c1268f3af8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7455,12 +7455,6 @@ declare namespace monaco.languages { TypeParameter = 25 } - export const symbolKindNames: { - [symbol: number]: string; - }; - - export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string; - export enum SymbolTag { Deprecated = 1 } From b288ef1be837f120afc939c6ed78c471965d63e6 Mon Sep 17 00:00:00 2001 From: yshaojun Date: Sat, 15 Jul 2023 12:09:45 +0800 Subject: [PATCH 0152/1180] feat: update test case --- .../editor/test/browser/viewModel/modelLineProjection.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts b/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts index 06de7665c0271..530ae84b56285 100644 --- a/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts +++ b/src/vs/editor/test/browser/viewModel/modelLineProjection.test.ts @@ -921,7 +921,7 @@ suite('SplitLinesCollection', () => { })), [ { inlineDecorations: [{ startOffset: 8, endOffset: 23 }] }, - { inlineDecorations: [{ startOffset: 4, endOffset: 42 }] }, + { inlineDecorations: [{ startOffset: 4, endOffset: 30 }] }, { inlineDecorations: [{ startOffset: 4, endOffset: 16 }] }, { inlineDecorations: undefined }, { inlineDecorations: undefined }, From dd6af83b854b86d233de36a03b7af1d4ec8744e2 Mon Sep 17 00:00:00 2001 From: yshaojun Date: Sat, 15 Jul 2023 22:58:51 +0800 Subject: [PATCH 0153/1180] fix: prevent duplicate reason(#186206) --- .../unicodeHighlighter/browser/unicodeHighlighter.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts index 9b77b25b72eba..122648ba83c1f 100644 --- a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts +++ b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts @@ -429,6 +429,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa } const result: MarkdownHover[] = []; + const existedReason = new Map(); let index = 300; for (const d of lineDecorations) { @@ -480,6 +481,11 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa break; } + if (existedReason.has(reason)) { + continue; + } + existedReason.set(reason, true); + const adjustSettingsArgs: ShowExcludeOptionsArgs = { codePoint: codePoint, reason: highlightInfo.reason, From 2a19176aa6719e12975e4730990ef81fb5e757e8 Mon Sep 17 00:00:00 2001 From: yshaojun Date: Sun, 16 Jul 2023 14:55:48 +0800 Subject: [PATCH 0154/1180] fix: modified editor width(#175397) --- src/vs/editor/browser/widget/diffEditorWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index e21c1e9f3beb2..123bbc901c0bb 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -1368,7 +1368,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._originalDomNode.style.width = splitPoint + 'px'; this._originalDomNode.style.left = '0px'; - this._modifiedDomNode.style.width = (width - splitPoint) + 'px'; + this._modifiedDomNode.style.width = (width - splitPoint - DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH) + 'px'; this._modifiedDomNode.style.left = splitPoint + 'px'; this._overviewDomElement.style.top = '0px'; From 02d3b49d8035a9b30db3b0ae706796af9b1a4260 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Sun, 16 Jul 2023 20:38:37 -0700 Subject: [PATCH 0155/1180] Notebook extension recommendatation on open. (#188030) --- .../notebook/browser/notebookEditor.ts | 23 +++++++++++++- .../services/notebookWorkerServiceImpl.ts | 12 ++++++++ .../common/services/notebookSimpleWorker.ts | 30 +++++++++++++++++++ .../common/services/notebookWorkerService.ts | 1 + 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts index af68d86e8a7f2..159a26de4424d 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts @@ -46,6 +46,7 @@ import { EnablementState } from 'vs/workbench/services/extensionManagement/commo import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup'; import { streamToBuffer } from 'vs/base/common/buffer'; import { ILogService } from 'vs/platform/log/common/log'; +import { INotebookEditorWorkerService } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerService'; const NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'NotebookEditorViewState'; @@ -89,7 +90,8 @@ export class NotebookEditor extends EditorPane implements INotebookEditorPane { @INotebookService private readonly _notebookService: INotebookService, @IExtensionsWorkbenchService private readonly _extensionsWorkbenchService: IExtensionsWorkbenchService, @IWorkingCopyBackupService private readonly _workingCopyBackupService: IWorkingCopyBackupService, - @ILogService private readonly logService: ILogService + @ILogService private readonly logService: ILogService, + @INotebookEditorWorkerService private readonly _notebookEditorWorkerService: INotebookEditorWorkerService, ) { super(NotebookEditor.ID, telemetryService, themeService, storageService); this._editorMemento = this.getEditorMemento(_editorGroupService, configurationService, NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY); @@ -318,6 +320,7 @@ export class NotebookEditor extends EditorPane implements INotebookEditorPane { } this._handlePerfMark(perf, input); + this._handlePromptRecommendations(model.notebook); } catch (e) { this.logService.warn('NotebookEditorWidget#setInput failed', e); if (isEditorOpenError(e)) { @@ -425,6 +428,24 @@ export class NotebookEditor extends EditorPane implements INotebookEditorPane { }); } + private _handlePromptRecommendations(model: NotebookTextModel) { + this._notebookEditorWorkerService.canPromptRecommendation(model.uri).then(shouldPrompt => { + type WorkbenchNotebookShouldPromptRecommendationClassification = { + owner: 'rebornix'; + comment: 'The notebook file metrics. Used to get a better understanding of if we should prompt for notebook extension recommendations'; + shouldPrompt: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Should we prompt for notebook extension recommendations' }; + }; + + type WorkbenchNotebookShouldPromptRecommendationEvent = { + shouldPrompt: boolean; + }; + + this.telemetryService.publicLog2('notebook/shouldPromptRecommendation', { + shouldPrompt: shouldPrompt + }); + }); + } + override clearInput(): void { this._inputListener.clear(); diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts index 6a1d82f3b26af..65980c57a9c77 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts @@ -35,6 +35,12 @@ export class NotebookEditorWorkerServiceImpl extends Disposable implements INote return client.computeDiff(original, modified); }); } + + canPromptRecommendation(model: URI): Promise { + return this._workerManager.withWorker().then(client => { + return client.canPromptRecommendation(model); + }); + } } class WorkerManager extends Disposable { @@ -218,6 +224,12 @@ class NotebookWorkerClient extends Disposable { }); } + canPromptRecommendation(modelUri: URI) { + return this._withSyncedResources([modelUri]).then(proxy => { + return proxy.canPromptRecommendation(modelUri.toString()); + }); + } + private _getOrCreateModelManager(proxy: NotebookEditorSimpleWorker): NotebookEditorModelManager { if (!this._modelManager) { this._modelManager = this._register(new NotebookEditorModelManager(proxy, this._notebookService)); diff --git a/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts b/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts index 685d07a5073f5..1b8d4055433b4 100644 --- a/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts +++ b/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts @@ -13,6 +13,7 @@ import { CellKind, ICellDto2, IMainCellDto, INotebookDiffResult, IOutputDto, Not import { Range } from 'vs/editor/common/core/range'; import { INotebookWorkerHost } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerHost'; import { VSBuffer } from 'vs/base/common/buffer'; +import { SearchParams } from 'vs/editor/common/model/textModelSearch'; function bufferHash(buffer: VSBuffer): number { let initialHashVal = numberHash(104579, 0); @@ -275,6 +276,35 @@ export class NotebookEditorSimpleWorker implements IRequestHandler, IDisposable }; } + canPromptRecommendation(modelUrl: string): boolean { + const model = this._getModel(modelUrl); + const cells = model.cells; + + for (let i = 0; i < cells.length; i++) { + const cell = cells[i]; + if (cell.cellKind === CellKind.Markup) { + continue; + } + + const lineCount = cell.textBuffer.getLineCount(); + const maxLineCount = Math.min(lineCount, 20); + const range = new Range(1, 1, maxLineCount, cell.textBuffer.getLineLength(maxLineCount) + 1); + const searchParams = new SearchParams('import\\s*pandas', true, false, null); + const searchData = searchParams.parseSearchRequest(); + + if (!searchData) { + continue; + } + + const cellMatches = cell.textBuffer.findMatchesLineByLine(range, searchData, true, 1); + if (cellMatches.length > 0) { + return true; + } + } + + return false; + } + protected _getModel(uri: string): MirrorNotebookDocument { return this._models[uri]; } diff --git a/src/vs/workbench/contrib/notebook/common/services/notebookWorkerService.ts b/src/vs/workbench/contrib/notebook/common/services/notebookWorkerService.ts index ec7081a2852c7..8155c9d58dbb6 100644 --- a/src/vs/workbench/contrib/notebook/common/services/notebookWorkerService.ts +++ b/src/vs/workbench/contrib/notebook/common/services/notebookWorkerService.ts @@ -15,4 +15,5 @@ export interface INotebookEditorWorkerService { canComputeDiff(original: URI, modified: URI): boolean; computeDiff(original: URI, modified: URI): Promise; + canPromptRecommendation(model: URI): Promise; } From 4dd562c7b0a6d1429bc146ec41255a0f9ca1bc40 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 17 Jul 2023 10:58:06 +0200 Subject: [PATCH 0156/1180] Fix gaps in updating the profile (#188050) #156144 Fix gaps in updating the profile --- .../userDataProfile/common/userDataProfile.ts | 2 +- .../common/userDataProfileService.test.ts | 9 + .../common/userDataProfilesManifestMerge.ts | 7 +- .../common/userDataProfilesManifestSync.ts | 2 +- .../userDataProfilesManifestMerge.test.ts | 13 +- .../userDataProfilesManifestSync.test.ts | 41 +++++ .../parts/activitybar/activitybarActions.ts | 3 +- .../browser/parts/titlebar/windowTitle.ts | 1 - .../browser/extensions.contribution.ts | 43 ++--- .../browser/preferences.contribution.ts | 169 ++++++++---------- .../browser/commands/configureSnippets.ts | 160 ++++++++--------- .../snippets/browser/snippets.contribution.ts | 4 +- .../tasks/browser/task.contribution.ts | 57 +++--- .../browser/userDataProfile.ts | 4 +- .../browser/configurationService.ts | 3 +- .../extensionManagementChannelClient.ts | 6 +- .../common/webExtensionManagementService.ts | 6 +- .../keybinding/browser/keybindingService.ts | 15 +- .../browser/userDataProfileManagement.ts | 18 +- .../userDataProfile/common/userDataProfile.ts | 3 +- .../common/userDataProfileService.ts | 13 +- .../test/browser/workbenchTestServices.ts | 2 +- 22 files changed, 294 insertions(+), 287 deletions(-) diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 83065021bdb47..e42d012c995a8 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -365,7 +365,7 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf throw new Error(`Profile '${profileToUpdate.name}' does not exist`); } - profile = toUserDataProfile(profile.id, options.name ?? profile.name, profile.location, this.profilesCacheHome, { shortName: options.shortName ?? profile.shortName, transient: options.transient ?? profile.isTransient, useDefaultFlags: options.useDefaultFlags ?? profile.useDefaultFlags }); + profile = toUserDataProfile(profile.id, options.name ?? profile.name, profile.location, this.profilesCacheHome, { shortName: options.shortName ?? profile.shortName, transient: options.transient ?? profile.isTransient, useDefaultFlags: options.useDefaultFlags ?? profile.useDefaultFlags }, this.defaultProfile); this.updateProfiles([], [], [profile]); return profile; diff --git a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts index dbcd309c77e48..38f2415522402 100644 --- a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts +++ b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts @@ -226,4 +226,13 @@ suite('UserDataProfileService (Common)', () => { assert.strictEqual(profile.extensionsResource.toString(), testObject.defaultProfile.extensionsResource.toString()); }); + test('update profile using default profile for keybindings', async () => { + let profile = await testObject.createNamedProfile('name'); + profile = await testObject.updateProfile(profile, { useDefaultFlags: { keybindings: true } }); + + assert.strictEqual(profile.isDefault, false); + assert.deepStrictEqual(profile.useDefaultFlags, { keybindings: true }); + assert.strictEqual(profile.keybindingsResource.toString(), testObject.defaultProfile.keybindingsResource.toString()); + }); + }); diff --git a/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts b/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts index 43df2e6df1520..072554b04f8a7 100644 --- a/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts +++ b/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { equals } from 'vs/base/common/objects'; +import { IUserDataProfile, UseDefaultProfileFlags } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ISyncUserDataProfile } from 'vs/platform/userDataSync/common/userDataSync'; interface IRelaxedMergeResult { @@ -17,6 +18,7 @@ interface IUserDataProfileInfo { readonly id: string; readonly name: string; readonly shortName?: string; + readonly useDefaultFlags?: UseDefaultProfileFlags; } export function merge(local: IUserDataProfile[], remote: ISyncUserDataProfile[] | null, lastSync: ISyncUserDataProfile[] | null, ignored: string[]): IMergeResult { @@ -117,7 +119,7 @@ function compare(from: IUserDataProfileInfo[] | null, to: IUserDataProfileInfo[] const removed = fromKeys.filter(key => !toKeys.includes(key)); const updated: string[] = []; - for (const { id, name, shortName } of from) { + for (const { id, name, shortName, useDefaultFlags } of from) { if (removed.includes(id)) { continue; } @@ -125,6 +127,7 @@ function compare(from: IUserDataProfileInfo[] | null, to: IUserDataProfileInfo[] if (!toProfile || toProfile.name !== name || toProfile.shortName !== shortName + || !equals(toProfile.useDefaultFlags, useDefaultFlags) ) { updated.push(id); } diff --git a/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts b/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts index 9f179f239af52..606983a1c0acf 100644 --- a/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts +++ b/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts @@ -206,7 +206,7 @@ export class UserDataProfilesManifestSynchroniser extends AbstractSynchroniser i if (localProfile) { promises.push((async () => { this.logService.trace(`${this.syncResourceLogLabel}: Updating '${profile.name}' profile...`); - await this.userDataProfilesService.updateProfile(localProfile, { name: profile.name, shortName: profile.shortName }); + await this.userDataProfilesService.updateProfile(localProfile, { name: profile.name, shortName: profile.shortName, useDefaultFlags: profile.useDefaultFlags }); this.logService.info(`${this.syncResourceLogLabel}: Updated profile '${profile.name}'.`); })()); } else { diff --git a/src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts b/src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts index 5eb007eb9b2f7..b0036c3869be8 100644 --- a/src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts +++ b/src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts @@ -71,6 +71,8 @@ suite('UserDataProfilesManifestMerge', () => { toUserDataProfile('5', '5', URI.file('5'), URI.file('cache')), toUserDataProfile('6', '6', URI.file('6'), URI.file('cache')), toUserDataProfile('8', '8', URI.file('8'), URI.file('cache')), + toUserDataProfile('10', '10', URI.file('8'), URI.file('cache'), { useDefaultFlags: { tasks: true } }), + toUserDataProfile('11', '11', URI.file('1'), URI.file('cache'), { useDefaultFlags: { keybindings: true } }), ]; const base: ISyncUserDataProfile[] = [ { id: '1', name: '1', collection: '1' }, @@ -79,6 +81,8 @@ suite('UserDataProfilesManifestMerge', () => { { id: '4', name: '4', collection: '4' }, { id: '5', name: '5', collection: '5' }, { id: '6', name: '6', collection: '6' }, + { id: '10', name: '10', collection: '10', useDefaultFlags: { tasks: true } }, + { id: '11', name: '11', collection: '11' }, ]; const remoteProfiles: ISyncUserDataProfile[] = [ { id: '1', name: '1', collection: '1' }, @@ -87,15 +91,18 @@ suite('UserDataProfilesManifestMerge', () => { { id: '4', name: 'changed remote', collection: '4' }, { id: '5', name: '5', collection: '5' }, { id: '7', name: '7', collection: '7' }, + { id: '9', name: '9', collection: '9', useDefaultFlags: { snippets: true } }, + { id: '10', name: '10', collection: '10' }, + { id: '11', name: '11', collection: '11' }, ]; const actual = merge(localProfiles, remoteProfiles, base, []); - assert.deepStrictEqual(actual.local.added, [remoteProfiles[5]]); + assert.deepStrictEqual(actual.local.added, [remoteProfiles[5], remoteProfiles[6]]); assert.deepStrictEqual(actual.local.removed, [localProfiles[4]]); - assert.deepStrictEqual(actual.local.updated, [remoteProfiles[2], remoteProfiles[3]]); + assert.deepStrictEqual(actual.local.updated, [remoteProfiles[2], remoteProfiles[3], remoteProfiles[7]]); assert.deepStrictEqual(actual.remote?.added, [localProfiles[5]]); - assert.deepStrictEqual(actual.remote?.updated, [localProfiles[0]]); + assert.deepStrictEqual(actual.remote?.updated, [localProfiles[0], localProfiles[7]]); assert.deepStrictEqual(actual.remote?.removed, [remoteProfiles[1]]); }); diff --git a/src/vs/platform/userDataSync/test/common/userDataProfilesManifestSync.test.ts b/src/vs/platform/userDataSync/test/common/userDataProfilesManifestSync.test.ts index 068718a3f859b..d1c7b6f572d4b 100644 --- a/src/vs/platform/userDataSync/test/common/userDataProfilesManifestSync.test.ts +++ b/src/vs/platform/userDataSync/test/common/userDataProfilesManifestSync.test.ts @@ -217,6 +217,47 @@ suite('UserDataProfilesManifestSync', () => { assert.deepStrictEqual(getLocalProfiles(testClient), [{ id: '1', name: 'name 1', shortName: undefined, useDefaultFlags: { keybindings: true } }]); }); + test('sync profile when the profile is updated to use default profile locally', async () => { + await client2.instantiationService.get(IUserDataProfilesService).createProfile('1', 'name 1'); + await client2.sync(); + + await testObject.sync(await testClient.getResourceManifest()); + + const profile = testClient.instantiationService.get(IUserDataProfilesService).profiles.find(p => p.id === '1')!; + testClient.instantiationService.get(IUserDataProfilesService).updateProfile(profile, { useDefaultFlags: { keybindings: true } }); + + await testObject.sync(await testClient.getResourceManifest()); + assert.strictEqual(testObject.status, SyncStatus.Idle); + assert.deepStrictEqual(testObject.conflicts.conflicts, []); + + const { content } = await testClient.read(testObject.resource); + assert.ok(content !== null); + const actual = parseRemoteProfiles(content!); + assert.deepStrictEqual(actual, [{ id: '1', name: 'name 1', collection: '1', useDefaultFlags: { keybindings: true } }]); + assert.deepStrictEqual(getLocalProfiles(testClient), [{ id: '1', name: 'name 1', shortName: undefined, useDefaultFlags: { keybindings: true } }]); + }); + + test('sync profile when the profile is updated to use default profile remotely', async () => { + const profile = await client2.instantiationService.get(IUserDataProfilesService).createProfile('1', 'name 1'); + await client2.sync(); + + await testObject.sync(await testClient.getResourceManifest()); + + client2.instantiationService.get(IUserDataProfilesService).updateProfile(profile, { useDefaultFlags: { keybindings: true } }); + await client2.sync(); + + await testObject.sync(await testClient.getResourceManifest()); + assert.strictEqual(testObject.status, SyncStatus.Idle); + assert.deepStrictEqual(testObject.conflicts.conflicts, []); + + const { content } = await testClient.read(testObject.resource); + assert.ok(content !== null); + const actual = parseRemoteProfiles(content!); + assert.deepStrictEqual(actual, [{ id: '1', name: 'name 1', collection: '1', useDefaultFlags: { keybindings: true } }]); + + assert.deepStrictEqual(getLocalProfiles(testClient), [{ id: '1', name: 'name 1', shortName: undefined, useDefaultFlags: { keybindings: true } }]); + }); + function parseRemoteProfiles(content: string): ISyncUserDataProfile[] { const syncData: ISyncData = JSON.parse(content); return JSON.parse(syncData.content); diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index 6fbd655eb6778..d09cfa07930cd 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -9,7 +9,6 @@ import { EventType, addDisposableListener, EventHelper, append, $, clearNode, hi import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch'; import { Action, IAction, Separator, SubmenuAction, toAction } from 'vs/base/common/actions'; -import { Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IMenuService, MenuId, IMenu, registerAction2, Action2, IAction2Options } from 'vs/platform/actions/common/actions'; @@ -485,7 +484,7 @@ export class GlobalActivityActionViewItem extends MenuActivityActionViewItem { @IKeybindingService keybindingService: IKeybindingService, ) { super(MenuId.GlobalActivity, action, contextMenuActionsProvider, true, colors, activityHoverOptions, themeService, hoverService, menuService, contextMenuService, contextKeyService, configurationService, environmentService, keybindingService); - this._register(Event.any(this.userDataProfileService.onDidUpdateCurrentProfile, this.userDataProfileService.onDidChangeCurrentProfile)(() => this.updateProfileBadge())); + this._register(this.userDataProfileService.onDidChangeCurrentProfile(() => this.updateProfileBadge())); } override render(container: HTMLElement): void { diff --git a/src/vs/workbench/browser/parts/titlebar/windowTitle.ts b/src/vs/workbench/browser/parts/titlebar/windowTitle.ts index 805ee48cd2957..bcfc971b2a485 100644 --- a/src/vs/workbench/browser/parts/titlebar/windowTitle.ts +++ b/src/vs/workbench/browser/parts/titlebar/windowTitle.ts @@ -76,7 +76,6 @@ export class WindowTitle extends Disposable { this._register(this.contextService.onDidChangeWorkspaceName(() => this.titleUpdater.schedule())); this._register(this.labelService.onDidChangeFormatters(() => this.titleUpdater.schedule())); this._register(this.userDataProfileService.onDidChangeCurrentProfile(() => this.titleUpdater.schedule())); - this._register(this.userDataProfileService.onDidUpdateCurrentProfile(() => this.titleUpdater.schedule())); } private onConfigurationChanged(event: IConfigurationChangeEvent): void { diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index bd7165c5d1246..52c03ecba67cd 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -78,7 +78,6 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStringDictionary } from 'vs/base/common/collections'; import { CONTEXT_KEYBINDINGS_EDITOR } from 'vs/workbench/contrib/preferences/common/preferences'; import { DeprecatedExtensionsChecker } from 'vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker'; -import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; // Singletons registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService, InstantiationType.Eager /* Auto updates extensions */); @@ -473,7 +472,6 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi @IInstantiationService private readonly instantiationService: IInstantiationService, @IDialogService private readonly dialogService: IDialogService, @ICommandService private readonly commandService: ICommandService, - @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, ) { super(); const hasGalleryContext = CONTEXT_HAS_GALLERY.bindTo(contextKeyService); @@ -517,31 +515,22 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi // Global actions private registerGlobalActions(): void { - const getTitle = (title: string) => !this.userDataProfileService.currentProfile.isDefault && this.userDataProfileService.currentProfile.useDefaultFlags?.extensions - ? `${title} (${localize('default profile', "Default Profile")})` - : title; - const registerOpenExtensionsActionDisposables = this._register(new DisposableStore()); - const registerOpenExtensionsAction = () => { - registerOpenExtensionsActionDisposables.clear(); - registerOpenExtensionsActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { - command: { - id: VIEWLET_ID, - title: getTitle(localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions")) - }, - group: '2_configuration', - order: 3 - })); - registerOpenExtensionsActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { - command: { - id: VIEWLET_ID, - title: getTitle(localize('showExtensions', "Extensions")) - }, - group: '2_configuration', - order: 3 - })); - }; - registerOpenExtensionsAction(); - this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => registerOpenExtensionsAction())); + this._register(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { + command: { + id: VIEWLET_ID, + title: localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions") + }, + group: '2_configuration', + order: 3 + })); + this._register(MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { + command: { + id: VIEWLET_ID, + title: localize('showExtensions', "Extensions") + }, + group: '2_configuration', + order: 3 + })); this.registerExtensionAction({ id: 'workbench.extensions.action.installExtensions', diff --git a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts index 90a505ca3d7c5..71973bd765387 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts @@ -12,7 +12,6 @@ import 'vs/css!./media/preferences'; import { EditorContributionInstantiation, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/suggest'; import * as nls from 'vs/nls'; -import { Event } from 'vs/base/common/event'; import { Action2, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -188,46 +187,37 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon } private registerSettingsActions() { - const registerOpenSettingsActionDisposables = this._register(new DisposableStore()); - const registerOpenSettingsAction = () => { - registerOpenSettingsActionDisposables.clear(); - const getTitle = (title: string) => !this.userDataProfileService.currentProfile.isDefault && this.userDataProfileService.currentProfile.useDefaultFlags?.settings - ? `${title} (${nls.localize('default profile', "Default Profile")})` - : title; - registerOpenSettingsActionDisposables.add(registerAction2(class extends Action2 { - constructor() { - super({ - id: SETTINGS_COMMAND_OPEN_SETTINGS, - title: { - value: getTitle(nls.localize('settings', "Settings")), - mnemonicTitle: getTitle(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings")), - original: 'Settings' - }, - keybinding: { - weight: KeybindingWeight.WorkbenchContrib, - when: null, - primary: KeyMod.CtrlCmd | KeyCode.Comma, - }, - menu: [{ - id: MenuId.GlobalActivity, - group: '2_configuration', - order: 1 - }, { - id: MenuId.MenubarPreferencesMenu, - group: '2_configuration', - order: 1 - }], - }); - } - run(accessor: ServicesAccessor, args: string | IOpenSettingsActionOptions) { - // args takes a string for backcompat - const opts = typeof args === 'string' ? { query: args } : sanitizeOpenSettingsArgs(args); - return accessor.get(IPreferencesService).openSettings(opts); - } - })); - }; - registerOpenSettingsAction(); - this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => registerOpenSettingsAction())); + this._register(registerAction2(class extends Action2 { + constructor() { + super({ + id: SETTINGS_COMMAND_OPEN_SETTINGS, + title: { + value: nls.localize('settings', "Settings"), + mnemonicTitle: nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), + original: 'Settings' + }, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + when: null, + primary: KeyMod.CtrlCmd | KeyCode.Comma, + }, + menu: [{ + id: MenuId.GlobalActivity, + group: '2_configuration', + order: 1 + }, { + id: MenuId.MenubarPreferencesMenu, + group: '2_configuration', + order: 1 + }], + }); + } + run(accessor: ServicesAccessor, args: string | IOpenSettingsActionOptions) { + // args takes a string for backcompat + const opts = typeof args === 'string' ? { query: args } : sanitizeOpenSettingsArgs(args); + return accessor.get(IPreferencesService).openSettings(opts); + } + })); registerAction2(class extends Action2 { constructor() { super({ @@ -306,13 +296,13 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon } }); - const registerOpenUserSettingsEditorFromJsonActionDisposable = this._register(new MutableDisposable()); + const registerOpenUserSettingsEditorFromJsonActionDisposables = this._register(new MutableDisposable()); const openUserSettingsEditorWhen = ContextKeyExpr.and( ContextKeyExpr.or(ResourceContextKey.Resource.isEqualTo(this.userDataProfileService.currentProfile.settingsResource.toString()), ResourceContextKey.Resource.isEqualTo(this.userDataProfilesService.defaultProfile.settingsResource.toString())), ContextKeyExpr.not('isInDiffEditor')); const registerOpenUserSettingsEditorFromJsonAction = () => { - registerOpenUserSettingsEditorFromJsonActionDisposable.value = registerAction2(class extends Action2 { + registerOpenUserSettingsEditorFromJsonActionDisposables.value = registerAction2(class extends Action2 { constructor() { super({ id: '_workbench.openUserSettingsEditor', @@ -816,58 +806,49 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon private registerKeybindingsActions() { const that = this; const category = { value: nls.localize('preferences', "Preferences"), original: 'Preferences' }; - const registerOpenGlobalKeybindingsActionDisposables = this._register(new DisposableStore()); - const registerOpenGlobalKeybindingsAction = () => { - registerOpenGlobalKeybindingsActionDisposables.clear(); - const id = 'workbench.action.openGlobalKeybindings'; - const shortTitle = !that.userDataProfileService.currentProfile.isDefault && that.userDataProfileService.currentProfile.useDefaultFlags?.keybindings - ? nls.localize('keyboardShortcutsFromDefault', "Keyboard Shortcuts ({0})", nls.localize('default profile', "Default Profile")) - : nls.localize('keyboardShortcuts', "Keyboard Shortcuts"); - registerOpenGlobalKeybindingsActionDisposables.add(registerAction2(class extends Action2 { - constructor() { - super({ - id, - title: { value: nls.localize('openGlobalKeybindings', "Open Keyboard Shortcuts"), original: 'Open Keyboard Shortcuts' }, - shortTitle, - category, - icon: preferencesOpenSettingsIcon, - keybinding: { - when: null, - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyS) - }, - menu: [ - { id: MenuId.CommandPalette }, - { - id: MenuId.EditorTitle, - when: ResourceContextKey.Resource.isEqualTo(that.userDataProfileService.currentProfile.keybindingsResource.toString()), - group: 'navigation', - order: 1, - }, - { - id: MenuId.GlobalActivity, - group: '2_configuration', - order: 3 - } - ] - }); - } - run(accessor: ServicesAccessor, args: string | undefined) { - const query = typeof args === 'string' ? args : undefined; - return accessor.get(IPreferencesService).openGlobalKeybindingSettings(false, { query }); - } - })); - registerOpenGlobalKeybindingsActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { - command: { + const id = 'workbench.action.openGlobalKeybindings'; + this._register(registerAction2(class extends Action2 { + constructor() { + super({ id, - title: shortTitle, - }, - group: '2_configuration', - order: 3 - })); - }; - registerOpenGlobalKeybindingsAction(); - this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => registerOpenGlobalKeybindingsAction())); + title: { value: nls.localize('openGlobalKeybindings', "Open Keyboard Shortcuts"), original: 'Open Keyboard Shortcuts' }, + shortTitle: nls.localize('keyboardShortcuts', "Keyboard Shortcuts"), + category, + icon: preferencesOpenSettingsIcon, + keybinding: { + when: null, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyS) + }, + menu: [ + { id: MenuId.CommandPalette }, + { + id: MenuId.EditorTitle, + when: ResourceContextKey.Resource.isEqualTo(that.userDataProfileService.currentProfile.keybindingsResource.toString()), + group: 'navigation', + order: 1, + }, + { + id: MenuId.GlobalActivity, + group: '2_configuration', + order: 3 + } + ] + }); + } + run(accessor: ServicesAccessor, args: string | undefined) { + const query = typeof args === 'string' ? args : undefined; + return accessor.get(IPreferencesService).openGlobalKeybindingSettings(false, { query }); + } + })); + this._register(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { + command: { + id, + title: nls.localize('keyboardShortcuts', "Keyboard Shortcuts"), + }, + group: '2_configuration', + order: 3 + })); registerAction2(class extends Action2 { constructor() { super({ diff --git a/src/vs/workbench/contrib/snippets/browser/commands/configureSnippets.ts b/src/vs/workbench/contrib/snippets/browser/commands/configureSnippets.ts index 7f8948aae61c7..9d2a199fe186e 100644 --- a/src/vs/workbench/contrib/snippets/browser/commands/configureSnippets.ts +++ b/src/vs/workbench/contrib/snippets/browser/commands/configureSnippets.ts @@ -4,21 +4,18 @@ *--------------------------------------------------------------------------------------------*/ import { isValidBasename } from 'vs/base/common/extpath'; -import { Disposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { Event } from 'vs/base/common/event'; import { extname } from 'vs/base/common/path'; import { basename, joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { ILanguageService } from 'vs/editor/common/languages/language'; import * as nls from 'vs/nls'; -import { MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { MenuId } from 'vs/platform/actions/common/actions'; import { IFileService } from 'vs/platform/files/common/files'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { SnippetsAction } from 'vs/workbench/contrib/snippets/browser/commands/abstractSnippetsActions'; import { ISnippetsService } from 'vs/workbench/contrib/snippets/browser/snippets'; import { SnippetSource } from 'vs/workbench/contrib/snippets/browser/snippetsFile'; @@ -224,97 +221,80 @@ async function createLanguageSnippetFile(pick: ISnippetPick, fileService: IFileS await textFileService.write(pick.filepath, contents); } -export class ConfigureSnippetsActions extends Disposable implements IWorkbenchContribution { - - constructor( - @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, - ) { - super(); - const disposable = this._register(new MutableDisposable()); - disposable.value = this.registerAction(); - this._register(Event.any(userDataProfileService.onDidChangeCurrentProfile, userDataProfileService.onDidUpdateCurrentProfile)(() => disposable.value = this.registerAction())); +export class ConfigureSnippetsAction extends SnippetsAction { + constructor() { + super({ + id: 'workbench.action.openSnippets', + title: { + value: nls.localize('openSnippet.label', "Configure User Snippets"), + original: 'Configure User Snippets' + }, + shortTitle: { + value: nls.localize('userSnippets', "User Snippets"), + mnemonicTitle: nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets"), + original: 'User Snippets' + }, + f1: true, + menu: [ + { id: MenuId.MenubarPreferencesMenu, group: '2_configuration', order: 4 }, + { id: MenuId.GlobalActivity, group: '2_configuration', order: 4 }, + ] + }); } - private registerAction(): IDisposable { - const getTitle = (title: string) => !this.userDataProfileService.currentProfile.isDefault && this.userDataProfileService.currentProfile.useDefaultFlags?.snippets - ? `${title} (${nls.localize('default', "Default Profile")})` - : title; - return registerAction2(class extends SnippetsAction { - constructor() { - super({ - id: 'workbench.action.openSnippets', - title: { - value: nls.localize('openSnippet.label', "Configure User Snippets"), - original: 'Configure User Snippets' - }, - shortTitle: { - value: getTitle(nls.localize('userSnippets', "User Snippets")), - mnemonicTitle: getTitle(nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets")), - original: 'User Snippets' - }, - f1: true, - menu: [ - { id: MenuId.MenubarPreferencesMenu, group: '2_configuration', order: 4 }, - { id: MenuId.GlobalActivity, group: '2_configuration', order: 4 }, - ] - }); - } - - async run(accessor: ServicesAccessor): Promise { - - const snippetService = accessor.get(ISnippetsService); - const quickInputService = accessor.get(IQuickInputService); - const opener = accessor.get(IOpenerService); - const languageService = accessor.get(ILanguageService); - const userDataProfileService = accessor.get(IUserDataProfileService); - const workspaceService = accessor.get(IWorkspaceContextService); - const fileService = accessor.get(IFileService); - const textFileService = accessor.get(ITextFileService); - const labelService = accessor.get(ILabelService); - - const picks = await computePicks(snippetService, userDataProfileService, languageService, labelService); - const existing: QuickPickInput[] = picks.existing; - - type SnippetPick = IQuickPickItem & { uri: URI } & { scope: string }; - const globalSnippetPicks: SnippetPick[] = [{ - scope: nls.localize('new.global_scope', 'global'), - label: nls.localize('new.global', "New Global Snippets file..."), - uri: userDataProfileService.currentProfile.snippetsHome - }]; - - const workspaceSnippetPicks: SnippetPick[] = []; - for (const folder of workspaceService.getWorkspace().folders) { - workspaceSnippetPicks.push({ - scope: nls.localize('new.workspace_scope', "{0} workspace", folder.name), - label: nls.localize('new.folder', "New Snippets file for '{0}'...", folder.name), - uri: folder.toResource('.vscode') - }); - } + async run(accessor: ServicesAccessor): Promise { + + const snippetService = accessor.get(ISnippetsService); + const quickInputService = accessor.get(IQuickInputService); + const opener = accessor.get(IOpenerService); + const languageService = accessor.get(ILanguageService); + const userDataProfileService = accessor.get(IUserDataProfileService); + const workspaceService = accessor.get(IWorkspaceContextService); + const fileService = accessor.get(IFileService); + const textFileService = accessor.get(ITextFileService); + const labelService = accessor.get(ILabelService); + + const picks = await computePicks(snippetService, userDataProfileService, languageService, labelService); + const existing: QuickPickInput[] = picks.existing; + + type SnippetPick = IQuickPickItem & { uri: URI } & { scope: string }; + const globalSnippetPicks: SnippetPick[] = [{ + scope: nls.localize('new.global_scope', 'global'), + label: nls.localize('new.global', "New Global Snippets file..."), + uri: userDataProfileService.currentProfile.snippetsHome + }]; + + const workspaceSnippetPicks: SnippetPick[] = []; + for (const folder of workspaceService.getWorkspace().folders) { + workspaceSnippetPicks.push({ + scope: nls.localize('new.workspace_scope', "{0} workspace", folder.name), + label: nls.localize('new.folder', "New Snippets file for '{0}'...", folder.name), + uri: folder.toResource('.vscode') + }); + } - if (existing.length > 0) { - existing.unshift({ type: 'separator', label: nls.localize('group.global', "Existing Snippets") }); - existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); - } else { - existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); - } + if (existing.length > 0) { + existing.unshift({ type: 'separator', label: nls.localize('group.global', "Existing Snippets") }); + existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); + } else { + existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); + } - const pick = await quickInputService.pick(([] as QuickPickInput[]).concat(existing, globalSnippetPicks, workspaceSnippetPicks, picks.future), { - placeHolder: nls.localize('openSnippet.pickLanguage', "Select Snippets File or Create Snippets"), - matchOnDescription: true - }); - - if (globalSnippetPicks.indexOf(pick as SnippetPick) >= 0) { - return createSnippetFile((pick as SnippetPick).scope, (pick as SnippetPick).uri, quickInputService, fileService, textFileService, opener); - } else if (workspaceSnippetPicks.indexOf(pick as SnippetPick) >= 0) { - return createSnippetFile((pick as SnippetPick).scope, (pick as SnippetPick).uri, quickInputService, fileService, textFileService, opener); - } else if (ISnippetPick.is(pick)) { - if (pick.hint) { - await createLanguageSnippetFile(pick, fileService, textFileService); - } - return opener.open(pick.filepath); - } + const pick = await quickInputService.pick(([] as QuickPickInput[]).concat(existing, globalSnippetPicks, workspaceSnippetPicks, picks.future), { + placeHolder: nls.localize('openSnippet.pickLanguage', "Select Snippets File or Create Snippets"), + matchOnDescription: true + }); + if (globalSnippetPicks.indexOf(pick as SnippetPick) >= 0) { + return createSnippetFile((pick as SnippetPick).scope, (pick as SnippetPick).uri, quickInputService, fileService, textFileService, opener); + } else if (workspaceSnippetPicks.indexOf(pick as SnippetPick) >= 0) { + return createSnippetFile((pick as SnippetPick).scope, (pick as SnippetPick).uri, quickInputService, fileService, textFileService, opener); + } else if (ISnippetPick.is(pick)) { + if (pick.hint) { + await createLanguageSnippetFile(pick, fileService, textFileService); } - }); + return opener.open(pick.filepath); + } + } } diff --git a/src/vs/workbench/contrib/snippets/browser/snippets.contribution.ts b/src/vs/workbench/contrib/snippets/browser/snippets.contribution.ts index b78f735e1fcfb..0ad6445077f6d 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippets.contribution.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippets.contribution.ts @@ -11,7 +11,7 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import * as JSONContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { ConfigureSnippetsActions } from 'vs/workbench/contrib/snippets/browser/commands/configureSnippets'; +import { ConfigureSnippetsAction } from 'vs/workbench/contrib/snippets/browser/commands/configureSnippets'; import { ApplyFileSnippetAction } from 'vs/workbench/contrib/snippets/browser/commands/fileTemplateSnippets'; import { InsertSnippetAction } from 'vs/workbench/contrib/snippets/browser/commands/insertSnippet'; import { SurroundWithSnippetEditorAction } from 'vs/workbench/contrib/snippets/browser/commands/surroundWithSnippet'; @@ -32,10 +32,10 @@ registerAction2(InsertSnippetAction); CommandsRegistry.registerCommandAlias('editor.action.showSnippets', 'editor.action.insertSnippet'); registerAction2(SurroundWithSnippetEditorAction); registerAction2(ApplyFileSnippetAction); +registerAction2(ConfigureSnippetsAction); // workbench contribs const workbenchContribRegistry = Registry.as(WorkbenchExtensions.Workbench); -workbenchContribRegistry.registerWorkbenchContribution(ConfigureSnippetsActions, LifecyclePhase.Restored); workbenchContribRegistry.registerWorkbenchContribution(SnippetCodeActions, LifecyclePhase.Restored); // config diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index fa2b3ec19f23d..d20bb9d437083 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -5,8 +5,7 @@ import * as nls from 'vs/nls'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { Event } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { MenuRegistry, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -40,7 +39,6 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry'; import { TerminalMenuBarGroup } from 'vs/workbench/contrib/terminal/browser/terminalMenus'; import { isString } from 'vs/base/common/types'; -import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(RunAutomaticTasks, LifecyclePhase.Eventually); @@ -356,43 +354,32 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { class UserTasksGlobalActionContribution extends Disposable implements IWorkbenchContribution { - constructor( - @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, - ) { + constructor() { super(); this.registerActions(); } private registerActions() { - const registerOpenUserTasksActionDisposables = this._register(new DisposableStore()); - const registerOpenSettingsAction = () => { - registerOpenUserTasksActionDisposables.clear(); - const id = 'workbench.action.tasks.openUserTasks'; - const userTasksTitle = nls.localize('userTasks', "User Tasks"); - const title = !this.userDataProfileService.currentProfile.isDefault && this.userDataProfileService.currentProfile.useDefaultFlags?.tasks - ? `${userTasksTitle} (${nls.localize('default profile', "Default Profile")})` - : userTasksTitle; - registerOpenUserTasksActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { - command: { - id, - title - }, - when: TaskExecutionSupportedContext, - group: '2_configuration', - order: 4 - })); - registerOpenUserTasksActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { - command: { - id, - title - }, - when: TaskExecutionSupportedContext, - group: '2_configuration', - order: 4 - })); - }; - registerOpenSettingsAction(); - this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => registerOpenSettingsAction())); + const id = 'workbench.action.tasks.openUserTasks'; + const title = nls.localize('userTasks', "User Tasks"); + this._register(MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { + command: { + id, + title + }, + when: TaskExecutionSupportedContext, + group: '2_configuration', + order: 4 + })); + this._register(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { + command: { + id, + title + }, + when: TaskExecutionSupportedContext, + group: '2_configuration', + order: 4 + })); } } workbenchRegistry.registerWorkbenchContribution(UserTasksGlobalActionContribution, LifecyclePhase.Restored); diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 3c8e7b62c303e..709d9d213f19b 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -100,7 +100,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements this._register(this.userDataProfilesService.onDidChangeProfiles(() => this.registerProfilesActions())); this.registerCurrentProfilesActions(); - this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => this.registerCurrentProfilesActions())); + this._register(this.userDataProfileService.onDidChangeCurrentProfile(() => this.registerCurrentProfilesActions())); this.registerCreateFromCurrentProfileAction(); this.registerCreateProfileAction(); @@ -577,7 +577,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements extensions: result.items.includes(extensions) } : undefined; if (profile) { - await this.userDataProfileManagementService.updateProfile(profile, { name: result.name, useDefaultFlags }); + await this.userDataProfileManagementService.updateProfile(profile, { name: result.name, useDefaultFlags: profile.useDefaultFlags && !useDefaultFlags ? {} : useDefaultFlags }); } else { if (isString(source)) { await this.userDataProfileImportExportService.importProfile(URI.parse(source), { mode: 'apply', name: result.name, useDefaultFlags }); diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 9a920e59af042..cb75f62e36c53 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -717,7 +717,8 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat e.join((async () => { const promises: Promise[] = []; promises.push(this.localUserConfiguration.reset(e.profile.settingsResource, e.profile.tasksResource, { scopes: getLocalUserConfigurationScopes(e.profile, !!this.remoteUserConfiguration) })); - if (e.previous.isDefault !== e.profile.isDefault) { + if (e.previous.isDefault !== e.profile.isDefault + || !!e.previous.useDefaultFlags?.settings !== !!e.profile.useDefaultFlags?.settings) { this.createApplicationConfiguration(); if (this.applicationConfiguration) { promises.push(this.reloadApplicationConfiguration(true)); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts index 54fa99d070402..aa017e86fb375 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts @@ -25,7 +25,11 @@ export abstract class ProfileAwareExtensionManagementChannelClient extends BaseE protected readonly uriIdentityService: IUriIdentityService, ) { super(channel); - this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => { + if (!this.uriIdentityService.extUri.isEqual(e.previous.extensionsResource, e.profile.extensionsResource)) { + e.join(this.whenProfileChanged(e)); + } + })); } protected override fireEvent(event: Emitter, data: InstallExtensionEvent): Promise; diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 5aa0db557152d..d26b6ed0bdd23 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -64,7 +64,11 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, ) { super(extensionGalleryService, telemetryService, logService, productService, userDataProfilesService); - this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => { + if (!this.uriIdentityService.extUri.isEqual(e.previous.extensionsResource, e.profile.extensionsResource)) { + e.join(this.whenProfileChanged(e)); + } + })); } private filterEvent({ profileLocation, applicationScoped }: { profileLocation?: URI; applicationScoped?: boolean }): boolean { diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index 82356b72fde90..e6112182d25ed 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -51,7 +51,8 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IKeyboard, INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/browser/navigatorKeyboard'; import { getAllUnboundCommands } from 'vs/workbench/services/keybinding/browser/unboundCommands'; import { IUserKeybindingItem, KeybindingIO, OutputBuilder } from 'vs/workbench/services/keybinding/common/keybindingIO'; -import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; interface ContributedKeyBinding { command: string; @@ -192,6 +193,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { @IHostService private readonly hostService: IHostService, @IExtensionService extensionService: IExtensionService, @IFileService fileService: IFileService, + @IUriIdentityService uriIdentityService: IUriIdentityService, @ILogService logService: ILogService, @IKeyboardLayoutService private readonly keyboardLayoutService: IKeyboardLayoutService ) { @@ -210,7 +212,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { this._cachedResolver = null; - this.userKeybindings = this._register(new UserKeybindings(userDataProfileService, fileService, logService)); + this.userKeybindings = this._register(new UserKeybindings(userDataProfileService, uriIdentityService, fileService, logService)); this.userKeybindings.initialize().then(() => { if (this.userKeybindings.keybindings.length) { this.updateResolver(); @@ -699,6 +701,7 @@ class UserKeybindings extends Disposable { constructor( private readonly userDataProfileService: IUserDataProfileService, + private readonly uriIdentityService: IUriIdentityService, private readonly fileService: IFileService, logService: ILogService, ) { @@ -724,10 +727,14 @@ class UserKeybindings extends Disposable { } })); - this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenCurrentProfileChanged(e)))); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => { + if (!this.uriIdentityService.extUri.isEqual(e.previous.keybindingsResource, e.profile.keybindingsResource)) { + e.join(this.whenCurrentProfileChanged()); + } + })); } - private async whenCurrentProfileChanged(e: DidChangeUserDataProfileEvent): Promise { + private async whenCurrentProfileChanged(): Promise { this.watch(); this.reloadConfigurationScheduler.schedule(); } diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index 75d7d57e639c3..9468c15aee2d9 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -43,18 +43,24 @@ export class UserDataProfileManagementService extends Disposable implements IUse this._register(userDataProfilesService.onDidChangeProfiles(e => this.onDidChangeProfiles(e))); this._register(userDataProfilesService.onDidResetWorkspaces(() => this.onDidResetWorkspaces())); this._register(userDataProfileService.onDidChangeCurrentProfile(e => this.onDidChangeCurrentProfile(e))); + this._register(userDataProfilesService.onDidChangeProfiles(e => { + const updatedCurrentProfile = e.updated.find(p => this.userDataProfileService.currentProfile.id === p.id); + if (updatedCurrentProfile) { + this.changeCurrentProfile(updatedCurrentProfile, localize('reload message when updated', "The current profile has been updated. Please reload to switch back to the updated profile")); + } + })); } private onDidChangeProfiles(e: DidChangeProfilesEvent): void { if (e.removed.some(profile => profile.id === this.userDataProfileService.currentProfile.id)) { - this.enterProfile(this.userDataProfilesService.defaultProfile, localize('reload message when removed', "The current profile has been removed. Please reload to switch back to default profile")); + this.changeCurrentProfile(this.userDataProfilesService.defaultProfile, localize('reload message when removed', "The current profile has been removed. Please reload to switch back to default profile")); return; } } private onDidResetWorkspaces(): void { if (!this.userDataProfileService.currentProfile.isDefault) { - this.enterProfile(this.userDataProfilesService.defaultProfile, localize('reload message when removed', "The current profile has been removed. Please reload to switch back to default profile")); + this.changeCurrentProfile(this.userDataProfilesService.defaultProfile, localize('reload message when removed', "The current profile has been removed. Please reload to switch back to default profile")); return; } } @@ -67,14 +73,14 @@ export class UserDataProfileManagementService extends Disposable implements IUse async createAndEnterProfile(name: string, options?: IUserDataProfileOptions): Promise { const profile = await this.userDataProfilesService.createNamedProfile(name, options, toWorkspaceIdentifier(this.workspaceContextService.getWorkspace())); - await this.enterProfile(profile); + await this.changeCurrentProfile(profile); this.telemetryService.publicLog2('profileManagementActionExecuted', { id: 'createAndEnterProfile' }); return profile; } async createAndEnterTransientProfile(): Promise { const profile = await this.userDataProfilesService.createTransientProfile(toWorkspaceIdentifier(this.workspaceContextService.getWorkspace())); - await this.enterProfile(profile); + await this.changeCurrentProfile(profile); this.telemetryService.publicLog2('profileManagementActionExecuted', { id: 'createAndEnterTransientProfile' }); return profile; } @@ -110,11 +116,11 @@ export class UserDataProfileManagementService extends Disposable implements IUse return; } await this.userDataProfilesService.setProfileForWorkspace(workspaceIdentifier, profile); - await this.enterProfile(profile); + await this.changeCurrentProfile(profile); this.telemetryService.publicLog2('profileManagementActionExecuted', { id: 'switchProfile' }); } - private async enterProfile(profile: IUserDataProfile, reloadMessage?: string): Promise { + private async changeCurrentProfile(profile: IUserDataProfile, reloadMessage?: string): Promise { const isRemoteWindow = !!this.environmentService.remoteAuthority; if (!isRemoteWindow) { diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index 3c56ae564f290..d68ed2e329e8e 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -27,9 +27,8 @@ export interface DidChangeUserDataProfileEvent { export const IUserDataProfileService = createDecorator('IUserDataProfileService'); export interface IUserDataProfileService { readonly _serviceBrand: undefined; - readonly onDidUpdateCurrentProfile: Event; - readonly onDidChangeCurrentProfile: Event; readonly currentProfile: IUserDataProfile; + readonly onDidChangeCurrentProfile: Event; updateCurrentProfile(currentProfile: IUserDataProfile): Promise; getShortName(profile: IUserDataProfile): string; } diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts index c86fa236bab59..7135c0be4419a 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts @@ -6,6 +6,7 @@ import { Promises } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; +import { equals } from 'vs/base/common/objects'; import { ThemeIcon } from 'vs/base/common/themables'; import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { defaultUserDataProfileIcon, DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; @@ -17,9 +18,6 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi private readonly _onDidChangeCurrentProfile = this._register(new Emitter()); readonly onDidChangeCurrentProfile = this._onDidChangeCurrentProfile.event; - private readonly _onDidUpdateCurrentProfile = this._register(new Emitter()); - readonly onDidUpdateCurrentProfile = this._onDidUpdateCurrentProfile.event; - private _currentProfile: IUserDataProfile; get currentProfile(): IUserDataProfile { return this._currentProfile; } @@ -29,17 +27,10 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi ) { super(); this._currentProfile = currentProfile; - this._register(userDataProfilesService.onDidChangeProfiles(e => { - const updatedCurrentProfile = e.updated.find(p => this._currentProfile.id === p.id); - if (updatedCurrentProfile) { - this._currentProfile = updatedCurrentProfile; - this._onDidUpdateCurrentProfile.fire(); - } - })); } async updateCurrentProfile(userDataProfile: IUserDataProfile): Promise { - if (this._currentProfile.id === userDataProfile.id) { + if (equals(this._currentProfile, userDataProfile)) { return; } const previous = this._currentProfile; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index a333fabb14e34..c892739221a43 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -2039,12 +2039,12 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens } copyExtensions(): Promise { throw new Error('Not Supported'); } installExtensionsFromProfile(): Promise { throw new Error('Not Supported'); } + whenProfileChanged(from: IUserDataProfile, to: IUserDataProfile): Promise { throw new Error('Not Supported'); } } export class TestUserDataProfileService implements IUserDataProfileService { readonly _serviceBrand: undefined; - readonly onDidUpdateCurrentProfile = Event.None; readonly onDidChangeCurrentProfile = Event.None; readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' }), URI.file('tests').with({ scheme: 'vscode-tests' })); async updateCurrentProfile(): Promise { } From fa00dc8eabaccb1f3e917cb85aa82b8e679c1163 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 17 Jul 2023 11:19:32 +0200 Subject: [PATCH 0157/1180] feedback (#188052) #156144 feedback --- .../browser/userDataProfile.ts | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 709d9d213f19b..f6d372a3a22b2 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -428,11 +428,11 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements const disposables = new DisposableStore(); const title = profile ? localize('save profile', "Edit Profile...") : localize('create new profle', "Create New Profile..."); - const settings: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Settings, label: localize('settings', "Settings"), picked: profile?.useDefaultFlags?.settings }; - const keybindings: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Keybindings, label: localize('keybindings', "Keyboard Shortcuts"), picked: profile?.useDefaultFlags?.keybindings }; - const snippets: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Snippets, label: localize('snippets', "User Snippets"), picked: profile?.useDefaultFlags?.snippets }; - const tasks: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Tasks, label: localize('tasks', "User Tasks"), picked: profile?.useDefaultFlags?.tasks }; - const extensions: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Extensions, label: localize('extensions', "Extensions"), picked: profile?.useDefaultFlags?.extensions }; + const settings: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Settings, label: localize('settings', "Settings"), picked: !profile?.useDefaultFlags?.settings }; + const keybindings: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Keybindings, label: localize('keybindings', "Keyboard Shortcuts"), picked: !profile?.useDefaultFlags?.keybindings }; + const snippets: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Snippets, label: localize('snippets', "User Snippets"), picked: !profile?.useDefaultFlags?.snippets }; + const tasks: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Tasks, label: localize('tasks', "User Tasks"), picked: !profile?.useDefaultFlags?.tasks }; + const extensions: IQuickPickItem & { id: ProfileResourceType } = { id: ProfileResourceType.Extensions, label: localize('extensions', "Extensions"), picked: !profile?.useDefaultFlags?.extensions }; const resources = [settings, keybindings, snippets, tasks, extensions]; const quickPick = this.quickInputService.createQuickPick(); @@ -450,13 +450,14 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements quickPick.hideCheckAll = true; quickPick.ignoreFocusOut = true; quickPick.customLabel = profile ? localize('save', "Save") : localize('create', "Create"); - quickPick.description = localize('customise the profile', "Select configurations to share from the Default profile:"); + quickPick.description = localize('customise the profile', "Choose what to configure in your Profile:"); quickPick.items = [...resources]; - const updateSelection = () => { + const update = () => { + quickPick.items = resources; quickPick.selectedItems = resources.filter(item => item.picked); }; - updateSelection(); + update(); const validate = () => { if (!profile && this.userDataProfilesService.profiles.some(p => p.name === quickPick.value)) { @@ -464,8 +465,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements quickPick.severity = Severity.Error; return; } - if (resources.every(resource => resource.picked)) { - quickPick.validationMessage = localize('cannot share all', "Cannot share all configurations from the Default Profile."); + if (resources.every(resource => !resource.picked)) { + quickPick.validationMessage = localize('invalid configurations', "The profile should contain at least one configuration."); quickPick.severity = Severity.Error; return; } @@ -474,8 +475,17 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements }; disposables.add(quickPick.onDidChangeSelection(items => { + let needUpdate = false; for (const resource of resources) { resource.picked = items.includes(resource); + const description = resource.picked ? undefined : localize('use default profile', "Use Default Profile"); + if (resource.description !== description) { + resource.description = description; + needUpdate = true; + } + } + if (needUpdate) { + update(); } validate(); })); @@ -541,7 +551,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements for (const resource of resources) { resource.picked = option.source?.useDefaultFlags?.[resource.id]; } - updateSelection(); + update(); } }; @@ -569,13 +579,15 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements this.telemetryService.publicLog2<{}, CreateProfileInfoClassification>('userDataProfile.successCreate'); try { - const useDefaultFlags: UseDefaultProfileFlags | undefined = result.items.length ? { - settings: result.items.includes(settings), - keybindings: result.items.includes(keybindings), - snippets: result.items.includes(snippets), - tasks: result.items.includes(tasks), - extensions: result.items.includes(extensions) - } : undefined; + const useDefaultFlags: UseDefaultProfileFlags | undefined = result.items.length === resources.length + ? undefined + : { + settings: !result.items.includes(settings), + keybindings: !result.items.includes(keybindings), + snippets: !result.items.includes(snippets), + tasks: !result.items.includes(tasks), + extensions: !result.items.includes(extensions) + }; if (profile) { await this.userDataProfileManagementService.updateProfile(profile, { name: result.name, useDefaultFlags: profile.useDefaultFlags && !useDefaultFlags ? {} : useDefaultFlags }); } else { From 433c7361021d5d9ebe080d1869d816f1c37e5b89 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 17 Jul 2023 12:09:36 +0200 Subject: [PATCH 0158/1180] Fix #177142 (#188053) --- .../common/preferencesContribution.ts | 41 ++++++++----------- .../browser/configurationService.ts | 10 ----- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts b/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts index b0f2ac1333d66..896ddc2d6032e 100644 --- a/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts +++ b/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts @@ -103,39 +103,32 @@ export class PreferencesContribution implements IWorkbenchContribution { private start(): void { this.textModelResolverService.registerTextModelContentProvider('vscode', { - provideTextContent: (uri: URI): Promise | null => { + provideTextContent: async (uri: URI): Promise => { if (uri.scheme !== 'vscode') { return null; } if (uri.authority === 'schemas') { - const schemaModel = this.getSchemaModel(uri); - if (schemaModel) { - return Promise.resolve(schemaModel); - } + return this.getSchemaModel(uri); } - return Promise.resolve(this.preferencesService.resolveModel(uri)); + return this.preferencesService.resolveModel(uri); } }); } - private getSchemaModel(uri: URI): ITextModel | null { - let schema = schemaRegistry.getSchemaContributions().schemas[uri.toString()]; - if (schema) { - const modelContent = JSON.stringify(schema); - const languageSelection = this.languageService.createById('jsonc'); - const model = this.modelService.createModel(modelContent, languageSelection, uri); - const disposables = new DisposableStore(); - disposables.add(schemaRegistry.onDidChangeSchema(schemaUri => { - if (schemaUri === uri.toString()) { - schema = schemaRegistry.getSchemaContributions().schemas[uri.toString()]; - model.setValue(JSON.stringify(schema)); - } - })); - disposables.add(model.onWillDispose(() => disposables.dispose())); - - return model; - } - return null; + private getSchemaModel(uri: URI): ITextModel { + let schema = schemaRegistry.getSchemaContributions().schemas[uri.toString()] ?? {} /* Use empty schema if not yet registered */; + const modelContent = JSON.stringify(schema); + const languageSelection = this.languageService.createById('jsonc'); + const model = this.modelService.createModel(modelContent, languageSelection, uri); + const disposables = new DisposableStore(); + disposables.add(schemaRegistry.onDidChangeSchema(schemaUri => { + if (schemaUri === uri.toString()) { + schema = schemaRegistry.getSchemaContributions().schemas[uri.toString()]; + model.setValue(JSON.stringify(schema)); + } + })); + disposables.add(model.onWillDispose(() => disposables.dispose())); + return model; } dispose(): void { diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index cb75f62e36c53..bc40358f62fac 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -1129,16 +1129,6 @@ class RegisterConfigurationSchemasContribution extends Disposable implements IWo ) { super(); - this.registerSchemas({ - defaultSettingsSchema: {}, - userSettingsSchema: {}, - profileSettingsSchema: {}, - machineSettingsSchema: {}, - workspaceSettingsSchema: {}, - folderSettingsSchema: {}, - configDefaultsSchema: {}, - }); - extensionService.whenInstalledExtensionsRegistered().then(() => { this.registerConfigurationSchemas(); From 35573c42a59946d4ea0c5b533055f86a5585abbf Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 17 Jul 2023 08:55:02 +0200 Subject: [PATCH 0159/1180] Update to @vscode/proxy-agent 0.16.0 --- package.json | 4 +- remote/package.json | 2 +- remote/yarn.lock | 110 +++++++++++++++++++++++++------------------- yarn.lock | 109 +++++++++++++++++++++++-------------------- 4 files changed, 123 insertions(+), 102 deletions(-) diff --git a/package.json b/package.json index a1961f94d9dd9..3c6fd8edce9e4 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/policy-watcher": "^1.1.4", - "@vscode/proxy-agent": "^0.15.0", + "@vscode/proxy-agent": "^0.16.0", "@vscode/ripgrep": "^1.15.5", "@vscode/spdlog": "^0.13.10", "@vscode/sqlite3": "5.1.6-vscode", @@ -231,4 +231,4 @@ "optionalDependencies": { "windows-foreground-love": "0.5.0" } -} \ No newline at end of file +} diff --git a/remote/package.json b/remote/package.json index 9b92d007a4704..e10bd518df423 100644 --- a/remote/package.json +++ b/remote/package.json @@ -7,7 +7,7 @@ "@microsoft/1ds-post-js": "^3.2.2", "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", - "@vscode/proxy-agent": "^0.15.0", + "@vscode/proxy-agent": "^0.16.0", "@vscode/ripgrep": "^1.15.5", "@vscode/spdlog": "^0.13.10", "@vscode/vscode-languagedetection": "1.0.21", diff --git a/remote/yarn.lock b/remote/yarn.lock index 8084ab6e27a49..7c74dbf3e57f9 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -48,27 +48,27 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -"@tootallnate/once@1", "@tootallnate/once@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-3.0.0.tgz#d52238c9052d746c9689523e650160e70786bc9a" + integrity sha512-OAdBVB7rlwvLD+DiecSAyVKzKVmSfXbouCyM5I6wHGi4MGXIyFqErg1IvyJ7PI1e+GYZuZh7cCHV/c4LA8SKMw== "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== -"@vscode/proxy-agent@^0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.15.0.tgz#b8fb8b89180a71295a8f8682775f69ab1dcf6860" - integrity sha512-HpD4A9CUOwKbC6vLa0+MEsCo/qlgbue9U9s8Z7NzJDdf2YEGjUaYf9Mvj5T1LhJX20Hv1COvkGcc7zPhtIbgbA== - dependencies: - "@tootallnate/once" "^1.1.2" - agent-base "^6.0.2" - debug "^4.3.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - socks-proxy-agent "^5.0.0" +"@vscode/proxy-agent@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.16.0.tgz#32054387f7aaf26d1b5d53f553d53bfd8489eab8" + integrity sha512-b8yBHgdngDrP+9HPJtnPUJjPHd+zfEvOYoc8KioWJVs0rFVT2U77nFDVC70Mrrscf87ya2a/sPY32nTrwFfOQQ== + dependencies: + "@tootallnate/once" "^3.0.0" + agent-base "^7.0.1" + debug "^4.3.4" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + socks-proxy-agent "^8.0.1" optionalDependencies: "@vscode/windows-ca-certs" "^0.3.1" @@ -120,7 +120,7 @@ agent-base@4: dependencies: es6-promisify "^5.0.0" -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -134,6 +134,13 @@ agent-base@^4.3.0: dependencies: es6-promisify "^5.0.0" +agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -237,10 +244,10 @@ debug@4: dependencies: ms "^2.1.1" -debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" @@ -356,14 +363,13 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" + agent-base "^7.1.0" + debug "^4.3.4" https-proxy-agent@^2.2.3: version "2.2.4" @@ -381,6 +387,14 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz#0277e28f13a07d45c663633841e20a40aaafe0ab" + integrity sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ== + dependencies: + agent-base "^7.0.2" + debug "4" + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -396,10 +410,10 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== is-extglob@^2.1.1: version "2.1.1" @@ -691,27 +705,27 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" -smart-buffer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" - integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== +socks-proxy-agent@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz#ffc5859a66dac89b0c4dab90253b96705f3e7120" + integrity sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ== dependencies: - agent-base "6" - debug "4" - socks "^2.3.3" + agent-base "^7.0.1" + debug "^4.3.4" + socks "^2.7.1" -socks@^2.3.3: - version "2.6.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" - integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== +socks@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== dependencies: - ip "^1.1.5" - smart-buffer "^4.1.0" + ip "^2.0.0" + smart-buffer "^4.2.0" string-width@^1.0.1: version "1.0.2" diff --git a/yarn.lock b/yarn.lock index ac27990a8ae39..76bce0cf9da6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -822,16 +822,16 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== -"@tootallnate/once@1", "@tootallnate/once@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@tootallnate/once@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-3.0.0.tgz#d52238c9052d746c9689523e650160e70786bc9a" + integrity sha512-OAdBVB7rlwvLD+DiecSAyVKzKVmSfXbouCyM5I6wHGi4MGXIyFqErg1IvyJ7PI1e+GYZuZh7cCHV/c4LA8SKMw== + "@trysound/sax@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" @@ -1304,17 +1304,17 @@ bindings "^1.5.0" node-addon-api "^6.0.0" -"@vscode/proxy-agent@^0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.15.0.tgz#b8fb8b89180a71295a8f8682775f69ab1dcf6860" - integrity sha512-HpD4A9CUOwKbC6vLa0+MEsCo/qlgbue9U9s8Z7NzJDdf2YEGjUaYf9Mvj5T1LhJX20Hv1COvkGcc7zPhtIbgbA== +"@vscode/proxy-agent@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.16.0.tgz#32054387f7aaf26d1b5d53f553d53bfd8489eab8" + integrity sha512-b8yBHgdngDrP+9HPJtnPUJjPHd+zfEvOYoc8KioWJVs0rFVT2U77nFDVC70Mrrscf87ya2a/sPY32nTrwFfOQQ== dependencies: - "@tootallnate/once" "^1.1.2" - agent-base "^6.0.2" - debug "^4.3.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - socks-proxy-agent "^5.0.0" + "@tootallnate/once" "^3.0.0" + agent-base "^7.0.1" + debug "^4.3.4" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + socks-proxy-agent "^8.0.1" optionalDependencies: "@vscode/windows-ca-certs" "^0.3.1" @@ -1644,12 +1644,12 @@ agent-base@^4.3.0: dependencies: es6-promisify "^5.0.0" -agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== +agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== dependencies: - debug "4" + debug "^4.3.4" ajv-formats@^2.1.1: version "2.1.1" @@ -3200,7 +3200,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== @@ -5379,15 +5379,6 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - 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" @@ -5397,6 +5388,14 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + http2-wrapper@^1.0.0-beta.5.2: version "1.0.3" resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" @@ -5429,6 +5428,14 @@ https-proxy-agent@^5.0.1: agent-base "6" debug "4" +https-proxy-agent@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz#0277e28f13a07d45c663633841e20a40aaafe0ab" + integrity sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ== + dependencies: + agent-base "^7.0.2" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5591,10 +5598,10 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== -ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== is-absolute-url@^2.0.0: version "2.1.0" @@ -9010,10 +9017,10 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -smart-buffer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" - integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== snapdragon-node@^2.0.1: version "2.1.1" @@ -9045,22 +9052,22 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== +socks-proxy-agent@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz#ffc5859a66dac89b0c4dab90253b96705f3e7120" + integrity sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ== dependencies: - agent-base "6" - debug "4" - socks "^2.3.3" + agent-base "^7.0.1" + debug "^4.3.4" + socks "^2.7.1" -socks@^2.3.3: - version "2.6.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" - integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== +socks@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== dependencies: - ip "^1.1.5" - smart-buffer "^4.1.0" + ip "^2.0.0" + smart-buffer "^4.2.0" sort-keys-length@^1.0.0: version "1.0.1" From 8d4cd145ac6c9d99a10d1323cec1b50eb358e37a Mon Sep 17 00:00:00 2001 From: yshaojun Date: Mon, 17 Jul 2023 18:32:12 +0800 Subject: [PATCH 0160/1180] chore: use Set instead of Map --- .../contrib/unicodeHighlighter/browser/unicodeHighlighter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts index 122648ba83c1f..eea1de6f65bc8 100644 --- a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts +++ b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts @@ -429,7 +429,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa } const result: MarkdownHover[] = []; - const existedReason = new Map(); + const existedReason = new Set(); let index = 300; for (const d of lineDecorations) { @@ -484,7 +484,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa if (existedReason.has(reason)) { continue; } - existedReason.set(reason, true); + existedReason.add(reason); const adjustSettingsArgs: ShowExcludeOptionsArgs = { codePoint: codePoint, From 7c00c24205df7efb78361268c09297c3b0b50098 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 17 Jul 2023 14:30:08 +0200 Subject: [PATCH 0161/1180] hook up rich slash commands with UI --- .../api/common/extHostChatSlashCommand.ts | 2 +- .../contrib/chat/common/chatServiceImpl.ts | 49 ++++++++++++++++--- .../contrib/chat/common/chatSlashCommands.ts | 9 +++- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/api/common/extHostChatSlashCommand.ts b/src/vs/workbench/api/common/extHostChatSlashCommand.ts index 1a0375199c46d..9d2161171afd1 100644 --- a/src/vs/workbench/api/common/extHostChatSlashCommand.ts +++ b/src/vs/workbench/api/common/extHostChatSlashCommand.ts @@ -71,7 +71,7 @@ export class ExtHostChatSlashCommands implements ExtHostChatSlashCommandsShape { { history: context.history.map(typeConvert.ChatMessage.to) }, new Progress(p => { throwIfDone(); - this._proxy.$handleProgressChunk(requestId, { value: p.message.value }); + this._proxy.$handleProgressChunk(requestId, { content: p.message.value }); }), token ); diff --git a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts index 68a14aaf8b7db..14cd0ef90036f 100644 --- a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts @@ -17,12 +17,15 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; +import { Progress } from 'vs/platform/progress/common/progress'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { ChatModel, ChatWelcomeMessageModel, IChatModel, ISerializableChatData, ISerializableChatsData } from 'vs/workbench/contrib/chat/common/chatModel'; -import { IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatProgress, IChatProvider, IChatProviderInfo, IChatReplyFollowup, IChatService, IChatUserActionEvent, ISlashCommand, ISlashCommandProvider, InteractiveSessionCopyKind, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; +import { ChatMessageRole, IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; +import { IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatProgress, IChatProvider, IChatProviderInfo, IChatReplyFollowup, IChatResponse, IChatService, IChatUserActionEvent, ISlashCommand, ISlashCommandProvider, InteractiveSessionCopyKind, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; +import { IChatSlashCommandService, IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; const serializedChatKey = 'interactive.sessions'; @@ -145,7 +148,8 @@ export class ChatService extends Disposable implements IChatService { @IInstantiationService private readonly instantiationService: IInstantiationService, @ITelemetryService private readonly telemetryService: ITelemetryService, @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService + @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, + @IChatSlashCommandService private readonly chatSlashCommandService: IChatSlashCommandService, ) { super(); @@ -449,7 +453,27 @@ export class ChatService extends Disposable implements IChatService { if (usedSlashCommand?.command) { this._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); } - let rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token); + + let rawResponse: IChatResponse | null | undefined; + + if ((typeof resolvedCommand === 'string' && typeof message === 'string' && this.chatSlashCommandService.hasCommand(resolvedCommand))) { + // contributed slash commands + // TODO: spell this out in the UI + const history: IChatMessage[] = []; + for (const request of model.getRequests()) { + if (typeof request.message !== 'string' || !request.response) { + continue; + } + history.push({ role: ChatMessageRole.User, content: request.message }); + history.push({ role: ChatMessageRole.Assistant, content: request.response?.response.value }); + } + await this.chatSlashCommandService.executeCommand(resolvedCommand, message.substring(resolvedCommand.length + 1).trimStart(), new Progress(p => progressCallback(p)), history, token); + rawResponse = { session: model.session! }; + + } else { + rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token); + } + if (token.isCancellationRequested) { return; } else { @@ -510,11 +534,15 @@ export class ChatService extends Disposable implements IChatService { private async handleSlashCommand(sessionId: string, command: string): Promise { const slashCommands = await this.getSlashCommands(sessionId, CancellationToken.None); for (const slashCommand of slashCommands ?? []) { - if (command.startsWith(`/${slashCommand.command}`) && slashCommand.provider) { - return await slashCommand.provider.resolveSlashCommand(command, CancellationToken.None) ?? command; + if (command.startsWith(`/${slashCommand.command}`)) { + if (slashCommand.provider) { + return await slashCommand.provider.resolveSlashCommand(command, CancellationToken.None) ?? command; + } else if (this.chatSlashCommandService.hasCommand(slashCommand.command)) { + return slashCommand.command; + } + } } - return command; } @@ -542,9 +570,16 @@ export class ChatService extends Disposable implements IChatService { .then(commands => commands?.map(c => ({ ...c, provider: p })))) ]); + const serviceResults = this.chatSlashCommandService.getCommands().map(data => { + return { + command: data.name, + detail: data.detail, + }; + }); + try { const slashCommands = (await providerResults).filter(c => !!c) as ISlashCommand[][]; - return withNullAsUndefined(slashCommands.flat()); + return slashCommands.flat().concat(serviceResults); } catch (e) { this.logService.error(e); diff --git a/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts b/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts index 1b4cbcc31e6c9..587c62e6f8a88 100644 --- a/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts +++ b/src/vs/workbench/contrib/chat/common/chatSlashCommands.ts @@ -58,7 +58,7 @@ export interface IChatSlashData { } export interface IChatSlashFragment { - value: string; + content: string; } export type IChatSlashCallback = { (prompt: string, progress: IProgress, history: IChatMessage[], token: CancellationToken): Promise }; @@ -71,6 +71,7 @@ export interface IChatSlashCommandService { registerSlashCallback(id: string, command: IChatSlashCallback): IDisposable; executeCommand(id: string, prompt: string, progress: IProgress, history: IChatMessage[], token: CancellationToken): Promise; getCommands(): Array; + hasCommand(id: string): boolean; } type Tuple = { data: IChatSlashData; command?: IChatSlashCallback }; @@ -128,6 +129,10 @@ export class ChatSlashCommandService implements IChatSlashCommandService { return Array.from(this._commands.values(), v => v.data); } + hasCommand(id: string): boolean { + return this._commands.has(id); + } + async executeCommand(id: string, prompt: string, progress: IProgress, history: IChatMessage[], token: CancellationToken): Promise { const data = this._commands.get(id); if (!data) { @@ -217,7 +222,7 @@ registerAction2(class extends Action2 { pick.cmd.id, prompt, new Progress(value => { - p.report({ message: value.value }); + p.report({ message: value.content }); console.log(value); }), [], From e5cdd7d0fd91d1bbadda2402415ce1d1dfbfe938 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 17 Jul 2023 06:28:37 -0700 Subject: [PATCH 0162/1180] Make Cargo.lock a readonly file in vscode --- .vscode/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5d2930c5a923c..7eefe0c57f686 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,6 +36,7 @@ "files.readonlyInclude": { "**/node_modules/**": true, "**/yarn.lock": true, + "**/Cargo.lock": true, "src/vs/workbench/workbench.web.main.css": true, "src/vs/workbench/workbench.desktop.main.css": true, "src/vs/workbench/workbench.desktop.main.nls.js": true, From fc0a8da96fd7010960c8f857f114ef90167f38d5 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 17 Jul 2023 08:32:25 -0700 Subject: [PATCH 0163/1180] fix #188081 --- .../browser/terminal.accessibility.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 26042ec1cb190..9e364caf3da7e 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 @@ -92,7 +92,7 @@ registerTerminalAction({ { primary: KeyMod.Shift | KeyCode.Tab, weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) + when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, TerminalContextKeys.focus, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } ], run: async (c) => { From cc997383d8f34d1eb55f00c28abf6711a79d681e Mon Sep 17 00:00:00 2001 From: aamunger Date: Mon, 17 Jul 2023 10:38:18 -0700 Subject: [PATCH 0164/1180] store title passed from jupyter to use as tab name --- .../browser/interactive.contribution.ts | 1 + .../browser/interactiveEditorInput.ts | 21 ++++++++++--------- .../common/workingCopyBackupService.ts | 5 +++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index da64485f9094a..afa4414c3c0c3 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -392,6 +392,7 @@ registerAction2(class extends Action2 { counter++; } while (existingNotebookDocument.has(notebookUri.toString())); + InteractiveEditorInput.setName(notebookUri, title); logService.debug('Open new interactive window:', notebookUri.toString(), inputUri.toString()); diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts index 49e3601838a23..aece1b21e47f3 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts @@ -25,6 +25,14 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot return instantiationService.createInstance(InteractiveEditorInput, resource, inputResource, title, language); } + private static windowNames: Record = {}; + + static setName(notebookUri: URI, title: string | undefined) { + if (title) { + this.windowNames[notebookUri.path] = title; + } + } + static readonly ID: string = 'workbench.input.interactive'; public override get editorId(): string { @@ -35,7 +43,7 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot return InteractiveEditorInput.ID; } - private _initTitle?: string; + private name: string; get language() { return this._inputModelRef?.object.textEditorModel.getLanguageId() ?? this._initLanguage; @@ -91,7 +99,7 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot super(); this._notebookEditorInput = input; this._register(this._notebookEditorInput); - this._initTitle = title; + this.name = title ?? InteractiveEditorInput.windowNames[resource.path] ?? paths.basename(resource.path, paths.extname(resource.path)); this._initLanguage = languageId; this._resource = resource; this._inputResource = inputResource; @@ -209,14 +217,7 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot } override getName() { - if (this._initTitle) { - return this._initTitle; - } - - const p = this.primary.resource!.path; - const basename = paths.basename(p); - - return basename.substr(0, basename.length - paths.extname(p).length); + return this.name; } override isModified() { diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts index f9ec56ad11ad6..2486e142b717c 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts @@ -134,8 +134,9 @@ export abstract class WorkingCopyBackupService implements IWorkingCopyBackupServ if (backupWorkspaceHome) { return new WorkingCopyBackupServiceImpl(backupWorkspaceHome, this.fileService, this.logService); } - - return new InMemoryWorkingCopyBackupService(); + else { + return new WorkingCopyBackupServiceImpl(URI.file('c:\\temp\\backup'), this.fileService, this.logService); + } } reinitialize(backupWorkspaceHome: URI | undefined): void { From 1bd2fc7937140bf342459ff895a87dff9b219eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Tue, 18 Jul 2023 01:42:13 +0800 Subject: [PATCH 0165/1180] fix: Close #187788, recovery tree view state (#187902) --- .../contrib/files/browser/views/explorerView.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 4572956371be1..9e8b4ec5af800 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -173,7 +173,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { private viewHasSomeCollapsibleRootItem: IContextKey; private viewVisibleContextKey: IContextKey; - + private setTreeInputPromise: Promise | undefined; private horizontalScrolling: boolean | undefined; private dragHandler!: DelayedDragHandler; @@ -522,7 +522,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { // save view state this._register(this.storageService.onWillSaveState(() => { - this.storageService.store(ExplorerView.TREE_VIEW_STATE_STORAGE_KEY, JSON.stringify(this.tree.getViewState()), StorageScope.WORKSPACE, StorageTarget.MACHINE); + this.storeTreeViewState(); })); } @@ -540,6 +540,10 @@ export class ExplorerView extends ViewPane implements IExplorerView { } } + private storeTreeViewState() { + this.storageService.store(ExplorerView.TREE_VIEW_STATE_STORAGE_KEY, JSON.stringify(this.tree.getViewState()), StorageScope.WORKSPACE, StorageTarget.MACHINE); + } + private setContextKeys(stat: ExplorerItem | null | undefined): void { const folders = this.contextService.getWorkspace().folders; const resource = stat ? stat.resource : folders[folders.length - 1].uri; @@ -666,6 +670,11 @@ export class ExplorerView extends ViewPane implements IExplorerView { return Promise.resolve(undefined); } + // Wait for the last execution to complete before executing + if (this.setTreeInputPromise) { + await this.setTreeInputPromise; + } + const initialInputSetup = !this.tree.getInput(); if (initialInputSetup) { perf.mark('code/willResolveExplorer'); @@ -688,7 +697,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { } const previousInput = this.tree.getInput(); - const promise = this.tree.setInput(input, viewState).then(async () => { + const promise = this.setTreeInputPromise = this.tree.setInput(input, viewState).then(async () => { if (Array.isArray(input)) { if (!viewState || previousInput instanceof ExplorerItem) { // There is no view state for this workspace (we transitioned from a folder workspace?), expand up to five roots. @@ -883,6 +892,8 @@ export class ExplorerView extends ViewPane implements IExplorerView { const treeInputArray = Array.isArray(treeInput) ? treeInput : Array.from(treeInput.children.values()); // Has collapsible root when anything is expanded this.viewHasSomeCollapsibleRootItem.set(hasExpandedNode(this.tree, treeInputArray)); + // synchronize state to cache + this.storeTreeViewState(); } override dispose(): void { From bafd442c4e1406e5eee5261bc1e1d82174c054de Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 17 Jul 2023 10:56:27 -0700 Subject: [PATCH 0166/1180] cli: improve `code tunnel` with existing tunnels (#188091) - Apply the name/tunnel-name from the CLI to automatically (do a normal tag sync). Previously the CLI could host tunnels that were unusable unless the consumer did the tag setup, which they should not. - Allow "tunnel ID" to be specified in the new `.` format that devtunnels has adopted. --- cli/src/commands/args.rs | 1 + cli/src/commands/tunnels.rs | 35 ++++++++++++++++++--------- cli/src/tunnels/dev_tunnels.rs | 43 +++++++++++++++++++++++++++------- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index a97e1fc387075..e716e58b7c0ef 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -548,6 +548,7 @@ pub enum OutputFormat { #[derive(Args, Clone, Debug, Default)] pub struct ExistingTunnelArgs { /// Name you'd like to assign preexisting tunnel to use to connect the tunnel + /// Old option, new code sohuld just use `--name`. #[clap(long, hide = true)] pub tunnel_name: Option, diff --git a/cli/src/commands/tunnels.rs b/cli/src/commands/tunnels.rs index 24e349bb72047..c098188135e0f 100644 --- a/cli/src/commands/tunnels.rs +++ b/cli/src/commands/tunnels.rs @@ -59,20 +59,31 @@ impl From for crate::auth::AuthProvider { } } -impl From for Option { - fn from(d: ExistingTunnelArgs) -> Option { - if let (Some(tunnel_id), Some(tunnel_name), Some(cluster), Some(host_token)) = - (d.tunnel_id, d.tunnel_name, d.cluster, d.host_token) - { +fn fulfill_existing_tunnel_args( + d: ExistingTunnelArgs, + name_arg: &Option, +) -> Option { + let tunnel_name = d.tunnel_name.or_else(|| name_arg.clone()); + + match (d.tunnel_id, d.cluster, d.host_token) { + (Some(tunnel_id), None, Some(host_token)) => { + let i = tunnel_id.find('.')?; Some(dev_tunnels::ExistingTunnel { - tunnel_id, + tunnel_id: tunnel_id[..i].to_string(), + cluster: tunnel_id[i + 1..].to_string(), tunnel_name, host_token, - cluster, }) - } else { - None } + + (Some(tunnel_id), Some(cluster), Some(host_token)) => Some(dev_tunnels::ExistingTunnel { + tunnel_id, + tunnel_name, + host_token, + cluster, + }), + + _ => None, } } @@ -412,8 +423,10 @@ async fn serve_with_csa( let auth = Auth::new(&paths, log.clone()); let mut dt = dev_tunnels::DevTunnels::new(&log, auth, &paths); loop { - let tunnel = if let Some(d) = gateway_args.tunnel.clone().into() { - dt.start_existing_tunnel(d).await + let tunnel = if let Some(t) = + fulfill_existing_tunnel_args(gateway_args.tunnel.clone(), &gateway_args.name) + { + dt.start_existing_tunnel(t).await } else { dt.start_new_launcher_tunnel(gateway_args.name.as_deref(), gateway_args.random_name) .await diff --git a/cli/src/tunnels/dev_tunnels.rs b/cli/src/tunnels/dev_tunnels.rs index c4ca9741b8872..a04bdbcaf6d34 100644 --- a/cli/src/tunnels/dev_tunnels.rs +++ b/cli/src/tunnels/dev_tunnels.rs @@ -229,7 +229,7 @@ lazy_static! { #[derive(Clone, Debug)] pub struct ExistingTunnel { /// Name you'd like to assign preexisting tunnel to use to connect to the VS Code Server - pub tunnel_name: String, + pub tunnel_name: Option, /// Token to authenticate and use preexisting tunnel pub host_token: String, @@ -393,7 +393,12 @@ impl DevTunnels { }; tunnel = self - .sync_tunnel_tags(&persisted.name, tunnel, &HOST_TUNNEL_REQUEST_OPTIONS) + .sync_tunnel_tags( + &self.client, + &persisted.name, + tunnel, + &HOST_TUNNEL_REQUEST_OPTIONS, + ) .await?; let locator = TunnelLocator::try_from(&tunnel).unwrap(); @@ -532,6 +537,7 @@ impl DevTunnels { /// other version tags. async fn sync_tunnel_tags( &self, + client: &TunnelManagementClient, name: &str, tunnel: Tunnel, options: &TunnelRequestOptions, @@ -558,7 +564,7 @@ impl DevTunnels { let result = spanf!( self.log, self.log.span("dev-tunnel.protocol-tag-update"), - self.client.update_tunnel(&tunnel_update, options) + client.update_tunnel(&tunnel_update, options) ); result.map_err(|e| wrap(e, "tunnel tag update failed").into()) @@ -639,6 +645,12 @@ impl DevTunnels { Ok(()) } + fn get_placeholder_name() -> String { + let mut n = clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy()); + n.make_ascii_lowercase(); + n + } + async fn get_name_for_tunnel( &mut self, preferred_name: Option<&str>, @@ -670,10 +682,7 @@ impl DevTunnels { use_random_name = true; } - let mut placeholder_name = - clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy()); - placeholder_name.make_ascii_lowercase(); - + let mut placeholder_name = Self::get_placeholder_name(); if !is_name_free(&placeholder_name) { for i in 2.. { let fixed_name = format!("{}{}", placeholder_name, i); @@ -715,7 +724,10 @@ impl DevTunnels { tunnel: ExistingTunnel, ) -> Result { let tunnel_details = PersistedTunnel { - name: tunnel.tunnel_name, + name: match tunnel.tunnel_name { + Some(n) => n, + None => Self::get_placeholder_name(), + }, id: tunnel.tunnel_id, cluster: tunnel.cluster, }; @@ -725,10 +737,23 @@ impl DevTunnels { tunnel.host_token.clone(), )); + let client = mgmt.into(); + self.sync_tunnel_tags( + &client, + &tunnel_details.name, + Tunnel { + cluster_id: Some(tunnel_details.cluster.clone()), + tunnel_id: Some(tunnel_details.id.clone()), + ..Default::default() + }, + &HOST_TUNNEL_REQUEST_OPTIONS, + ) + .await?; + self.start_tunnel( tunnel_details.locator(), &tunnel_details, - mgmt.into(), + client, StaticAccessTokenProvider::new(tunnel.host_token), ) .await From 1b291302df4068cad0516b8600e003c72c4a9b97 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 17 Jul 2023 19:57:00 +0200 Subject: [PATCH 0167/1180] Implement apply extension to all profiles (#188093) * Revert "remove the extension action to apply in all profiles #157492 (#187815)" This reverts commit 429d6d203af96da2edb38682ba8b9fd0ed173be2. * implement #157492 --- .../abstractExtensionManagementService.ts | 41 +++++++++++++- .../common/extensionManagement.ts | 1 + .../common/extensionManagementIpc.ts | 9 ++++ .../node/extensionManagementService.ts | 54 ++++++++++++++----- .../userDataSync/common/extensionsMerge.ts | 5 ++ .../userDataSync/common/extensionsSync.ts | 8 ++- .../userDataSync/common/userDataSync.ts | 2 + .../browser/extensions.contribution.ts | 18 +++++++ .../browser/extensionsWorkbenchService.ts | 9 ++-- .../extensionManagementChannelClient.ts | 8 +++ .../common/extensionManagementService.ts | 8 +++ .../common/webExtensionManagementService.ts | 22 +++++--- .../remoteExtensionManagementService.ts | 4 +- .../test/browser/workbenchTestServices.ts | 1 + 14 files changed, 162 insertions(+), 28 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index 2ed53a4b0d7de..96195aae781e1 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -23,6 +23,7 @@ import { ExtensionType, IExtensionManifest, isApplicationScopedExtension, Target import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; export type ExtensionVerificationStatus = boolean | string; @@ -69,11 +70,15 @@ export abstract class AbstractExtensionManagementService extends Disposable impl protected _onDidUninstallExtension = this._register(new Emitter()); get onDidUninstallExtension() { return this._onDidUninstallExtension.event; } + protected readonly _onDidUpdateExtensionMetadata = this._register(new Emitter()); + get onDidUpdateExtensionMetadata() { return this._onDidUpdateExtensionMetadata.event; } + private readonly participants: IExtensionManagementParticipant[] = []; constructor( @IExtensionGalleryService protected readonly galleryService: IExtensionGalleryService, @ITelemetryService protected readonly telemetryService: ITelemetryService, + @IUriIdentityService protected readonly uriIdentityService: IUriIdentityService, @ILogService protected readonly logService: ILogService, @IProductService protected readonly productService: IProductService, @IUserDataProfilesService protected readonly userDataProfilesService: IUserDataProfilesService, @@ -147,6 +152,40 @@ export abstract class AbstractExtensionManagementService extends Disposable impl return this.uninstallExtension(extension, options); } + async toggleAppliationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise { + if (isApplicationScopedExtension(extension.manifest)) { + return extension; + } + + if (extension.isApplicationScoped) { + let local = await this.updateMetadata(extension, { isApplicationScoped: false }, this.userDataProfilesService.defaultProfile.extensionsResource); + if (!this.uriIdentityService.extUri.isEqual(fromProfileLocation, this.userDataProfilesService.defaultProfile.extensionsResource)) { + local = await this.copyExtension(extension, this.userDataProfilesService.defaultProfile.extensionsResource, fromProfileLocation); + } + + for (const profile of this.userDataProfilesService.profiles) { + const existing = (await this.getInstalled(ExtensionType.User, profile.extensionsResource)) + .find(e => areSameExtensions(e.identifier, extension.identifier)); + if (existing) { + this._onDidUpdateExtensionMetadata.fire(existing); + } else { + this._onDidUninstallExtension.fire({ identifier: extension.identifier, profileLocation: profile.extensionsResource }); + } + } + return local; + } + + else { + const local = this.uriIdentityService.extUri.isEqual(fromProfileLocation, this.userDataProfilesService.defaultProfile.extensionsResource) + ? await this.updateMetadata(extension, { isApplicationScoped: true }, this.userDataProfilesService.defaultProfile.extensionsResource) + : await this.copyExtension(extension, fromProfileLocation, this.userDataProfilesService.defaultProfile.extensionsResource, { isApplicationScoped: true }); + + this._onDidInstallExtensions.fire([{ identifier: local.identifier, operation: InstallOperation.Install, local, profileLocation: this.userDataProfilesService.defaultProfile.extensionsResource, applicationScoped: true }]); + return local; + } + + } + getExtensionsControlManifest(): Promise { const now = new Date().getTime(); @@ -705,12 +744,12 @@ export abstract class AbstractExtensionManagementService extends Disposable impl abstract reinstallFromGallery(extension: ILocalExtension): Promise; abstract cleanUp(): Promise; - abstract onDidUpdateExtensionMetadata: Event; abstract updateMetadata(local: ILocalExtension, metadata: Partial, profileLocation?: URI): Promise; protected abstract getCurrentExtensionsManifestLocation(): URI; protected abstract createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallExtensionTaskOptions): IInstallExtensionTask; protected abstract createUninstallExtensionTask(extension: ILocalExtension, options: UninstallExtensionTaskOptions): IUninstallExtensionTask; + protected abstract copyExtension(extension: ILocalExtension, fromProfileLocation: URI, toProfileLocation: URI, metadata?: Partial): Promise; } export function joinErrors(errorOrErrors: (Error | string) | (Array)): Error { diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 23df3ac6abd94..9a9abb281fce8 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -478,6 +478,7 @@ export interface IExtensionManagementService { installFromLocation(location: URI, profileLocation: URI): Promise; installExtensionsFromProfile(extensions: IExtensionIdentifier[], fromProfileLocation: URI, toProfileLocation: URI): Promise; uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise; + toggleAppliationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise; reinstallFromGallery(extension: ILocalExtension): Promise; getInstalled(type?: ExtensionType, profileLocation?: URI): Promise; getExtensionsControlManifest(): Promise; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index c1d91312b4577..fbefe7b124751 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -142,6 +142,10 @@ export class ExtensionManagementChannel implements IServerChannel { const extensions = await this.service.getInstalled(args[0], transformIncomingURI(args[1], uriTransformer)); return extensions.map(e => transformOutgoingExtension(e, uriTransformer)); } + case 'toggleAppliationScope': { + const extension = await this.service.toggleAppliationScope(transformIncomingExtension(args[0], uriTransformer), transformIncomingURI(args[1], uriTransformer)); + return transformOutgoingExtension(extension, uriTransformer); + } case 'copyExtensions': { return this.service.copyExtensions(transformIncomingURI(args[0], uriTransformer), transformIncomingURI(args[1], uriTransformer)); } @@ -277,6 +281,11 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt .then(extension => transformIncomingExtension(extension, null)); } + toggleAppliationScope(local: ILocalExtension, fromProfileLocation: URI): Promise { + return this.channel.call('toggleAppliationScope', [local, fromProfileLocation]) + .then(extension => transformIncomingExtension(extension, null)); + } + copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise { return this.channel.call('copyExtensions', [fromProfileLocation, toProfileLocation]); } diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 9ad1f4c6759dc..5852d66a9c42e 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -32,7 +32,7 @@ import { Metadata, InstallVSIXOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, computeTargetPlatform, ExtensionKey, getGalleryExtensionId, groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; +import { IExtensionsProfileScannerService, IScannedProfileExtension } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { IExtensionsScannerService, IScannedExtension, ScanOptions } from 'vs/platform/extensionManagement/common/extensionsScannerService'; import { ExtensionsDownloader } from 'vs/platform/extensionManagement/node/extensionDownloader'; import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle'; @@ -71,9 +71,6 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi private readonly manifestCache: ExtensionsManifestCache; private readonly extensionsDownloader: ExtensionsDownloader; - private readonly _onDidUpdateExtensionMetadata = this._register(new Emitter()); - override readonly onDidUpdateExtensionMetadata = this._onDidUpdateExtensionMetadata.event; - private readonly installGalleryExtensionsTasks = new Map(); constructor( @@ -87,10 +84,10 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi @IInstantiationService instantiationService: IInstantiationService, @IFileService private readonly fileService: IFileService, @IProductService productService: IProductService, - @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, + @IUriIdentityService uriIdentityService: IUriIdentityService, @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService ) { - super(galleryService, telemetryService, logService, productService, userDataProfilesService); + super(galleryService, telemetryService, uriIdentityService, logService, productService, userDataProfilesService); const extensionLifecycle = this._register(instantiationService.createInstance(ExtensionsLifecycle)); this.extensionsScanner = this._register(instantiationService.createInstance(ExtensionsScanner, extension => extensionLifecycle.postUninstall(extension))); this.manifestCache = this._register(new ExtensionsManifestCache(userDataProfilesService, fileService, uriIdentityService, this, this.logService)); @@ -227,6 +224,10 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return this.installFromGallery(galleryExtension); } + protected copyExtension(extension: ILocalExtension, fromProfileLocation: URI, toProfileLocation: URI, metadata: Partial): Promise { + return this.extensionsScanner.copyExtension(extension, fromProfileLocation, toProfileLocation, metadata); + } + copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise { return this.extensionsScanner.copyExtensions(fromProfileLocation, toProfileLocation); } @@ -531,20 +532,25 @@ export class ExtensionsScanner extends Disposable { async scanMetadata(local: ILocalExtension, profileLocation?: URI): Promise { if (profileLocation) { - const extensions = await this.extensionsProfileScannerService.scanProfileExtensions(profileLocation); - return extensions.find(e => areSameExtensions(e.identifier, local.identifier))?.metadata; + const extension = await this.getScannedExtension(local, profileLocation); + return extension?.metadata; } else { return this.extensionsScannerService.scanMetadata(local.location); } } + private async getScannedExtension(local: ILocalExtension, profileLocation: URI): Promise { + const extensions = await this.extensionsProfileScannerService.scanProfileExtensions(profileLocation); + return extensions.find(e => areSameExtensions(e.identifier, local.identifier)); + } + async updateMetadata(local: ILocalExtension, metadata: Partial, profileLocation?: URI): Promise { if (profileLocation) { await this.extensionsProfileScannerService.updateMetadata([[local, metadata]], profileLocation); } else { await this.extensionsScannerService.updateMetadata(local.location, metadata); } - return this.scanLocalExtension(local.location, local.type); + return this.scanLocalExtension(local.location, local.type, profileLocation); } getUninstalledExtensions(): Promise> { @@ -573,6 +579,20 @@ export class ExtensionsScanner extends Disposable { await this.withUninstalledExtensions(uninstalled => delete uninstalled[ExtensionKey.create(extension).toString()]); } + async copyExtension(extension: ILocalExtension, fromProfileLocation: URI, toProfileLocation: URI, metadata: Partial): Promise { + const source = await this.getScannedExtension(extension, fromProfileLocation); + const target = await this.getScannedExtension(extension, toProfileLocation); + metadata = { ...source?.metadata, ...metadata }; + + if (target) { + await this.extensionsProfileScannerService.updateMetadata([[extension, { ...target.metadata, ...metadata }]], toProfileLocation); + } else { + await this.extensionsProfileScannerService.addExtensionsToProfile([[extension, metadata]], toProfileLocation); + } + + return this.scanLocalExtension(extension.location, extension.type, toProfileLocation); + } + async copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise { const fromExtensions = await this.scanExtensions(ExtensionType.User, fromProfileLocation); const extensions: [ILocalExtension, Metadata | undefined][] = await Promise.all(fromExtensions @@ -633,10 +653,18 @@ export class ExtensionsScanner extends Disposable { } } - private async scanLocalExtension(location: URI, type: ExtensionType): Promise { - const scannedExtension = await this.extensionsScannerService.scanExistingExtension(location, type, { includeInvalid: true }); - if (scannedExtension) { - return this.toLocalExtension(scannedExtension); + private async scanLocalExtension(location: URI, type: ExtensionType, profileLocation?: URI): Promise { + if (profileLocation) { + const scannedExtensions = await this.extensionsScannerService.scanUserExtensions({ profileLocation }); + const scannedExtension = scannedExtensions.find(e => this.uriIdentityService.extUri.isEqual(e.location, location)); + if (scannedExtension) { + return this.toLocalExtension(scannedExtension); + } + } else { + const scannedExtension = await this.extensionsScannerService.scanExistingExtension(location, type, { includeInvalid: true }); + if (scannedExtension) { + return this.toLocalExtension(scannedExtension); + } } throw new Error(nls.localize('cannot read', "Cannot read the extension from {0}", location.path)); } diff --git a/src/vs/platform/userDataSync/common/extensionsMerge.ts b/src/vs/platform/userDataSync/common/extensionsMerge.ts index f6caa270272d9..49c0d23827171 100644 --- a/src/vs/platform/userDataSync/common/extensionsMerge.ts +++ b/src/vs/platform/userDataSync/common/extensionsMerge.ts @@ -278,6 +278,11 @@ function areSame(fromExtension: ISyncExtension, toExtension: ISyncExtension, che return false; } + if (fromExtension.isApplicationScoped !== toExtension.isApplicationScoped) { + /* extension application scope has changed */ + return false; + } + if (checkInstalledProperty && fromExtension.installed !== toExtension.installed) { /* extension installed property changed */ return false; diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index aff6b64258522..aa22d90107dee 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -18,7 +18,7 @@ import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagemen import { IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService, ILocalExtension, ExtensionManagementError, ExtensionManagementErrorCode, IGalleryExtension, DISABLED_EXTENSIONS_STORAGE_PATH, EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT, EXTENSION_INSTALL_SYNC_CONTEXT, InstallExtensionInfo } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionStorageService, IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; -import { ExtensionType, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, IExtensionIdentifier, isApplicationScopedExtension } from 'vs/platform/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -375,8 +375,11 @@ export class LocalExtensionsProvider { const disabledExtensions = extensionEnablementService.getDisabledExtensions(); return installedExtensions .map(extension => { - const { identifier, isBuiltin, manifest, preRelease, pinned } = extension; + const { identifier, isBuiltin, manifest, preRelease, pinned, isApplicationScoped } = extension; const syncExntesion: ILocalSyncExtension = { identifier, preRelease, version: manifest.version, pinned: !!pinned }; + if (!isApplicationScopedExtension(manifest)) { + syncExntesion.isApplicationScoped = isApplicationScoped; + } if (disabledExtensions.some(disabledExtension => areSameExtensions(disabledExtension, identifier))) { syncExntesion.disabled = true; } @@ -481,6 +484,7 @@ export class LocalExtensionsProvider { installGivenVersion: e.pinned && !!e.version, installPreReleaseVersion: e.preRelease, profileLocation: profile.extensionsResource, + isApplicationScoped: e.isApplicationScoped, context: { [EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT]: true, [EXTENSION_INSTALL_SYNC_CONTEXT]: true } } }); diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index d64a2dff8e86f..245552ec53a3e 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -337,6 +337,7 @@ export interface ILocalSyncExtension { preRelease: boolean; disabled?: boolean; installed?: boolean; + isApplicationScoped?: boolean; state?: IStringDictionary; } @@ -347,6 +348,7 @@ export interface IRemoteSyncExtension { preRelease?: boolean; disabled?: boolean; installed?: boolean; + isApplicationScoped?: boolean; state?: IStringDictionary; } diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 52c03ecba67cd..a705f12a9a3e9 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -1431,6 +1431,24 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi } }); + this.registerExtensionAction({ + id: 'workbench.extensions.action.toggleApplyToAllProfiles', + title: { value: localize('workbench.extensions.action.toggleApplyToAllProfiles', "Apply Extension to all Profiles"), original: `Apply Extension to all Profiles` }, + toggled: ContextKeyExpr.has('isApplicationScopedExtension'), + menu: { + id: MenuId.ExtensionContext, + group: '2_configure', + when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate()), + order: 4 + }, + run: async (accessor: ServicesAccessor, id: string) => { + const extension = this.extensionsWorkbenchService.local.find(e => areSameExtensions({ id }, e.identifier)); + if (extension) { + return this.extensionsWorkbenchService.toggleApplyExtensionToAllProfiles(extension); + } + } + }); + this.registerExtensionAction({ id: 'workbench.extensions.action.ignoreRecommendation', title: { value: localize('workbench.extensions.action.ignoreRecommendation', "Ignore Recommendation"), original: `Ignore Recommendation` }, diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index b333b339afe7f..de295f7e1565d 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -50,7 +50,7 @@ import { getLocale } from 'vs/platform/languagePacks/common/languagePacks'; import { ILocaleService } from 'vs/workbench/services/localization/common/locale'; import { TelemetryTrustedValue } from 'vs/platform/telemetry/common/telemetryUtils'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; interface IExtensionStateProvider { (extension: Extension): T; @@ -775,7 +775,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension @ILocaleService private readonly localeService: ILocaleService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IFileService private readonly fileService: IFileService, - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, ) { super(); const preferPreReleasesValue = configurationService.getValue('_extensions.preferPreReleases'); @@ -1622,9 +1622,10 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } async toggleApplyExtensionToAllProfiles(extension: IExtension): Promise { - if (extension.local && !isApplicationScopedExtension(extension.local.manifest)) { - await this.extensionManagementService.updateMetadata(extension.local, { isApplicationScoped: !extension.local.isApplicationScoped }, this.userDataProfilesService.defaultProfile.extensionsResource); + if (!extension.local || isApplicationScopedExtension(extension.local.manifest)) { + return; } + await this.extensionManagementService.toggleAppliationScope(extension.local, this.userDataProfileService.currentProfile.extensionsResource); } private isInstalledExtensionSynced(extension: ILocalExtension): boolean { diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts index aa017e86fb375..305332829c99f 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts @@ -89,6 +89,14 @@ export abstract class ProfileAwareExtensionManagementChannelClient extends BaseE return super.updateMetadata(local, metadata, await this.getProfileLocation(extensionsProfileResource)); } + override async toggleAppliationScope(local: ILocalExtension, fromProfileLocation: URI): Promise { + return super.toggleAppliationScope(local, await this.getProfileLocation(fromProfileLocation)); + } + + override async copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise { + return super.copyExtensions(await this.getProfileLocation(fromProfileLocation), await this.getProfileLocation(toProfileLocation)); + } + private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { const previousProfileLocation = await this.getProfileLocation(e.previous.extensionsResource); const currentProfileLocation = await this.getProfileLocation(e.profile.extensionsResource); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts index 1b378e1b24a55..8001988f5ea2e 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts @@ -560,6 +560,14 @@ export class ExtensionManagementService extends Disposable implements IWorkbench await Promise.allSettled(this.servers.map(server => server.extensionManagementService.cleanUp())); } + toggleAppliationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise { + const server = this.getServer(extension); + if (server) { + return server.extensionManagementService.toggleAppliationScope(extension, fromProfileLocation); + } + throw new Error('Not Supported'); + } + copyExtensions(from: URI, to: URI): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { throw new Error('Not Supported'); diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index d26b6ed0bdd23..f100b353488a6 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -45,13 +45,9 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe get onProfileAwareDidUninstallExtension() { return super.onDidUninstallExtension; } override get onDidUninstallExtension() { return Event.filter(this.onProfileAwareDidUninstallExtension, e => this.filterEvent(e), this.disposables); } - private readonly _onDidChangeProfile = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); readonly onDidChangeProfile = this._onDidChangeProfile.event; - private readonly _onDidUpdateExtensionMetadata = this._register(new Emitter()); - override readonly onDidUpdateExtensionMetadata = this._onDidUpdateExtensionMetadata.event; - constructor( @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, @ITelemetryService telemetryService: ITelemetryService, @@ -61,9 +57,9 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @IProductService productService: IProductService, @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, - @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, + @IUriIdentityService uriIdentityService: IUriIdentityService, ) { - super(extensionGalleryService, telemetryService, logService, productService, userDataProfilesService); + super(extensionGalleryService, telemetryService, uriIdentityService, logService, productService, userDataProfilesService); this._register(userDataProfileService.onDidChangeCurrentProfile(e => { if (!this.uriIdentityService.extUri.isEqual(e.previous.extensionsResource, e.profile.extensionsResource)) { e.join(this.whenProfileChanged(e)); @@ -123,6 +119,20 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return this.install(location, { profileLocation }); } + protected async copyExtension(extension: ILocalExtension, fromProfileLocation: URI, toProfileLocation: URI, metadata: Partial): Promise { + const target = await this.webExtensionsScannerService.scanExistingExtension(extension.location, extension.type, toProfileLocation); + const source = await this.webExtensionsScannerService.scanExistingExtension(extension.location, extension.type, fromProfileLocation); + metadata = { ...source?.metadata, ...metadata }; + + let scanned; + if (target) { + scanned = await this.webExtensionsScannerService.updateMetadata(extension, { ...target.metadata, ...metadata }, toProfileLocation); + } else { + scanned = await this.webExtensionsScannerService.addExtension(extension.location, metadata, toProfileLocation); + } + return toLocalExtension(scanned); + } + async installExtensionsFromProfile(extensions: IExtensionIdentifier[], fromProfileLocation: URI, toProfileLocation: URI): Promise { const result: ILocalExtension[] = []; const extensionsToInstall = (await this.webExtensionsScannerService.scanUserExtensions(fromProfileLocation)) diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts index 30e29d6784dd1..476712eaf1f0d 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts @@ -15,7 +15,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { localize } from 'vs/nls'; import { IProductService } from 'vs/platform/product/common/productService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IExtensionManagementServer, IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { Promises } from 'vs/base/common/async'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { IFileService } from 'vs/platform/files/common/files'; @@ -25,7 +25,7 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c import { IRemoteUserDataProfilesService } from 'vs/workbench/services/userDataProfile/common/remoteUserDataProfiles'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -export class NativeRemoteExtensionManagementService extends RemoteExtensionManagementService implements IProfileAwareExtensionManagementService { +export class NativeRemoteExtensionManagementService extends RemoteExtensionManagementService { constructor( channel: IChannel, diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index c892739221a43..b350719272050 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -2038,6 +2038,7 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens throw new Error('Method not implemented.'); } copyExtensions(): Promise { throw new Error('Not Supported'); } + toggleAppliationScope(): Promise { throw new Error('Not Supported'); } installExtensionsFromProfile(): Promise { throw new Error('Not Supported'); } whenProfileChanged(from: IUserDataProfile, to: IUserDataProfile): Promise { throw new Error('Not Supported'); } } From 581b805cd028889070ff5ce5dddbef410dd5a24d Mon Sep 17 00:00:00 2001 From: aamunger Date: Mon, 17 Jul 2023 11:07:04 -0700 Subject: [PATCH 0168/1180] whoopsie --- .../services/workingCopy/common/workingCopyBackupService.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts index 2486e142b717c..f9ec56ad11ad6 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts @@ -134,9 +134,8 @@ export abstract class WorkingCopyBackupService implements IWorkingCopyBackupServ if (backupWorkspaceHome) { return new WorkingCopyBackupServiceImpl(backupWorkspaceHome, this.fileService, this.logService); } - else { - return new WorkingCopyBackupServiceImpl(URI.file('c:\\temp\\backup'), this.fileService, this.logService); - } + + return new InMemoryWorkingCopyBackupService(); } reinitialize(backupWorkspaceHome: URI | undefined): void { From 60fb53a583c52cb3f8da516b300eb0493ced1c24 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 17 Jul 2023 13:12:37 -0700 Subject: [PATCH 0169/1180] use () instead of symbol --- src/vs/editor/common/languages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 3a08292c8d62c..246d32bddd6d2 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1179,7 +1179,7 @@ export const symbolKindNames: { [symbol: number]: string } = { * @internal */ export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string { - return localize('symbolAriaLabel', '{0} Symbol: {1}', symbolName, symbolKindNames[kind]); + return localize('symbolAriaLabel', '{0} ({1})', symbolName, symbolKindNames[kind]); } export const enum SymbolTag { From ac27273e482b3fc470315d372e8999271c750295 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 17 Jul 2023 14:12:10 -0700 Subject: [PATCH 0170/1180] Try to revoke tokens that are getting deleted Best effort. Fixes https://github.com/microsoft/vscode/issues/152055 --- .../extension-browser.webpack.config.js | 3 +- .../src/browser/buffer.ts | 8 +++ .../src/common/logger.ts | 3 + extensions/github-authentication/src/flows.ts | 3 +- .../github-authentication/src/github.ts | 1 + .../github-authentication/src/githubServer.ts | 62 ++++++++++++++++++- .../github-authentication/src/node/buffer.ts | 8 +++ 7 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 extensions/github-authentication/src/browser/buffer.ts create mode 100644 extensions/github-authentication/src/node/buffer.ts diff --git a/extensions/github-authentication/extension-browser.webpack.config.js b/extensions/github-authentication/extension-browser.webpack.config.js index 37b207eb056d1..f109e203569be 100644 --- a/extensions/github-authentication/extension-browser.webpack.config.js +++ b/extensions/github-authentication/extension-browser.webpack.config.js @@ -21,7 +21,8 @@ module.exports = withBrowserDefaults({ 'uuid': path.resolve(__dirname, 'node_modules/uuid/dist/esm-browser/index.js'), './node/authServer': path.resolve(__dirname, 'src/browser/authServer'), './node/crypto': path.resolve(__dirname, 'src/browser/crypto'), - './node/fetch': path.resolve(__dirname, 'src/browser/fetch') + './node/fetch': path.resolve(__dirname, 'src/browser/fetch'), + './node/buffer': path.resolve(__dirname, 'src/browser/buffer'), } } }); diff --git a/extensions/github-authentication/src/browser/buffer.ts b/extensions/github-authentication/src/browser/buffer.ts new file mode 100644 index 0000000000000..7192f5f104adc --- /dev/null +++ b/extensions/github-authentication/src/browser/buffer.ts @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export function base64Encode(text: string): string { + return btoa(text); +} diff --git a/extensions/github-authentication/src/common/logger.ts b/extensions/github-authentication/src/common/logger.ts index 84225bd707f9d..cf90c4176a9ba 100644 --- a/extensions/github-authentication/src/common/logger.ts +++ b/extensions/github-authentication/src/common/logger.ts @@ -26,4 +26,7 @@ export class Log { this.output.error(message); } + public warn(message: string): void { + this.output.warn(message); + } } diff --git a/extensions/github-authentication/src/flows.ts b/extensions/github-authentication/src/flows.ts index f3f9277bdc1d4..5bc9d09538519 100644 --- a/extensions/github-authentication/src/flows.ts +++ b/extensions/github-authentication/src/flows.ts @@ -201,7 +201,8 @@ const allFlows: IFlow[] = [ supportsGitHubEnterpriseServer: false, supportsHostedGitHubEnterprise: true, supportsRemoteExtensionHost: true, - supportsWebWorkerExtensionHost: true, + // Web worker can't open a port to listen for the redirect + supportsWebWorkerExtensionHost: false, // exchanging a code for a token requires a client secret supportsNoClientSecret: false, supportsSupportedClients: true, diff --git a/extensions/github-authentication/src/github.ts b/extensions/github-authentication/src/github.ts index c710cbe4f2f6f..71aa17bd5ccdf 100644 --- a/extensions/github-authentication/src/github.ts +++ b/extensions/github-authentication/src/github.ts @@ -363,6 +363,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid sessions.splice(sessionIndex, 1); await this.storeSessions(sessions); + await this._githubServer.logout(session); this._sessionChangeEmitter.fire({ added: [], removed: [session], changed: [] }); } else { diff --git a/extensions/github-authentication/src/githubServer.ts b/extensions/github-authentication/src/githubServer.ts index 7ac5cd8c5778f..0729c4c50776a 100644 --- a/extensions/github-authentication/src/githubServer.ts +++ b/extensions/github-authentication/src/githubServer.ts @@ -12,6 +12,8 @@ import { crypto } from './node/crypto'; import { fetching } from './node/fetch'; import { ExtensionHost, GitHubTarget, getFlows } from './flows'; import { NETWORK_ERROR, USER_CANCELLATION_ERROR } from './common/errors'; +import { Config } from './config'; +import { base64Encode } from './node/buffer'; // This is the error message that we throw if the login was cancelled for any reason. Extensions // calling `getSession` can handle this error to know that the user cancelled the login. @@ -22,6 +24,7 @@ const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect'; export interface IGitHubServer { login(scopes: string): Promise; + logout(session: vscode.AuthenticationSession): Promise; getUserInfo(token: string): Promise<{ id: string; accountName: string }>; sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise; friendlyName: string; @@ -78,9 +81,14 @@ export class GitHubServer implements IGitHubServer { } // TODO@joaomoreno TODO@TylerLeonhardt + private _isNoCorsEnvironment: boolean | undefined; private async isNoCorsEnvironment(): Promise { + if (this._isNoCorsEnvironment !== undefined) { + return this._isNoCorsEnvironment; + } const uri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/dummy`)); - return (uri.scheme === 'https' && /^((insiders\.)?vscode|github)\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority)); + this._isNoCorsEnvironment = (uri.scheme === 'https' && /^((insiders\.)?vscode|github)\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority)); + return this._isNoCorsEnvironment; } public async login(scopes: string): Promise { @@ -144,6 +152,58 @@ export class GitHubServer implements IGitHubServer { throw new Error(userCancelled ? CANCELLATION_ERROR : 'No auth flow succeeded.'); } + public async logout(session: vscode.AuthenticationSession): Promise { + this._logger.trace(`Deleting session (${session.id}) from server...`); + + if (!Config.gitHubClientSecret) { + this._logger.warn('No client secret configured for GitHub authentication. The token has been deleted with best effort on this system, but we are unable to delete the token on server without the client secret.'); + return; + } + + // Only attempt to delete OAuth tokens. They are always prefixed with `gho_`. + // https://docs.github.com/en/rest/apps/oauth-applications#about-oauth-apps-and-oauth-authorizations-of-github-apps + if (!session.accessToken.startsWith('gho_')) { + this._logger.warn('The token being deleted is not an OAuth token. It has been deleted locally, but we cannot delete it on server.'); + return; + } + + if (!isSupportedTarget(this._type, this._ghesUri)) { + this._logger.trace('GitHub.com and GitHub hosted GitHub Enterprise are the only options that support deleting tokens on the server. Skipping.'); + return; + } + + const authHeader = 'Basic ' + base64Encode(`${Config.gitHubClientId}:${Config.gitHubClientSecret}`); + const uri = this.getServerUri(`/applications/${Config.gitHubClientId}/token`); + + try { + // Defined here: https://docs.github.com/en/rest/apps/oauth-applications?apiVersion=2022-11-28#delete-an-app-token + const result = await fetching(uri.toString(true), { + method: 'DELETE', + headers: { + Accept: 'application/vnd.github+json', + Authorization: authHeader, + 'X-GitHub-Api-Version': '2022-11-28', + 'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})` + }, + body: JSON.stringify({ access_token: session.accessToken }), + }); + + if (result.status === 204) { + this._logger.trace(`Successfully deleted token from session (${session.id}) from server.`); + return; + } + + try { + const body = await result.text(); + throw new Error(body); + } catch (e) { + throw new Error(`${result.status} ${result.statusText}`); + } + } catch (e) { + this._logger.warn('Failed to delete token from server.' + e.message ?? e); + } + } + private getServerUri(path: string = '') { const apiUri = this.baseUri; // github.com and Hosted GitHub Enterprise instances diff --git a/extensions/github-authentication/src/node/buffer.ts b/extensions/github-authentication/src/node/buffer.ts new file mode 100644 index 0000000000000..8e6208aa22a7b --- /dev/null +++ b/extensions/github-authentication/src/node/buffer.ts @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export function base64Encode(text: string): string { + return Buffer.from(text, 'binary').toString('base64'); +} From e77c16cf6b217f813f3caaa7528e31b15bff231a Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 17 Jul 2023 14:22:44 -0700 Subject: [PATCH 0171/1180] tidy --- .../browser/accessibility.contribution.ts | 38 ++++++++++++------- .../accessibility/browser/accessibleView.ts | 1 + 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts index d391b388ac6c2..9675240039f11 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts @@ -22,7 +22,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { NEW_UNTITLED_FILE_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileConstants'; import { ModesHoverController } from 'vs/editor/contrib/hover/browser/hover'; -import { withNullAsUndefined } from 'vs/base/common/types'; +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; registerAccessibilityConfiguration(); @@ -101,32 +101,44 @@ workbenchRegistry.registerWorkbenchContribution(EditorAccessibilityHelpContribut class HoverAccessibleViewContribution extends Disposable { static ID: 'hoverAccessibleViewContribution'; + private _options: IAccessibleViewOptions = { + ariaLabel: localize('hoverAccessibleView', "Hover Accessible View"), language: 'typescript', type: AccessibleViewType.View + }; constructor() { super(); this._register(AccessibleViewAction.addImplementation(90, 'hover', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const codeEditorService = accessor.get(ICodeEditorService); const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); - if (!editor) { + const editorHoverContent = editor ? ModesHoverController.get(editor)?.getWidgetContent() ?? undefined : undefined; + if (!editorHoverContent) { return false; } - const controller = ModesHoverController.get(editor); - const content = withNullAsUndefined(controller?.getWidgetContent()); - if (!controller || !content) { + accessibleViewService.show({ + verbositySettingKey: 'hover', + provideContent() { return editorHoverContent; }, + onClose() { }, + options: this._options + }); + return true; + }, EditorContextKeys.hoverFocused)); + this._register(AccessibleViewAction.addImplementation(90, 'extension-hover', accessor => { + const accessibleViewService = accessor.get(IAccessibleViewService); + const contextViewService = accessor.get(IContextViewService); + const contextViewElement = contextViewService.getContextViewElement(); + const extensionHoverContent = contextViewElement?.textContent ?? undefined; + if (contextViewElement.classList.contains('accessible-view-container') || !extensionHoverContent) { + // The accessible view, itself, uses the context view service to display the text. We don't want to read that. return false; } accessibleViewService.show({ verbositySettingKey: 'hover', - provideContent() { return content; }, - onClose() { - controller.focus(); - }, - options: { - ariaLabel: localize('hoverAccessibleView', "Hover Accessible View"), language: 'typescript', type: AccessibleViewType.View - } + provideContent() { return extensionHoverContent; }, + onClose() { }, + options: this._options }); return true; - }, EditorContextKeys.hoverFocused)); + })); } } diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 8754d601121b7..f6bfc202d9195 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -113,6 +113,7 @@ class AccessibleView extends Disposable { const delegate: IContextViewDelegate = { getAnchor: () => { return { x: (window.innerWidth / 2) - (DEFAULT.WIDTH / 2), y: DEFAULT.TOP }; }, render: (container) => { + container.classList.add('accessible-view-container'); return this._render(provider, container); }, onHide: () => { From 2d6e67f34eaa10910603d2923ffdd03fb53bbdea Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 17 Jul 2023 14:26:31 -0700 Subject: [PATCH 0172/1180] increase priority for editor since it has a context key --- .../contrib/accessibility/browser/accessibility.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts index 9675240039f11..e84811c0e0536 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts @@ -106,7 +106,7 @@ class HoverAccessibleViewContribution extends Disposable { }; constructor() { super(); - this._register(AccessibleViewAction.addImplementation(90, 'hover', accessor => { + this._register(AccessibleViewAction.addImplementation(95, 'hover', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const codeEditorService = accessor.get(ICodeEditorService); const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); From 58718c99056fc6f516f77d96918cf99495de15a9 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 17 Jul 2023 14:56:09 -0700 Subject: [PATCH 0173/1180] Update pandas detection. (#188113) --- .../notebook/common/services/notebookSimpleWorker.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts b/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts index 1b8d4055433b4..b0b8c5153ab32 100644 --- a/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts +++ b/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts @@ -286,10 +286,14 @@ export class NotebookEditorSimpleWorker implements IRequestHandler, IDisposable continue; } + if (cell.language !== 'python') { + continue; + } + const lineCount = cell.textBuffer.getLineCount(); const maxLineCount = Math.min(lineCount, 20); const range = new Range(1, 1, maxLineCount, cell.textBuffer.getLineLength(maxLineCount) + 1); - const searchParams = new SearchParams('import\\s*pandas', true, false, null); + const searchParams = new SearchParams('import\\s*pandas|from\\s*pandas', true, false, null); const searchData = searchParams.parseSearchRequest(); if (!searchData) { From 4390ebc406732e5b4eed22a1d7aa4fc0ef4a9460 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:13:06 -0700 Subject: [PATCH 0174/1180] Format loader and add more comments (#188115) --- src/vs/base/worker/workerMain.ts | 2 +- src/vs/loader.js | 3652 +++++++++++++++--------------- 2 files changed, 1827 insertions(+), 1827 deletions(-) diff --git a/src/vs/base/worker/workerMain.ts b/src/vs/base/worker/workerMain.ts index 65df427d79eb0..ec18c5ca0f468 100644 --- a/src/vs/base/worker/workerMain.ts +++ b/src/vs/base/worker/workerMain.ts @@ -54,7 +54,7 @@ try { const func = ( trustedTypesPolicy - ? globalThis.eval(trustedTypesPolicy.createScript('', 'true')) + ? globalThis.eval(trustedTypesPolicy.createScript('', 'true')) // CodeQL [SM01632] fetch + eval is used on the web worker instead of importScripts if possible because importScripts is synchronous and we observed deadlocks on Safari : new Function('true') // CodeQL [SM01632] fetch + eval is used on the web worker instead of importScripts if possible because importScripts is synchronous and we observed deadlocks on Safari ); func.call(globalThis); diff --git a/src/vs/loader.js b/src/vs/loader.js index cebfe6da858ea..c2d38dfca0ee9 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -22,60 +22,60 @@ const _amdLoaderGlobal = this; const _commonjsGlobal = typeof global === 'object' ? global : {}; var AMDLoader; (function (AMDLoader) { - AMDLoader.global = _amdLoaderGlobal; - class Environment { - get isWindows() { - this._detect(); - return this._isWindows; - } - get isNode() { - this._detect(); - return this._isNode; - } - get isElectronRenderer() { - this._detect(); - return this._isElectronRenderer; - } - get isWebWorker() { - this._detect(); - return this._isWebWorker; - } - get isElectronNodeIntegrationWebWorker() { - this._detect(); - return this._isElectronNodeIntegrationWebWorker; - } - constructor() { - this._detected = false; - this._isWindows = false; - this._isNode = false; - this._isElectronRenderer = false; - this._isWebWorker = false; - this._isElectronNodeIntegrationWebWorker = false; - } - _detect() { - if (this._detected) { - return; - } - this._detected = true; - this._isWindows = Environment._isWindows(); - this._isNode = (typeof module !== 'undefined' && !!module.exports); - this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); - this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function'); - this._isElectronNodeIntegrationWebWorker = this._isWebWorker && (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'worker'); - } - static _isWindows() { - if (typeof navigator !== 'undefined') { - if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) { - return true; - } - } - if (typeof process !== 'undefined') { - return (process.platform === 'win32'); - } - return false; - } - } - AMDLoader.Environment = Environment; + AMDLoader.global = _amdLoaderGlobal; + class Environment { + get isWindows() { + this._detect(); + return this._isWindows; + } + get isNode() { + this._detect(); + return this._isNode; + } + get isElectronRenderer() { + this._detect(); + return this._isElectronRenderer; + } + get isWebWorker() { + this._detect(); + return this._isWebWorker; + } + get isElectronNodeIntegrationWebWorker() { + this._detect(); + return this._isElectronNodeIntegrationWebWorker; + } + constructor() { + this._detected = false; + this._isWindows = false; + this._isNode = false; + this._isElectronRenderer = false; + this._isWebWorker = false; + this._isElectronNodeIntegrationWebWorker = false; + } + _detect() { + if (this._detected) { + return; + } + this._detected = true; + this._isWindows = Environment._isWindows(); + this._isNode = (typeof module !== 'undefined' && !!module.exports); + this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); + this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function'); + this._isElectronNodeIntegrationWebWorker = this._isWebWorker && (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'worker'); + } + static _isWindows() { + if (typeof navigator !== 'undefined') { + if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) { + return true; + } + } + if (typeof process !== 'undefined') { + return (process.platform === 'win32'); + } + return false; + } + } + AMDLoader.Environment = Environment; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -83,36 +83,36 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - class LoaderEvent { - constructor(type, detail, timestamp) { - this.type = type; - this.detail = detail; - this.timestamp = timestamp; - } - } - AMDLoader.LoaderEvent = LoaderEvent; - class LoaderEventRecorder { - constructor(loaderAvailableTimestamp) { - this._events = [new LoaderEvent(1 /* LoaderEventType.LoaderAvailable */, '', loaderAvailableTimestamp)]; - } - record(type, detail) { - this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp())); - } - getEvents() { - return this._events; - } - } - AMDLoader.LoaderEventRecorder = LoaderEventRecorder; - class NullLoaderEventRecorder { - record(type, detail) { - // Nothing to do - } - getEvents() { - return []; - } - } - NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); - AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; + class LoaderEvent { + constructor(type, detail, timestamp) { + this.type = type; + this.detail = detail; + this.timestamp = timestamp; + } + } + AMDLoader.LoaderEvent = LoaderEvent; + class LoaderEventRecorder { + constructor(loaderAvailableTimestamp) { + this._events = [new LoaderEvent(1 /* LoaderEventType.LoaderAvailable */, '', loaderAvailableTimestamp)]; + } + record(type, detail) { + this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp())); + } + getEvents() { + return this._events; + } + } + AMDLoader.LoaderEventRecorder = LoaderEventRecorder; + class NullLoaderEventRecorder { + record(type, detail) { + // Nothing to do + } + getEvents() { + return []; + } + } + NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); + AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -120,99 +120,99 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - class Utilities { - /** - * This method does not take care of / vs \ - */ - static fileUriToFilePath(isWindows, uri) { - uri = decodeURI(uri).replace(/%23/g, '#'); - if (isWindows) { - if (/^file:\/\/\//.test(uri)) { - // This is a URI without a hostname => return only the path segment - return uri.substr(8); - } - if (/^file:\/\//.test(uri)) { - return uri.substr(5); - } - } - else { - if (/^file:\/\//.test(uri)) { - return uri.substr(7); - } - } - // Not sure... - return uri; - } - static startsWith(haystack, needle) { - return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; - } - static endsWith(haystack, needle) { - return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle; - } - // only check for "?" before "#" to ensure that there is a real Query-String - static containsQueryString(url) { - return /^[^\#]*\?/gi.test(url); - } - /** - * Does `url` start with http:// or https:// or file:// or / ? - */ - static isAbsolutePath(url) { - return /^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(url); - } - static forEachProperty(obj, callback) { - if (obj) { - let key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - callback(key, obj[key]); - } - } - } - } - static isEmpty(obj) { - let isEmpty = true; - Utilities.forEachProperty(obj, () => { - isEmpty = false; - }); - return isEmpty; - } - static recursiveClone(obj) { - if (!obj || typeof obj !== 'object' || obj instanceof RegExp) { - return obj; - } - if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) { - // only clone "simple" objects - return obj; - } - let result = Array.isArray(obj) ? [] : {}; - Utilities.forEachProperty(obj, (key, value) => { - if (value && typeof value === 'object') { - result[key] = Utilities.recursiveClone(value); - } - else { - result[key] = value; - } - }); - return result; - } - static generateAnonymousModule() { - return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '==='; - } - static isAnonymousModule(id) { - return Utilities.startsWith(id, '===anonymous'); - } - static getHighPerformanceTimestamp() { - if (!this.PERFORMANCE_NOW_PROBED) { - this.PERFORMANCE_NOW_PROBED = true; - this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function'); - } - return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); - } - } - Utilities.NEXT_ANONYMOUS_ID = 1; - Utilities.PERFORMANCE_NOW_PROBED = false; - Utilities.HAS_PERFORMANCE_NOW = false; - AMDLoader.Utilities = Utilities; + class Utilities { + /** + * This method does not take care of / vs \ + */ + static fileUriToFilePath(isWindows, uri) { + uri = decodeURI(uri).replace(/%23/g, '#'); + if (isWindows) { + if (/^file:\/\/\//.test(uri)) { + // This is a URI without a hostname => return only the path segment + return uri.substr(8); + } + if (/^file:\/\//.test(uri)) { + return uri.substr(5); + } + } + else { + if (/^file:\/\//.test(uri)) { + return uri.substr(7); + } + } + // Not sure... + return uri; + } + static startsWith(haystack, needle) { + return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; + } + static endsWith(haystack, needle) { + return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle; + } + // only check for "?" before "#" to ensure that there is a real Query-String + static containsQueryString(url) { + return /^[^\#]*\?/gi.test(url); + } + /** + * Does `url` start with http:// or https:// or file:// or / ? + */ + static isAbsolutePath(url) { + return /^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(url); + } + static forEachProperty(obj, callback) { + if (obj) { + let key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + callback(key, obj[key]); + } + } + } + } + static isEmpty(obj) { + let isEmpty = true; + Utilities.forEachProperty(obj, () => { + isEmpty = false; + }); + return isEmpty; + } + static recursiveClone(obj) { + if (!obj || typeof obj !== 'object' || obj instanceof RegExp) { + return obj; + } + if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) { + // only clone "simple" objects + return obj; + } + let result = Array.isArray(obj) ? [] : {}; + Utilities.forEachProperty(obj, (key, value) => { + if (value && typeof value === 'object') { + result[key] = Utilities.recursiveClone(value); + } + else { + result[key] = value; + } + }); + return result; + } + static generateAnonymousModule() { + return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '==='; + } + static isAnonymousModule(id) { + return Utilities.startsWith(id, '===anonymous'); + } + static getHighPerformanceTimestamp() { + if (!this.PERFORMANCE_NOW_PROBED) { + this.PERFORMANCE_NOW_PROBED = true; + this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function'); + } + return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); + } + } + Utilities.NEXT_ANONYMOUS_ID = 1; + Utilities.PERFORMANCE_NOW_PROBED = false; + Utilities.HAS_PERFORMANCE_NOW = false; + AMDLoader.Utilities = Utilities; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -220,318 +220,318 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - function ensureError(err) { - if (err instanceof Error) { - return err; - } - const result = new Error(err.message || String(err) || 'Unknown Error'); - if (err.stack) { - result.stack = err.stack; - } - return result; - } - AMDLoader.ensureError = ensureError; - ; - class ConfigurationOptionsUtil { - /** - * Ensure configuration options make sense - */ - static validateConfigurationOptions(options) { - function defaultOnError(err) { - if (err.phase === 'loading') { - console.error('Loading "' + err.moduleId + '" failed'); - console.error(err); - console.error('Here are the modules that depend on it:'); - console.error(err.neededBy); - return; - } - if (err.phase === 'factory') { - console.error('The factory function of "' + err.moduleId + '" has thrown an exception'); - console.error(err); - console.error('Here are the modules that depend on it:'); - console.error(err.neededBy); - return; - } - } - options = options || {}; - if (typeof options.baseUrl !== 'string') { - options.baseUrl = ''; - } - if (typeof options.isBuild !== 'boolean') { - options.isBuild = false; - } - if (typeof options.paths !== 'object') { - options.paths = {}; - } - if (typeof options.config !== 'object') { - options.config = {}; - } - if (typeof options.catchError === 'undefined') { - options.catchError = false; - } - if (typeof options.recordStats === 'undefined') { - options.recordStats = false; - } - if (typeof options.urlArgs !== 'string') { - options.urlArgs = ''; - } - if (typeof options.onError !== 'function') { - options.onError = defaultOnError; - } - if (!Array.isArray(options.ignoreDuplicateModules)) { - options.ignoreDuplicateModules = []; - } - if (options.baseUrl.length > 0) { - if (!AMDLoader.Utilities.endsWith(options.baseUrl, '/')) { - options.baseUrl += '/'; - } - } - if (typeof options.cspNonce !== 'string') { - options.cspNonce = ''; - } - if (typeof options.preferScriptTags === 'undefined') { - options.preferScriptTags = false; - } - if (options.nodeCachedData && typeof options.nodeCachedData === 'object') { - if (typeof options.nodeCachedData.seed !== 'string') { - options.nodeCachedData.seed = 'seed'; - } - if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) { - options.nodeCachedData.writeDelay = 1000 * 7; - } - if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') { - const err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); - err.phase = 'configuration'; - options.onError(err); - options.nodeCachedData = undefined; - } - } - return options; - } - static mergeConfigurationOptions(overwrite = null, base = null) { - let result = AMDLoader.Utilities.recursiveClone(base || {}); - // Merge known properties and overwrite the unknown ones - AMDLoader.Utilities.forEachProperty(overwrite, (key, value) => { - if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') { - result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value); - } - else if (key === 'paths' && typeof result.paths !== 'undefined') { - AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.paths[key2] = value2); - } - else if (key === 'config' && typeof result.config !== 'undefined') { - AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.config[key2] = value2); - } - else { - result[key] = AMDLoader.Utilities.recursiveClone(value); - } - }); - return ConfigurationOptionsUtil.validateConfigurationOptions(result); - } - } - AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; - class Configuration { - constructor(env, options) { - this._env = env; - this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); - this._createIgnoreDuplicateModulesMap(); - this._createSortedPathsRules(); - if (this.options.baseUrl === '') { - if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) { - let nodeMain = this.options.nodeRequire.main.filename; - let dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); - this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); - } - } - } - _createIgnoreDuplicateModulesMap() { - // Build a map out of the ignoreDuplicateModules array - this.ignoreDuplicateModulesMap = {}; - for (let i = 0; i < this.options.ignoreDuplicateModules.length; i++) { - this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true; - } - } - _createSortedPathsRules() { - // Create an array our of the paths rules, sorted descending by length to - // result in a more specific -> less specific order - this.sortedPathsRules = []; - AMDLoader.Utilities.forEachProperty(this.options.paths, (from, to) => { - if (!Array.isArray(to)) { - this.sortedPathsRules.push({ - from: from, - to: [to] - }); - } - else { - this.sortedPathsRules.push({ - from: from, - to: to - }); - } - }); - this.sortedPathsRules.sort((a, b) => { - return b.from.length - a.from.length; - }); - } - /** - * Clone current configuration and overwrite options selectively. - * @param options The selective options to overwrite with. - * @result A new configuration - */ - cloneAndMerge(options) { - return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options)); - } - /** - * Get current options bag. Useful for passing it forward to plugins. - */ - getOptionsLiteral() { - return this.options; - } - _applyPaths(moduleId) { - let pathRule; - for (let i = 0, len = this.sortedPathsRules.length; i < len; i++) { - pathRule = this.sortedPathsRules[i]; - if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) { - let result = []; - for (let j = 0, lenJ = pathRule.to.length; j < lenJ; j++) { - result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length)); - } - return result; - } - } - return [moduleId]; - } - _addUrlArgsToUrl(url) { - if (AMDLoader.Utilities.containsQueryString(url)) { - return url + '&' + this.options.urlArgs; - } - else { - return url + '?' + this.options.urlArgs; - } - } - _addUrlArgsIfNecessaryToUrl(url) { - if (this.options.urlArgs) { - return this._addUrlArgsToUrl(url); - } - return url; - } - _addUrlArgsIfNecessaryToUrls(urls) { - if (this.options.urlArgs) { - for (let i = 0, len = urls.length; i < len; i++) { - urls[i] = this._addUrlArgsToUrl(urls[i]); - } - } - return urls; - } - /** - * Transform a module id to a location. Appends .js to module ids - */ - moduleIdToPaths(moduleId) { - if (this._env.isNode) { - const isNodeModule = (this.options.amdModulesPattern instanceof RegExp - && !this.options.amdModulesPattern.test(moduleId)); - if (isNodeModule) { - // This is a node module... - if (this.isBuild()) { - // ...and we are at build time, drop it - return ['empty:']; - } - else { - // ...and at runtime we create a `shortcut`-path - return ['node|' + moduleId]; - } - } - } - let result = moduleId; - let results; - if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) { - results = this._applyPaths(result); - for (let i = 0, len = results.length; i < len; i++) { - if (this.isBuild() && results[i] === 'empty:') { - continue; - } - if (!AMDLoader.Utilities.isAbsolutePath(results[i])) { - results[i] = this.options.baseUrl + results[i]; - } - if (!AMDLoader.Utilities.endsWith(results[i], '.js') && !AMDLoader.Utilities.containsQueryString(results[i])) { - results[i] = results[i] + '.js'; - } - } - } - else { - if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.containsQueryString(result)) { - result = result + '.js'; - } - results = [result]; - } - return this._addUrlArgsIfNecessaryToUrls(results); - } - /** - * Transform a module id or url to a location. - */ - requireToUrl(url) { - let result = url; - if (!AMDLoader.Utilities.isAbsolutePath(result)) { - result = this._applyPaths(result)[0]; - if (!AMDLoader.Utilities.isAbsolutePath(result)) { - result = this.options.baseUrl + result; - } - } - return this._addUrlArgsIfNecessaryToUrl(result); - } - /** - * Flag to indicate if current execution is as part of a build. - */ - isBuild() { - return this.options.isBuild; - } - shouldInvokeFactory(strModuleId) { - if (!this.options.isBuild) { - // outside of a build, all factories should be invoked - return true; - } - // during a build, only explicitly marked or anonymous modules get their factories invoked - if (AMDLoader.Utilities.isAnonymousModule(strModuleId)) { - return true; - } - if (this.options.buildForceInvokeFactory && this.options.buildForceInvokeFactory[strModuleId]) { - return true; - } - return false; - } - /** - * Test if module `moduleId` is expected to be defined multiple times - */ - isDuplicateMessageIgnoredFor(moduleId) { - return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId); - } - /** - * Get the configuration settings for the provided module id - */ - getConfigForModule(moduleId) { - if (this.options.config) { - return this.options.config[moduleId]; - } - } - /** - * Should errors be caught when executing module factories? - */ - shouldCatchError() { - return this.options.catchError; - } - /** - * Should statistics be recorded? - */ - shouldRecordStats() { - return this.options.recordStats; - } - /** - * Forward an error to the error handler. - */ - onError(err) { - this.options.onError(err); - } - } - AMDLoader.Configuration = Configuration; + function ensureError(err) { + if (err instanceof Error) { + return err; + } + const result = new Error(err.message || String(err) || 'Unknown Error'); + if (err.stack) { + result.stack = err.stack; + } + return result; + } + AMDLoader.ensureError = ensureError; + ; + class ConfigurationOptionsUtil { + /** + * Ensure configuration options make sense + */ + static validateConfigurationOptions(options) { + function defaultOnError(err) { + if (err.phase === 'loading') { + console.error('Loading "' + err.moduleId + '" failed'); + console.error(err); + console.error('Here are the modules that depend on it:'); + console.error(err.neededBy); + return; + } + if (err.phase === 'factory') { + console.error('The factory function of "' + err.moduleId + '" has thrown an exception'); + console.error(err); + console.error('Here are the modules that depend on it:'); + console.error(err.neededBy); + return; + } + } + options = options || {}; + if (typeof options.baseUrl !== 'string') { + options.baseUrl = ''; + } + if (typeof options.isBuild !== 'boolean') { + options.isBuild = false; + } + if (typeof options.paths !== 'object') { + options.paths = {}; + } + if (typeof options.config !== 'object') { + options.config = {}; + } + if (typeof options.catchError === 'undefined') { + options.catchError = false; + } + if (typeof options.recordStats === 'undefined') { + options.recordStats = false; + } + if (typeof options.urlArgs !== 'string') { + options.urlArgs = ''; + } + if (typeof options.onError !== 'function') { + options.onError = defaultOnError; + } + if (!Array.isArray(options.ignoreDuplicateModules)) { + options.ignoreDuplicateModules = []; + } + if (options.baseUrl.length > 0) { + if (!AMDLoader.Utilities.endsWith(options.baseUrl, '/')) { + options.baseUrl += '/'; + } + } + if (typeof options.cspNonce !== 'string') { + options.cspNonce = ''; + } + if (typeof options.preferScriptTags === 'undefined') { + options.preferScriptTags = false; + } + if (options.nodeCachedData && typeof options.nodeCachedData === 'object') { + if (typeof options.nodeCachedData.seed !== 'string') { + options.nodeCachedData.seed = 'seed'; + } + if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) { + options.nodeCachedData.writeDelay = 1000 * 7; + } + if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') { + const err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); + err.phase = 'configuration'; + options.onError(err); + options.nodeCachedData = undefined; + } + } + return options; + } + static mergeConfigurationOptions(overwrite = null, base = null) { + let result = AMDLoader.Utilities.recursiveClone(base || {}); + // Merge known properties and overwrite the unknown ones + AMDLoader.Utilities.forEachProperty(overwrite, (key, value) => { + if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') { + result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value); + } + else if (key === 'paths' && typeof result.paths !== 'undefined') { + AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.paths[key2] = value2); + } + else if (key === 'config' && typeof result.config !== 'undefined') { + AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.config[key2] = value2); + } + else { + result[key] = AMDLoader.Utilities.recursiveClone(value); + } + }); + return ConfigurationOptionsUtil.validateConfigurationOptions(result); + } + } + AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; + class Configuration { + constructor(env, options) { + this._env = env; + this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); + this._createIgnoreDuplicateModulesMap(); + this._createSortedPathsRules(); + if (this.options.baseUrl === '') { + if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) { + let nodeMain = this.options.nodeRequire.main.filename; + let dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); + this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); + } + } + } + _createIgnoreDuplicateModulesMap() { + // Build a map out of the ignoreDuplicateModules array + this.ignoreDuplicateModulesMap = {}; + for (let i = 0; i < this.options.ignoreDuplicateModules.length; i++) { + this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true; + } + } + _createSortedPathsRules() { + // Create an array our of the paths rules, sorted descending by length to + // result in a more specific -> less specific order + this.sortedPathsRules = []; + AMDLoader.Utilities.forEachProperty(this.options.paths, (from, to) => { + if (!Array.isArray(to)) { + this.sortedPathsRules.push({ + from: from, + to: [to] + }); + } + else { + this.sortedPathsRules.push({ + from: from, + to: to + }); + } + }); + this.sortedPathsRules.sort((a, b) => { + return b.from.length - a.from.length; + }); + } + /** + * Clone current configuration and overwrite options selectively. + * @param options The selective options to overwrite with. + * @result A new configuration + */ + cloneAndMerge(options) { + return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options)); + } + /** + * Get current options bag. Useful for passing it forward to plugins. + */ + getOptionsLiteral() { + return this.options; + } + _applyPaths(moduleId) { + let pathRule; + for (let i = 0, len = this.sortedPathsRules.length; i < len; i++) { + pathRule = this.sortedPathsRules[i]; + if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) { + let result = []; + for (let j = 0, lenJ = pathRule.to.length; j < lenJ; j++) { + result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length)); + } + return result; + } + } + return [moduleId]; + } + _addUrlArgsToUrl(url) { + if (AMDLoader.Utilities.containsQueryString(url)) { + return url + '&' + this.options.urlArgs; + } + else { + return url + '?' + this.options.urlArgs; + } + } + _addUrlArgsIfNecessaryToUrl(url) { + if (this.options.urlArgs) { + return this._addUrlArgsToUrl(url); + } + return url; + } + _addUrlArgsIfNecessaryToUrls(urls) { + if (this.options.urlArgs) { + for (let i = 0, len = urls.length; i < len; i++) { + urls[i] = this._addUrlArgsToUrl(urls[i]); + } + } + return urls; + } + /** + * Transform a module id to a location. Appends .js to module ids + */ + moduleIdToPaths(moduleId) { + if (this._env.isNode) { + const isNodeModule = (this.options.amdModulesPattern instanceof RegExp + && !this.options.amdModulesPattern.test(moduleId)); + if (isNodeModule) { + // This is a node module... + if (this.isBuild()) { + // ...and we are at build time, drop it + return ['empty:']; + } + else { + // ...and at runtime we create a `shortcut`-path + return ['node|' + moduleId]; + } + } + } + let result = moduleId; + let results; + if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) { + results = this._applyPaths(result); + for (let i = 0, len = results.length; i < len; i++) { + if (this.isBuild() && results[i] === 'empty:') { + continue; + } + if (!AMDLoader.Utilities.isAbsolutePath(results[i])) { + results[i] = this.options.baseUrl + results[i]; + } + if (!AMDLoader.Utilities.endsWith(results[i], '.js') && !AMDLoader.Utilities.containsQueryString(results[i])) { + results[i] = results[i] + '.js'; + } + } + } + else { + if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.containsQueryString(result)) { + result = result + '.js'; + } + results = [result]; + } + return this._addUrlArgsIfNecessaryToUrls(results); + } + /** + * Transform a module id or url to a location. + */ + requireToUrl(url) { + let result = url; + if (!AMDLoader.Utilities.isAbsolutePath(result)) { + result = this._applyPaths(result)[0]; + if (!AMDLoader.Utilities.isAbsolutePath(result)) { + result = this.options.baseUrl + result; + } + } + return this._addUrlArgsIfNecessaryToUrl(result); + } + /** + * Flag to indicate if current execution is as part of a build. + */ + isBuild() { + return this.options.isBuild; + } + shouldInvokeFactory(strModuleId) { + if (!this.options.isBuild) { + // outside of a build, all factories should be invoked + return true; + } + // during a build, only explicitly marked or anonymous modules get their factories invoked + if (AMDLoader.Utilities.isAnonymousModule(strModuleId)) { + return true; + } + if (this.options.buildForceInvokeFactory && this.options.buildForceInvokeFactory[strModuleId]) { + return true; + } + return false; + } + /** + * Test if module `moduleId` is expected to be defined multiple times + */ + isDuplicateMessageIgnoredFor(moduleId) { + return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId); + } + /** + * Get the configuration settings for the provided module id + */ + getConfigForModule(moduleId) { + if (this.options.config) { + return this.options.config[moduleId]; + } + } + /** + * Should errors be caught when executing module factories? + */ + shouldCatchError() { + return this.options.catchError; + } + /** + * Should statistics be recorded? + */ + shouldRecordStats() { + return this.options.recordStats; + } + /** + * Forward an error to the error handler. + */ + onError(err) { + this.options.onError(err); + } + } + AMDLoader.Configuration = Configuration; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -539,503 +539,503 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - /** - * Load `scriptSrc` only once (avoid multiple ", ))) + .unwrap() + } +} + +/// Handle returned when getting a stream to the server, used to refcount +/// connections to a server so it can be disposed when there are no more clients. +struct ConnectionHandle { + client_counter: Arc>, +} + +impl ConnectionHandle { + pub fn new(client_counter: Arc>) -> Self { + client_counter.send_modify(|v| { + *v += 1; + }); + Self { client_counter } + } +} + +impl Drop for ConnectionHandle { + fn drop(&mut self) { + self.client_counter.send_modify(|v| { + *v -= 1; + }); + } +} + +type StartData = (PathBuf, Arc>); + +/// State stored in the ConnectionManager for each server version. +struct VersionState { + downloaded: bool, + socket_path: Barrier>, +} + +type ConnectionStateMap = Arc>>; + +/// Manages the connections to running web UI instances. Multiple web servers +/// can run concurrently, with routing based on the URL path. +struct ConnectionManager { + pub platform: Platform, + pub log: log::Logger, + args: ServeWebArgs, + /// Cache where servers are stored + cache: DownloadCache, + /// Mapping of (Quality, Commit) to the state each server is in + state: ConnectionStateMap, + /// Update service instance + update_service: UpdateService, + /// Cache of the latest released version, storing the time we checked as well + latest_version: tokio::sync::Mutex>, +} + +fn key_for_release(release: &Release) -> (Quality, String) { + (release.quality, release.commit.clone()) +} + +impl ConnectionManager { + pub fn new(ctx: &CommandContext, platform: Platform, args: ServeWebArgs) -> Arc { + Arc::new(Self { + platform, + args, + log: ctx.log.clone(), + cache: DownloadCache::new(ctx.paths.web_server_storage()), + update_service: UpdateService::new( + ctx.log.clone(), + Arc::new(ReqwestSimpleHttp::with_client(ctx.http.clone())), + ), + state: ConnectionStateMap::default(), + latest_version: tokio::sync::Mutex::default(), + }) + } + + /// Gets a connection to a server version + pub async fn get_connection( + &self, + release: Release, + ) -> Result<(AsyncPipe, ConnectionHandle), CodeError> { + // todo@connor4312: there is likely some performance benefit to + // implementing a 'keepalive' for these connections. + let (path, counter) = self.get_version_data(release).await?; + let handle = ConnectionHandle::new(counter); + let rw = get_socket_rw_stream(&path).await?; + Ok((rw, handle)) + } + + /// Gets the latest release for the CLI quality, caching its result for some + /// time to allow for fast loads. + pub async fn get_latest_release(&self) -> Result { + let mut latest = self.latest_version.lock().await; + let now = Instant::now(); + if let Some((checked_at, release)) = &*latest { + if checked_at.elapsed() < Duration::from_secs(RELEASE_CACHE_SECS) { + return Ok(release.clone()); + } + } + + let quality = VSCODE_CLI_QUALITY + .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) + .and_then(|q| { + Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) + })?; + + let release = self + .update_service + .get_latest_commit(self.platform, TargetKind::Web, quality) + .await + .map_err(|e| CodeError::UpdateCheckFailed(e.to_string())); + + // If the update service is unavailable and we have stale data, use that + if let (Err(e), Some((_, previous))) = (&release, &*latest) { + warning!(self.log, "error getting latest release, using stale: {}", e); + return Ok(previous.clone()); + } + + let release = release?; + debug!(self.log, "refreshed latest release: {}", release); + *latest = Some((now, release.clone())); + + Ok(release) + } + + /// Gets the StartData for the a version of the VS Code server, triggering + /// download/start if necessary. It returns `CodeError::ServerNotYetDownloaded` + /// while the server is downloading, which is used to have a refresh loop on the page. + async fn get_version_data(&self, release: Release) -> Result { + self.get_version_data_inner(release)? + .wait() + .await + .unwrap() + .map_err(CodeError::ServerDownloadError) + } + + fn get_version_data_inner( + &self, + release: Release, + ) -> Result>, CodeError> { + let mut state = self.state.lock().unwrap(); + let key = key_for_release(&release); + if let Some(s) = state.get_mut(&key) { + if !s.downloaded { + if s.socket_path.is_open() { + s.downloaded = true; + } else { + return Err(CodeError::ServerNotYetDownloaded); + } + } + + return Ok(s.socket_path.clone()); + } + + let (socket_path, opener) = new_barrier(); + let state_map_dup = self.state.clone(); + let args = StartArgs { + args: self.args.clone(), + log: self.log.clone(), + opener, + release, + }; + + if let Some(p) = self.cache.exists(&args.release.commit) { + state.insert( + key.clone(), + VersionState { + socket_path: socket_path.clone(), + downloaded: true, + }, + ); + + tokio::spawn(async move { + Self::start_version(args, p).await; + state_map_dup.lock().unwrap().remove(&key); + }); + Ok(socket_path) + } else { + state.insert( + key.clone(), + VersionState { + socket_path, + downloaded: false, + }, + ); + let update_service = self.update_service.clone(); + let cache = self.cache.clone(); + tokio::spawn(async move { + Self::download_version(args, update_service.clone(), cache.clone()).await; + state_map_dup.lock().unwrap().remove(&key); + }); + Err(CodeError::ServerNotYetDownloaded) + } + } + + /// Downloads a server version into the cache and starts it. + async fn download_version( + args: StartArgs, + update_service: UpdateService, + cache: DownloadCache, + ) { + let release_for_fut = args.release.clone(); + let log_for_fut = args.log.clone(); + let dir_fut = cache.create(&args.release.commit, |target_dir| async move { + info!(log_for_fut, "Downloading server {}", release_for_fut.commit); + let tmpdir = tempfile::tempdir().unwrap(); + let response = update_service.get_download_stream(&release_for_fut).await?; + + let name = response.url_path_basename().unwrap(); + let archive_path = tmpdir.path().join(name); + http::download_into_file( + &archive_path, + log_for_fut.get_download_logger("Downloading server:"), + response, + ) + .await?; + unzip_downloaded_release(&archive_path, &target_dir, SilentCopyProgress())?; + Ok(()) + }); + + match dir_fut.await { + Err(e) => args.opener.open(Err(e.to_string())), + Ok(dir) => Self::start_version(args, dir).await, + } + } + + /// Starts a downloaded server that can be found in the given `path`. + async fn start_version(args: StartArgs, path: PathBuf) { + info!(args.log, "Starting server {}", args.release.commit); + + let executable = path + .join("bin") + .join(args.release.quality.server_entrypoint()); + let socket_path = get_socket_name(); + + #[cfg(not(windows))] + let mut cmd = Command::new(&executable); + #[cfg(windows)] + let mut cmd = { + let mut cmd = Command::new("cmd"); + cmd.arg("/Q"); + cmd.arg("/C"); + cmd.arg(&executable); + cmd + }; + + cmd.stdin(std::process::Stdio::null()); + cmd.stderr(std::process::Stdio::piped()); + cmd.stdout(std::process::Stdio::piped()); + cmd.arg("--socket-path"); + cmd.arg(&socket_path); + + // License agreement already checked by the `server_web` function. + cmd.args(["--accept-server-license-terms"]); + + if let Some(a) = &args.args.server_data_dir { + cmd.arg("--server-data-dir"); + cmd.arg(a); + } + if let Some(a) = &args.args.user_data_dir { + cmd.arg("--user-data-dir"); + cmd.arg(a); + } + if let Some(a) = &args.args.extensions_dir { + cmd.arg("--extensions-dir"); + cmd.arg(a); + } + if args.args.without_connection_token { + cmd.arg("--without-connection-token"); + } + if let Some(ct) = &args.args.connection_token { + cmd.arg("--connection-token"); + cmd.arg(ct); + } + + // removed, otherwise the workbench will not be usable when running the CLI from sources. + cmd.env_remove("VSCODE_DEV"); + + let mut child = match cmd.spawn() { + Ok(c) => c, + Err(e) => { + args.opener.open(Err(e.to_string())); + return; + } + }; + + let (mut stdout, mut stderr) = ( + BufReader::new(child.stdout.take().unwrap()).lines(), + BufReader::new(child.stderr.take().unwrap()).lines(), + ); + + // wrapped option to prove that we only use this once in the loop + let (counter_tx, mut counter_rx) = tokio::sync::watch::channel(0); + let mut opener = Some((args.opener, socket_path, Arc::new(counter_tx))); + let commit_prefix = &args.release.commit[..7]; + let kill_timer = tokio::time::sleep(Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS)); + pin!(kill_timer); + + loop { + tokio::select! { + Ok(Some(l)) = stdout.next_line() => { + info!(args.log, "[{} stdout]: {}", commit_prefix, l); + + if l.contains("Server bound to") { + if let Some((opener, path, counter_tx)) = opener.take() { + opener.open(Ok((path, counter_tx))); + } + } + } + Ok(Some(l)) = stderr.next_line() => { + info!(args.log, "[{} stderr]: {}", commit_prefix, l); + }, + n = counter_rx.changed() => { + kill_timer.as_mut().reset(match n { + // err means that the record was dropped + Err(_) => tokio::time::Instant::now(), + Ok(_) => { + if *counter_rx.borrow() == 0 { + tokio::time::Instant::now() + Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS) + } else { + tokio::time::Instant::now() + Duration::from_secs(SERVER_ACTIVE_TIMEOUT_SECS) + } + } + }); + } + _ = &mut kill_timer => { + info!(args.log, "[{} process]: idle timeout reached, ending", commit_prefix); + let _ = child.kill().await; + break; + } + e = child.wait() => { + info!(args.log, "[{} process]: exited: {:?}", commit_prefix, e); + break; + } + } + } + } +} + +struct StartArgs { + log: log::Logger, + args: ServeWebArgs, + release: Release, + opener: BarrierOpener>, +} diff --git a/cli/src/self_update.rs b/cli/src/self_update.rs index 2e95719a3b9b3..4a878dc544716 100644 --- a/cli/src/self_update.rs +++ b/cli/src/self_update.rs @@ -11,7 +11,7 @@ use crate::{ options::Quality, update_service::{unzip_downloaded_release, Platform, Release, TargetKind, UpdateService}, util::{ - errors::{wrap, AnyError, CorruptDownload, UpdatesNotConfigured}, + errors::{wrap, AnyError, CodeError, CorruptDownload}, http, io::{ReportCopyProgress, SilentCopyProgress}, }, @@ -27,14 +27,16 @@ pub struct SelfUpdate<'a> { impl<'a> SelfUpdate<'a> { pub fn new(update_service: &'a UpdateService) -> Result { let commit = VSCODE_CLI_COMMIT - .ok_or_else(|| UpdatesNotConfigured("unknown build commit".to_string()))?; + .ok_or_else(|| CodeError::UpdatesNotConfigured("unknown build commit"))?; let quality = VSCODE_CLI_QUALITY - .ok_or_else(|| UpdatesNotConfigured("no configured quality".to_string())) - .and_then(|q| Quality::try_from(q).map_err(UpdatesNotConfigured))?; + .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) + .and_then(|q| { + Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) + })?; let platform = Platform::env_default().ok_or_else(|| { - UpdatesNotConfigured("Unknown platform, please report this error".to_string()) + CodeError::UpdatesNotConfigured("Unknown platform, please report this error") })?; Ok(Self { diff --git a/cli/src/state.rs b/cli/src/state.rs index 1b1ff343da5cd..8815e2df40ce4 100644 --- a/cli/src/state.rs +++ b/cli/src/state.rs @@ -212,4 +212,10 @@ impl LauncherPaths { ) }) } + + /// Suggested path for web server storage + pub fn web_server_storage(&self) -> PathBuf { + self.root.join("serve-web") + } + } diff --git a/cli/src/tunnels/legal.rs b/cli/src/tunnels/legal.rs index 676ccb7da55bf..35316af4fde9a 100644 --- a/cli/src/tunnels/legal.rs +++ b/cli/src/tunnels/legal.rs @@ -2,9 +2,9 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use crate::constants::{IS_INTERACTIVE_CLI, PRODUCT_NAME_LONG}; +use crate::constants::IS_INTERACTIVE_CLI; use crate::state::{LauncherPaths, PersistedState}; -use crate::util::errors::{AnyError, MissingLegalConsent}; +use crate::util::errors::{AnyError, CodeError}; use crate::util::input::prompt_yn; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; @@ -46,23 +46,14 @@ pub fn require_consent( if accept_server_license_terms { load.consented = Some(true); } else if !*IS_INTERACTIVE_CLI { - return Err(MissingLegalConsent( - "Run this command again with --accept-server-license-terms to indicate your agreement." - .to_string(), - ) - .into()); + return Err(CodeError::NeedsInteractiveLegalConsent.into()); } else { match prompt_yn(prompt) { Ok(true) => { load.consented = Some(true); } - Ok(false) => { - return Err(AnyError::from(MissingLegalConsent(format!( - "Sorry you cannot use {} CLI without accepting the terms.", - PRODUCT_NAME_LONG - )))) - } - Err(e) => return Err(AnyError::from(MissingLegalConsent(e.to_string()))), + Ok(false) => return Err(CodeError::DeniedLegalConset.into()), + Err(_) => return Err(CodeError::NeedsInteractiveLegalConsent.into()), } } diff --git a/cli/src/update_service.rs b/cli/src/update_service.rs index b03d8ea596319..d218e4a133394 100644 --- a/cli/src/update_service.rs +++ b/cli/src/update_service.rs @@ -11,7 +11,7 @@ use crate::{ constants::VSCODE_CLI_UPDATE_ENDPOINT, debug, log, options, spanf, util::{ - errors::{AnyError, CodeError, UpdatesNotConfigured, WrappedError}, + errors::{AnyError, CodeError, WrappedError}, http::{BoxedHttp, SimpleResponse}, io::ReportCopyProgress, tar, zipper, @@ -19,6 +19,7 @@ use crate::{ }; /// Implementation of the VS Code Update service for use in the CLI. +#[derive(Clone)] pub struct UpdateService { client: BoxedHttp, log: log::Logger, @@ -54,6 +55,10 @@ fn quality_download_segment(quality: options::Quality) -> &'static str { } } +fn get_update_endpoint() -> Result<&'static str, CodeError> { + VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(|| CodeError::UpdatesNotConfigured("no service url")) +} + impl UpdateService { pub fn new(log: log::Logger, http: BoxedHttp) -> Self { UpdateService { client: http, log } @@ -66,8 +71,7 @@ impl UpdateService { quality: options::Quality, version: &str, ) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; @@ -108,8 +112,7 @@ impl UpdateService { target: TargetKind, quality: options::Quality, ) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; @@ -144,8 +147,7 @@ impl UpdateService { /// Gets the download stream for the release. pub async fn get_download_stream(&self, release: &Release) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = release .target .download_segment(release.platform) diff --git a/cli/src/util/errors.rs b/cli/src/util/errors.rs index c82e14acc8b02..38d9b36f54bf5 100644 --- a/cli/src/util/errors.rs +++ b/cli/src/util/errors.rs @@ -108,16 +108,6 @@ impl StatusError { } } -// When the user has not consented to the licensing terms in using the Launcher -#[derive(Debug)] -pub struct MissingLegalConsent(pub String); - -impl std::fmt::Display for MissingLegalConsent { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - // When the provided connection token doesn't match the one used to set up the original VS Code Server // This is most likely due to a new user joining. #[derive(Debug)] @@ -313,20 +303,6 @@ impl std::fmt::Display for ServerHasClosed { } } -#[derive(Debug)] -pub struct UpdatesNotConfigured(pub String); - -impl UpdatesNotConfigured { - pub fn no_url() -> Self { - UpdatesNotConfigured("no service url".to_owned()) - } -} - -impl std::fmt::Display for UpdatesNotConfigured { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "Update service is not configured: {}", self.0) - } -} #[derive(Debug)] pub struct ServiceAlreadyRegistered(); @@ -517,10 +493,28 @@ pub enum CodeError { KeyringTimeout, #[error("no host is connected to the tunnel relay")] NoTunnelEndpoint, + #[error("could not parse `host`: {0}")] + InvalidHostAddress(std::net::AddrParseError), + #[error("could not start server on the given host/port: {0}")] + CouldNotListenOnInterface(hyper::Error), + #[error( + "Run this command again with --accept-server-license-terms to indicate your agreement." + )] + NeedsInteractiveLegalConsent, + #[error("Sorry, you cannot use this CLI without accepting the terms.")] + DeniedLegalConset, + #[error("The server is not yet downloaded, try again shortly.")] + ServerNotYetDownloaded, + #[error("An error was encountered downloading the server, please retry: {0}")] + ServerDownloadError(String), + #[error("Updates are are not available: {0}")] + UpdatesNotConfigured(&'static str), + // todo: can be specialized when update service is moved to CodeErrors + #[error("Could not check for update: {0}")] + UpdateCheckFailed(String), } makeAnyError!( - MissingLegalConsent, MismatchConnectionToken, DevTunnelError, StatusError, @@ -543,7 +537,6 @@ makeAnyError!( ServerHasClosed, ServiceAlreadyRegistered, WindowsNeedsElevation, - UpdatesNotConfigured, CorruptDownload, MissingHomeDirectory, OAuthError, diff --git a/cli/src/util/sync.rs b/cli/src/util/sync.rs index 8b653cd2d535c..67c777b75ed21 100644 --- a/cli/src/util/sync.rs +++ b/cli/src/util/sync.rs @@ -63,7 +63,7 @@ impl BarrierOpener { /// and is thereafter permanently closed. It can contain a value. pub fn new_barrier() -> (Barrier, BarrierOpener) where - T: Copy, + T: Clone, { let (closed_tx, closed_rx) = watch::channel(None); (Barrier(closed_rx), BarrierOpener(Arc::new(closed_tx))) diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 3b8233173033f..4770e9ef0bd9b 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -15,7 +15,7 @@ import { whenDeleted, writeFileSync } from 'vs/base/node/pfs'; import { findFreePort } from 'vs/base/node/ports'; import { watchFileContents } from 'vs/platform/files/node/watcher/nodejs/nodejsWatcherLib'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; -import { buildHelpMessage, buildVersionMessage, OPTIONS } from 'vs/platform/environment/node/argv'; +import { buildHelpMessage, buildVersionMessage, NATIVE_CLI_COMMANDS, OPTIONS } from 'vs/platform/environment/node/argv'; import { addArg, parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper'; import { getStdinFilePath, hasStdinWithoutTty, readFromStdin, stdinDataListener } from 'vs/platform/environment/node/stdin'; import { createWaitMarkerFileSync } from 'vs/platform/environment/node/wait'; @@ -51,31 +51,33 @@ export async function main(argv: string[]): Promise { return; } - if (args.tunnel) { - if (!product.tunnelApplicationName) { - console.error(`'tunnel' command not supported in ${product.applicationName}`); - return; - } - const tunnelArgs = argv.slice(argv.indexOf('tunnel') + 1); // all arguments behind `tunnel` - return new Promise((resolve, reject) => { - let tunnelProcess: ChildProcess; - const stdio: StdioOptions = ['ignore', 'pipe', 'pipe']; - if (process.env['VSCODE_DEV']) { - tunnelProcess = spawn('cargo', ['run', '--', 'tunnel', ...tunnelArgs], { cwd: join(getAppRoot(), 'cli'), stdio }); - } else { - const appPath = process.platform === 'darwin' - // ./Contents/MacOS/Electron => ./Contents/Resources/app/bin/code-tunnel-insiders - ? join(dirname(dirname(process.execPath)), 'Resources', 'app') - : dirname(process.execPath); - const tunnelCommand = join(appPath, 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`); - tunnelProcess = spawn(tunnelCommand, ['tunnel', ...tunnelArgs], { cwd: cwd(), stdio }); + for (const subcommand of NATIVE_CLI_COMMANDS) { + if (args[subcommand]) { + if (!product.tunnelApplicationName) { + console.error(`'${subcommand}' command not supported in ${product.applicationName}`); + return; } + const tunnelArgs = argv.slice(argv.indexOf(subcommand) + 1); // all arguments behind `tunnel` + return new Promise((resolve, reject) => { + let tunnelProcess: ChildProcess; + const stdio: StdioOptions = ['ignore', 'pipe', 'pipe']; + if (process.env['VSCODE_DEV']) { + tunnelProcess = spawn('cargo', ['run', '--', subcommand, ...tunnelArgs], { cwd: join(getAppRoot(), 'cli'), stdio }); + } else { + const appPath = process.platform === 'darwin' + // ./Contents/MacOS/Electron => ./Contents/Resources/app/bin/code-tunnel-insiders + ? join(dirname(dirname(process.execPath)), 'Resources', 'app') + : dirname(process.execPath); + const tunnelCommand = join(appPath, 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`); + tunnelProcess = spawn(tunnelCommand, [subcommand, ...tunnelArgs], { cwd: cwd(), stdio }); + } - tunnelProcess.stdout!.pipe(process.stdout); - tunnelProcess.stderr!.pipe(process.stderr); - tunnelProcess.on('exit', resolve); - tunnelProcess.on('error', reject); - }); + tunnelProcess.stdout!.pipe(process.stdout); + tunnelProcess.stderr!.pipe(process.stderr); + tunnelProcess.on('exit', resolve); + tunnelProcess.on('error', reject); + }); + } } // Help diff --git a/src/vs/platform/environment/common/argv.ts b/src/vs/platform/environment/common/argv.ts index 17476d941872f..b63a262137f3a 100644 --- a/src/vs/platform/environment/common/argv.ts +++ b/src/vs/platform/environment/common/argv.ts @@ -3,15 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +export interface INativeCliOptions { + 'cli-data-dir'?: string; + 'disable-telemetry'?: boolean; + 'telemetry-level'?: string; +} + /** * A list of command line arguments we support natively. */ export interface NativeParsedArgs { // subcommands - tunnel?: { - 'cli-data-dir'?: string; - 'disable-telemetry'?: boolean; - 'telemetry-level'?: string; + tunnel?: INativeCliOptions & { user: { login: { 'access-token'?: string; @@ -19,6 +22,7 @@ export interface NativeParsedArgs { }; }; }; + 'serve-web'?: INativeCliOptions; _: string[]; 'folder-uri'?: string[]; // undefined or array of 1 or more 'file-uri'?: string[]; // undefined or array of 1 or more diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index b3e423e20f9cf..63243fcf3a00f 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -44,6 +44,8 @@ export type OptionDescriptions = { Subcommand }; +export const NATIVE_CLI_COMMANDS = ['tunnel', 'serve-web'] as const; + export const OPTIONS: OptionDescriptions> = { 'tunnel': { type: 'subcommand', @@ -66,6 +68,15 @@ export const OPTIONS: OptionDescriptions> = { } } }, + 'serve-web': { + type: 'subcommand', + description: 'Make the current machine accessible from vscode.dev or other machines through a secure tunnel', + options: { + 'cli-data-dir': { type: 'string', args: 'dir', description: localize('cliDataDir', "Directory where CLI metadata should be stored.") }, + 'disable-telemetry': { type: 'boolean' }, + 'telemetry-level': { type: 'string' }, + } + }, 'diff': { type: 'boolean', cat: 'o', alias: 'd', args: ['file', 'file'], description: localize('diff', "Compare two files with each other.") }, 'merge': { type: 'boolean', cat: 'o', alias: 'm', args: ['path1', 'path2', 'base', 'result'], description: localize('merge', "Perform a three-way merge by providing paths for two modified versions of a file, the common origin of both modified versions and the output file to save merge results.") }, diff --git a/src/vs/platform/environment/node/argvHelper.ts b/src/vs/platform/environment/node/argvHelper.ts index 74a7369225d6e..d8cefb6df673d 100644 --- a/src/vs/platform/environment/node/argvHelper.ts +++ b/src/vs/platform/environment/node/argvHelper.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { localize } from 'vs/nls'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; -import { ErrorReporter, OPTIONS, parseArgs } from 'vs/platform/environment/node/argv'; +import { ErrorReporter, NATIVE_CLI_COMMANDS, OPTIONS, parseArgs } from 'vs/platform/environment/node/argv'; function parseAndValidate(cmdLineArgs: string[], reportWarnings: boolean): NativeParsedArgs { const onMultipleValues = (id: string, val: string) => { @@ -21,14 +21,14 @@ function parseAndValidate(cmdLineArgs: string[], reportWarnings: boolean): Nativ }; const getSubcommandReporter = (command: string) => ({ onUnknownOption: (id: string) => { - if (command !== 'tunnel') { + if (!(NATIVE_CLI_COMMANDS as readonly string[]).includes(command)) { console.warn(localize('unknownSubCommandOption', "Warning: '{0}' is not in the list of known options for subcommand '{1}'", id, command)); } }, onMultipleValues, onEmptyValue, onDeprecatedOption, - getSubcommandReporter: command !== 'tunnel' ? getSubcommandReporter : undefined + getSubcommandReporter: (NATIVE_CLI_COMMANDS as readonly string[]).includes(command) ? getSubcommandReporter : undefined }); const errorReporter: ErrorReporter = { onUnknownOption: (id) => { From 6408ba941f7e961e00eb7a4cc66745894127ab03 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 22 Aug 2023 17:50:58 +0200 Subject: [PATCH 1096/1180] fixes https://github.com/microsoft/vscode/issues/190961, fixes https://github.com/microsoft/vscode/issues/190959 --- .../diff/algorithms/joinSequenceDiffs.ts | 23 +++++++++++++++++++ .../advanced.expected.diff.json | 4 ++-- .../advanced.expected.diff.json | 4 ++-- .../noise-1/advanced.expected.diff.json | 4 ++-- .../ts-class/advanced.expected.diff.json | 4 ++-- .../advanced.expected.diff.json | 12 +++++----- .../ts-example1/advanced.expected.diff.json | 4 ++-- .../advanced.expected.diff.json | 4 ++-- .../ws-alignment/advanced.expected.diff.json | 4 ++-- 9 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts index b76c82d371bf5..c79d557e40913 100644 --- a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts +++ b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts @@ -149,6 +149,29 @@ export function removeRandomMatches(sequence1: LinesSliceCharSequence, sequence2 diffs = result; } while (counter++ < 10 && shouldRepeat); + // Remove short suffixes/prefixes + for (let i = 0; i < diffs.length; i++) { + const cur = diffs[i]; + + let range1 = cur.seq1Range; + let range2 = cur.seq2Range; + + const fullRange1 = sequence1.extendToFullLines(cur.seq1Range); + const prefix = sequence1.getText(new OffsetRange(fullRange1.start, cur.seq1Range.start)); + if (prefix.length > 0 && prefix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 100) { + range1 = cur.seq1Range.deltaStart(-prefix.length); + range2 = cur.seq2Range.deltaStart(-prefix.length); + } + + const suffix = sequence1.getText(new OffsetRange(cur.seq1Range.endExclusive, fullRange1.endExclusive)); + if (suffix.length > 0 && (suffix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 150)) { + range1 = range1.deltaEnd(suffix.length); + range2 = range2.deltaEnd(suffix.length); + } + + diffs[i] = new SequenceDiff(range1, range2); + } + return diffs; } diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json index 2b8f1b4ab1afd..5cbd3c45666de 100644 --- a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[29,37)", "innerChanges": [ { - "originalRange": "[29,1 -> 60,48]", - "modifiedRange": "[29,1 -> 36,66]" + "originalRange": "[29,1 -> 61,1]", + "modifiedRange": "[29,1 -> 37,1]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json index 8ac0682b508ac..b1de25a5907cb 100644 --- a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[6,11)", "innerChanges": [ { - "originalRange": "[6,2 -> 11,49]", - "modifiedRange": "[6,2 -> 6,91]" + "originalRange": "[6,1 -> 11,49]", + "modifiedRange": "[6,1 -> 6,91]" }, { "originalRange": "[12,76 -> 12,76]", diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json index 5a679831447e3..20190a83798bf 100644 --- a/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json @@ -21,8 +21,8 @@ "modifiedRange": "[53,6 -> 53,45]" }, { - "originalRange": "[52,77 -> 55,53]", - "modifiedRange": "[53,98 -> 65,66]" + "originalRange": "[52,77 -> 56,1]", + "modifiedRange": "[53,98 -> 66,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json index 92f5e20707fe7..0b00ea98beb98 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json @@ -47,8 +47,8 @@ "modifiedRange": "[8,12)", "innerChanges": [ { - "originalRange": "[11,10 -> 20,25]", - "modifiedRange": "[8,10 -> 11,51]" + "originalRange": "[11,10 -> 21,1]", + "modifiedRange": "[8,10 -> 12,1]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json index f6817defb4923..3835a5ceb3c7d 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json @@ -43,8 +43,8 @@ "modifiedRange": "[14,18)", "innerChanges": [ { - "originalRange": "[14,120 -> 14,211]", - "modifiedRange": "[14,120 -> 17,1]" + "originalRange": "[14,120 -> 15,1]", + "modifiedRange": "[14,120 -> 18,1]" } ] }, @@ -65,8 +65,8 @@ "modifiedRange": "[21,18 -> 21,43]" }, { - "originalRange": "[17,71 -> 23,4]", - "modifiedRange": "[21,74 -> 21,81]" + "originalRange": "[17,71 -> 24,1]", + "modifiedRange": "[21,74 -> 22,1]" } ] }, @@ -93,8 +93,8 @@ "modifiedRange": "[26,38)", "innerChanges": [ { - "originalRange": "[28,1 -> 30,31]", - "modifiedRange": "[26,1 -> 37,9]" + "originalRange": "[28,1 -> 31,1]", + "modifiedRange": "[26,1 -> 38,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json index d8eac8523e6c1..c7cd88a788bb0 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json @@ -27,8 +27,8 @@ "modifiedRange": "[17,80)", "innerChanges": [ { - "originalRange": "[13,10 -> 14,43]", - "modifiedRange": "[17,10 -> 79,2]" + "originalRange": "[13,10 -> 15,1]", + "modifiedRange": "[17,10 -> 80,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json index aa65f823a8599..7a52e0e84aa89 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[9,15)", "innerChanges": [ { - "originalRange": "[9,124 -> 9,124]", - "modifiedRange": "[9,124 -> 14,143]" + "originalRange": "[9,124 -> 10,1]", + "modifiedRange": "[9,124 -> 15,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json index 85a9a2fe92892..66e738ab04138 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json @@ -23,8 +23,8 @@ "modifiedRange": "[7,18)", "innerChanges": [ { - "originalRange": "[7,5 -> 12,17]", - "modifiedRange": "[7,5 -> 16,7]" + "originalRange": "[7,1 -> 13,1]", + "modifiedRange": "[7,1 -> 17,1]" }, { "originalRange": "[13,6 -> 13,11]", From 2cfdb5302a4e23cf51903b4e7df1875a5d611b6d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 23 Aug 2023 11:50:46 +0200 Subject: [PATCH 1097/1180] fix #189138 (#191051) * fix #189138 * feedback --- .../services/configuration/browser/configuration.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 8f942efdd0ee9..591bddbe576af 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -259,8 +259,8 @@ class FileServiceBasedConfiguration extends Disposable { const resolveContents = async (resources: URI[]): Promise<(string | undefined)[]> => { return Promise.all(resources.map(async resource => { try { - const content = (await this.fileService.readFile(resource)).value.toString(); - return content; + const content = await this.fileService.readFile(resource, { atomic: true }); + return content.value.toString(); } catch (error) { this.logService.trace(`Error while resolving configuration file '${resource.toString()}': ${errors.getErrorMessage(error)}`); if ((error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND @@ -494,7 +494,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable { } async resolveContent(): Promise { - const content = await this.fileService.readFile(this.configurationResource); + const content = await this.fileService.readFile(this.configurationResource, { atomic: true }); return content.value.toString(); } @@ -764,7 +764,7 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable { } async resolveContent(workspaceIdentifier: IWorkspaceIdentifier): Promise { - const content = await this.fileService.readFile(workspaceIdentifier.configPath); + const content = await this.fileService.readFile(workspaceIdentifier.configPath, { atomic: true }); return content.value.toString(); } From 3e9a48f4888bd51b524e40de18efe255242bff09 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 23 Aug 2023 02:52:31 -0700 Subject: [PATCH 1098/1180] eng: reapply test leak fixes (#190890) * eng: reapply test leak fixes Re-applies #190623 which I merged before everyone had a chance to review. Alex and Ben, you were the two people whose code this touches and didn't review it in the original PR. * :lipstick: * fix merge * better handling of editor listeners --------- Co-authored-by: Benjamin Pasero --- src/vs/base/browser/ui/grid/gridview.ts | 1 + src/vs/base/browser/ui/splitview/splitview.ts | 4 +-- src/vs/base/browser/ui/toolbar/toolbar.ts | 2 +- .../diffEditorWidget2/diffEditorEditors.ts | 4 +-- .../suggest/browser/suggestController.ts | 2 +- src/vs/platform/actions/browser/buttonbar.ts | 2 +- src/vs/workbench/browser/dnd.ts | 5 ++-- .../browser/parts/editor/editorGroupView.ts | 2 +- .../parts/editor/editorGroupWatermark.ts | 2 +- .../browser/parts/editor/tabsTitleControl.ts | 10 +++---- .../common/editor/editorGroupModel.ts | 11 ++++++++ .../browser/editors/textFileEditorTracker.ts | 2 +- .../browser/textFileEditorTracker.test.ts | 3 +++ .../browser/inlineChatController.ts | 3 ++- .../inlineChat/browser/inlineChatSession.ts | 2 ++ .../inlineChat/browser/inlineChatWidget.ts | 8 +++--- .../test/browser/inlineChatController.test.ts | 26 +++++-------------- .../markers/test/browser/markersModel.test.ts | 3 +++ .../editor/browser/codeEditorService.ts | 4 +-- .../services/editor/browser/editorService.ts | 6 ++--- .../browser/browserTextFileService.ts | 2 +- .../textfile/browser/textFileService.ts | 4 ++- .../common/textFileSaveParticipant.ts | 6 ++++- .../test/browser/textFileEditorModel.test.ts | 6 ++--- .../storedFileWorkingCopySaveParticipant.ts | 2 ++ .../workingCopyFileOperationParticipant.ts | 2 ++ .../test/browser/workbenchTestServices.ts | 13 +++++----- 27 files changed, 78 insertions(+), 59 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index c89c6a7a063f1..9445c64286a63 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -705,6 +705,7 @@ class BranchNode implements ISplitView, IDisposable { this.splitviewSashResetDisposable.dispose(); this.childrenSashResetDisposable.dispose(); this.childrenChangeDisposable.dispose(); + this.onDidScrollDisposable.dispose(); this.splitview.dispose(); } } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index b822db43751e5..28f18d4253713 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -565,11 +565,11 @@ export class SplitView extends Disposable { this.sashContainer = append(this.el, $('.sash-container')); this.viewContainer = $('.split-view-container'); - this.scrollable = new Scrollable({ + this.scrollable = this._register(new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 125, scheduleAtNextAnimationFrame - }); + })); this.scrollableElement = this._register(new SmoothScrollableElement(this.viewContainer, { vertical: this.orientation === Orientation.VERTICAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden, horizontal: this.orientation === Orientation.HORIZONTAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index 1a6089b59583c..bcb90361b41e8 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -52,7 +52,7 @@ export class ToolBar extends Disposable { private _onDidChangeDropdownVisibility = this._register(new EventMultiplexer()); readonly onDidChangeDropdownVisibility = this._onDidChangeDropdownVisibility.event; - private disposables = new DisposableStore(); + private disposables = this._register(new DisposableStore()); constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) { super(); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts index cce99a94271f3..ee764c81aedf3 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts @@ -35,8 +35,8 @@ export class DiffEditorEditors extends Disposable { ) { super(); - this.original = this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {}); - this.modified = this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {}); + this.original = this._register(this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {})); + this.modified = this._register(this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {})); this._register(autorunHandleChanges({ createEmptyChangeSummary: () => ({} as IDiffEditorConstructionOptions), diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index 887fb23cb2d68..6450e989bcebf 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -143,7 +143,7 @@ export class SuggestController implements IEditorContribution { // context key: update insert/replace mode const ctxInsertMode = SuggestContext.InsertMode.bindTo(_contextKeyService); ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode); - this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode)); + this._toDispose.add(this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode))); this.widget = this._toDispose.add(new IdleValue(() => { diff --git a/src/vs/platform/actions/browser/buttonbar.ts b/src/vs/platform/actions/browser/buttonbar.ts index cb6ab4c31dfb7..4965d6bb5cdeb 100644 --- a/src/vs/platform/actions/browser/buttonbar.ts +++ b/src/vs/platform/actions/browser/buttonbar.ts @@ -55,7 +55,7 @@ export class MenuWorkbenchButtonBar extends ButtonBar { 'workbenchActionExecuted', { id: e.action.id, from: options.telemetrySource! } ); - }, this._store); + }, undefined, this._store); } const conifgProvider: IButtonConfigProvider = options?.buttonConfigProvider ?? (() => ({ showLabel: true })); diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index c196ac2132e91..52afb8083d89f 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -12,7 +12,7 @@ import { ITreeDragOverReaction } from 'vs/base/browser/ui/tree/tree'; import { coalesce } from 'vs/base/common/arrays'; import { UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; import { Emitter } from 'vs/base/common/event'; -import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, IDisposable, markAsSingleton } from 'vs/base/common/lifecycle'; import { stringify } from 'vs/base/common/marshalling'; import { Mimes } from 'vs/base/common/mime'; import { FileAccess, Schemas } from 'vs/base/common/network'; @@ -427,6 +427,7 @@ export class CompositeDragAndDropObserver extends Disposable { static get INSTANCE(): CompositeDragAndDropObserver { if (!CompositeDragAndDropObserver.instance) { CompositeDragAndDropObserver.instance = new CompositeDragAndDropObserver(); + markAsSingleton(CompositeDragAndDropObserver.instance); } return CompositeDragAndDropObserver.instance; @@ -523,7 +524,7 @@ export class CompositeDragAndDropObserver extends Disposable { if (callbacks.onDragEnd) { this.onDragEnd.event(e => { callbacks.onDragEnd!(e); - }); + }, this, disposableStore); } return this._register(disposableStore); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index c80fa632d3e8b..01b92a4b7e2b8 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -244,7 +244,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { const groupEditorsCountContext = EditorGroupEditorsCountContext.bindTo(this.scopedContextKeyService); const groupLockedContext = ActiveEditorGroupLockedContext.bindTo(this.scopedContextKeyService); - const activeEditorListener = new MutableDisposable(); + const activeEditorListener = this._register(new MutableDisposable()); const observeActiveEditor = () => { activeEditorListener.clear(); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts index 55d6506ababe2..ff8a2778c7c45 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts @@ -90,7 +90,7 @@ export class EditorGroupWatermark extends Disposable { } private registerListeners(): void { - this.lifecycleService.onDidShutdown(() => this.dispose()); + this._register(this.lifecycleService.onDidShutdown(() => this.dispose())); this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('workbench.tips.enabled')) { diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index d712b1a146b5e..3272b3e483923 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -184,7 +184,7 @@ export class TabsTitleControl extends TitleControl { this.updateTabSizing(false); // Tabs Scrollbar - this.tabsScrollbar = this._register(this.createTabsScrollbar(this.tabsContainer)); + this.tabsScrollbar = this.createTabsScrollbar(this.tabsContainer); this.tabsAndActionsContainer.appendChild(this.tabsScrollbar.getDomNode()); // Tabs Container listeners @@ -206,19 +206,19 @@ export class TabsTitleControl extends TitleControl { } private createTabsScrollbar(scrollable: HTMLElement): ScrollableElement { - const tabsScrollbar = new ScrollableElement(scrollable, { + const tabsScrollbar = this._register(new ScrollableElement(scrollable, { horizontal: ScrollbarVisibility.Auto, horizontalScrollbarSize: this.getTabsScrollbarSizing(), vertical: ScrollbarVisibility.Hidden, scrollYToX: true, useShadows: false - }); + })); - tabsScrollbar.onScroll(e => { + this._register(tabsScrollbar.onScroll(e => { if (e.scrollLeftChanged) { scrollable.scrollLeft = e.scrollLeft; } - }); + })); return tabsScrollbar; } diff --git a/src/vs/workbench/common/editor/editorGroupModel.ts b/src/vs/workbench/common/editor/editorGroupModel.ts index 7fc1ae6cbc07f..8e3c7b7a811c6 100644 --- a/src/vs/workbench/common/editor/editorGroupModel.ts +++ b/src/vs/workbench/common/editor/editorGroupModel.ts @@ -180,6 +180,8 @@ export class EditorGroupModel extends Disposable { private editors: EditorInput[] = []; private mru: EditorInput[] = []; + private readonly editorListeners = new Set(); + private locked = false; private preview: EditorInput | null = null; // editor in preview state @@ -405,6 +407,7 @@ export class EditorGroupModel extends Disposable { private registerEditorListeners(editor: EditorInput): void { const listeners = new DisposableStore(); + this.editorListeners.add(listeners); // Re-emit disposal of editor input as our own event listeners.add(Event.once(editor.onWillDispose)(() => { @@ -453,6 +456,7 @@ export class EditorGroupModel extends Disposable { listeners.add(this.onDidModelChange(event => { if (event.kind === GroupModelChangeKind.EDITOR_CLOSE && event.editor?.matches(editor)) { dispose(listeners); + this.editorListeners.delete(listeners); } })); } @@ -1077,4 +1081,11 @@ export class EditorGroupModel extends Disposable { return this._id; } + + override dispose(): void { + dispose(Array.from(this.editorListeners)); + this.editorListeners.clear(); + + super.dispose(); + } } diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts index fb876ba670a7b..afa94056cd5d2 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts @@ -47,7 +47,7 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr this._register(this.hostService.onDidChangeFocus(hasFocus => hasFocus ? this.reloadVisibleTextFileEditors() : undefined)); // Lifecycle - this.lifecycleService.onDidShutdown(() => this.dispose()); + this._register(this.lifecycleService.onDidShutdown(() => this.dispose())); } //#region Text File: Ensure every dirty text and untitled file is opened in an editor diff --git a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts index bc69b29a381f4..b0afe7cc55479 100644 --- a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts @@ -77,6 +77,7 @@ suite('Files - TextFileEditorTracker', () => { instantiationService.stub(IWorkspaceTrustRequestService, new TestWorkspaceTrustRequestService(false)); const editorService: EditorService = instantiationService.createInstance(EditorService); + disposables.add(editorService); instantiationService.stub(IEditorService, editorService); const accessor = instantiationService.createInstance(TestServiceAccessor); @@ -93,6 +94,7 @@ suite('Files - TextFileEditorTracker', () => { const resource = toResource.call(this, '/path/index.txt'); const model = await accessor.textFileService.files.resolve(resource) as IResolvedTextFileEditorModel; + disposables.add(model); model.textEditorModel.setValue('Super Good'); assert.strictEqual(snapshotToString(model.createSnapshot()!), 'Super Good'); @@ -141,6 +143,7 @@ suite('Files - TextFileEditorTracker', () => { } const model = await accessor.textFileService.files.resolve(resource) as IResolvedTextFileEditorModel; + disposables.add(model); model.textEditorModel.setValue('Super Good'); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 104830cc852ca..f91de7e3ee8e5 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -100,7 +100,7 @@ export class InlineChatController implements IEditorContribution { private _messages = this._store.add(new Emitter()); - private readonly _sessionStore: DisposableStore = new DisposableStore(); + private readonly _sessionStore: DisposableStore = this._store.add(new DisposableStore()); private readonly _stashedSession: MutableDisposable = this._store.add(new MutableDisposable()); private _activeSession?: Session; private _strategy?: EditModeStrategy; @@ -146,6 +146,7 @@ export class InlineChatController implements IEditorContribution { } dispose(): void { + this._strategy?.dispose(); this._stashedSession.clear(); this.finishExistingSession(); this._store.dispose(); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts index 434aea1f4d21c..fcbb998dc792c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts @@ -385,6 +385,8 @@ export interface IInlineChatSessionService { // recordings(): readonly Recording[]; + + dispose(): void; } type SessionData = { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 31d9fa9c36b91..343749ce5c699 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -230,7 +230,7 @@ export class InlineChatWidget { })); const uri = URI.from({ scheme: 'vscode', authority: 'inline-chat', path: `/inline-chat/model${InlineChatWidget._modelPool++}.txt` }); - this._inputModel = this._modelService.getModel(uri) ?? this._modelService.createModel('', null, uri); + this._inputModel = this._store.add(this._modelService.getModel(uri) ?? this._modelService.createModel('', null, uri)); this._inputEditor.setModel(this._inputModel); // --- context keys @@ -359,13 +359,13 @@ export class InlineChatWidget { this._store.add(feedbackToolbar); // preview editors - this._previewDiffEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedDiffEditorWidget2, this._elements.previewDiff, { + this._previewDiffEditor = this._store.add(new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedDiffEditorWidget2, this._elements.previewDiff, { ..._previewEditorEditorOptions, onlyShowAccessibleDiffViewer: this._accessibilityService.isScreenReaderOptimized(), - }, { modifiedEditor: codeEditorWidgetOptions, originalEditor: codeEditorWidgetOptions }, parentEditor))); + }, { modifiedEditor: codeEditorWidgetOptions, originalEditor: codeEditorWidgetOptions }, parentEditor)))); this._previewCreateTitle = this._store.add(_instantiationService.createInstance(ResourceLabel, this._elements.previewCreateTitle, { supportIcons: true })); - this._previewCreateEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedCodeEditorWidget, this._elements.previewCreate, _previewEditorEditorOptions, codeEditorWidgetOptions, parentEditor))); + this._previewCreateEditor = this._store.add(new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedCodeEditorWidget, this._elements.previewCreate, _previewEditorEditorOptions, codeEditorWidgetOptions, parentEditor)))); this._elements.message.tabIndex = 0; this._elements.message.ariaLabel = this._accessibleViewService.getOpenAriaHint(AccessibilityVerbositySettingId.InlineChat); diff --git a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts index ab5e4b27e1bae..7a9beea7519e6 100644 --- a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts +++ b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts @@ -24,7 +24,6 @@ import { IEditorProgressService, IProgressRunner } from 'vs/platform/progress/co import { mock } from 'vs/base/test/common/mock'; import { Emitter, Event } from 'vs/base/common/event'; import { equals } from 'vs/base/common/arrays'; -import { timeout } from 'vs/base/common/async'; import { IChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chat'; import { IChatResponseViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; @@ -114,11 +113,11 @@ suite('InteractiveChatController', function () { }] ); - instaService = workbenchInstantiationService(undefined, store).createChild(serviceCollection); - inlineChatSessionService = instaService.get(IInlineChatSessionService); + instaService = store.add(workbenchInstantiationService(undefined, store).createChild(serviceCollection)); + inlineChatSessionService = store.add(instaService.get(IInlineChatSessionService)); - model = instaService.get(IModelService).createModel('Hello\nWorld\nHello Again\nHello World\n', null); - editor = instantiateTestCodeEditor(instaService, model); + model = store.add(instaService.get(IModelService).createModel('Hello\nWorld\nHello Again\nHello World\n', null)); + editor = store.add(instantiateTestCodeEditor(instaService, model)); store.add(inlineChatService.addProvider({ debugName: 'Unit Test', @@ -142,8 +141,6 @@ suite('InteractiveChatController', function () { }); teardown(function () { - editor.dispose(); - model.dispose(); store.clear(); ctrl?.dispose(); }); @@ -295,19 +292,8 @@ suite('InteractiveChatController', function () { wholeRange: new Range(3, 1, 3, 3) }; }, - async provideResponse(session, request) { - - // SLOW response - await timeout(50000); - - return { - type: InlineChatResponseType.EditorEdit, - id: Math.random(), - edits: [{ - range: new Range(1, 1, 1, 1), // EDIT happens outside of whole range - text: `${request.prompt}\n${request.prompt}` - }] - }; + provideResponse(session, request) { + return new Promise(() => { }); } }); store.add(d); diff --git a/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts b/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts index 9cb2c9dc650a4..b8334c948d6e0 100644 --- a/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts +++ b/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts @@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri'; import { IMarker, MarkerSeverity, IRelatedInformation } from 'vs/platform/markers/common/markers'; import { MarkersModel, Marker, ResourceMarkers, RelatedInformation } from 'vs/workbench/contrib/markers/browser/markersModel'; import { groupBy } from 'vs/base/common/collections'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; class TestMarkersModel extends MarkersModel { @@ -27,6 +28,8 @@ class TestMarkersModel extends MarkersModel { suite('MarkersModel Test', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('marker ids are unique', function () { const marker1 = anErrorWithRange(3); const marker2 = anErrorWithRange(3); diff --git a/src/vs/workbench/services/editor/browser/codeEditorService.ts b/src/vs/workbench/services/editor/browser/codeEditorService.ts index 657f203312ca6..9930f85f58c59 100644 --- a/src/vs/workbench/services/editor/browser/codeEditorService.ts +++ b/src/vs/workbench/services/editor/browser/codeEditorService.ts @@ -25,8 +25,8 @@ export class CodeEditorService extends AbstractCodeEditorService { ) { super(themeService); - this.registerCodeEditorOpenHandler(this.doOpenCodeEditor.bind(this)); - this.registerCodeEditorOpenHandler(this.doOpenCodeEditorFromDiff.bind(this)); + this._register(this.registerCodeEditorOpenHandler(this.doOpenCodeEditor.bind(this))); + this._register(this.registerCodeEditorOpenHandler(this.doOpenCodeEditorFromDiff.bind(this))); } getActiveCodeEditor(): ICodeEditor | null { diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index e241e493f656d..f997b3ecfbd15 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -83,9 +83,9 @@ export class EditorService extends Disposable implements EditorServiceImpl { // Editor & group changes this.editorGroupService.whenReady.then(() => this.onEditorGroupsReady()); - this.editorGroupService.onDidChangeActiveGroup(group => this.handleActiveEditorChange(group)); - this.editorGroupService.onDidAddGroup(group => this.registerGroupListeners(group as IEditorGroupView)); - this.editorsObserver.onDidMostRecentlyActiveEditorsChange(() => this._onDidMostRecentlyActiveEditorsChange.fire()); + this._register(this.editorGroupService.onDidChangeActiveGroup(group => this.handleActiveEditorChange(group))); + this._register(this.editorGroupService.onDidAddGroup(group => this.registerGroupListeners(group as IEditorGroupView))); + this._register(this.editorsObserver.onDidMostRecentlyActiveEditorsChange(() => this._onDidMostRecentlyActiveEditorsChange.fire())); // Out of workspace file watchers this._register(this.onDidVisibleEditorsChange(() => this.handleVisibleEditorsChange())); diff --git a/src/vs/workbench/services/textfile/browser/browserTextFileService.ts b/src/vs/workbench/services/textfile/browser/browserTextFileService.ts index 78957c01afd44..188ca299d5fc1 100644 --- a/src/vs/workbench/services/textfile/browser/browserTextFileService.ts +++ b/src/vs/workbench/services/textfile/browser/browserTextFileService.ts @@ -54,7 +54,7 @@ export class BrowserTextFileService extends AbstractTextFileService { private registerListeners(): void { // Lifecycle - this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdown(), 'veto.textFiles')); + this._register(this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdown(), 'veto.textFiles'))); } private onBeforeShutdown(): boolean { diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index 45015baa45876..f7a87fb1b4bcd 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -89,7 +89,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex private provideDecorations(): void { // Text file model decorations - this.decorationsService.registerDecorationsProvider(new class extends Disposable implements IDecorationsProvider { + const provider = this._register(new class extends Disposable implements IDecorationsProvider { readonly label = localize('textFileModelDecorations', "Text File Model Decorations"); @@ -161,6 +161,8 @@ export abstract class AbstractTextFileService extends Disposable implements ITex return undefined; } }(this.files)); + + this._register(this.decorationsService.registerDecorationsProvider(provider)); } //#endregin diff --git a/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts b/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts index ab3cb0a0e8a69..3dc16d1a46ec1 100644 --- a/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts +++ b/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts @@ -60,11 +60,15 @@ export class TextFileSaveParticipant extends Disposable { model.textEditorModel?.pushStackElement(); }, () => { // user cancel - cts.dispose(true); + cts.cancel(); + }).finally(() => { + cts.dispose(); }); } override dispose(): void { this.saveParticipants.splice(0, this.saveParticipants.length); + + super.dispose(); } } diff --git a/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts b/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts index 7595d417a5f94..7ca2a09bfb144 100644 --- a/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts +++ b/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts @@ -548,7 +548,7 @@ suite('Files - TextFileEditorModel', () => { test('Update Dirty', async function () { let eventCounter = 0; - const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); + const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); model.setDirty(true); assert.ok(!model.isDirty()); // needs to be resolved @@ -638,8 +638,8 @@ suite('Files - TextFileEditorModel', () => { }); test('save() and isDirty() - proper with check for mtimes', async function () { - const input1 = createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async2.txt')); - const input2 = createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async.txt')); + const input1 = disposables.add(createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async2.txt'))); + const input2 = disposables.add(createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async.txt'))); const model1 = await input1.resolve() as TextFileEditorModel; const model2 = await input2.resolve() as TextFileEditorModel; diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts index 18be856eb47f9..11bddb67625a5 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts @@ -69,5 +69,7 @@ export class StoredFileWorkingCopySaveParticipant extends Disposable { override dispose(): void { this.saveParticipants.splice(0, this.saveParticipants.length); + + super.dispose(); } } diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts b/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts index e75246b8b83ef..f3f4dd8f05ef7 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts @@ -46,5 +46,7 @@ export class WorkingCopyFileOperationParticipant extends Disposable { override dispose(): void { this.participants.clear(); + + super.dispose(); } } diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 0fffe75c46f53..c566bc464015b 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -283,15 +283,16 @@ export function workbenchInstantiationService( instantiationService.stub(IUndoRedoService, instantiationService.createInstance(UndoRedoService)); const themeService = new TestThemeService(); instantiationService.stub(IThemeService, themeService); - instantiationService.stub(ILanguageConfigurationService, new TestLanguageConfigurationService()); + instantiationService.stub(ILanguageConfigurationService, disposables.add(new TestLanguageConfigurationService())); instantiationService.stub(IModelService, disposables.add(instantiationService.createInstance(ModelService))); const fileService = overrides?.fileService ? overrides.fileService(instantiationService) : new TestFileService(); instantiationService.stub(IFileService, fileService); const uriIdentityService = new UriIdentityService(fileService); + disposables.add(uriIdentityService); instantiationService.stub(IFilesConfigurationService, disposables.add(new TestFilesConfigurationService(contextKeyService, configService, workspaceContextService, environmentService, uriIdentityService, fileService))); instantiationService.stub(IUriIdentityService, uriIdentityService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService())); - instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService()))); + instantiationService.stub(IUserDataProfileService, disposables.add(new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService))); instantiationService.stub(IWorkingCopyBackupService, overrides?.workingCopyBackupService ? overrides?.workingCopyBackupService(instantiationService) : new TestWorkingCopyBackupService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(INotificationService, new TestNotificationService()); @@ -305,7 +306,7 @@ export function workbenchInstantiationService( instantiationService.stub(ITextFileService, overrides?.textFileService ? overrides.textFileService(instantiationService) : disposables.add(instantiationService.createInstance(TestTextFileService))); instantiationService.stub(IHostService, instantiationService.createInstance(TestHostService)); instantiationService.stub(ITextModelService, disposables.add(instantiationService.createInstance(TextModelResolverService))); - instantiationService.stub(ILoggerService, new TestLoggerService(TestEnvironmentService.logsHome)); + instantiationService.stub(ILoggerService, disposables.add(new TestLoggerService(TestEnvironmentService.logsHome))); instantiationService.stub(ILogService, new NullLogService()); const editorGroupService = new TestEditorGroupsService([new TestEditorGroupView(0)]); instantiationService.stub(IEditorGroupsService, editorGroupService); @@ -314,10 +315,10 @@ export function workbenchInstantiationService( instantiationService.stub(IEditorService, editorService); instantiationService.stub(IWorkingCopyEditorService, disposables.add(instantiationService.createInstance(WorkingCopyEditorService))); instantiationService.stub(IEditorResolverService, disposables.add(instantiationService.createInstance(EditorResolverService))); - const textEditorService = overrides?.textEditorService ? overrides.textEditorService(instantiationService) : instantiationService.createInstance(TextEditorService); + const textEditorService = overrides?.textEditorService ? overrides.textEditorService(instantiationService) : disposables.add(instantiationService.createInstance(TextEditorService)); instantiationService.stub(ITextEditorService, textEditorService); instantiationService.stub(ICodeEditorService, disposables.add(new CodeEditorService(editorService, themeService, configService))); - instantiationService.stub(IPaneCompositePartService, new TestPaneCompositeService()); + instantiationService.stub(IPaneCompositePartService, disposables.add(new TestPaneCompositeService())); instantiationService.stub(IListService, new TestListService()); const hoverService = instantiationService.stub(IHoverService, instantiationService.createInstance(TestHoverService)); instantiationService.stub(IQuickInputService, disposables.add(new QuickInputService(configService, instantiationService, keybindingService, contextKeyService, themeService, layoutService, hoverService))); From 6885d66040854a29aeee7383ca14efa181c51a74 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 23 Aug 2023 20:19:42 +0800 Subject: [PATCH 1099/1180] adjust tabs and spaces consistent (#184861) --- extensions/html-language-features/.vscode/settings.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/html-language-features/.vscode/settings.json b/extensions/html-language-features/.vscode/settings.json index 569ac10cf8f05..17b02728e8c55 100644 --- a/extensions/html-language-features/.vscode/settings.json +++ b/extensions/html-language-features/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.insertSpaces": false, "prettier.semi": true, - "prettier.singleQuote": true, - "prettier.printWidth": 120, -} \ No newline at end of file + "prettier.singleQuote": true, + "prettier.printWidth": 120 +} From f712b1caba3ecc03f979f09ec8bfc623a0f312ac Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 23 Aug 2023 05:32:06 -0700 Subject: [PATCH 1100/1180] Hook up xterm.js trace log level --- .../workbench/contrib/terminal/browser/xterm/xtermTerminal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index b58476377303b..fcf7a078831ca 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -961,7 +961,7 @@ export function getXtermScaledDimensions(font: ITerminalFont, width: number, hei function vscodeToXtermLogLevel(logLevel: LogLevel): XtermLogLevel { switch (logLevel) { - case LogLevel.Trace: + case LogLevel.Trace: return 'trace'; case LogLevel.Debug: return 'debug'; case LogLevel.Info: return 'info'; case LogLevel.Warning: return 'warn'; From d141a1fccee14db6829359b9d8e6d0a153d10f4f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 23 Aug 2023 05:47:07 -0700 Subject: [PATCH 1101/1180] xterm@5.3.0-beta.61 --- package.json | 16 ++++----- remote/package.json | 16 ++++----- remote/web/package.json | 12 +++---- remote/web/yarn.lock | 58 +++++++++++++++--------------- remote/yarn.lock | 78 ++++++++++++++++++++--------------------- yarn.lock | 78 ++++++++++++++++++++--------------------- 6 files changed, 129 insertions(+), 129 deletions(-) diff --git a/package.json b/package.json index 425451a5559ab..584247e9fa406 100644 --- a/package.json +++ b/package.json @@ -95,14 +95,14 @@ "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.58", - "xterm-addon-canvas": "0.5.0-beta.19", - "xterm-addon-image": "0.6.0-beta.11", - "xterm-addon-search": "0.13.0-beta.17", - "xterm-addon-serialize": "0.11.0-beta.17", - "xterm-addon-unicode11": "0.6.0-beta.9", - "xterm-addon-webgl": "0.16.0-beta.27", - "xterm-headless": "5.3.0-beta.58", + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-serialize": "0.11.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30", + "xterm-headless": "5.3.0-beta.61", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, diff --git a/remote/package.json b/remote/package.json index 6d6a0152a55a3..8fe0e55c1dedb 100644 --- a/remote/package.json +++ b/remote/package.json @@ -27,14 +27,14 @@ "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.58", - "xterm-addon-canvas": "0.5.0-beta.19", - "xterm-addon-image": "0.6.0-beta.11", - "xterm-addon-search": "0.13.0-beta.17", - "xterm-addon-serialize": "0.11.0-beta.17", - "xterm-addon-unicode11": "0.6.0-beta.9", - "xterm-addon-webgl": "0.16.0-beta.27", - "xterm-headless": "5.3.0-beta.58", + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-serialize": "0.11.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30", + "xterm-headless": "5.3.0-beta.61", "yauzl": "^2.9.2", "yazl": "^2.4.3" } diff --git a/remote/web/package.json b/remote/web/package.json index 05686230a4305..6075a563e3497 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -11,11 +11,11 @@ "tas-client-umd": "0.1.8", "vscode-oniguruma": "1.7.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.58", - "xterm-addon-canvas": "0.5.0-beta.19", - "xterm-addon-image": "0.6.0-beta.11", - "xterm-addon-search": "0.13.0-beta.17", - "xterm-addon-unicode11": "0.6.0-beta.9", - "xterm-addon-webgl": "0.16.0-beta.27" + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index dc817e45bf1c2..b56fac51a4541 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -68,32 +68,32 @@ vscode-textmate@9.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c" integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg== -xterm-addon-canvas@0.5.0-beta.19: - version "0.5.0-beta.19" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.19.tgz#a2b67554191fae29c901c4a4b398fc28dc345afe" - integrity sha512-eF6b7SBZslmwqCLiWTGnjna4bdjd28cQ+ivZH8SVjE5xP3JGAHGWs/fZm5E3eR6pcHEOkX++/FxByuvhOVXIXQ== - -xterm-addon-image@0.6.0-beta.11: - version "0.6.0-beta.11" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.11.tgz#17dffc5f38480a4fac231649ef6e313a8f46d614" - integrity sha512-KPsqJo8sSAawO4ze7xvjtS5evbPtlscy16NiSAteh/1AgOffmTnVhJTs3W84dnks2b13FaMEI/WOiCDIJjDV3A== - -xterm-addon-search@0.13.0-beta.17: - version "0.13.0-beta.17" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.17.tgz#5379cf3085370c55241d99e95b008c0cbf4e6e53" - integrity sha512-0OKwV9isk4OXHLlhRE8Ohqnmpcd0ExWKtorjeaFxqm4f6xc30qZcJTs0hSMzVZ83foedPJcd6hH0hW2pnxOz3Q== - -xterm-addon-unicode11@0.6.0-beta.9: - version "0.6.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.9.tgz#1f476f77cf8c8e4e7ca1a1421b85ac45405db679" - integrity sha512-DH9OIH0EakIdCnzZcIH7NLgUqXwa8WT9fqmi+2CWzt4NN1AH5kSE/3Vk+/uurE5upxDloKw6dtLH9XHpfULV6g== - -xterm-addon-webgl@0.16.0-beta.27: - version "0.16.0-beta.27" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.27.tgz#f4133a40044f0b6448ea87152abf6c9009729100" - integrity sha512-YiwCvTvgfcNGtQdpzcgxKINE6mG63cPfDxfoxCAbodNGYF66k9VzhIXNdCQtVtu+s6+pEc9YequENe78SSZloA== - -xterm@5.3.0-beta.58: - version "5.3.0-beta.58" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.58.tgz#4bae06639c90952b270e4714938c151ce339b5f0" - integrity sha512-EIOgp+7aqCToI0XjDqORXAe2lJS/XSZXWPzCpyTDmF+DJ56gyw+913gdPoIEWOw3mRylrJtEyIpFcdW7CDA6rQ== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== + +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== + +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== + +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== + +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== + +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== diff --git a/remote/yarn.lock b/remote/yarn.lock index 68c99905917cf..4716df355d54d 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -877,45 +877,45 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xterm-addon-canvas@0.5.0-beta.19: - version "0.5.0-beta.19" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.19.tgz#a2b67554191fae29c901c4a4b398fc28dc345afe" - integrity sha512-eF6b7SBZslmwqCLiWTGnjna4bdjd28cQ+ivZH8SVjE5xP3JGAHGWs/fZm5E3eR6pcHEOkX++/FxByuvhOVXIXQ== - -xterm-addon-image@0.6.0-beta.11: - version "0.6.0-beta.11" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.11.tgz#17dffc5f38480a4fac231649ef6e313a8f46d614" - integrity sha512-KPsqJo8sSAawO4ze7xvjtS5evbPtlscy16NiSAteh/1AgOffmTnVhJTs3W84dnks2b13FaMEI/WOiCDIJjDV3A== - -xterm-addon-search@0.13.0-beta.17: - version "0.13.0-beta.17" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.17.tgz#5379cf3085370c55241d99e95b008c0cbf4e6e53" - integrity sha512-0OKwV9isk4OXHLlhRE8Ohqnmpcd0ExWKtorjeaFxqm4f6xc30qZcJTs0hSMzVZ83foedPJcd6hH0hW2pnxOz3Q== - -xterm-addon-serialize@0.11.0-beta.17: - version "0.11.0-beta.17" - resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.17.tgz#170738ab615e2974c593d41531d41c02b8af1da7" - integrity sha512-zNsUQfIbRD8fL0gHGJJ14DXL22Kduv6pR+QnISReoQqhEEsWANPKpOduJLce7B4y+BJuiOGkT7R7qbMKbj9Ecw== - -xterm-addon-unicode11@0.6.0-beta.9: - version "0.6.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.9.tgz#1f476f77cf8c8e4e7ca1a1421b85ac45405db679" - integrity sha512-DH9OIH0EakIdCnzZcIH7NLgUqXwa8WT9fqmi+2CWzt4NN1AH5kSE/3Vk+/uurE5upxDloKw6dtLH9XHpfULV6g== - -xterm-addon-webgl@0.16.0-beta.27: - version "0.16.0-beta.27" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.27.tgz#f4133a40044f0b6448ea87152abf6c9009729100" - integrity sha512-YiwCvTvgfcNGtQdpzcgxKINE6mG63cPfDxfoxCAbodNGYF66k9VzhIXNdCQtVtu+s6+pEc9YequENe78SSZloA== - -xterm-headless@5.3.0-beta.58: - version "5.3.0-beta.58" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.58.tgz#e6a3dbfafdb28435130ce3925ac3194c0ee2c281" - integrity sha512-ekzr3LX8p26qHDyVRs3lys08veHFv9wGOKaHd49kMgktICHsikJ48HNJq5Twp3ZnXyqlIP9CV34BZJ1SBfWmtQ== - -xterm@5.3.0-beta.58: - version "5.3.0-beta.58" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.58.tgz#4bae06639c90952b270e4714938c151ce339b5f0" - integrity sha512-EIOgp+7aqCToI0XjDqORXAe2lJS/XSZXWPzCpyTDmF+DJ56gyw+913gdPoIEWOw3mRylrJtEyIpFcdW7CDA6rQ== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== + +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== + +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== + +xterm-addon-serialize@0.11.0-beta.20: + version "0.11.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.20.tgz#e879b34d214761403f1081833f9221c6903bf0c3" + integrity sha512-OXnC1SATaz7kEFjFWhyv9MJaXi8yHdPjazpGLNi11h33CRTKtCQiqqPBHU87dztnXmpEX6Jw0/jr3zlyXuAmnw== + +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== + +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== + +xterm-headless@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.61.tgz#28654550cb572709b99ea3eb8672d4568ae141c9" + integrity sha512-yfkbPLUtKjE4K7DsZ204A1BuOKpu6Usqi6rIYWT4XRMi+LjnkTbBjGr2BSjyJ3Gmtm+cSgBD0SvRN+V3xNxbxA== + +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== yallist@^4.0.0: version "4.0.0" diff --git a/yarn.lock b/yarn.lock index 96c77bcd45a71..5595e14de3704 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10759,45 +10759,45 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm-addon-canvas@0.5.0-beta.19: - version "0.5.0-beta.19" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.19.tgz#a2b67554191fae29c901c4a4b398fc28dc345afe" - integrity sha512-eF6b7SBZslmwqCLiWTGnjna4bdjd28cQ+ivZH8SVjE5xP3JGAHGWs/fZm5E3eR6pcHEOkX++/FxByuvhOVXIXQ== - -xterm-addon-image@0.6.0-beta.11: - version "0.6.0-beta.11" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.11.tgz#17dffc5f38480a4fac231649ef6e313a8f46d614" - integrity sha512-KPsqJo8sSAawO4ze7xvjtS5evbPtlscy16NiSAteh/1AgOffmTnVhJTs3W84dnks2b13FaMEI/WOiCDIJjDV3A== - -xterm-addon-search@0.13.0-beta.17: - version "0.13.0-beta.17" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.17.tgz#5379cf3085370c55241d99e95b008c0cbf4e6e53" - integrity sha512-0OKwV9isk4OXHLlhRE8Ohqnmpcd0ExWKtorjeaFxqm4f6xc30qZcJTs0hSMzVZ83foedPJcd6hH0hW2pnxOz3Q== - -xterm-addon-serialize@0.11.0-beta.17: - version "0.11.0-beta.17" - resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.17.tgz#170738ab615e2974c593d41531d41c02b8af1da7" - integrity sha512-zNsUQfIbRD8fL0gHGJJ14DXL22Kduv6pR+QnISReoQqhEEsWANPKpOduJLce7B4y+BJuiOGkT7R7qbMKbj9Ecw== - -xterm-addon-unicode11@0.6.0-beta.9: - version "0.6.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.9.tgz#1f476f77cf8c8e4e7ca1a1421b85ac45405db679" - integrity sha512-DH9OIH0EakIdCnzZcIH7NLgUqXwa8WT9fqmi+2CWzt4NN1AH5kSE/3Vk+/uurE5upxDloKw6dtLH9XHpfULV6g== - -xterm-addon-webgl@0.16.0-beta.27: - version "0.16.0-beta.27" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.27.tgz#f4133a40044f0b6448ea87152abf6c9009729100" - integrity sha512-YiwCvTvgfcNGtQdpzcgxKINE6mG63cPfDxfoxCAbodNGYF66k9VzhIXNdCQtVtu+s6+pEc9YequENe78SSZloA== - -xterm-headless@5.3.0-beta.58: - version "5.3.0-beta.58" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.58.tgz#e6a3dbfafdb28435130ce3925ac3194c0ee2c281" - integrity sha512-ekzr3LX8p26qHDyVRs3lys08veHFv9wGOKaHd49kMgktICHsikJ48HNJq5Twp3ZnXyqlIP9CV34BZJ1SBfWmtQ== - -xterm@5.3.0-beta.58: - version "5.3.0-beta.58" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.58.tgz#4bae06639c90952b270e4714938c151ce339b5f0" - integrity sha512-EIOgp+7aqCToI0XjDqORXAe2lJS/XSZXWPzCpyTDmF+DJ56gyw+913gdPoIEWOw3mRylrJtEyIpFcdW7CDA6rQ== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== + +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== + +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== + +xterm-addon-serialize@0.11.0-beta.20: + version "0.11.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.20.tgz#e879b34d214761403f1081833f9221c6903bf0c3" + integrity sha512-OXnC1SATaz7kEFjFWhyv9MJaXi8yHdPjazpGLNi11h33CRTKtCQiqqPBHU87dztnXmpEX6Jw0/jr3zlyXuAmnw== + +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== + +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== + +xterm-headless@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.61.tgz#28654550cb572709b99ea3eb8672d4568ae141c9" + integrity sha512-yfkbPLUtKjE4K7DsZ204A1BuOKpu6Usqi6rIYWT4XRMi+LjnkTbBjGr2BSjyJ3Gmtm+cSgBD0SvRN+V3xNxbxA== + +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== y18n@^3.2.1: version "3.2.2" From 8e524deece95d3aa772af5ce974e8a3a4aca422f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 23 Aug 2023 14:57:53 +0200 Subject: [PATCH 1102/1180] not rendering when model is too large for tokenization --- .../contrib/stickyScroll/browser/stickyScrollController.ts | 5 ++--- .../contrib/codeEditor/browser/largeFileOptimizations.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts index 37647eccdf65a..5764622526da7 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts @@ -370,7 +370,6 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _readConfiguration() { const options = this._editor.getOption(EditorOption.stickyScroll); - if (options.enabled === false) { this._editor.removeOverlayWidget(this._stickyScrollWidget); this._sessionStore.clear(); @@ -429,10 +428,10 @@ export class StickyScrollController extends Disposable implements IEditorContrib } private _renderStickyScroll() { - if (!(this._editor.hasModel())) { + const model = this._editor.getModel(); + if (!model || model.isTooLargeForTokenization()) { return; } - const model = this._editor.getModel(); const stickyLineVersion = this._stickyLineCandidateProvider.getVersionId(); if (stickyLineVersion === undefined || stickyLineVersion === model.getVersionId()) { this._widgetState = this.findScrollWidgetState(); diff --git a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts index 80e766a2a4f3f..52ac3a4afb10b 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts @@ -44,7 +44,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC 'Variable 0 will be a file name.' ] }, - "{0}: tokenization, wrapping and folding have been turned off for this large file in order to reduce memory usage and avoid freezing or crashing.", + "{0}: tokenization, wrapping, folding and sticky scroll have been turned off for this large file in order to reduce memory usage and avoid freezing or crashing.", path.basename(model.uri.path) ); From 2d3235f7474a807220f5a3c48219f92ab331c9e6 Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 23 Aug 2023 23:17:37 +0800 Subject: [PATCH 1103/1180] =?UTF-8?q?immediately=20search=20after=20enter?= =?UTF-8?q?=20pressed=20in=20files=20to=20include/exclude=20te=E2=80=A6=20?= =?UTF-8?q?(#190473)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit immediately search after enter pressed in files to include/exclude text fields. --- src/vs/workbench/contrib/search/browser/searchView.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index cf7506c874c94..6df2f29509513 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -1454,9 +1454,11 @@ export class SearchView extends ViewPane { if (options.triggeredOnType && !this.searchConfig.searchOnType) { return; } if (!this.pauseSearching) { + + const delay = options.triggeredOnType ? options.delay : 0; this.triggerQueryDelayer.trigger(() => { this._onQueryChanged(options.preserveFocus, options.triggeredOnType); - }, options.delay); + }, delay); } } From 2e95e033cf014820e60f382c759be2b25a231114 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 23 Aug 2023 08:20:33 -0700 Subject: [PATCH 1104/1180] support for fastAndSlow picks in quick search (#191002) --- .../browser/notebookSearchContributions.ts | 2 +- .../search/browser/notebookSearchService.ts | 83 +++++++----- .../quickTextSearch/textSearchQuickAccess.ts | 72 +++++++---- .../contrib/search/browser/replaceService.ts | 4 +- .../search/browser/search.contribution.ts | 4 +- .../contrib/search/browser/searchModel.ts | 112 +++++++++++----- .../contrib/search/browser/searchView.ts | 10 +- .../{browser => common}/notebookSearch.ts | 6 +- .../search/test/browser/searchModel.test.ts | 121 +++++++++++++----- .../searchEditor/browser/searchEditor.ts | 4 +- .../services/search/common/search.ts | 4 +- .../services/search/common/searchService.ts | 80 ++++++++---- 12 files changed, 339 insertions(+), 163 deletions(-) rename src/vs/workbench/contrib/search/{browser => common}/notebookSearch.ts (75%) diff --git a/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts b/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts index 03b44bf002672..57d73a21c3fdd 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts +++ b/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts @@ -7,7 +7,7 @@ import { ReplacePreviewContentProvider } from 'vs/workbench/contrib/search/brows import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; import { NotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearchService'; export function registerContributions(): void { diff --git a/src/vs/workbench/contrib/search/browser/notebookSearchService.ts b/src/vs/workbench/contrib/search/browser/notebookSearchService.ts index adee7532d41f2..19b45f30903a0 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearchService.ts +++ b/src/vs/workbench/contrib/search/browser/notebookSearchService.ts @@ -18,10 +18,10 @@ import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/mode import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { INotebookExclusiveDocumentFilter, NotebookData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; import { IFileMatchWithCells, ICellMatch, CellSearchModel, contentMatchesToTextSearchMatches, webviewMatchesToTextSearchMatches, genericCellMatchesToTextSearchMatches } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; import { IEditorResolverService, priorityToRank } from 'vs/workbench/services/editor/common/editorResolverService'; -import { ITextQuery, IFileQuery, QueryType, ISearchProgressItem, ISearchComplete, ISearchConfigurationProperties, ISearchService } from 'vs/workbench/services/search/common/search'; +import { ITextQuery, QueryType, ISearchProgressItem, ISearchComplete, ISearchConfigurationProperties, IFileQuery, ISearchService } from 'vs/workbench/services/search/common/search'; import * as arrays from 'vs/base/common/arrays'; import { isNumber } from 'vs/base/common/types'; @@ -123,48 +123,67 @@ export class NotebookSearchService implements INotebookSearchService { return Array.from(uris.keys()); } - async notebookSearch(query: ITextQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { + notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): { + openFilesToScan: ResourceSet; + completeData: Promise; + allScannedFiles: Promise; + } { if (query.type !== QueryType.Text) { return { - completeData: { + openFilesToScan: new ResourceSet(), + completeData: Promise.resolve({ messages: [], limitHit: false, results: [], - }, - scannedFiles: new ResourceSet() + }), + allScannedFiles: Promise.resolve(new ResourceSet()), }; } - const searchStart = Date.now(); const localNotebookWidgets = this.getLocalNotebookWidgets(); const localNotebookFiles = localNotebookWidgets.map(widget => widget.viewModel!.uri); - const localResultPromise = this.getLocalNotebookResults(query, token, localNotebookWidgets, searchInstanceID); - const searchLocalEnd = Date.now(); + const getAllResults = (): { completeData: Promise; allScannedFiles: Promise } => { + const searchStart = Date.now(); - const experimentalNotebooksEnabled = this.configurationService.getValue('search').experimental?.closedNotebookRichContentResults ?? false; + const localResultPromise = this.getLocalNotebookResults(query, token ?? CancellationToken.None, localNotebookWidgets, searchInstanceID); + const searchLocalEnd = Date.now(); - let closedResultsPromise: Promise = Promise.resolve(undefined); - if (experimentalNotebooksEnabled) { - closedResultsPromise = this.getClosedNotebookResults(query, new ResourceSet(localNotebookFiles, uri => this.uriIdentityService.extUri.getComparisonKey(uri)), token); - } + const experimentalNotebooksEnabled = this.configurationService.getValue('search').experimental?.closedNotebookRichContentResults ?? false; - const resolved = (await Promise.all([localResultPromise, closedResultsPromise])).filter((result): result is INotebookSearchMatchResults => !!result); - const resultArray = resolved.map(elem => elem.results); + let closedResultsPromise: Promise = Promise.resolve(undefined); + if (experimentalNotebooksEnabled) { + closedResultsPromise = this.getClosedNotebookResults(query, new ResourceSet(localNotebookFiles, uri => this.uriIdentityService.extUri.getComparisonKey(uri)), token ?? CancellationToken.None); + } - const results = arrays.coalesce(resultArray.flatMap(map => Array.from(map.values()))); - const scannedFiles = new ResourceSet(resultArray.flatMap(map => Array.from(map.keys())), uri => this.uriIdentityService.extUri.getComparisonKey(uri)); - if (onProgress) { - results.forEach(onProgress); - } - this.logService.trace(`local notebook search time | ${searchLocalEnd - searchStart}ms`); + const promise = Promise.all([localResultPromise, closedResultsPromise]); + return { + completeData: promise.then(resolvedPromise => { + const resolved = resolvedPromise.filter((e): e is INotebookSearchMatchResults => !!e); + const resultArray = resolved.map(elem => elem.results); + const results = arrays.coalesce(resultArray.flatMap(map => Array.from(map.values()))); + if (onProgress) { + results.forEach(onProgress); + } + this.logService.trace(`local notebook search time | ${searchLocalEnd - searchStart}ms`); + return { + messages: [], + limitHit: resolved.reduce((prev, cur) => prev || cur.limitHit, false), + results, + }; + }), + allScannedFiles: promise.then(resolvedPromise => { + const resolved = resolvedPromise.filter((e): e is INotebookSearchMatchResults => !!e); + const resultArray = resolved.map(elem => elem.results); + return new ResourceSet(resultArray.flatMap(map => Array.from(map.keys())), uri => this.uriIdentityService.extUri.getComparisonKey(uri)); + }) + }; + }; + const promiseResults = getAllResults(); return { - completeData: { - messages: [], - limitHit: resolved.reduce((prev, cur) => prev || cur.limitHit, false), - results, - }, - scannedFiles + openFilesToScan: new ResourceSet(localNotebookFiles), + completeData: promiseResults.completeData, + allScannedFiles: promiseResults.allScannedFiles }; } @@ -272,10 +291,10 @@ export class NotebookSearchService implements INotebookSearchService { regex: query.contentPattern.isRegExp, wholeWord: query.contentPattern.isWordMatch, caseSensitive: query.contentPattern.isCaseSensitive, - includeMarkupInput: query.contentPattern.notebookInfo?.isInNotebookMarkdownInput, - includeMarkupPreview: query.contentPattern.notebookInfo?.isInNotebookMarkdownPreview, - includeCodeInput: query.contentPattern.notebookInfo?.isInNotebookCellInput, - includeOutput: query.contentPattern.notebookInfo?.isInNotebookCellOutput, + includeMarkupInput: query.contentPattern.notebookInfo?.isInNotebookMarkdownInput ?? true, + includeMarkupPreview: query.contentPattern.notebookInfo?.isInNotebookMarkdownPreview ?? true, + includeCodeInput: query.contentPattern.notebookInfo?.isInNotebookCellInput ?? true, + includeOutput: query.contentPattern.notebookInfo?.isInNotebookCellOutput ?? true, }, token, false, true, searchID); diff --git a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts index ad3d5da68ff17..15a82a6cf6a44 100644 --- a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts @@ -12,12 +12,12 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; import { WorkbenchCompressibleObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService'; -import { IPickerQuickAccessItem, PickerQuickAccessProvider } from 'vs/platform/quickinput/browser/pickerQuickAccess'; -import { IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { FastAndSlowPicks, IPickerQuickAccessItem, PickerQuickAccessProvider, Picks } from 'vs/platform/quickinput/browser/pickerQuickAccess'; +import { IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IViewsService } from 'vs/workbench/common/views'; import { searchDetailsIcon, searchOpenInFileIcon } from 'vs/workbench/contrib/search/browser/searchIcons'; -import { Match, MatchInNotebook, RenderableMatch, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; +import { FileMatch, Match, MatchInNotebook, RenderableMatch, SearchModel, searchComparer } from 'vs/workbench/contrib/search/browser/searchModel'; import { SearchView, getEditorSelectionFromMatch } from 'vs/workbench/contrib/search/browser/searchView'; import { getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search'; import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -75,8 +75,10 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider('search'); } - private async doSearch(contentPattern: string): Promise { - + private doSearch(contentPattern: string, token: CancellationToken): { + syncResults: FileMatch[]; + asyncResults: Promise; + } | undefined { if (contentPattern === '') { return undefined; } @@ -89,8 +91,16 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider folder.uri), this._getTextQueryBuilderOptions(charsPerLine)); - await this.searchModel.search(query, undefined); - return this.searchModel.searchResult; + const result = this.searchModel.search(query, undefined, token); + + const getAsyncResults = async () => { + await result.asyncResults; + return this.searchModel.searchResult.matches().filter(e => result.syncResults.indexOf(e) === -1); + }; + return { + syncResults: this.searchModel.searchResult.matches(), + asyncResults: getAsyncResults() + }; } private moveToSearchViewlet(model: SearchModel, currentElem: RenderableMatch) { @@ -107,31 +117,24 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { - - const searchResult = await this.doSearch(contentPattern); - - if (!searchResult) { - return []; - } + private _getPicksFromMatches(matches: FileMatch[], limit: number): (IQuickPickSeparator | IPickerQuickAccessItem)[] { + matches = matches.sort(searchComparer); + const files = matches.length > limit ? matches.slice(0, limit) : matches; const picks: Array = []; - const matches = searchResult.matches(); - const files = matches.length > MAX_FILES_SHOWN ? matches.slice(0, MAX_FILES_SHOWN) : matches; - for (let fileIndex = 0; fileIndex < matches.length; fileIndex++) { - if (fileIndex === MAX_FILES_SHOWN) { + if (fileIndex === limit) { picks.push({ type: 'separator', }); picks.push({ - label: 'See More Files', + label: localize('QuickSearchSeeMoreFiles', "See More Files"), iconClass: ThemeIcon.asClassName(searchDetailsIcon), accept: async () => { - this.moveToSearchViewlet(this.searchModel, matches[MAX_FILES_SHOWN]); + this.moveToSearchViewlet(this.searchModel, matches[limit]); } }); break; @@ -159,7 +162,7 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { this.moveToSearchViewlet(this.searchModel, element); @@ -173,10 +176,10 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider | Promise | FastAndSlowPicks> | FastAndSlowPicks | null { + const allMatches = this.doSearch(contentPattern, token); + + if (!allMatches) { + return null; } + const matches = allMatches.syncResults; + const syncResult = this._getPicksFromMatches(matches, MAX_FILES_SHOWN); - return picks; + if (matches.length >= MAX_FILES_SHOWN) { + return syncResult; + } + + return { + picks: syncResult, + additionalPicks: allMatches.asyncResults.then((asyncResults) => { + return this._getPicksFromMatches(asyncResults, MAX_FILES_SHOWN - matches.length); + }) + }; } } diff --git a/src/vs/workbench/contrib/search/browser/replaceService.ts b/src/vs/workbench/contrib/search/browser/replaceService.ts index d45d1f289ed42..8dd187bff0a24 100644 --- a/src/vs/workbench/contrib/search/browser/replaceService.ts +++ b/src/vs/workbench/contrib/search/browser/replaceService.ts @@ -11,7 +11,7 @@ import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IModelService } from 'vs/editor/common/services/model'; import { ILanguageService } from 'vs/editor/common/languages/language'; -import { Match, FileMatch, FileMatchOrMatch, ISearchWorkbenchService, MatchInNotebook } from 'vs/workbench/contrib/search/browser/searchModel'; +import { Match, FileMatch, FileMatchOrMatch, ISearchViewModelWorkbenchService, MatchInNotebook } from 'vs/workbench/contrib/search/browser/searchModel'; import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -63,7 +63,7 @@ class ReplacePreviewModel extends Disposable { @ILanguageService private readonly languageService: ILanguageService, @ITextModelService private readonly textModelResolverService: ITextModelService, @IReplaceService private readonly replaceService: IReplaceService, - @ISearchWorkbenchService private readonly searchWorkbenchService: ISearchWorkbenchService + @ISearchViewModelWorkbenchService private readonly searchWorkbenchService: ISearchViewModelWorkbenchService ) { super(); } diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 0aa08eff74d0f..a48332a48f29c 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -27,7 +27,7 @@ import { SearchView } from 'vs/workbench/contrib/search/browser/searchView'; import { registerContributions as searchWidgetContributions } from 'vs/workbench/contrib/search/browser/searchWidget'; import { SymbolsQuickAccessProvider } from 'vs/workbench/contrib/search/browser/symbolsQuickAccess'; import { ISearchHistoryService, SearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService'; -import { ISearchWorkbenchService, SearchWorkbenchService } from 'vs/workbench/contrib/search/browser/searchModel'; +import { ISearchViewModelWorkbenchService, SearchViewModelWorkbenchService } from 'vs/workbench/contrib/search/browser/searchModel'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { SearchSortOrder, SEARCH_EXCLUDE_CONFIG, VIEWLET_ID, ViewMode, VIEW_ID } from 'vs/workbench/services/search/common/search'; import { Extensions, IConfigurationMigrationRegistry } from 'vs/workbench/common/configuration'; @@ -45,7 +45,7 @@ import 'vs/workbench/contrib/search/browser/searchActionsTopBar'; import 'vs/workbench/contrib/search/browser/searchActionsTextQuickAccess'; import { TEXT_SEARCH_QUICK_ACCESS_PREFIX, TextSearchQuickAccess } from 'vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess'; -registerSingleton(ISearchWorkbenchService, SearchWorkbenchService, InstantiationType.Delayed); +registerSingleton(ISearchViewModelWorkbenchService, SearchViewModelWorkbenchService, InstantiationType.Delayed); registerSingleton(ISearchHistoryService, SearchHistoryService, InstantiationType.Delayed); replaceContributions(); diff --git a/src/vs/workbench/contrib/search/browser/searchModel.ts b/src/vs/workbench/contrib/search/browser/searchModel.ts index 82bf57c763605..95a4644baf44f 100644 --- a/src/vs/workbench/contrib/search/browser/searchModel.ts +++ b/src/vs/workbench/contrib/search/browser/searchModel.ts @@ -36,9 +36,9 @@ import { CellFindMatchWithIndex, CellWebviewFindMatch, ICellViewModel } from 'vs import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { CellSearchModel, ICellMatch, contentMatchesToTextSearchMatches, isIFileMatchWithCells, rawCellPrefix, webviewMatchesToTextSearchMatches } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; import { ReplacePattern } from 'vs/workbench/services/search/common/replace'; import { IFileMatch, IPatternInfo, ISearchComplete, ISearchConfigurationProperties, ISearchProgressItem, ISearchRange, ISearchService, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchPreviewOptions, ITextSearchResult, ITextSearchStats, OneLineRange, resultIsMatch, SearchCompletionExitCode, SearchSortOrder } from 'vs/workbench/services/search/common/search'; import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; @@ -2002,34 +2002,63 @@ export class SearchModel extends Disposable { this._searchResultChangedListener = this._register(this._searchResult.onChange((e) => this._onSearchResultChanged.fire(e))); } - private async doSearch(query: ITextQuery, progressEmitter: Emitter, searchQuery: ITextQuery, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise { - const searchStart = Date.now(); - const tokenSource = this.currentCancelTokenSource = new CancellationTokenSource(); - const onProgressCall = (p: ISearchProgressItem) => { + + private doSearch(query: ITextQuery, progressEmitter: Emitter, searchQuery: ITextQuery, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void, callerToken?: CancellationToken): { + asyncResults: Promise; + syncResults: IFileMatch[]; + } { + const asyncGenerateOnProgress = async (p: ISearchProgressItem) => { progressEmitter.fire(); this.onSearchProgress(p, searchInstanceID); + onProgress?.(p); + }; + const syncGenerateOnProgress = (p: ISearchProgressItem) => { + progressEmitter.fire(); + this.onSearchProgress(p, searchInstanceID, true); onProgress?.(p); }; - const notebookResult = await this.notebookSearchService.notebookSearch(query, this.currentCancelTokenSource.token, searchInstanceID, onProgressCall); - const currentResult = await this.searchService.textSearch( + const tokenSource = this.currentCancelTokenSource = new CancellationTokenSource(callerToken); + + const notebookResult = this.notebookSearchService.notebookSearch(query, tokenSource.token, searchInstanceID, syncGenerateOnProgress); + const textResult = this.searchService.textSearchSplitSyncAsync( searchQuery, - this.currentCancelTokenSource.token, onProgressCall, - notebookResult?.scannedFiles + this.currentCancelTokenSource.token, asyncGenerateOnProgress, + notebookResult.openFilesToScan, + notebookResult.allScannedFiles, ); - tokenSource.dispose(); - const searchLength = Date.now() - searchStart; - this.logService.trace(`whole search time | ${searchLength}ms`); + + const syncResults = textResult.syncResults.results; + syncResults.forEach(p => { if (p) { syncGenerateOnProgress(p); } }); + + const getAsyncResults = async (): Promise => { + const searchStart = Date.now(); + + // resolve async parts of search + const allClosedEditorResults = await textResult.asyncResults; + const resolvedNotebookResults = await notebookResult.completeData; + tokenSource.dispose(); + const searchLength = Date.now() - searchStart; + const resolvedResult = { + results: [...allClosedEditorResults.results, ...resolvedNotebookResults.results], + messages: [...allClosedEditorResults.messages, ...resolvedNotebookResults.messages], + limitHit: allClosedEditorResults.limitHit || resolvedNotebookResults.limitHit, + exit: allClosedEditorResults.exit, + stats: allClosedEditorResults.stats, + }; + this.logService.trace(`whole search time | ${searchLength}ms`); + return resolvedResult; + }; return { - results: currentResult.results.concat(notebookResult.completeData.results), - messages: currentResult.messages.concat(notebookResult.completeData.messages), - limitHit: currentResult.limitHit || notebookResult.completeData.limitHit, - exit: currentResult.exit, - stats: currentResult.stats, + asyncResults: getAsyncResults(), + syncResults }; } - async search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void): Promise { + search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void, callerToken?: CancellationToken): { + asyncResults: Promise; + syncResults: IFileMatch[]; + } { this.cancelSearch(true); this._searchQuery = query; @@ -2046,11 +2075,21 @@ export class SearchModel extends Disposable { // In search on type case, delay the streaming of results just a bit, so that we don't flash the only "local results" fast path this._startStreamDelay = new Promise(resolve => setTimeout(resolve, this.searchConfig.searchOnType ? 150 : 0)); - const currentRequest = this.doSearch(query, progressEmitter, this._searchQuery, searchInstanceID, onProgress); + const req = this.doSearch(query, progressEmitter, this._searchQuery, searchInstanceID, onProgress, callerToken); + const asyncResults = req.asyncResults; + const syncResults = req.syncResults; + + if (onProgress) { + syncResults.forEach(p => { + if (p) { + onProgress(p); + } + }); + } const start = Date.now(); - Promise.race([currentRequest, Event.toPromise(progressEmitter.event)]).finally(() => { + Promise.race([asyncResults, Event.toPromise(progressEmitter.event)]).finally(() => { /* __GDPR__ "searchResultsFirstRender" : { "owner": "roblourens", @@ -2060,12 +2099,14 @@ export class SearchModel extends Disposable { this.telemetryService.publicLog('searchResultsFirstRender', { duration: Date.now() - start }); }); - currentRequest.then( + asyncResults.then( value => this.onSearchCompleted(value, Date.now() - start, searchInstanceID), e => this.onSearchError(e, Date.now() - start)); - try { - return await currentRequest; + return { + asyncResults: asyncResults, + syncResults: syncResults + }; } finally { /* __GDPR__ "searchResultsFinished" : { @@ -2131,14 +2172,23 @@ export class SearchModel extends Disposable { } } - private async onSearchProgress(p: ISearchProgressItem, searchInstanceID: string) { + private onSearchProgress(p: ISearchProgressItem, searchInstanceID: string, sync = true) { if ((p).resource) { this._resultQueue.push(p); - await this._startStreamDelay; - if (this._resultQueue.length) { - this._searchResult.add(this._resultQueue, searchInstanceID, true); - this._resultQueue.length = 0; + if (sync) { + if (this._resultQueue.length) { + this._searchResult.add(this._resultQueue, searchInstanceID, true); + this._resultQueue.length = 0; + } + } else { + this._startStreamDelay.then(() => { + if (this._resultQueue.length) { + this._searchResult.add(this._resultQueue, searchInstanceID, true); + this._resultQueue.length = 0; + } + }); } + } } @@ -2171,7 +2221,7 @@ export type FileMatchOrMatch = FileMatch | Match; export type RenderableMatch = FolderMatch | FolderMatchWithResource | FileMatch | Match; -export class SearchWorkbenchService implements ISearchWorkbenchService { +export class SearchViewModelWorkbenchService implements ISearchViewModelWorkbenchService { declare readonly _serviceBrand: undefined; private _searchModel: SearchModel | null = null; @@ -2187,9 +2237,9 @@ export class SearchWorkbenchService implements ISearchWorkbenchService { } } -export const ISearchWorkbenchService = createDecorator('searchWorkbenchService'); +export const ISearchViewModelWorkbenchService = createDecorator('searchViewModelWorkbenchService'); -export interface ISearchWorkbenchService { +export interface ISearchViewModelWorkbenchService { readonly _serviceBrand: undefined; readonly searchModel: SearchModel; diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 6df2f29509513..d6be8a289987c 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -70,7 +70,7 @@ import * as Constants from 'vs/workbench/contrib/search/common/constants'; import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { getOutOfWorkspaceEditorResources, SearchStateKey, SearchUIState } from 'vs/workbench/contrib/search/common/search'; import { ISearchHistoryService, ISearchHistoryValues, SearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService'; -import { FileMatch, FileMatchOrMatch, FolderMatch, FolderMatchWithResource, IChangeEvent, ISearchWorkbenchService, Match, MatchInNotebook, RenderableMatch, searchMatchComparer, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; +import { FileMatch, FileMatchOrMatch, FolderMatch, FolderMatchWithResource, IChangeEvent, ISearchViewModelWorkbenchService, Match, MatchInNotebook, RenderableMatch, searchMatchComparer, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; import { createEditorFromSearchResult } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IPreferencesService, ISettingsEditorOptions } from 'vs/workbench/services/preferences/common/preferences'; @@ -174,7 +174,7 @@ export class SearchView extends ViewPane { @IViewDescriptorService viewDescriptorService: IViewDescriptorService, @IConfigurationService configurationService: IConfigurationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @ISearchWorkbenchService private readonly searchWorkbenchService: ISearchWorkbenchService, + @ISearchViewModelWorkbenchService private readonly searchViewModelWorkbenchService: ISearchViewModelWorkbenchService, @IContextKeyService contextKeyService: IContextKeyService, @IReplaceService private readonly replaceService: IReplaceService, @ITextFileService private readonly textFileService: ITextFileService, @@ -235,7 +235,7 @@ export class SearchView extends ViewPane { } }); - this.viewModel = this._register(this.searchWorkbenchService.searchModel); + this.viewModel = this._register(this.searchViewModelWorkbenchService.searchModel); this.queryBuilder = this.instantiationService.createInstance(QueryBuilder); this.memento = new Memento(this.id, storageService); this.viewletState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); @@ -1743,8 +1743,8 @@ export class SearchView extends ViewPane { this.tree.setSelection([]); this.tree.setFocus([]); - return this.viewModel.search(query) - .then(onComplete, onError); + const result = this.viewModel.search(query); + return result.asyncResults.then(onComplete, onError); } private onOpenSettings(e: dom.EventLike): void { diff --git a/src/vs/workbench/contrib/search/browser/notebookSearch.ts b/src/vs/workbench/contrib/search/common/notebookSearch.ts similarity index 75% rename from src/vs/workbench/contrib/search/browser/notebookSearch.ts rename to src/vs/workbench/contrib/search/common/notebookSearch.ts index 2fb526582198e..5237c1bd03c75 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearch.ts +++ b/src/vs/workbench/contrib/search/common/notebookSearch.ts @@ -14,5 +14,9 @@ export interface INotebookSearchService { readonly _serviceBrand: undefined; - notebookSearch(query: ITextQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }>; + notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): { + openFilesToScan: ResourceSet; + completeData: Promise; + allScannedFiles: Promise; + }; } diff --git a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts index 0adcb1e47d426..ca0a09f0c3156 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts @@ -14,7 +14,7 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextSearchMatch, OneLineRange, QueryType, TextSearchMatch } from 'vs/workbench/services/search/common/search'; +import { IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextQuery, ITextSearchMatch, OneLineRange, QueryType, TextSearchMatch } from 'vs/workbench/services/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { CellMatch, MatchInNotebook, SearchModel } from 'vs/workbench/contrib/search/browser/searchModel'; @@ -36,7 +36,7 @@ import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBr import { FindMatch, IReadonlyTextBuffer } from 'vs/editor/common/model'; import { ResourceMap, ResourceSet } from 'vs/base/common/map'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; const nullEvent = new class { id: number = -1; @@ -112,6 +112,20 @@ suite('SearchModel', () => { }); }); + }, + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: new Promise(resolve => { + queueMicrotask(() => { + results.forEach(onProgress!); + resolve(complete!); + }); + }) + }; } }; } @@ -129,6 +143,17 @@ suite('SearchModel', () => { reject(error); }); }); + }, + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: new Promise((resolve, reject) => { + reject(error); + }) + }; } }; } @@ -151,16 +176,47 @@ suite('SearchModel', () => { resolve({}); }); }); + }, + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + token?.onCancellationRequested(() => tokenSource.cancel()); + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: new Promise(resolve => { + queueMicrotask(() => { + resolve({}); + }); + }) + }; } }; } + function searchServiceWithDeferredPromise(p: Promise): ISearchService { + return { + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: p, + }; + } + }; + } function notebookSearchServiceWithInfo(results: IFileMatchWithCells[], tokenSource: CancellationTokenSource | undefined): INotebookSearchService { return { _serviceBrand: undefined, - notebookSearch(query: ISearchQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void, notebookURIs?: ResourceSet): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { + notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): { + openFilesToScan: ResourceSet; + completeData: Promise; + allScannedFiles: Promise; + } { token?.onCancellationRequested(() => tokenSource?.cancel()); const localResults = new ResourceMap(uri => uri.path); @@ -171,15 +227,15 @@ suite('SearchModel', () => { if (onProgress) { arrays.coalesce([...localResults.values()]).forEach(onProgress); } - return Promise.resolve( - { - completeData: { - messages: [], - results: arrays.coalesce([...localResults.values()]), - limitHit: false - }, - scannedFiles: new ResourceSet([...localResults.keys()]), - }); + return { + openFilesToScan: new ResourceSet([...localResults.keys()]), + completeData: Promise.resolve({ + messages: [], + results: arrays.coalesce([...localResults.values()]), + limitHit: false + }), + allScannedFiles: Promise.resolve(new ResourceSet()), + }; } }; } @@ -194,7 +250,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; const actual = testObject.searchResult.matches(); @@ -216,17 +272,14 @@ suite('SearchModel', () => { test('Search Model: Search can return notebook results', async () => { - const notebookUri = createFileUriFromPathFromRoot('/1'); - const results = [ aRawMatch('/2', new TextSearchMatch('test', new OneLineRange(1, 1, 5)), new TextSearchMatch('this is a test', new OneLineRange(1, 11, 15))), aRawMatch('/3', new TextSearchMatch('test', lineOneRange))]; - const searchService = instantiationService.stub(ISearchService, searchServiceWithResults(results, { limitHit: false, messages: [], results })); + instantiationService.stub(ISearchService, searchServiceWithResults(results, { limitHit: false, messages: [], results })); sinon.stub(CellMatch.prototype, 'addContext'); - const textSearch = sinon.spy(searchService, 'textSearch'); const mdInputCell = { cellKind: CellKind.Markup, textBuffer: { getLineContent(lineNumber: number): string { @@ -297,12 +350,10 @@ suite('SearchModel', () => { const notebookSearchService = instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([aRawMatchWithCells('/1', cellMatchMd, cellMatchCode)], undefined)); const notebookSearch = sinon.spy(notebookSearchService, "notebookSearch"); const model: SearchModel = instantiationService.createInstance(SearchModel); - await model.search({ contentPattern: { pattern: 'test' }, type: QueryType.Text, folderQueries }); + await model.search({ contentPattern: { pattern: 'test' }, type: QueryType.Text, folderQueries }).asyncResults; const actual = model.searchResult.matches(); assert(notebookSearch.calledOnce); - assert(textSearch.getCall(0).args[3]?.size === 1); - assert(textSearch.getCall(0).args[3]?.has(notebookUri)); // ensure that the textsearch knows not to re-source the notebooks assert.strictEqual(3, actual.length); assert.strictEqual(URI.file(`${getRootName()}/1`).toString(), actual[0].resource.toString()); @@ -351,7 +402,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; assert.ok(target.calledThrice); assert.ok(target.calledWith('searchResultsFirstRender')); @@ -368,7 +419,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; return result.then(() => { return timeout(1).then(() => { @@ -390,7 +441,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; return result.then(() => { return timeout(1).then(() => { @@ -410,15 +461,15 @@ suite('SearchModel', () => { instantiationService.stub(ITelemetryService, 'publicLog', target1); instantiationService.stub(ISearchService, searchServiceWithError(new Error('error'))); + instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; return result.then(() => { }, () => { return timeout(1).then(() => { assert.ok(target1.calledWith('searchResultsFirstRender')); assert.ok(target1.calledWith('searchResultsFinished')); - // assert.ok(target2.calledOnce); }); }); }); @@ -430,14 +481,16 @@ suite('SearchModel', () => { instantiationService.stub(ITelemetryService, 'publicLog', target1); const deferredPromise = new DeferredPromise(); - instantiationService.stub(ISearchService, 'textSearch', deferredPromise.p); + + instantiationService.stub(ISearchService, searchServiceWithDeferredPromise(deferredPromise.p)); + instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; deferredPromise.cancel(); - return result.then(() => { }, () => { + return result.then(() => { }, async () => { return timeout(1).then(() => { assert.ok(target1.calledWith('searchResultsFirstRender')); assert.ok(target1.calledWith('searchResultsFinished')); @@ -456,7 +509,7 @@ suite('SearchModel', () => { instantiationService.stub(ISearchService, searchServiceWithResults(results, { limitHit: false, messages: [], results: [] })); instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; assert.ok(!testObject.searchResult.isEmpty()); instantiationService.stub(ISearchService, searchServiceWithResults([])); @@ -487,24 +540,24 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 're' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 're' }, type: QueryType.Text, folderQueries }).asyncResults; testObject.replaceString = 'hello'; let match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 're', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 're', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 're(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 're(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; testObject.replaceString = 'hello$1'; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('helloe', match.replaceString); diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index 783e8bea1dc02..e9bc0f046cd37 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -567,8 +567,8 @@ export class SearchEditor extends AbstractTextCodeEditor const { configurationModel } = await startInput.resolveModels(); configurationModel.updateConfig(config); - - startInput.ongoingSearchOperation = this.searchModel.search(query).finally(() => { + const result = this.searchModel.search(query); + startInput.ongoingSearchOperation = result.asyncResults.finally(() => { this.ongoingOperations--; if (this.ongoingOperations === 0) { this.searchOperation.stop(); diff --git a/src/vs/workbench/services/search/common/search.ts b/src/vs/workbench/services/search/common/search.ts index 1702df607532e..caded264a85a2 100644 --- a/src/vs/workbench/services/search/common/search.ts +++ b/src/vs/workbench/services/search/common/search.ts @@ -19,6 +19,7 @@ import * as paths from 'vs/base/common/path'; import { isCancellationError } from 'vs/base/common/errors'; import { TextSearchCompleteMessageType } from 'vs/workbench/services/search/common/searchExtTypes'; import { isThenable } from 'vs/base/common/async'; +import { ResourceSet } from 'vs/base/common/map'; export { TextSearchCompleteMessageType }; @@ -41,7 +42,8 @@ export const ISearchService = createDecorator('searchService'); */ export interface ISearchService { readonly _serviceBrand: undefined; - textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void, notebookURIs?: Set): Promise; + textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Promise; + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined, notebookFilesToIgnore?: ResourceSet, asyncNotebookFilesToIgnore?: Promise): { syncResults: ISearchComplete; asyncResults: Promise }; fileSearch(query: IFileQuery, token?: CancellationToken): Promise; clearCache(cacheKey: string): Promise; registerSearchResultProvider(scheme: string, type: SearchProviderType, provider: ISearchResultProvider): IDisposable; diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 63b1c192a8668..bbabce133c8da 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -73,37 +73,63 @@ export class SearchService extends Disposable implements ISearchService { }); } - async textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (item: ISearchProgressItem) => void, notebookURIs?: ResourceSet): Promise { - // Get local results from dirty/untitled - const localResults = this.getLocalResults(query); + async textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (item: ISearchProgressItem) => void): Promise { + const results = this.textSearchSplitSyncAsync(query, token, onProgress); + const openEditorResults = results.syncResults; + const otherResults = await results.asyncResults; + return { + limitHit: otherResults.limitHit || openEditorResults.limitHit, + results: [...otherResults.results, ...openEditorResults.results], + messages: [...otherResults.messages, ...openEditorResults.messages] + }; + } + + textSearchSplitSyncAsync( + query: ITextQuery, + token?: CancellationToken | undefined, + onProgress?: ((result: ISearchProgressItem) => void) | undefined, + notebookFilesToIgnore?: ResourceSet, + asyncNotebookFilesToIgnore?: Promise + ): { + syncResults: ISearchComplete; + asyncResults: Promise; + } { + // Get open editor results from dirty/untitled + const openEditorResults = this.getOpenEditorResults(query); if (onProgress) { - arrays.coalesce([...localResults.results.values()]).forEach(onProgress); + arrays.coalesce([...openEditorResults.results.values()]).filter(e => !(notebookFilesToIgnore && notebookFilesToIgnore.has(e.resource))).forEach(onProgress); } - const onProviderProgress = (progress: ISearchProgressItem) => { - if (isFileMatch(progress)) { - // Match - if (!localResults.results.has(progress.resource) && !(notebookURIs && notebookURIs.has(progress.resource)) && onProgress) { // don't override local results - onProgress(progress); + const syncResults: ISearchComplete = { + results: arrays.coalesce([...openEditorResults.results.values()]), + limitHit: openEditorResults.limitHit ?? false, + messages: [] + }; + + const getAsyncResults = async () => { + const resolvedAsyncNotebookFilesToIgnore = await asyncNotebookFilesToIgnore ?? new ResourceSet(); + const onProviderProgress = (progress: ISearchProgressItem) => { + if (isFileMatch(progress)) { + // Match + if (!openEditorResults.results.has(progress.resource) && !resolvedAsyncNotebookFilesToIgnore.has(progress.resource) && onProgress) { // don't override open editor results + onProgress(progress); + } + } else if (onProgress) { + // Progress + onProgress(progress); } - } else if (onProgress) { - // Progress - onProgress(progress); - } - if (isProgressMessage(progress)) { - this.logService.debug('SearchService#search', progress.message); - } + if (isProgressMessage(progress)) { + this.logService.debug('SearchService#search', progress.message); + } + }; + return await this.doSearch(query, token, onProviderProgress); }; - const otherResults = await this.doSearch(query, token, onProviderProgress); return { - ...otherResults, - ...{ - limitHit: otherResults.limitHit || localResults.limitHit - }, - results: [...otherResults.results, ...arrays.coalesce([...localResults.results.values()])] + syncResults, + asyncResults: getAsyncResults() }; } @@ -404,8 +430,8 @@ export class SearchService extends Disposable implements ISearchService { } } - private getLocalResults(query: ITextQuery): { results: ResourceMap; limitHit: boolean } { - const localResults = new ResourceMap(uri => this.uriIdentityService.extUri.getComparisonKey(uri)); + private getOpenEditorResults(query: ITextQuery): { results: ResourceMap; limitHit: boolean } { + const openEditorResults = new ResourceMap(uri => this.uriIdentityService.extUri.getComparisonKey(uri)); let limitHit = false; if (query.type === QueryType.Text) { @@ -465,18 +491,18 @@ export class SearchService extends Disposable implements ISearchService { } const fileMatch = new FileMatch(originalResource); - localResults.set(originalResource, fileMatch); + openEditorResults.set(originalResource, fileMatch); const textSearchResults = editorMatchesToTextSearchResults(matches, model, query.previewOptions); fileMatch.results = addContextToEditorMatches(textSearchResults, model, query); } else { - localResults.set(originalResource, null); + openEditorResults.set(originalResource, null); } }); } return { - results: localResults, + results: openEditorResults, limitHit }; } From ca2c1636f87ea4705f32345c2e348e815996e129 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 23 Aug 2023 17:09:57 +0200 Subject: [PATCH 1105/1180] Improves moved code detection feature --- .../diffEditorDecorations.ts | 15 +- .../diffEditorWidget2/diffEditorViewModel.ts | 28 ++- .../diffEditorWidget2.contribution.ts | 27 +++ .../diffEditorWidget2/diffEditorWidget2.ts | 25 ++- .../widget/diffEditorWidget2/lineAlignment.ts | 6 +- .../diffEditorWidget2/movedBlocksLines.ts | 164 ++++++++++++++++-- .../widget/diffEditorWidget2/style.css | 16 ++ .../browser/widget/diffEditorWidget2/utils.ts | 3 + src/vs/editor/common/editorContextKeys.ts | 1 + 9 files changed, 245 insertions(+), 40 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts index 194f37c98824b..9a4b5bcf09493 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts @@ -34,13 +34,13 @@ export class DiffEditorDecorations extends Disposable { return null; } - const currentMove = this._diffModel.read(reader)!.syncedMovedTexts.read(reader); + const movedTextToCompare = this._diffModel.read(reader)!.movedTextToCompare.read(reader); const renderIndicators = this._options.renderIndicators.read(reader); const showEmptyDecorations = this._options.showEmptyDecorations.read(reader); const originalDecorations: IModelDeltaDecoration[] = []; const modifiedDecorations: IModelDeltaDecoration[] = []; - if (!currentMove) { + if (!movedTextToCompare) { for (const m of diff.mappings) { if (!m.lineRangeMapping.originalRange.isEmpty) { originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); @@ -68,14 +68,14 @@ export class DiffEditorDecorations extends Disposable { } } - if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !currentMove) { + 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 (currentMove) { - for (const m of currentMove.changes) { + if (movedTextToCompare) { + for (const m of movedTextToCompare.changes) { const fullRangeOriginal = m.originalRange.toInclusiveRange(); if (fullRangeOriginal) { originalDecorations.push({ range: fullRangeOriginal, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); @@ -91,12 +91,13 @@ export class DiffEditorDecorations extends Disposable { } } } + const activeMovedText = this._diffModel.read(reader)!.activeMovedText.read(reader); for (const m of diff.movedTexts) { originalDecorations.push({ range: m.lineRangeMapping.original.toInclusiveRange()!, options: { description: 'moved', - blockClassName: 'movedOriginal' + (m === currentMove ? ' currentMove' : ''), + blockClassName: 'movedOriginal' + (m === activeMovedText ? ' currentMove' : ''), blockPadding: [MovedBlocksLinesPart.movedCodeBlockPadding, 0, MovedBlocksLinesPart.movedCodeBlockPadding, MovedBlocksLinesPart.movedCodeBlockPadding], } }); @@ -104,7 +105,7 @@ export class DiffEditorDecorations extends Disposable { modifiedDecorations.push({ range: m.lineRangeMapping.modified.toInclusiveRange()!, options: { description: 'moved', - blockClassName: 'movedModified' + (m === currentMove ? ' currentMove' : ''), + blockClassName: 'movedModified' + (m === activeMovedText ? ' currentMove' : ''), blockPadding: [4, 0, 4, 4], } }); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 4927ebeb9c1e9..8dea4d6cc5691 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -48,7 +48,21 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo } ); - public readonly syncedMovedTexts = observableValue('syncedMovedText', undefined); + public readonly movedTextToCompare = observableValue('movedTextToCompare', undefined); + + private readonly _activeMovedText = observableValue('activeMovedText', undefined); + private readonly _hoveredMovedText = observableValue('hoveredMovedText', undefined); + + + public readonly activeMovedText = derived(r => this.movedTextToCompare.read(r) ?? this._hoveredMovedText.read(r) ?? this._activeMovedText.read(r)); + + public setActiveMovedText(movedText: MovedText | undefined): void { + this._activeMovedText.set(movedText, undefined); + } + + public setHoveredMovedText(movedText: MovedText | undefined): void { + this._hoveredMovedText.set(movedText, undefined); + } constructor( public readonly model: IDiffEditorModel, @@ -114,8 +128,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo transaction(tx => { this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); updateUnchangedRegions(result, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); } } @@ -132,8 +146,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo transaction(tx => { this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); updateUnchangedRegions(result, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); } } @@ -180,8 +194,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const state = DiffState.fromDiffResult(result); this._diff.set(state, tx); this._isDiffUpToDate.set(true, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); })); } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts index 13c654d867f71..7421abcd3862c 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Codicon } from 'vs/base/common/codicons'; +import { KeyCode } from 'vs/base/common/keyCodes'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction2, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { findFocusedDiffEditor } from 'vs/editor/browser/widget/diffEditor.contribution'; @@ -128,3 +129,29 @@ export class SwitchSide extends EditorAction2 { } registerAction2(SwitchSide); + +export class ExitCompareMove extends EditorAction2 { + constructor() { + super({ + id: 'diffEditor.exitCompareMove', + title: { value: localize('exitCompareMove', "Exit Compare Move"), original: 'Exit Compare Move' }, + icon: Codicon.close, + precondition: EditorContextKeys.comparingMovedCode, + f1: false, + category: diffEditorCategory, + keybinding: { + weight: 10000, + primary: KeyCode.Escape, + } + }); + } + + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void { + const diffEditor = findFocusedDiffEditor(accessor); + if (diffEditor instanceof DiffEditorWidget2) { + diffEditor.exitCompareMove(); + } + } +} + +registerAction2(ExitCompareMove); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 63973ae2e03be..5bc2b098e2b72 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -111,6 +111,12 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { isEmbeddedDiffEditorKey.set(this._options.isInEmbeddedEditor.read(reader)); })); + const comparingMovedCodeKey = EditorContextKeys.comparingMovedCode.bindTo(this._contextKeyService); + this._register(autorun(reader => { + /** @description update comparingMovedCodeKey */ + comparingMovedCodeKey.set(!!this._diffModel.read(reader)?.movedTextToCompare.read(reader)); + })); + const diffEditorRenderSideBySideInlineBreakpointReachedContextKeyValue = EditorContextKeys.diffEditorRenderSideBySideInlineBreakpointReached.bindTo(this._contextKeyService); this._register(autorun(reader => { /** @description update accessibleDiffViewerVisible context key */ @@ -223,19 +229,6 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { ), })); - 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)); - m.syncedMovedTexts.set(movedText, undefined); - })); - this._register(this._editors.modified.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); - if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); - m.syncedMovedTexts.set(movedText, undefined); - })); - // Revert change when an arrow is clicked. this._register(this._editors.modified.onMouseDown(event => { if (!event.event.rightButton && event.target.position && event.target.element?.className.includes('arrow-revert-change')) { @@ -518,6 +511,12 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { } destination.focus(); } + + exitCompareMove(): void { + const model = this._diffModel.get(); + if (!model) { return; } + model.movedTextToCompare.set(undefined, undefined); + } } function translatePosition(posInOriginal: Position, mappings: LineRangeMapping[]): Range { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts index 3a95ce2894291..56357753f6251 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts @@ -103,7 +103,7 @@ export class ViewZoneManager extends Disposable { const alignmentsSyncedMovedText = derived((reader) => { /** @description alignments */ - const syncedMovedText = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); if (!syncedMovedText) { return null; } state.read(reader); const mappings = syncedMovedText.changes.map(c => new DiffMapping(c)); @@ -171,7 +171,7 @@ export class ViewZoneManager extends Disposable { const modLineHeight = this._editors.modified.getOption(EditorOption.lineHeight); - const syncedMovedText = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); const mightContainNonBasicASCII = this._editors.original.getModel()?.mightContainNonBasicASCII() ?? false; const mightContainRTL = this._editors.original.getModel()?.mightContainRTL() ?? false; @@ -424,7 +424,7 @@ export class ViewZoneManager extends Disposable { this._register(autorun(reader => { /** @description update editor top offsets */ - const m = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const m = this._diffModel.read(reader)?.movedTextToCompare.read(reader); let deltaOrigToMod = 0; if (m) { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts index 4453cb7ce2dbc..6a5316decbad4 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -3,15 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { h } from 'vs/base/browser/dom'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +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, derived, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable'; +import { IObservable, autorun, 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'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; +import { PlaceholderViewZone, ViewZoneOverlayWidget, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { OffsetRange, OffsetRangeSet } from 'vs/editor/common/core/offsetRange'; +import { MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { localize } from 'vs/nls'; export class MovedBlocksLinesPart extends Disposable { public static readonly movedCodeBlockPadding = 4; @@ -51,9 +59,50 @@ export class MovedBlocksLinesPart extends Disposable { })); this._register(keepAlive(this._state, true)); + + const movedBlockViewZones = derived(reader => { + const model = this._diffModel.read(reader); + const d = model?.diff.read(reader); + if (!d) { return []; } + return d.movedTexts.map(move => ({ + move, + original: new PlaceholderViewZone(constObservable(move.lineRangeMapping.original.startLineNumber - 1), 18), + modified: new PlaceholderViewZone(constObservable(move.lineRangeMapping.modified.startLineNumber - 1), 18), + })); + }); + + this._register(applyViewZones(this._editors.original, movedBlockViewZones.map(zones => zones.map(z => z.original)))); + this._register(applyViewZones(this._editors.modified, movedBlockViewZones.map(zones => zones.map(z => z.modified)))); + + this._register(autorunWithStore((reader, store) => { + const blocks = movedBlockViewZones.read(reader); + for (const b of blocks) { + store.add(new MovedBlockOverlayWidget(this._editors.original, b.original, b.move, 'original', this._diffModel.get()!)); + store.add(new MovedBlockOverlayWidget(this._editors.modified, b.modified, b.move, 'modified', this._diffModel.get()!)); + } + })); + + 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); + } + m.setActiveMovedText(movedText); + })); + this._register(this._editors.modified.onDidChangeCursorPosition(e => { + const m = this._diffModel.get(); + if (!m) { return; } + const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); + if (movedText !== m.movedTextToCompare.get()) { + m.movedTextToCompare.set(undefined, undefined); + } + m.setActiveMovedText(movedText); + })); } - private readonly _state = derived(reader => { + private readonly _state = derivedWithStore('state', (reader, store) => { /** @description update moved blocks lines */ this._element.replaceChildren(); @@ -125,21 +174,35 @@ export class MovedBlocksLinesPart extends Disposable { rect.setAttribute('height', `${rectHeight}`); this._element.appendChild(rect); + const g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - if (line.move === model.syncedMovedTexts.read(reader)) { - path.classList.add('currentMove'); - } + path.setAttribute('d', `M ${0} ${line.from} L ${verticalY} ${line.from} L ${verticalY} ${line.to} L ${right - arrowWidth} ${line.to}`); path.setAttribute('fill', 'none'); - this._element.appendChild(path); + g.appendChild(path); const arrowRight = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); arrowRight.classList.add('arrow'); - if (line.move === model.syncedMovedTexts.read(reader)) { - arrowRight.classList.add('currentMove'); - } + + store.add(autorun(reader => { + path.classList.toggle('currentMove', line.move === model.activeMovedText.read(reader)); + arrowRight.classList.toggle('currentMove', line.move === model.activeMovedText.read(reader)); + })); + arrowRight.setAttribute('points', `${right - arrowWidth},${line.to - arrowHeight / 2} ${right},${line.to} ${right - arrowWidth},${line.to + arrowHeight / 2}`); - this._element.appendChild(arrowRight); + g.appendChild(arrowRight); + + this._element.appendChild(g); + + /* + TODO@hediet + path.addEventListener('mouseenter', () => { + model.setHoveredMovedText(line.move); + }); + path.addEventListener('mouseleave', () => { + model.setHoveredMovedText(undefined); + });*/ idx++; } @@ -184,3 +247,84 @@ class LinesLayout { return this._trackCount; } } + +class MovedBlockOverlayWidget extends ViewZoneOverlayWidget { + private readonly _nodes = h('div.diff-moved-code-block', { style: { marginRight: '4px' } }, [ + h('div.text-content@textContent'), + h('div.action-bar@actionBar'), + ]); + + constructor( + private readonly _editor: ICodeEditor, + _viewZone: PlaceholderViewZone, + private readonly _move: MovedText, + private readonly _kind: 'original' | 'modified', + private readonly _diffModel: DiffEditorViewModel, + ) { + const root = h('div.diff-hidden-lines-widget'); + super(_editor, _viewZone, root.root); + root.root.appendChild(this._nodes.root); + + const editorLayout = observableFromEvent(this._editor.onDidLayoutChange, () => this._editor.getLayoutInfo()); + + this._register(applyStyle(this._nodes.root, { + paddingRight: editorLayout.map(l => l.verticalScrollbarWidth) + })); + + let text: string; + + if (_move.changes.length > 0) { + text = this._kind === 'original' ? localize( + 'codeMovedToWithChanges', + 'Code moved with changes to line {0}-{1}', + this._move.lineRangeMapping.modified.startLineNumber, + this._move.lineRangeMapping.modified.endLineNumberExclusive + ) : localize( + 'codeMovedFromWithChanges', + 'Code moved with changes from line {0}-{1}', + this._move.lineRangeMapping.original.startLineNumber, + this._move.lineRangeMapping.original.endLineNumberExclusive + ); + } else { + text = this._kind === 'original' ? localize( + 'codeMovedTo', + 'Code moved to line {0}-{1}', + this._move.lineRangeMapping.modified.startLineNumber, + this._move.lineRangeMapping.modified.endLineNumberExclusive + ) : localize( + 'codeMovedFrom', + 'Code moved from line {0}-{1}', + this._move.lineRangeMapping.original.startLineNumber, + this._move.lineRangeMapping.original.endLineNumberExclusive + ); + } + + const actionBar = this._register(new ActionBar(this._nodes.actionBar, { + highlightToggledItems: true, + })); + + const caption = new Action( + '', + text, + '', + false, + ); + actionBar.push(caption, { icon: false, label: true }); + + const actionCompare = new Action( + '', + 'Compare', + ThemeIcon.asClassName(Codicon.compareChanges), + true, + () => { + this._editor.focus(); + this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() ? undefined : this._move, undefined); + }, + ); + this._register(autorun(reader => { + const isActive = this._diffModel.movedTextToCompare.read(reader) === _move; + actionCompare.checked = isActive; + })); + actionBar.push(actionCompare, { icon: true, label: false }); + } +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/style.css b/src/vs/editor/browser/widget/diffEditorWidget2/style.css index 8fd6377362f6b..aa681f8f61766 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/style.css +++ b/src/vs/editor/browser/widget/diffEditorWidget2/style.css @@ -86,6 +86,10 @@ stroke: var(--vscode-diffEditor-moveActive-border); } +.monaco-diff-editor .moved-blocks-lines path { + pointer-events: visiblestroke; +} + .monaco-diff-editor .moved-blocks-lines .arrow { fill: var(--vscode-diffEditor-move-border); } @@ -121,3 +125,15 @@ .monaco-editor .fold-unchanged { cursor: pointer; } + +.monaco-diff-editor .diff-moved-code-block { + display: flex; + justify-content: flex-end; + margin-top: -4px; +} + +.monaco-diff-editor .diff-moved-code-block .action-bar .action-label.codicon { + width: 12px; + height: 12px; + font-size: 12px; +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts index 9a86bfd448bfe..8460b24326eb5 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts @@ -268,6 +268,8 @@ export interface CSSStyle { top: number | string; visibility: 'visible' | 'hidden' | 'collapse'; display: 'block' | 'inline' | 'inline-block' | 'flex' | 'none'; + paddingLeft: number | string; + paddingRight: number | string; } export function applyStyle(domNode: HTMLElement, style: Partial<{ [TKey in keyof CSSStyle]: CSSStyle[TKey] | IObservable | undefined }>) { @@ -280,6 +282,7 @@ export function applyStyle(domNode: HTMLElement, style: Partial<{ [TKey in keyof if (typeof val === 'number') { val = `${val}px`; } + key = key.replace(/[A-Z]/g, m => '-' + m.toLowerCase()); domNode.style[key as any] = val as any; } }); diff --git a/src/vs/editor/common/editorContextKeys.ts b/src/vs/editor/common/editorContextKeys.ts index c831d05fe2159..a2b1a88cc446b 100644 --- a/src/vs/editor/common/editorContextKeys.ts +++ b/src/vs/editor/common/editorContextKeys.ts @@ -27,6 +27,7 @@ export namespace EditorContextKeys { export const readOnly = new RawContextKey('editorReadonly', false, nls.localize('editorReadonly', "Whether the editor is read-only")); export const inDiffEditor = new RawContextKey('inDiffEditor', false, nls.localize('inDiffEditor', "Whether the context is a diff editor")); export const isEmbeddedDiffEditor = new RawContextKey('isEmbeddedDiffEditor', false, nls.localize('isEmbeddedDiffEditor', "Whether the context is an embedded diff editor")); + export const comparingMovedCode = new RawContextKey('comparingMovedCode', false, nls.localize('comparingMovedCode', "Whether a moved code block is selected for comparison")); export const accessibleDiffViewerVisible = new RawContextKey('accessibleDiffViewerVisible', false, nls.localize('accessibleDiffViewerVisible', "Whether the accessible diff viewer is visible")); export const diffEditorRenderSideBySideInlineBreakpointReached = new RawContextKey('diffEditorRenderSideBySideInlineBreakpointReached', false, nls.localize('diffEditorRenderSideBySideInlineBreakpointReached', "Whether the diff editor render side by side inline breakpoint is reached")); export const columnSelection = new RawContextKey('editorColumnSelection', false, nls.localize('editorColumnSelection', "Whether `editor.columnSelection` is enabled")); From 6225119b0ca825fd668780367894d9f6c6d8d9a6 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 23 Aug 2023 09:13:21 -0700 Subject: [PATCH 1106/1180] Show progress in chat placeholder content (#190782) * Show progress in chat placeholder content * Make property names consistent * Rename more properties * Address PR comments * Dispose of markdown render result * Look up `isPlaceholder` on `currentResponseData` --- .../contrib/chat/browser/chatListRenderer.ts | 28 ++++++++++++++++--- .../contrib/chat/browser/media/chat.css | 15 ++++++++++ .../contrib/chat/common/chatModel.ts | 21 ++++++++------ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 52f971ad1b941..dad24e99b6060 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -72,6 +72,7 @@ import { createFileIconThemableTreeContainerScope } from 'vs/workbench/contrib/f import { IFilesConfiguration } from 'vs/workbench/contrib/files/common/files'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { distinct } from 'vs/base/common/arrays'; +import { IPlaceholderMarkdownString } from 'vs/workbench/contrib/chat/common/chatModel'; const $ = dom.$; @@ -414,7 +415,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer content.dispose() }; + } + private renderMarkdown(markdown: IMarkdownString, element: ChatTreeItem, disposables: DisposableStore, templateData: IChatListItemTemplate, fillInIncompleteTokens = false): IMarkdownRenderResult { const disposablesList: IDisposable[] = []; let codeBlockIndex = 0; @@ -622,7 +638,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer): IWordCountResult | undefined { const rate = this.getProgressiveRenderRate(element); const numWordsToRender = renderData.lastRenderTime === 0 ? 1 : @@ -1189,3 +1205,7 @@ class ChatListTreeDataSource implements IAsyncDataSource; updateContent(responsePart: string | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void; asString(): string; @@ -88,8 +88,11 @@ export class ChatRequestModel implements IChatRequestModel { } } +export interface IPlaceholderMarkdownString extends IMarkdownString { + isPlaceholder: boolean; +} -type ResponsePart = { string: IMarkdownString; resolving?: boolean } | { treeData: IChatResponseProgressFileTreeData; resolving?: boolean }; +type ResponsePart = { string: IMarkdownString; isPlaceholder?: boolean } | { treeData: IChatResponseProgressFileTreeData; isPlaceholder?: undefined }; export class Response implements IResponse { private _onDidChangeValue = new Emitter(); public get onDidChangeValue() { @@ -99,11 +102,11 @@ export class Response implements IResponse { // responseParts internally tracks all the response parts, including strings which are currently resolving, so that they can be updated when they do resolve private _responseParts: ResponsePart[]; // responseData externally presents the response parts with consolidated contiguous strings (including strings which were previously resolving) - private _responseData: (IMarkdownString | IChatResponseProgressFileTreeData)[]; + private _responseData: (IMarkdownString | IPlaceholderMarkdownString | IChatResponseProgressFileTreeData)[]; // responseRepr externally presents the response parts with consolidated contiguous strings (excluding tree data) private _responseRepr: string; - get value(): (IMarkdownString | IChatResponseProgressFileTreeData)[] { + get value(): (IMarkdownString | IPlaceholderMarkdownString | IChatResponseProgressFileTreeData)[] { return this._responseData; } @@ -127,7 +130,7 @@ export class Response implements IResponse { const responsePartLength = this._responseParts.length - 1; const lastResponsePart = this._responseParts[responsePartLength]; - if (lastResponsePart.resolving === true || isCompleteInteractiveProgressTreeData(lastResponsePart)) { + if (lastResponsePart.isPlaceholder === true || isCompleteInteractiveProgressTreeData(lastResponsePart)) { // The last part is resolving or a tree data item, start a new part this._responseParts.push({ string: new MarkdownString(responsePart) }); } else { @@ -138,16 +141,16 @@ export class Response implements IResponse { this._updateRepr(quiet); } else if ('placeholder' in responsePart) { // Add a new resolving part - const responsePosition = this._responseParts.push({ string: new MarkdownString(responsePart.placeholder), resolving: true }) - 1; + const responsePosition = this._responseParts.push({ string: new MarkdownString(responsePart.placeholder), isPlaceholder: true }) - 1; this._updateRepr(quiet); responsePart.resolvedContent?.then((content) => { // Replace the resolving part's content with the resolved response if (typeof content === 'string') { - this._responseParts[responsePosition] = { string: new MarkdownString(content), resolving: true }; + this._responseParts[responsePosition] = { string: new MarkdownString(content), isPlaceholder: true }; this._updateRepr(quiet); } else if (content.treeData) { - this._responseParts[responsePosition] = { treeData: content.treeData, resolving: true }; + this._responseParts[responsePosition] = { treeData: content.treeData }; this._updateRepr(quiet); } }); @@ -160,6 +163,8 @@ export class Response implements IResponse { this._responseData = this._responseParts.map(part => { if (isCompleteInteractiveProgressTreeData(part)) { return part.treeData; + } else if (part.isPlaceholder) { + return { ...part.string, isPlaceholder: true }; } return part.string; }); From 702a76bf5da92be1c91954c41b850f9c2f15d5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20Ate=C5=9F=20Uzun?= Date: Wed, 23 Aug 2023 19:16:16 +0300 Subject: [PATCH 1107/1180] fix: localize string typo (#191046) * fix: localize string typo * fix: suffix typo --- .../contrib/extensions/browser/extensionsViews.ts | 2 +- .../contrib/files/browser/views/explorerViewer.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index f8d7c21cea7d6..fc8215dff5bef 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -1431,7 +1431,7 @@ export function getAriaLabelForExtension(extension: IExtension | null): string { if (!extension) { return ''; } - const publisher = extension.publisherDomain?.verified ? localize('extension.arialabel.verifiedPublihser', "Verified Publisher {0}", extension.publisherDisplayName) : localize('extension.arialabel.publihser', "Publisher {0}", extension.publisherDisplayName); + const publisher = extension.publisherDomain?.verified ? localize('extension.arialabel.verifiedPublisher', "Verified Publisher {0}", extension.publisherDisplayName) : localize('extension.arialabel.publisher', "Publisher {0}", extension.publisherDisplayName); const deprecated = extension?.deprecationInfo ? localize('extension.arialabel.deprecated', "Deprecated") : ''; const rating = extension?.rating ? localize('extension.arialabel.rating', "Rated {0} out of 5 stars by {1} users", extension.rating.toFixed(2), extension.ratingCount) : ''; return `${extension.displayName}, ${deprecated ? `${deprecated}, ` : ''}${extension.version}, ${publisher}, ${extension.description} ${rating ? `, ${rating}` : ''}`; diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 6560e68e9a531..a25c052188af3 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1391,11 +1391,11 @@ export class FileDragAndDrop implements ITreeDragAndDrop { const resourceEdit = new ResourceFileEdit(resource, newResource, { copy: true, overwrite: allowOverwrite }); resourceFileEdits.push(resourceEdit); } - const labelSufix = getFileOrFolderLabelSufix(sources); + const labelSuffix = getFileOrFolderLabelSuffix(sources); await this.explorerService.applyBulkEdit(resourceFileEdits, { confirmBeforeUndo: explorerConfig.confirmUndo === UndoConfirmLevel.Default || explorerConfig.confirmUndo === UndoConfirmLevel.Verbose, - undoLabel: localize('copy', "Copy {0}", labelSufix), - progressLabel: localize('copying', "Copying {0}", labelSufix), + undoLabel: localize('copy', "Copy {0}", labelSuffix), + progressLabel: localize('copying', "Copying {0}", labelSuffix), }); const editors = resourceFileEdits.filter(edit => { @@ -1410,11 +1410,11 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // Do not allow moving readonly items const resourceFileEdits = sources.filter(source => !source.isReadonly).map(source => new ResourceFileEdit(source.resource, joinPath(target.resource, source.name))); - const labelSufix = getFileOrFolderLabelSufix(sources); + const labelSuffix = getFileOrFolderLabelSuffix(sources); const options = { confirmBeforeUndo: this.configurationService.getValue().explorer.confirmUndo === UndoConfirmLevel.Verbose, - undoLabel: localize('move', "Move {0}", labelSufix), - progressLabel: localize('moving', "Moving {0}", labelSufix) + undoLabel: localize('move', "Move {0}", labelSuffix), + progressLabel: localize('moving', "Moving {0}", labelSuffix) }; try { @@ -1518,7 +1518,7 @@ export class ExplorerCompressionDelegate implements ITreeCompressionDelegate Date: Wed, 23 Aug 2023 10:18:57 -0700 Subject: [PATCH 1108/1180] =?UTF-8?q?Broken=20`search.action.replace`=20de?= =?UTF-8?q?fault=20mac=20shortcut=20(`=E2=87=A7`+`=E2=8C=98`+`1`)=20(#1911?= =?UTF-8?q?02)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #189866 --- src/vs/workbench/contrib/search/browser/searchView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index d6be8a289987c..07576765667a7 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -903,8 +903,8 @@ export class SearchView extends ViewPane { } let editable = false; - if (focus instanceof MatchInNotebook) { - editable = !focus.isWebviewMatch(); + if (focus instanceof Match) { + editable = (focus instanceof MatchInNotebook) ? !focus.isWebviewMatch() : true; } else if (focus instanceof FileMatch) { editable = !focus.hasOnlyReadOnlyMatches(); } else if (focus instanceof FolderMatch) { From bd67b50dfdf98e56bd79790ab7e2bc5a292ccdb4 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 23 Aug 2023 19:28:19 +0200 Subject: [PATCH 1109/1180] Remove tree item checkbox proposal from tests (#191084) Fixes #191081 --- extensions/vscode-api-tests/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index 9d50e393547ec..a28d4f806aa3e 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -45,8 +45,7 @@ "textSearchProvider", "timeline", "tokenInformation", - "treeItemCheckbox", - "treeViewActiveItem", + "treeViewActiveItem", "treeViewReveal", "workspaceTrust", "telemetry", From 01857efa503aeed4efeada51aded87d742399dee Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 10:29:59 -0700 Subject: [PATCH 1110/1180] allow different keybindings --- .../contrib/terminal/common/terminal.ts | 1 + .../terminal/common/terminalContextKey.ts | 4 +++ .../terminal/common/terminalStrings.ts | 4 +++ .../terminal.accessibility.contribution.ts | 32 +++++++++++++++++-- .../browser/terminalAccessibleBuffer.ts | 2 +- .../browser/terminalAccessibleWidget.ts | 19 +++++++++-- 6 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 77e37c5b5742e..6402859667a04 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -495,6 +495,7 @@ export const enum TerminalCommandId { HideSuggestWidget = 'workbench.action.terminal.hideSuggestWidget', FocusHover = 'workbench.action.terminal.focusHover', ShowEnvironmentContributions = 'workbench.action.terminal.showEnvironmentContributions', + FocusAndHideAccessibleBuffer = 'workbench.action.terminal.focusAndHideAccessibleBuffer', // Developer commands diff --git a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts index 1d480dbd6499b..ce4f7a4168cef 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts @@ -16,6 +16,7 @@ export const enum TerminalContextKeyStrings { Focus = 'terminalFocus', FocusInAny = 'terminalFocusInAny', AccessibleBufferFocus = 'terminalAccessibleBufferFocus', + AccessibleBufferOnLastLine = 'terminalAccessibleBufferOnLastLine', EditorFocus = 'terminalEditorFocus', TabsFocus = 'terminalTabsFocus', WebExtensionContributedProfile = 'terminalWebExtensionContributedProfile', @@ -51,6 +52,9 @@ export namespace TerminalContextKeys { /** Whether the accessible buffer is focused. */ export const accessibleBufferFocus = new RawContextKey(TerminalContextKeyStrings.AccessibleBufferFocus, false, localize('terminalAccessibleBufferFocusContextKey', "Whether the terminal accessible buffer is focused.")); + /** Whether the accessible buffer focus is on the last line. */ + export const accessibleBufferOnLastLine = new RawContextKey(TerminalContextKeyStrings.AccessibleBufferOnLastLine, false, localize('terminalAccessibleBufferOnLastLineContextKey', "Whether the accessible buffer focus is on the last line.")); + /** Whether a terminal in the editor area is focused. */ export const editorFocus = new RawContextKey(TerminalContextKeyStrings.EditorFocus, false, localize('terminalEditorFocusContextKey', "Whether a terminal in the editor area is focused.")); diff --git a/src/vs/workbench/contrib/terminal/common/terminalStrings.ts b/src/vs/workbench/contrib/terminal/common/terminalStrings.ts index 75e281c9f2df3..43b4589df6c08 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalStrings.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalStrings.ts @@ -22,6 +22,10 @@ export const terminalStrings = { value: localize('workbench.action.terminal.focus', "Focus Terminal"), original: 'Focus Terminal' }, + focusAndHideAccessibleBuffer: { + value: localize('workbench.action.terminal.focusAndHideAccessibleBuffer', "Focus Terminal and Hide Accessible Buffer"), + original: 'Focus Terminal and Hide Accessible Buffer' + }, kill: { value: localize('killTerminal', "Kill Terminal"), original: 'Kill Terminal', 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 b69943c18de8c..6fe33fdff356f 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 @@ -11,7 +11,7 @@ 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 { TerminalLocation, 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'; @@ -20,6 +20,7 @@ import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/brow import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { ITerminalProcessManager, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; +import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { TerminalAccessibleContentProvider } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp'; import { AccessibleBufferWidget, NavigationType } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer'; import { TextAreaSyncAddon } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon'; @@ -47,7 +48,7 @@ class TextAreaSyncContribution extends DisposableStore implements ITerminalContr } registerTerminalContribution(TextAreaSyncContribution.ID, TextAreaSyncContribution); -class AccessibleBufferContribution extends DisposableStore implements ITerminalContribution { +export class AccessibleBufferContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.accessible-buffer'; private _xterm: IXtermTerminal & { raw: Terminal } | undefined; static get(instance: ITerminalInstance): AccessibleBufferContribution | null { @@ -83,6 +84,9 @@ class AccessibleBufferContribution extends DisposableStore implements ITerminalC navigateToCommand(type: NavigationType): void { return this._accessibleBufferWidget?.navigateToCommand(type); } + hide(): void { + this._accessibleBufferWidget?.hide(); + } } registerTerminalContribution(AccessibleBufferContribution.ID, AccessibleBufferContribution); @@ -114,6 +118,7 @@ registerTerminalAction({ keybinding: [ { primary: KeyMod.Shift | KeyCode.Tab, + secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow, KeyMod.Alt | KeyCode.F2], weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, TerminalContextKeys.focus, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } @@ -204,3 +209,26 @@ registerTerminalAction({ await AccessibleBufferContribution.get(instance)?.navigateToCommand(NavigationType.Previous); } }); + +registerTerminalAction({ + id: TerminalCommandId.FocusAndHideAccessibleBuffer, + title: terminalStrings.focusAndHideAccessibleBuffer, + f1: false, + keybinding: { + when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, TerminalContextKeys.accessibleBufferOnLastLine), + primary: KeyMod.CtrlCmd | KeyCode.DownArrow, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + const instance = c.service.activeInstance || await c.service.createTerminal({ location: TerminalLocation.Panel }); + if (!instance) { + return; + } + const contribution = instance.getContribution('terminal.accessible-buffer'); + if (contribution) { + contribution.hide(); + } + instance.focus(true); + } +}); diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index fab258f94e6d1..bca9d64d23a2b 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -56,7 +56,7 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { @ITerminalLogService private readonly _logService: ITerminalLogService, @ITerminalService _terminalService: ITerminalService ) { - super(ClassName.AccessibleBuffer, _instance, _xterm, TerminalContextKeys.accessibleBufferFocus, _instantiationService, _modelService, _configurationService, _contextKeyService, _terminalService); + super(ClassName.AccessibleBuffer, _instance, _xterm, TerminalContextKeys.accessibleBufferFocus, TerminalContextKeys.accessibleBufferOnLastLine, _instantiationService, _modelService, _configurationService, _contextKeyService, _terminalService); this._bufferTracker = _instantiationService.createInstance(BufferContentTracker, _xterm); this.element.ariaRoleDescription = localize('terminal.integrated.accessibleBuffer', 'Terminal buffer'); this.updateEditor(); diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index 46a475b67f345..77fd61739349c 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -41,6 +41,7 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { protected _listeners: IDisposable[] = []; private readonly _focusedContextKey?: IContextKey; + private readonly _focusedLastLineContextKey?: IContextKey; private readonly _focusTracker?: dom.IFocusTracker; constructor( @@ -48,6 +49,7 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { protected readonly _instance: Pick, protected readonly _xterm: Pick & { raw: Terminal }, private _focusContextKey: RawContextKey | undefined, + private _focusLastLineContextKey: RawContextKey | undefined, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IModelService private readonly _modelService: IModelService, @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -87,11 +89,22 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._element.replaceChildren(this._editorContainer); this._xtermElement.insertAdjacentElement('beforebegin', this._element); - if (this._focusContextKey) { + if (this._focusContextKey && this._focusLastLineContextKey) { this._focusTracker = this.add(dom.trackFocus(this._editorContainer)); this._focusedContextKey = this._focusContextKey.bindTo(this._contextKeyService); - this.add(this._focusTracker.onDidFocus(() => this._focusedContextKey?.set(true))); - this.add(this._focusTracker.onDidBlur(() => this._focusedContextKey?.reset())); + this._focusedLastLineContextKey = this._focusLastLineContextKey.bindTo(this._contextKeyService); + this.add(this._focusTracker.onDidFocus(() => { + this._focusedContextKey?.set(true); + this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + })); + this.add(this._focusTracker.onDidBlur(() => { + this._focusedContextKey?.reset(); + this._focusedLastLineContextKey?.reset(); + })); + this._editorWidget.onDidChangeCursorPosition(() => { + console.log(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + }); } this.add(Event.runAndSubscribe(this._xterm.raw.onResize, () => this.layout())); From 30907cfef18c34f8d799910712a6194bae8b9a48 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 23 Aug 2023 19:31:51 +0200 Subject: [PATCH 1111/1180] TreeItem.label ignored by resourceUri for untitled editor (#191103) Fixes #189505 --- src/vs/workbench/browser/parts/views/treeView.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index aedd476a89d9d..c5dc8bf57e396 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -1217,7 +1217,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer Date: Wed, 23 Aug 2023 10:32:56 -0700 Subject: [PATCH 1112/1180] fix #189358 --- .../browser/terminal.accessibility.contribution.ts | 3 +-- 1 file changed, 1 insertion(+), 2 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 6fe33fdff356f..61d6cc20f6b77 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 @@ -166,8 +166,7 @@ registerTerminalAction({ weight: KeybindingWeight.WorkbenchContrib + 2 }, { - primary: KeyMod.CtrlCmd | KeyCode.DownArrow, - mac: { primary: KeyMod.Alt | KeyCode.DownArrow }, + primary: KeyMod.Alt | KeyCode.DownArrow, when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), weight: KeybindingWeight.WorkbenchContrib + 2 } From cbc3479604b22f3c573932a46766d43563bb2f06 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 10:41:27 -0700 Subject: [PATCH 1113/1180] Revert "Merge pull request #190776 from microsoft/merogge/delay" This reverts commit 990da210e0e4fc528570ab83d068259766ff4e49, reversing changes made to 1f76cf794b240be23d6135831ed41b160991804f. --- .../accessibility/browser/accessibilityContributions.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts index 80cdebaab8ebb..3d6968b88c40e 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts @@ -282,7 +282,6 @@ export class InlineCompletionsAccessibleViewContribution extends Disposable { this._register(AccessibleViewAction.addImplementation(95, 'inline-completions', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const codeEditorService = accessor.get(ICodeEditorService); - const contextViewService = accessor.get(IContextViewService); const show = () => { const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); if (!editor) { @@ -311,12 +310,10 @@ export class InlineCompletionsAccessibleViewContribution extends Disposable { editor.focus(); }, next() { - contextViewService.hideContextView(); - setTimeout(() => model.next().then(() => show()), 50); + model.next().then(() => show()); }, previous() { - contextViewService.hideContextView(); - setTimeout(() => model.previous().then(() => show()), 50); + model.previous().then(() => show()); }, options: this._options }); From 2ab4a3f547d378d5df7530922bd001376e714795 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 23 Aug 2023 10:41:33 -0700 Subject: [PATCH 1114/1180] tunnels: implement default port forwarding for managed RA's (#191099) * tunnels: implement default port forwarding for managed RA's The default implementation of port forwarding works from the shared process to traditional addressed remote authorities. However, this didn't work with managed remote authorities. Rather than implementing a chain of message passing from the shared process back up to the extension host, this PR reuses the `NodeRemoteTunnel` to provide default forwarding logic in the Node ext host. It also makes the `ManagedSocket` more generic for reuse there. Fixes #190859 * fix * address comments * address comments, fix build * rm import --- .../platform/remote/common/managedSocket.ts | 119 ++++++++++++++++++ src/vs/platform/tunnel/node/tunnelService.ts | 50 +++++--- .../api/browser/mainThreadManagedSockets.ts | 118 +++-------------- .../api/common/extHostExtensionService.ts | 6 +- .../api/common/extHostTunnelService.ts | 21 +++- .../api/node/extHost.node.services.ts | 3 + .../api/node/extHostTunnelService.ts | 112 ++++++++++++++++- .../browser/mainThreadManagedSockets.test.ts | 7 +- 8 files changed, 311 insertions(+), 125 deletions(-) diff --git a/src/vs/platform/remote/common/managedSocket.ts b/src/vs/platform/remote/common/managedSocket.ts index 9cbf5f326e868..0f55617264d9b 100644 --- a/src/vs/platform/remote/common/managedSocket.ts +++ b/src/vs/platform/remote/common/managedSocket.ts @@ -4,6 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { VSBuffer, encodeBase64 } from 'vs/base/common/buffer'; +import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { ISocket, SocketCloseEvent, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; export const makeRawSocketHeaders = (path: string, query: string, deubgLabel: string) => { // https://tools.ietf.org/html/rfc6455#section-4 @@ -24,3 +27,119 @@ export const makeRawSocketHeaders = (path: string, query: string, deubgLabel: st }; export const socketRawEndHeaderSequence = VSBuffer.fromString('\r\n\r\n'); + +export interface RemoteSocketHalf { + onData: Emitter; + onClose: Emitter; + onEnd: Emitter; +} + +/** Should be called immediately after making a ManagedSocket to make it ready for data flow. */ +export async function connectManagedSocket( + socket: T, + path: string, query: string, debugLabel: string, + half: RemoteSocketHalf +): Promise { + socket.write(VSBuffer.fromString(makeRawSocketHeaders(path, query, debugLabel))); + + const d = new DisposableStore(); + try { + return await new Promise((resolve, reject) => { + let dataSoFar: VSBuffer | undefined; + d.add(socket.onData(d_1 => { + if (!dataSoFar) { + dataSoFar = d_1; + } else { + dataSoFar = VSBuffer.concat([dataSoFar, d_1], dataSoFar.byteLength + d_1.byteLength); + } + + const index = dataSoFar.indexOf(socketRawEndHeaderSequence); + if (index === -1) { + return; + } + + resolve(socket); + // pause data events until the socket consumer is hooked up. We may + // immediately emit remaining data, but if not there may still be + // microtasks queued which would fire data into the abyss. + socket.pauseData(); + + const rest = dataSoFar.slice(index + socketRawEndHeaderSequence.byteLength); + if (rest.byteLength) { + half.onData.fire(rest); + } + })); + + d.add(socket.onClose(err => reject(err ?? new Error('socket closed')))); + d.add(socket.onEnd(() => reject(new Error('socket ended')))); + }); + } catch (e) { + socket.dispose(); + throw e; + } finally { + d.dispose(); + } +} + +export abstract class ManagedSocket extends Disposable implements ISocket { + private readonly pausableDataEmitter = this._register(new PauseableEmitter()); + + public onData: Event = (...args) => { + if (this.pausableDataEmitter.isPaused) { + queueMicrotask(() => this.pausableDataEmitter.resume()); + } + return this.pausableDataEmitter.event(...args); + }; + public onClose: Event; + public onEnd: Event; + + private readonly didDisposeEmitter = this._register(new Emitter()); + public onDidDispose = this.didDisposeEmitter.event; + + private ended = false; + + protected constructor( + private readonly debugLabel: string, + half: RemoteSocketHalf, + ) { + super(); + + this._register(half.onData); + this._register(half.onData.event(data => this.pausableDataEmitter.fire(data))); + + this.onClose = this._register(half.onClose).event; + this.onEnd = this._register(half.onEnd).event; + } + + /** Pauses data events until a new listener comes in onData() */ + public pauseData() { + this.pausableDataEmitter.pause(); + } + + /** Flushes data to the socket. */ + public drain(): Promise { + return Promise.resolve(); + } + + /** Ends the remote socket. */ + public end(): void { + this.ended = true; + this.closeRemote(); + } + + public abstract write(buffer: VSBuffer): void; + protected abstract closeRemote(): void; + + traceSocketEvent(type: SocketDiagnosticsEventType, data?: any): void { + SocketDiagnostics.traceSocketEvent(this, this.debugLabel, type, data); + } + + override dispose(): void { + if (!this.ended) { + this.closeRemote(); + } + + this.didDisposeEmitter.fire(); + super.dispose(); + } +} diff --git a/src/vs/platform/tunnel/node/tunnelService.ts b/src/vs/platform/tunnel/node/tunnelService.ts index 50eb82abc61fd..0894400360dfb 100644 --- a/src/vs/platform/tunnel/node/tunnelService.ts +++ b/src/vs/platform/tunnel/node/tunnelService.ts @@ -10,14 +10,15 @@ import { NodeSocket } from 'vs/base/parts/ipc/node/ipc.net'; import { Barrier } from 'vs/base/common/async'; import { Disposable } from 'vs/base/common/lifecycle'; +import { OS } from 'vs/base/common/platform'; +import { ISocket } from 'vs/base/parts/ipc/common/ipc.net'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; -import { connectRemoteAgentTunnel, IAddressProvider, IConnectionOptions } from 'vs/platform/remote/common/remoteAgentConnection'; -import { AbstractTunnelService, isAllInterfaces, ISharedTunnelsService as ISharedTunnelsService, isLocalhost, isPortPrivileged, isTunnelProvider, ITunnelProvider, ITunnelService, RemoteTunnel, TunnelPrivacyId } from 'vs/platform/tunnel/common/tunnel'; -import { ISignService } from 'vs/platform/sign/common/sign'; -import { OS } from 'vs/base/common/platform'; +import { IAddressProvider, IConnectionOptions, connectRemoteAgentTunnel } from 'vs/platform/remote/common/remoteAgentConnection'; import { IRemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService'; +import { ISignService } from 'vs/platform/sign/common/sign'; +import { AbstractTunnelService, ISharedTunnelsService, ITunnelProvider, ITunnelService, RemoteTunnel, TunnelPrivacyId, isAllInterfaces, isLocalhost, isPortPrivileged, isTunnelProvider } from 'vs/platform/tunnel/common/tunnel'; async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost: string, tunnelRemoteHost: string, tunnelRemotePort: number, tunnelLocalPort?: number): Promise { let readyTunnel: NodeRemoteTunnel | undefined; @@ -32,7 +33,7 @@ async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost return readyTunnel!; } -class NodeRemoteTunnel extends Disposable implements RemoteTunnel { +export class NodeRemoteTunnel extends Disposable implements RemoteTunnel { public readonly tunnelRemotePort: number; public tunnelLocalPort!: number; @@ -113,7 +114,7 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { const tunnelRemoteHost = (isLocalhost(this.tunnelRemoteHost) || isAllInterfaces(this.tunnelRemoteHost)) ? 'localhost' : this.tunnelRemoteHost; const protocol = await connectRemoteAgentTunnel(this._options, tunnelRemoteHost, this.tunnelRemotePort); - const remoteSocket = (protocol.getSocket()).socket; + const remoteSocket = protocol.getSocket(); const dataChunk = protocol.readEntireBuffer(); protocol.dispose(); @@ -132,17 +133,19 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { if (localSocket.localAddress) { this._socketsDispose.delete(localSocket.localAddress); } - remoteSocket.destroy(); + if (remoteSocket instanceof NodeSocket) { + remoteSocket.socket.destroy(); + } else { + remoteSocket.end(); + } }); - remoteSocket.on('end', () => localSocket.end()); - remoteSocket.on('close', () => localSocket.end()); - remoteSocket.on('error', () => { - localSocket.destroy(); - }); + if (remoteSocket instanceof NodeSocket) { + this._mirrorNodeSocket(localSocket, remoteSocket); + } else { + this._mirrorGenericSocket(localSocket, remoteSocket); + } - localSocket.pipe(remoteSocket); - remoteSocket.pipe(localSocket); if (localSocket.localAddress) { this._socketsDispose.set(localSocket.localAddress, () => { // Need to end instead of unpipe, otherwise whatever is connected locally could end up "stuck" with whatever state it had until manually exited. @@ -151,6 +154,25 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { }); } } + + private _mirrorGenericSocket(localSocket: net.Socket, remoteSocket: ISocket) { + remoteSocket.onClose(() => localSocket.destroy()); + remoteSocket.onEnd(() => localSocket.end()); + remoteSocket.onData(d => localSocket.write(d.buffer)); + localSocket.resume(); + } + + private _mirrorNodeSocket(localSocket: net.Socket, remoteNodeSocket: NodeSocket) { + const remoteSocket = remoteNodeSocket.socket; + remoteSocket.on('end', () => localSocket.end()); + remoteSocket.on('close', () => localSocket.end()); + remoteSocket.on('error', () => { + localSocket.destroy(); + }); + + remoteSocket.pipe(localSocket); + localSocket.pipe(remoteSocket); + } } export class BaseTunnelService extends AbstractTunnelService { diff --git a/src/vs/workbench/api/browser/mainThreadManagedSockets.ts b/src/vs/workbench/api/browser/mainThreadManagedSockets.ts index dbd5c34ac3e2f..5cae557028cfd 100644 --- a/src/vs/workbench/api/browser/mainThreadManagedSockets.ts +++ b/src/vs/workbench/api/browser/mainThreadManagedSockets.ts @@ -3,15 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MainContext, ExtHostContext, MainThreadManagedSocketsShape, ExtHostManagedSocketsShape } from 'vs/workbench/api/common/extHost.protocol'; -import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; -import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; -import { ManagedRemoteConnection, RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { VSBuffer } from 'vs/base/common/buffer'; +import { Emitter } from 'vs/base/common/event'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { ISocket, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net'; +import { ManagedSocket, RemoteSocketHalf, connectManagedSocket } from 'vs/platform/remote/common/managedSocket'; +import { ManagedRemoteConnection, RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IRemoteSocketFactoryService, ISocketFactory } from 'vs/platform/remote/common/remoteSocketFactoryService'; -import { ISocket, SocketCloseEvent, SocketCloseEventType, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; -import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event'; -import { makeRawSocketHeaders, socketRawEndHeaderSequence } from 'vs/platform/remote/common/managedSocket'; +import { ExtHostContext, ExtHostManagedSocketsShape, MainContext, MainThreadManagedSocketsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; @extHostNamedCustomer(MainContext.MainThreadManagedSockets) export class MainThreadManagedSockets extends Disposable implements MainThreadManagedSocketsShape { @@ -51,7 +51,7 @@ export class MainThreadManagedSockets extends Disposable implements MainThreadMa }; that._remoteSockets.set(socketId, half); - ManagedSocket.connect(socketId, that._proxy, path, query, debugLabel, half) + MainThreadManagedSocket.connect(socketId, that._proxy, path, query, debugLabel, half) .then( socket => { socket.onDidDispose(() => that._remoteSockets.delete(socketId)); @@ -91,117 +91,35 @@ export class MainThreadManagedSockets extends Disposable implements MainThreadMa } } -export interface RemoteSocketHalf { - onData: Emitter; - onClose: Emitter; - onEnd: Emitter; -} - -export class ManagedSocket extends Disposable implements ISocket { +export class MainThreadManagedSocket extends ManagedSocket { public static connect( socketId: number, proxy: ExtHostManagedSocketsShape, path: string, query: string, debugLabel: string, - half: RemoteSocketHalf - ): Promise { - const socket = new ManagedSocket(socketId, proxy, debugLabel, half.onClose, half.onData, half.onEnd); - - socket.write(VSBuffer.fromString(makeRawSocketHeaders(path, query, debugLabel))); - - const d = new DisposableStore(); - return new Promise((resolve, reject) => { - let dataSoFar: VSBuffer | undefined; - d.add(socket.onData(d => { - if (!dataSoFar) { - dataSoFar = d; - } else { - dataSoFar = VSBuffer.concat([dataSoFar, d], dataSoFar.byteLength + d.byteLength); - } - - const index = dataSoFar.indexOf(socketRawEndHeaderSequence); - if (index === -1) { - return; - } - - resolve(socket); - // pause data events until the socket consumer is hooked up. We may - // immediately emit remaining data, but if not there may still be - // microtasks queued which would fire data into the abyss. - socket.pauseData(); - - const rest = dataSoFar.slice(index + socketRawEndHeaderSequence.byteLength); - if (rest.byteLength) { - half.onData.fire(rest); - } - })); - - d.add(socket.onClose(err => reject(err ?? new Error('socket closed')))); - d.add(socket.onEnd(() => reject(new Error('socket ended')))); - }).finally(() => d.dispose()); + ): Promise { + const socket = new MainThreadManagedSocket(socketId, proxy, debugLabel, half); + return connectManagedSocket(socket, path, query, debugLabel, half); } - private readonly pausableDataEmitter = this._register(new PauseableEmitter()); - - public onData: Event = (...args) => { - if (this.pausableDataEmitter.isPaused) { - queueMicrotask(() => this.pausableDataEmitter.resume()); - } - return this.pausableDataEmitter.event(...args); - }; - public onClose: Event; - public onEnd: Event; - - private readonly didDisposeEmitter = this._register(new Emitter()); - public onDidDispose = this.didDisposeEmitter.event; - - private ended = false; - private constructor( private readonly socketId: number, private readonly proxy: ExtHostManagedSocketsShape, - private readonly debugLabel: string, - onCloseEmitter: Emitter, - onDataEmitter: Emitter, - onEndEmitter: Emitter, + debugLabel: string, + half: RemoteSocketHalf, ) { - super(); - - this._register(onDataEmitter); - this._register(onDataEmitter.event(data => this.pausableDataEmitter.fire(data))); - - this.onClose = this._register(onCloseEmitter).event; - this.onEnd = this._register(onEndEmitter).event; + super(debugLabel, half); } - /** Pauses data events until a new listener comes in onData() */ - pauseData() { - this.pausableDataEmitter.pause(); - } - - write(buffer: VSBuffer): void { + public override write(buffer: VSBuffer): void { this.proxy.$remoteSocketWrite(this.socketId, buffer); } - end(): void { - this.ended = true; + protected override closeRemote(): void { this.proxy.$remoteSocketEnd(this.socketId); } - drain(): Promise { + public override drain(): Promise { return this.proxy.$remoteSocketDrain(this.socketId); } - - traceSocketEvent(type: SocketDiagnosticsEventType, data?: any): void { - SocketDiagnostics.traceSocketEvent(this, this.debugLabel, type, data); - } - - override dispose(): void { - if (!this.ended) { - this.proxy.$remoteSocketEnd(this.socketId); - } - - this.didDisposeEmitter.fire(); - super.dispose(); - } } diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 0c35ea254f30b..0a0eebdd8a528 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -861,9 +861,11 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme performance.mark(`code/extHost/willResolveAuthority/${authorityPrefix}`); result = await resolver.resolve(remoteAuthority, { resolveAttempt, execServer }); performance.mark(`code/extHost/didResolveAuthorityOK/${authorityPrefix}`); - // todo@connor4312: we probably need to chain tunnels too, how does this work with 'public' tunnels? logInfo(`setting tunnel factory...`); - this._register(await this._extHostTunnelService.setTunnelFactory(resolver)); + this._register(await this._extHostTunnelService.setTunnelFactory( + resolver, + ExtHostManagedResolvedAuthority.isManagedResolvedAuthority(result) ? result : undefined + )); } else { logInfo(`invoking resolveExecServer() for ${remoteAuthority}`); performance.mark(`code/extHost/willResolveExecServer/${authorityPrefix}`); diff --git a/src/vs/workbench/api/common/extHostTunnelService.ts b/src/vs/workbench/api/common/extHostTunnelService.ts index 34fed87a67759..7040aca80d9da 100644 --- a/src/vs/workbench/api/common/extHostTunnelService.ts +++ b/src/vs/workbench/api/common/extHostTunnelService.ts @@ -54,7 +54,7 @@ export interface IExtHostTunnelService extends ExtHostTunnelServiceShape { openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise; getTunnels(): Promise; onDidChangeTunnels: vscode.Event; - setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise; + setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined, managedRemoteAuthority: vscode.ManagedResolvedAuthority | undefined): Promise; registerPortsAttributesProvider(portSelector: PortAttributesSelector, provider: vscode.PortAttributesProvider): IDisposable; registerTunnelProvider(provider: vscode.TunnelProvider, information: vscode.TunnelInformation): Promise; } @@ -165,7 +165,15 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe })); } - async setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise { + /** + * Applies the tunnel metadata and factory found in the remote authority + * resolver to the tunnel system. + * + * `managedRemoteAuthority` should be be passed if the resolver returned on. + * If this is the case, the tunnel cannot be connected to via a websocket from + * the share process, so a synethic tunnel factory is used as a default. + */ + async setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined, managedRemoteAuthority: vscode.ManagedResolvedAuthority | undefined): Promise { // Do not wait for any of the proxy promises here. // It will delay startup and there is nothing that needs to be waited for. if (provider) { @@ -176,8 +184,9 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe this._showCandidatePort = provider.showCandidatePort; this._proxy.$setCandidateFilter(); } - if (provider.tunnelFactory) { - this._forwardPortProvider = provider.tunnelFactory; + const tunnelFactory = provider.tunnelFactory ?? (managedRemoteAuthority ? this.makeManagedTunnelFactory(managedRemoteAuthority) : undefined); + if (tunnelFactory) { + this._forwardPortProvider = tunnelFactory; let privacyOptions = provider.tunnelFeatures?.privacyOptions ?? []; if (provider.tunnelFeatures?.public && (privacyOptions.length === 0)) { privacyOptions = [ @@ -210,6 +219,10 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe }); } + protected makeManagedTunnelFactory(_authority: vscode.ManagedResolvedAuthority): vscode.RemoteAuthorityResolver['tunnelFactory'] { + return undefined; // may be overridden + } + async $closeTunnel(remote: { host: string; port: number }, silent?: boolean): Promise { if (this._extensionTunnels.has(remote.host)) { const hostMap = this._extensionTunnels.get(remote.host)!; diff --git a/src/vs/workbench/api/node/extHost.node.services.ts b/src/vs/workbench/api/node/extHost.node.services.ts index 9a4ffa8b033bd..582cea087eee2 100644 --- a/src/vs/workbench/api/node/extHost.node.services.ts +++ b/src/vs/workbench/api/node/extHost.node.services.ts @@ -24,6 +24,8 @@ import { NodeExtHostVariableResolverProviderService } from 'vs/workbench/api/nod import { IExtHostVariableResolverProvider } from 'vs/workbench/api/common/extHostVariableResolverService'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { ISignService } from 'vs/platform/sign/common/sign'; +import { SignService } from 'vs/platform/sign/node/signService'; // ######################################################################### // ### ### @@ -34,6 +36,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; registerSingleton(IExtHostExtensionService, ExtHostExtensionService, InstantiationType.Eager); registerSingleton(ILoggerService, ExtHostLoggerService, InstantiationType.Delayed); registerSingleton(ILogService, new SyncDescriptor(ExtHostLogService, [false], true)); +registerSingleton(ISignService, SignService, InstantiationType.Delayed); registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths, InstantiationType.Eager); registerSingleton(IExtHostDebugService, ExtHostDebugService, InstantiationType.Eager); diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts index 56e0de8c85555..561f731654ddc 100644 --- a/src/vs/workbench/api/node/extHostTunnelService.ts +++ b/src/vs/workbench/api/node/extHostTunnelService.ts @@ -4,17 +4,26 @@ *--------------------------------------------------------------------------------------------*/ import { exec } from 'child_process'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { Emitter } from 'vs/base/common/event'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { MovingAverage } from 'vs/base/common/numbers'; import { isLinux } from 'vs/base/common/platform'; import * as resources from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; +import { ISocket, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net'; import { ILogService } from 'vs/platform/log/common/log'; +import { ManagedSocket, RemoteSocketHalf, connectManagedSocket } from 'vs/platform/remote/common/managedSocket'; +import { ManagedRemoteConnection } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { ISignService } from 'vs/platform/sign/common/sign'; import { isAllInterfaces, isLocalhost } from 'vs/platform/tunnel/common/tunnel'; +import { NodeRemoteTunnel } from 'vs/platform/tunnel/node/tunnelService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { ExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService'; import { CandidatePort } from 'vs/workbench/services/remote/common/tunnelModel'; +import * as vscode from 'vscode'; export function getSockets(stdout: string): Record { const lines = stdout.trim().split('\n'); @@ -171,8 +180,9 @@ export class NodeExtHostTunnelService extends ExtHostTunnelService { constructor( @IExtHostRpcService extHostRpc: IExtHostRpcService, - @IExtHostInitDataService initData: IExtHostInitDataService, - @ILogService logService: ILogService + @IExtHostInitDataService private readonly initData: IExtHostInitDataService, + @ILogService logService: ILogService, + @ISignService private readonly signService: ISignService, ) { super(extHostRpc, initData, logService); if (isLinux && initData.remote.isRemote && initData.remote.authority) { @@ -297,4 +307,102 @@ export class NodeExtHostTunnelService extends ExtHostTunnelService { } }); } + + protected override makeManagedTunnelFactory(authority: vscode.ManagedResolvedAuthority): vscode.RemoteAuthorityResolver['tunnelFactory'] { + return async (tunnelOptions) => { + const t = new NodeRemoteTunnel( + { + commit: this.initData.commit, + quality: this.initData.quality, + logService: this.logService, + ipcLogger: null, + // services and address providers have stubs since we don't need + // the connection identification that the renderer process uses + remoteSocketFactoryService: { + _serviceBrand: undefined, + async connect(_connectTo: ManagedRemoteConnection, path: string, query: string, debugLabel: string): Promise { + const result = await authority.makeConnection(); + return ExtHostManagedSocket.connect(result, path, query, debugLabel); + }, + register() { + throw new Error('not implemented'); + }, + }, + addressProvider: { + getAddress() { + return Promise.resolve({ + connectTo: new ManagedRemoteConnection(0), + connectionToken: authority.connectionToken, + }); + }, + }, + signService: this.signService, + }, + 'localhost', + tunnelOptions.remoteAddress.host || 'localhost', + tunnelOptions.remoteAddress.port, + tunnelOptions.localAddressPort, + ); + + await t.waitForReady(); + + const disposeEmitter = new Emitter(); + + return { + localAddress: t.localAddress, + remoteAddress: { port: t.tunnelRemotePort, host: t.tunnelRemoteHost }, + onDidDispose: disposeEmitter.event, + dispose: () => { + t.dispose(); + disposeEmitter.fire(); + disposeEmitter.dispose(); + }, + }; + }; + } +} + +class ExtHostManagedSocket extends ManagedSocket { + public static connect( + passing: vscode.ManagedMessagePassing, + path: string, query: string, debugLabel: string, + ): Promise { + const d = new DisposableStore(); + const half: RemoteSocketHalf = { + onClose: d.add(new Emitter()), + onData: d.add(new Emitter()), + onEnd: d.add(new Emitter()), + }; + + d.add(passing.onDidReceiveMessage(d => half.onData.fire(VSBuffer.wrap(d)))); + d.add(passing.onDidEnd(() => half.onEnd.fire())); + d.add(passing.onDidClose(error => half.onClose.fire({ + type: SocketCloseEventType.NodeSocketCloseEvent, + error, + hadError: !!error + }))); + + const socket = new ExtHostManagedSocket(passing, debugLabel, half); + socket._register(d); + return connectManagedSocket(socket, path, query, debugLabel, half); + } + + constructor( + private readonly passing: vscode.ManagedMessagePassing, + debugLabel: string, + half: RemoteSocketHalf, + ) { + super(debugLabel, half); + } + + public override write(buffer: VSBuffer): void { + this.passing.send(buffer.buffer); + } + protected override closeRemote(): void { + this.passing.end(); + } + + public override async drain(): Promise { + await this.passing.drain?.(); + } } diff --git a/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts b/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts index 611ec9727c04d..6eb1c08ad6546 100644 --- a/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts @@ -10,7 +10,8 @@ import { Emitter } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { SocketCloseEvent } from 'vs/base/parts/ipc/common/ipc.net'; import { mock } from 'vs/base/test/common/mock'; -import { ManagedSocket, RemoteSocketHalf } from 'vs/workbench/api/browser/mainThreadManagedSockets'; +import { RemoteSocketHalf } from 'vs/platform/remote/common/managedSocket'; +import { MainThreadManagedSocket } from 'vs/workbench/api/browser/mainThreadManagedSockets'; import { ExtHostManagedSocketsShape } from 'vs/workbench/api/common/extHost.protocol'; suite('MainThreadManagedSockets', () => { @@ -68,7 +69,7 @@ suite('MainThreadManagedSockets', () => { }); async function doConnect() { - const socket = ManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); + const socket = MainThreadManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); await extHost.expectEvent(evt => evt.data && evt.data.startsWith('GET ws://localhost/hello?world=true&skipWebSocketFrames=true HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key:'), 'websocket open event'); half.onData.fire(VSBuffer.fromString('Opened successfully ;)\r\n\r\n')); return await socket; @@ -79,7 +80,7 @@ suite('MainThreadManagedSockets', () => { }); test('includes trailing connection data', async () => { - const socketProm = ManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); + const socketProm = MainThreadManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); await extHost.expectEvent(evt => evt.data && evt.data.includes('GET ws://localhost'), 'websocket open event'); half.onData.fire(VSBuffer.fromString('Opened successfully ;)\r\n\r\nSome trailing data')); const socket = await socketProm; From ccf71f1571c764f6144e89f17a599d179f37a3d0 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 10:43:20 -0700 Subject: [PATCH 1115/1180] try to fix timing issue --- .../accessibility/browser/accessibilityContributions.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts index 3d6968b88c40e..1baf82143d41e 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts @@ -310,10 +310,12 @@ export class InlineCompletionsAccessibleViewContribution extends Disposable { editor.focus(); }, next() { - model.next().then(() => show()); + model.next(); + setTimeout(() => show(), 50); }, previous() { - model.previous().then(() => show()); + model.previous(); + setTimeout(() => show(), 50); }, options: this._options }); From c08c2a789bb3b943e338b5132a81494bb0fbc29a Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Wed, 23 Aug 2023 20:19:44 +0200 Subject: [PATCH 1116/1180] ignore unexpected dom nodes (#191113) Fixes #169854: ignore surprising dom nodes --- src/vs/editor/browser/controller/mouseTarget.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 0215f9031a6df..b39b8f95ba601 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -198,6 +198,13 @@ class ElementPath { ); } + public static isChildOfOverflowGuard(path: Uint8Array): boolean { + return ( + path.length >= 1 + && path[0] === PartFingerprint.OverflowGuard + ); + } + public static isChildOfOverflowingContentWidgets(path: Uint8Array): boolean { return ( path.length >= 1 @@ -538,6 +545,11 @@ export class MouseTargetFactory { let result: IMouseTarget | null = null; + if (!ElementPath.isChildOfOverflowGuard(request.targetPath) && !ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) { + // We only render dom nodes inside the overflow guard or in the overflowing content widgets + result = result || request.fulfillUnknown(); + } + result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest); result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest); result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest); From 82643e93f57fe752a587c0537fe4866e2d44eddf Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Wed, 23 Aug 2023 11:28:35 -0700 Subject: [PATCH 1117/1180] Changed action widget header ellipses (#191096) changed from ellipses to semi-colons --- .../contrib/codeAction/browser/codeActionMenu.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 0f645908a5ff6..fc33e04fdd0ae 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -22,13 +22,13 @@ interface ActionGroup { const uncategorizedCodeActionGroup = Object.freeze({ kind: CodeActionKind.Empty, title: localize('codeAction.widget.id.more', 'More Actions...') }); const codeActionGroups = Object.freeze([ - { kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix...') }, - { kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move...'), icon: Codicon.wrench }, - { kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With...'), icon: Codicon.symbolSnippet }, - { kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action...'), icon: Codicon.symbolFile }, + { kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix:') }, + { kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move:'), icon: Codicon.wrench }, + { kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With:'), icon: Codicon.symbolSnippet }, + { kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action:'), icon: Codicon.symbolFile }, uncategorizedCodeActionGroup, ]); From c9481326e71e5a842f1addf0cbd181cdb1749d11 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 23 Aug 2023 20:33:30 +0200 Subject: [PATCH 1118/1180] Use full line decorations for comment range (#191107) Fixes #188901 --- .../workbench/contrib/comments/browser/commentColors.ts | 2 -- .../comments/browser/commentThreadRangeDecorator.ts | 6 ++++-- .../workbench/contrib/comments/browser/media/review.css | 9 --------- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/comments/browser/commentColors.ts b/src/vs/workbench/contrib/comments/browser/commentColors.ts index bfc70a8a2470c..a300a745a56e3 100644 --- a/src/vs/workbench/contrib/comments/browser/commentColors.ts +++ b/src/vs/workbench/contrib/comments/browser/commentColors.ts @@ -15,9 +15,7 @@ const unresolvedCommentViewIcon = registerColor('commentsView.unresolvedIcon', { const resolvedCommentBorder = registerColor('editorCommentsWidget.resolvedBorder', { dark: resolvedCommentViewIcon, light: resolvedCommentViewIcon, hcDark: contrastBorder, hcLight: contrastBorder }, nls.localize('resolvedCommentBorder', 'Color of borders and arrow for resolved comments.')); const unresolvedCommentBorder = registerColor('editorCommentsWidget.unresolvedBorder', { dark: unresolvedCommentViewIcon, light: unresolvedCommentViewIcon, hcDark: contrastBorder, hcLight: contrastBorder }, nls.localize('unresolvedCommentBorder', 'Color of borders and arrow for unresolved comments.')); export const commentThreadRangeBackground = registerColor('editorCommentsWidget.rangeBackground', { dark: transparent(unresolvedCommentBorder, .1), light: transparent(unresolvedCommentBorder, .1), hcDark: transparent(unresolvedCommentBorder, .1), hcLight: transparent(unresolvedCommentBorder, .1) }, nls.localize('commentThreadRangeBackground', 'Color of background for comment ranges.')); -export const commentThreadRangeBorder = registerColor('editorCommentsWidget.rangeBorder', { dark: transparent(unresolvedCommentBorder, .4), light: transparent(unresolvedCommentBorder, .4), hcDark: transparent(unresolvedCommentBorder, .4), hcLight: transparent(unresolvedCommentBorder, .4) }, nls.localize('commentThreadRangeBorder', 'Color of border for comment ranges.')); export const commentThreadRangeActiveBackground = registerColor('editorCommentsWidget.rangeActiveBackground', { dark: transparent(unresolvedCommentBorder, .1), light: transparent(unresolvedCommentBorder, .1), hcDark: transparent(unresolvedCommentBorder, .1), hcLight: transparent(unresolvedCommentBorder, .1) }, nls.localize('commentThreadActiveRangeBackground', 'Color of background for currently selected or hovered comment range.')); -export const commentThreadRangeActiveBorder = registerColor('editorCommentsWidget.rangeActiveBorder', { dark: transparent(unresolvedCommentBorder, .4), light: transparent(unresolvedCommentBorder, .4), hcDark: transparent(unresolvedCommentBorder, .4), hcLight: transparent(unresolvedCommentBorder, .2) }, nls.localize('commentThreadActiveRangeBorder', 'Color of border for currently selected or hovered comment range.')); const commentThreadStateBorderColors = new Map([ [languages.CommentThreadState.Unresolved, unresolvedCommentBorder], diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts b/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts index 0c9828613d236..182a5f3b39741 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts @@ -44,7 +44,8 @@ export class CommentThreadRangeDecorator extends Disposable { description: CommentThreadRangeDecorator.description, isWholeLine: false, zIndex: 20, - className: 'comment-thread-range' + className: 'comment-thread-range', + shouldFillLineOnLineBreak: true }; this.decorationOptions = ModelDecorationOptions.createDynamic(decorationOptions); @@ -53,7 +54,8 @@ export class CommentThreadRangeDecorator extends Disposable { description: CommentThreadRangeDecorator.description, isWholeLine: false, zIndex: 20, - className: 'comment-thread-range-current' + className: 'comment-thread-range-current', + shouldFillLineOnLineBreak: true }; this.activeDecorationOptions = ModelDecorationOptions.createDynamic(activeDecorationOptions); diff --git a/src/vs/workbench/contrib/comments/browser/media/review.css b/src/vs/workbench/contrib/comments/browser/media/review.css index dc27b9a50ae0f..87c845189d8b9 100644 --- a/src/vs/workbench/contrib/comments/browser/media/review.css +++ b/src/vs/workbench/contrib/comments/browser/media/review.css @@ -487,21 +487,12 @@ div.preview.inline .monaco-editor .comment-range-glyph { background: var(--vscode-editorGutter-commentRangeForeground); } -.monaco-editor .comment-thread-range, -.monaco-editor .comment-thread-range-current { - border-width: 1px; - border-style: solid; - box-sizing: border-box; -} - .monaco-editor .comment-thread-range { background-color: var(--vscode-editorCommentsWidget-rangeBackground); - border-color: var(--vscode-editorCommentsWidget-rangeBorder); } .monaco-editor .comment-thread-range-current { background-color: var(--vscode-editorCommentsWidget-rangeActiveBackground); - border-color: var(--vscode-editorCommentsWidget-rangeActiveBorder); } .monaco-editor .margin-view-overlays .comment-range-glyph.line-hover, From 4e628263ac4b553c6c044bd30762886542a3164d Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 23 Aug 2023 11:37:09 -0700 Subject: [PATCH 1119/1180] Add quick search to command center (#191105) * Add quick search to command center Fixes #191088 * Adjust commandCenterOrder * Update src/vs/workbench/contrib/search/browser/search.contribution.ts Co-authored-by: Tyler James Leonhardt --------- Co-authored-by: Tyler James Leonhardt --- .../contrib/search/browser/search.contribution.ts | 10 ++++++++-- .../search/browser/searchActionsTextQuickAccess.ts | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index a48332a48f29c..2f9b6d54d73b8 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -128,8 +128,14 @@ quickAccessRegistry.registerQuickAccessProvider({ ctor: TextSearchQuickAccess, prefix: TEXT_SEARCH_QUICK_ACCESS_PREFIX, contextKey: 'inTextSearchPicker', - placeholder: nls.localize('textSearchPickerPlaceholder', "Search for text in your workspace files."), - helpEntries: [{ description: nls.localize('textSearchPickerHelp', "Show All Text Results (experimental)"), commandId: Constants.QuickTextSearchActionId }] + placeholder: nls.localize('textSearchPickerPlaceholder', "Search for text in your workspace files (experimental)."), + helpEntries: [ + { + description: nls.localize('textSearchPickerHelp', "Search for Text (Experimental)"), + commandId: Constants.QuickTextSearchActionId, + commandCenterOrder: 65, + } + ] }); // Configuration diff --git a/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts b/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts index ebf0558987d2f..3971c1f112c96 100644 --- a/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts @@ -18,8 +18,8 @@ registerAction2(class TextSearchQuickAccessAction extends Action2 { super({ id: Constants.QuickTextSearchActionId, title: { - value: nls.localize('quickTextSearch', "Quick Text Search"), - original: 'Quick Text Search' + value: nls.localize('quickTextSearch', "Quick Text Search (Experimental)"), + original: 'Quick Text Search (Experimental)' }, category, menu: [{ From a8c87ea06b83205ced3c733c64def35e562a089b Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 11:52:23 -0700 Subject: [PATCH 1120/1180] also go to previous --- .../browser/terminal.accessibility.contribution.ts | 3 +-- 1 file changed, 1 insertion(+), 2 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 61d6cc20f6b77..4eb13c439a680 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 @@ -193,8 +193,7 @@ registerTerminalAction({ weight: KeybindingWeight.WorkbenchContrib + 2 }, { - primary: KeyMod.CtrlCmd | KeyCode.UpArrow, - mac: { primary: KeyMod.Alt | KeyCode.UpArrow }, + primary: KeyMod.Alt | KeyCode.UpArrow, when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), weight: KeybindingWeight.WorkbenchContrib + 2 } From ca8d21f30bc6ba83f8d37fc1af851c5596b7ab41 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 11:56:49 -0700 Subject: [PATCH 1121/1180] add to commands to skip shell --- 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 6402859667a04..46692bccd1be5 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -570,6 +570,7 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [ TerminalCommandId.HideSuggestWidget, TerminalCommandId.FocusHover, AccessibilityCommandId.OpenAccessibilityHelp, + TerminalCommandId.FocusAndHideAccessibleBuffer, 'editor.action.toggleTabFocusMode', 'notifications.hideList', 'notifications.hideToasts', From fe71c9a5eba39efa9bcc9c80fa8928e496842dbe Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 12:48:54 -0700 Subject: [PATCH 1122/1180] fix #188926 --- .../browser/terminalAccessibleBuffer.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index fab258f94e6d1..3e1d2ad466d16 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -14,6 +14,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { ICurrentPartialCommand } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; import { ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; @@ -91,9 +92,9 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { this._resetPosition(); } - private _getEditorLineForCommand(command: ITerminalCommand): number | undefined { - let line = command.marker?.line; - if (line === undefined || !command.command.length || line < 0) { + private _getEditorLineForCommand(command: ITerminalCommand | ICurrentPartialCommand): number | undefined { + let line = 'marker' in command ? command.marker?.line : 'commandStartMarker' in command ? command.commandStartMarker?.line : undefined; + if (line === undefined || line < 0) { return; } line = this._bufferTracker.bufferToEditorLineMapping.get(line); @@ -105,6 +106,7 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { private _getCommandsWithEditorLine(): ICommandWithEditorLine[] | undefined { const commands = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.commands; + const currentCommand = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.currentCommand; if (!commands?.length) { return; } @@ -116,6 +118,12 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } result.push({ command, lineNumber }); } + if (currentCommand) { + const lineNumber = this._getEditorLineForCommand(currentCommand); + if (!!lineNumber) { + result.push({ command: currentCommand, lineNumber }); + } + } return result; } @@ -135,7 +143,7 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { { label: localize('terminal.integrated.symbolQuickPick.labelNoExitCode', '{0}', command.command), lineNumber, - exitCode: command.exitCode + exitCode: 'exitCode' in command ? command.exitCode : undefined }); } const quickPick = this._quickInputService.createQuickPick(); @@ -261,5 +269,5 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } } -interface ICommandWithEditorLine { command: ITerminalCommand; lineNumber: number } +interface ICommandWithEditorLine { command: ITerminalCommand | ICurrentPartialCommand; lineNumber: number } From 330fb1f905f91294f9fe124bcba8a154ec96dc54 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:37:12 -0700 Subject: [PATCH 1123/1180] Handle right arrow on quick search menu (#191115) Fixes #191110 --- .../quickTextSearch/textSearchQuickAccess.ts | 67 +++++++++++++------ .../contrib/search/browser/searchView.ts | 2 +- .../contrib/search/common/constants.ts | 2 +- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts index 15a82a6cf6a44..d17d209b9b1e4 100644 --- a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts @@ -7,22 +7,26 @@ import { IMatch } from 'vs/base/common/filters'; import { DisposableStore } 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'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; 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 { IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { IKeyMods, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IWorkbenchQuickAccessConfiguration } from 'vs/workbench/browser/quickaccess'; +import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { IViewsService } from 'vs/workbench/common/views'; import { searchDetailsIcon, searchOpenInFileIcon } from 'vs/workbench/contrib/search/browser/searchIcons'; import { FileMatch, Match, MatchInNotebook, RenderableMatch, SearchModel, searchComparer } from 'vs/workbench/contrib/search/browser/searchModel'; import { SearchView, getEditorSelectionFromMatch } from 'vs/workbench/contrib/search/browser/searchView'; -import { getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search'; -import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IWorkbenchSearchConfiguration, getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search'; +import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/services/search/common/queryBuilder'; -import { IPatternInfo, ISearchConfigurationProperties, ITextQuery, VIEW_ID } from 'vs/workbench/services/search/common/search'; +import { IPatternInfo, ITextQuery, VIEW_ID } from 'vs/workbench/services/search/common/search'; export const TEXT_SEARCH_QUICK_ACCESS_PREFIX = '% '; @@ -46,8 +50,8 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider('search'); + private get configuration() { + const editorConfig = this._configurationService.getValue().workbench?.editor; + const searchConfig = this._configurationService.getValue().search; + const quickAccessConfig = this._configurationService.getValue().workbench.quickOpen; + + return { + openEditorPinned: !editorConfig?.enablePreviewFromQuickOpen || !editorConfig?.enablePreview, + preserveInput: quickAccessConfig.preserveInput, + maxResults: searchConfig.maxResults, + smartCase: searchConfig.smartCase, + }; } private doSearch(contentPattern: string, token: CancellationToken): { @@ -170,11 +183,7 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { - await this._editorService.openEditor({ - resource: fileMatch.resource, - options - }, ACTIVE_GROUP); - }, + accept: async (keyMods, event) => { + await this.handleAccept(fileMatch, { + keyMods, + selection: getEditorSelectionFromMatch(element, this.searchModel), + preserveFocus: event.inBackground, + forcePinned: event.inBackground, + indexedCellOptions: element instanceof MatchInNotebook ? { index: element.cellIndex, selection: element.range() } : undefined + }); + } }); } } return picks; } + + private async handleAccept(fileMatch: FileMatch, options: { keyMods?: IKeyMods; selection?: ITextEditorSelection; preserveFocus?: boolean; range?: IRange; forcePinned?: boolean; forceOpenSideBySide?: boolean; indexedCellOptions?: { index: number; selection?: Range } }): Promise { + const editorOptions = { + preserveFocus: options.preserveFocus, + pinned: options.keyMods?.ctrlCmd || options.forcePinned || this.configuration.openEditorPinned, + selection: options.selection + }; + + // from https://github.com/microsoft/vscode/blob/f40dabca07a1622b2a0ae3ee741cfc94ab964bef/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts#L1037 + const targetGroup = options.keyMods?.alt || (this.configuration.openEditorPinned && options.keyMods?.ctrlCmd) || options.forceOpenSideBySide ? SIDE_GROUP : ACTIVE_GROUP; + + await this._editorService.openEditor({ + resource: fileMatch.resource, + options: editorOptions + }, targetGroup); + } + protected _getPicks(contentPattern: string, disposables: DisposableStore, token: CancellationToken): Picks | Promise | FastAndSlowPicks> | FastAndSlowPicks | null { const allMatches = this.doSearch(contentPattern, token); diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 07576765667a7..4cdc0341049a9 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -1894,7 +1894,7 @@ export class SearchView extends ViewPane { pinned, selection, revealIfVisible: true, - indexedCellOptions: element instanceof MatchInNotebook ? { cellIndex: element.cellIndex, selection: element.range } : undefined, + indexedCellOptions: element instanceof MatchInNotebook ? { index: element.cellIndex, selection: element.range() } : undefined, }; try { diff --git a/src/vs/workbench/contrib/search/common/constants.ts b/src/vs/workbench/contrib/search/common/constants.ts index d6e4fd9d7a99d..1f98bc77b3575 100644 --- a/src/vs/workbench/contrib/search/common/constants.ts +++ b/src/vs/workbench/contrib/search/common/constants.ts @@ -30,7 +30,7 @@ export const AddCursorsAtSearchResults = 'addCursorsAtSearchResults'; export const RevealInSideBarForSearchResults = 'search.action.revealInSideBar'; export const ReplaceInFilesActionId = 'workbench.action.replaceInFiles'; export const ShowAllSymbolsActionId = 'workbench.action.showAllSymbols'; -export const QuickTextSearchActionId = 'workbench.action.quickTextSearch'; +export const QuickTextSearchActionId = 'workbench.action.experimental.quickTextSearch'; export const CancelSearchActionId = 'search.action.cancel'; export const RefreshSearchResultsActionId = 'search.action.refreshSearchResults'; export const FocusNextSearchResultActionId = 'search.action.focusNextSearchResult'; From 9b9b9d57917db6495d9e49255682a03173933abe Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 13:41:33 -0700 Subject: [PATCH 1124/1180] use correct line number --- .../accessibility/browser/textAreaSyncAddon.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index 666f27389d9ff..379d6965b0acb 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -91,23 +91,22 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { return; } const buffer = this._terminal.buffer.active; - const line = buffer.getLine(buffer.cursorY)?.translateToString(true); + const lineNumber = currentCommand.commandStartMarker?.line; + if (!lineNumber) { + return; + } + const line = buffer.getLine(lineNumber)?.translateToString(true); if (!line) { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - if (currentCommand.commandStartX !== undefined) { - // Left prompt + if (!!currentCommand.commandStartX) { this._currentCommand = line.substring(currentCommand.commandStartX); this._cursorX = buffer.cursorX - currentCommand.commandStartX; - } else if (currentCommand.commandRightPromptStartX !== undefined) { - // Right prompt - this._currentCommand = line.substring(0, currentCommand.commandRightPromptStartX); - this._cursorX = buffer.cursorX; } else { this._currentCommand = undefined; this._cursorX = undefined; - this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: neither commandStartX nor commandRightPromptStartX`); + this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no commandStartX`); } } } From f96904ece94d72dc9b42db69444fdcf84608d80a Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 13:47:57 -0700 Subject: [PATCH 1125/1180] don't use messy inline --- .../accessibility/browser/terminalAccessibleBuffer.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index 3e1d2ad466d16..0835367c86e5b 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -93,7 +93,12 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } private _getEditorLineForCommand(command: ITerminalCommand | ICurrentPartialCommand): number | undefined { - let line = 'marker' in command ? command.marker?.line : 'commandStartMarker' in command ? command.commandStartMarker?.line : undefined; + let line: number | undefined; + if ('marker' in command) { + line = command.marker?.line; + } else if ('commandStartMarker' in command) { + line = command.commandStartMarker?.line; + } if (line === undefined || line < 0) { return; } From eca80ba5f50d404a09e7b02c1bbf24bb94211069 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 23 Aug 2023 13:49:01 -0700 Subject: [PATCH 1126/1180] better names --- .../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 379d6965b0acb..9916a6f60d08c 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -95,13 +95,13 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { if (!lineNumber) { return; } - const line = buffer.getLine(lineNumber)?.translateToString(true); - if (!line) { + const commandLine = buffer.getLine(lineNumber)?.translateToString(true); + if (!commandLine) { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } if (!!currentCommand.commandStartX) { - this._currentCommand = line.substring(currentCommand.commandStartX); + this._currentCommand = commandLine.substring(currentCommand.commandStartX); this._cursorX = buffer.cursorX - currentCommand.commandStartX; } else { this._currentCommand = undefined; From 557695b920d4779d63e80d9d1597dc57d9b2a7c2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 23 Aug 2023 14:10:55 -0700 Subject: [PATCH 1127/1180] Fix inlay hint location (#191122) --- .../src/languageFeatures/inlayHints.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts index 5363619579bf5..1b9d554688d88 100644 --- a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts +++ b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts @@ -77,7 +77,7 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin return response.body.map(hint => { const result = new vscode.InlayHint( Position.fromLocation(hint.position), - this.convertInlayHintText(model.uri, hint), + this.convertInlayHintText(hint), hint.kind && fromProtocolInlayHintKind(hint.kind) ); result.paddingLeft = hint.whitespaceBefore; @@ -86,19 +86,18 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin }); } - private convertInlayHintText(resource: vscode.Uri, tsHint: Proto.InlayHintItem): string | vscode.InlayHintLabelPart[] { + private convertInlayHintText(tsHint: Proto.InlayHintItem): string | vscode.InlayHintLabelPart[] { if (tsHint.displayParts) { return tsHint.displayParts.map((part): vscode.InlayHintLabelPart => { const out = new vscode.InlayHintLabelPart(part.text); if (part.span) { - out.location = Location.fromTextSpan(resource, part.span); + out.location = Location.fromTextSpan(this.client.toResource(part.span.file), part.span); } return out; }); } return tsHint.text; - } } From f605341af6b083f2b6d9c853d882b96955c690b7 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 23 Aug 2023 23:17:23 +0200 Subject: [PATCH 1128/1180] Syntax highlighting incorrect in vscode.python for the word 'file' (#191111) * Syntax highlighting incorrect in vscode.python for the word 'file' Fixes #188190 * Update colorization test --- extensions/theme-defaults/themes/dark_vs.json | 1 + .../theme-defaults/themes/hc_black.json | 3 +- .../theme-defaults/themes/hc_light.json | 6 +++- .../theme-defaults/themes/light_vs.json | 3 +- .../themes/kimbie-dark-color-theme.json | 3 +- .../themes/dimmed-monokai-color-theme.json | 3 +- .../themes/monokai-color-theme.json | 3 +- .../themes/quietlight-color-theme.json | 3 +- .../theme-red/themes/Red-color-theme.json | 3 +- .../themes/solarized-dark-color-theme.json | 3 +- .../themes/solarized-light-color-theme.json | 3 +- .../tomorrow-night-blue-color-theme.json | 3 +- .../test/colorize-results/test_py.json | 32 +++++++++---------- 13 files changed, 42 insertions(+), 27 deletions(-) diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 21af2d3cf3abd..2b9f0d5a5ab7b 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -34,6 +34,7 @@ "meta.embedded", "source.groovy.embedded", "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#D4D4D4" diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index 26dadd320a0b1..816fbf9395add 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -19,7 +19,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#FFFFFF" diff --git a/extensions/theme-defaults/themes/hc_light.json b/extensions/theme-defaults/themes/hc_light.json index fde5393f070d6..17c1af9ef346c 100644 --- a/extensions/theme-defaults/themes/hc_light.json +++ b/extensions/theme-defaults/themes/hc_light.json @@ -3,7 +3,11 @@ "name": "Light High Contrast", "tokenColors": [ { - "scope": ["meta.embedded", "source.groovy.embedded"], + "scope": [ + "meta.embedded", + "source.groovy.embedded", + "variable.legacy.builtin.python" + ], "settings": { "foreground": "#292929" } diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index 301730e078e93..5e2d5a7889e9f 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -38,7 +38,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#000000ff" diff --git a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json index eeb4eeb6b881b..3554c486209b8 100644 --- a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json +++ b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json @@ -64,7 +64,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#d3af86" diff --git a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json index ea84bededd50b..691680512a48f 100644 --- a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json +++ b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json @@ -71,7 +71,8 @@ { "scope": [ "meta.embedded", - "source.groovy.embedded" + "source.groovy.embedded", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#C5C8C6" diff --git a/extensions/theme-monokai/themes/monokai-color-theme.json b/extensions/theme-monokai/themes/monokai-color-theme.json index 6489b0dd39c33..9a51074871465 100644 --- a/extensions/theme-monokai/themes/monokai-color-theme.json +++ b/extensions/theme-monokai/themes/monokai-color-theme.json @@ -111,7 +111,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#F8F8F2" diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json index 9d55f2e362bc7..3705ed486088d 100644 --- a/extensions/theme-quietlight/themes/quietlight-color-theme.json +++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#333333" diff --git a/extensions/theme-red/themes/Red-color-theme.json b/extensions/theme-red/themes/Red-color-theme.json index c139400dc562d..233fd9e83da27 100644 --- a/extensions/theme-red/themes/Red-color-theme.json +++ b/extensions/theme-red/themes/Red-color-theme.json @@ -70,7 +70,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#F8F8F8" diff --git a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json index e10c6e6740335..e67135a9d99ce 100644 --- a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json +++ b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#839496" diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json index 8b4074c9a072d..d5f6dc11bf036 100644 --- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json +++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#657B83" diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index 8e24e6fe4de03..b0bdf8e90a9fa 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -70,7 +70,8 @@ "meta.embedded", "source.groovy.embedded", "meta.jsx.children", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { //"background": "#002451", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json index e858cd5f2013f..e8d718cad729f 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json @@ -1907,14 +1907,14 @@ "c": "reduce", "t": "source.python meta.function-call.python variable.legacy.builtin.python", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "variable.legacy.builtin.python: #D4D4D4", + "light_plus": "variable.legacy.builtin.python: #000000", + "dark_vs": "variable.legacy.builtin.python: #D4D4D4", + "light_vs": "variable.legacy.builtin.python: #000000", + "hc_black": "variable.legacy.builtin.python: #FFFFFF", + "dark_modern": "variable.legacy.builtin.python: #D4D4D4", + "hc_light": "variable.legacy.builtin.python: #292929", + "light_modern": "variable.legacy.builtin.python: #000000" } }, { @@ -6233,14 +6233,14 @@ "c": "raw_input", "t": "source.python meta.function-call.python variable.legacy.builtin.python", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "variable.legacy.builtin.python: #D4D4D4", + "light_plus": "variable.legacy.builtin.python: #000000", + "dark_vs": "variable.legacy.builtin.python: #D4D4D4", + "light_vs": "variable.legacy.builtin.python: #000000", + "hc_black": "variable.legacy.builtin.python: #FFFFFF", + "dark_modern": "variable.legacy.builtin.python: #D4D4D4", + "hc_light": "variable.legacy.builtin.python: #292929", + "light_modern": "variable.legacy.builtin.python: #000000" } }, { From 9f9ac662035fb28bac3d373d1385f2f0cf24143f Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:35:50 -0700 Subject: [PATCH 1129/1180] notebook-related bugfixes for quick search (#191130) --- .../quickTextSearch/textSearchQuickAccess.ts | 4 ++++ .../contrib/search/browser/searchModel.ts | 21 +++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts index d17d209b9b1e4..d01ad5ad73bbf 100644 --- a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts @@ -230,6 +230,10 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider | Promise | FastAndSlowPicks> | FastAndSlowPicks | null { + if (contentPattern === '') { + this.searchModel.searchResult.clear(); + return []; + } const allMatches = this.doSearch(contentPattern, token); if (!allMatches) { diff --git a/src/vs/workbench/contrib/search/browser/searchModel.ts b/src/vs/workbench/contrib/search/browser/searchModel.ts index 95a4644baf44f..0d8c8ec06c093 100644 --- a/src/vs/workbench/contrib/search/browser/searchModel.ts +++ b/src/vs/workbench/contrib/search/browser/searchModel.ts @@ -1142,13 +1142,16 @@ export class FolderMatch extends Disposable { raw.forEach(rawFileMatch => { const existingFileMatch = this.getDownstreamFileMatch(rawFileMatch.resource); if (existingFileMatch) { - rawFileMatch - .results! - .filter(resultIsMatch) - .forEach(m => { - textSearchResultToMatches(m, existingFileMatch) - .forEach(m => existingFileMatch.add(m)); - }); + + if (rawFileMatch.results) { + rawFileMatch + .results + .filter(resultIsMatch) + .forEach(m => { + textSearchResultToMatches(m, existingFileMatch) + .forEach(m => existingFileMatch.add(m)); + }); + } // add cell matches if (isIFileMatchWithCells(rawFileMatch)) { @@ -2009,7 +2012,7 @@ export class SearchModel extends Disposable { } { const asyncGenerateOnProgress = async (p: ISearchProgressItem) => { progressEmitter.fire(); - this.onSearchProgress(p, searchInstanceID); + this.onSearchProgress(p, searchInstanceID, false); onProgress?.(p); }; @@ -2020,7 +2023,7 @@ export class SearchModel extends Disposable { }; const tokenSource = this.currentCancelTokenSource = new CancellationTokenSource(callerToken); - const notebookResult = this.notebookSearchService.notebookSearch(query, tokenSource.token, searchInstanceID, syncGenerateOnProgress); + const notebookResult = this.notebookSearchService.notebookSearch(query, tokenSource.token, searchInstanceID, asyncGenerateOnProgress); const textResult = this.searchService.textSearchSplitSyncAsync( searchQuery, this.currentCancelTokenSource.token, asyncGenerateOnProgress, From d91da92c704ab5a054a12566a7c147853e13ed47 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 23 Aug 2023 14:36:39 -0700 Subject: [PATCH 1130/1180] testing: fix treatment of first child test items (#191131) Fixes #190976 --- .../testing/browser/explorerProjections/treeProjection.ts | 4 ++-- .../workbench/contrib/testing/browser/testingExplorerView.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts index fe492af83eb78..3e67da4150b87 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts @@ -224,7 +224,7 @@ export class TreeProjection extends Disposable implements ITestTreeProjection { } // The first element will cause the root to be hidden - const affectsRootElement = toRemove.parent?.children.size === 1; + const affectsRootElement = toRemove.depth === 1 && toRemove.parent?.children.size === 1; this.changedParents.add(affectsRootElement ? null : toRemove.parent); const queue: Iterable[] = [[toRemove]]; @@ -302,7 +302,7 @@ export class TreeProjection extends Disposable implements ITestTreeProjection { this.items.set(treeElement.test.item.extId, treeElement); // The first element will cause the root to be shown - const affectsRootElement = treeElement.parent?.children.size === 1; + const affectsRootElement = treeElement.depth === 1 && treeElement.parent?.children.size === 1; this.changedParents.add(affectsRootElement ? null : treeElement.parent); if (treeElement.depth === 0 || isCollapsedInSerializedTestTree(this.lastState, treeElement.test.item.extId) === false) { diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index 5080d93ece256..84e09da8c8f98 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -993,7 +993,7 @@ class TestingExplorerViewModel extends Disposable { this.projection.value = this.instantiationService.createInstance(TreeProjection, lastState); } - const scheduler = new RunOnceScheduler(() => this.applyProjectionChanges(), 200); + const scheduler = this._register(new RunOnceScheduler(() => this.applyProjectionChanges(), 200)); this.projection.value.onUpdate(() => { if (!scheduler.isScheduled()) { scheduler.schedule(); From 7b707177921e2ee40ffcb277544673b16532806e Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 23 Aug 2023 15:13:21 -0700 Subject: [PATCH 1131/1180] Fix #190631. Emit outline change event. (#191135) --- .../notebook/browser/contrib/outline/notebookOutline.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts index 36a8c18f69bc5..cf6589b6027c2 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts @@ -208,6 +208,7 @@ export class NotebookCellOutline implements IOutline { } private _outlineProvider: NotebookCellOutlineProvider | undefined; + private _localDisposables = new DisposableStore(); constructor( private readonly _editor: INotebookEditorPane, @@ -221,9 +222,14 @@ export class NotebookCellOutline implements IOutline { if (!notebookEditor?.hasModel()) { this._outlineProvider?.dispose(); this._outlineProvider = undefined; + this._localDisposables.clear(); } else { this._outlineProvider?.dispose(); + this._localDisposables.clear(); this._outlineProvider = instantiationService.createInstance(NotebookCellOutlineProvider, notebookEditor, _target); + this._localDisposables.add(this._outlineProvider.onDidChange(e => { + this._onDidChange.fire(e); + })); } }; @@ -231,8 +237,6 @@ export class NotebookCellOutline implements IOutline { installSelectionListener(); })); - - installSelectionListener(); const treeDataSource: IDataSource = { getChildren: parent => parent instanceof NotebookCellOutline ? (this._outlineProvider?.entries ?? []) : parent.children }; const delegate = new NotebookOutlineVirtualDelegate(); @@ -315,6 +319,7 @@ export class NotebookCellOutline implements IOutline { this._dispoables.dispose(); this._entriesDisposables.dispose(); this._outlineProvider?.dispose(); + this._localDisposables.dispose(); } } From bf9604c5687aba630ec949738f4e683a042e6b0c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 23 Aug 2023 15:15:07 -0700 Subject: [PATCH 1132/1180] Add event for when inlay hints are provided (#191134) --- .../src/languageFeatures/inlayHints.ts | 39 ++++++++++++++----- .../src/languageProvider.ts | 2 +- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts index 1b9d554688d88..4fa38e4986b9a 100644 --- a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts +++ b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import { DocumentSelector } from '../configuration/documentSelector'; import { LanguageDescription } from '../configuration/languageDescription'; +import { TelemetryReporter } from '../logging/telemetry'; import { API } from '../tsServer/api'; import type * as Proto from '../tsServer/protocol/protocol'; import { Location, Position } from '../typeConverters'; @@ -29,13 +30,16 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin public static readonly minVersion = API.v440; - private readonly _onDidChangeInlayHints = new vscode.EventEmitter(); + private readonly _onDidChangeInlayHints = this._register(new vscode.EventEmitter()); public readonly onDidChangeInlayHints = this._onDidChangeInlayHints.event; + private hasReportedTelemetry = false; + constructor( private readonly language: LanguageDescription, private readonly client: ITypeScriptServiceClient, - private readonly fileConfigurationManager: FileConfigurationManager + private readonly fileConfigurationManager: FileConfigurationManager, + private readonly telemetryReporter: TelemetryReporter, ) { super(); @@ -54,31 +58,47 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin })); } - async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { + async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { const filepath = this.client.toOpenTsFilePath(model); if (!filepath) { - return []; + return; } if (!areInlayHintsEnabledForFile(this.language, model)) { - return []; + return; } const start = model.offsetAt(range.start); const length = model.offsetAt(range.end) - start; await this.fileConfigurationManager.ensureConfigurationForDocument(model, token); + if (token.isCancellationRequested) { + return; + } + + if (!this.hasReportedTelemetry) { + this.hasReportedTelemetry = true; + /* __GDPR__ + "inlayHints.provide" : { + "owner": "mjbvz", + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.telemetryReporter.logTelemetry('inlayHints.provide', {}); + } const response = await this.client.execute('provideInlayHints', { file: filepath, start, length }, token); if (response.type !== 'response' || !response.success || !response.body) { - return []; + return; } return response.body.map(hint => { const result = new vscode.InlayHint( Position.fromLocation(hint.position), this.convertInlayHintText(hint), - hint.kind && fromProtocolInlayHintKind(hint.kind) + fromProtocolInlayHintKind(hint.kind) ); result.paddingLeft = hint.whitespaceBefore; result.paddingRight = hint.whitespaceAfter; @@ -127,13 +147,14 @@ export function register( selector: DocumentSelector, language: LanguageDescription, client: ITypeScriptServiceClient, - fileConfigurationManager: FileConfigurationManager + fileConfigurationManager: FileConfigurationManager, + telemetryReporter: TelemetryReporter, ) { return conditionalRegistration([ requireMinVersion(client, TypeScriptInlayHintsProvider.minVersion), requireSomeCapability(client, ClientCapability.Semantic), ], () => { - const provider = new TypeScriptInlayHintsProvider(language, client, fileConfigurationManager); + const provider = new TypeScriptInlayHintsProvider(language, client, fileConfigurationManager, telemetryReporter); return vscode.languages.registerInlayHintsProvider(selector.semantic, provider); }); } diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 1de34c6998ce5..7acbf733f0cea 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -74,7 +74,7 @@ export default class LanguageProvider extends Disposable { import('./languageFeatures/formatting').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), import('./languageFeatures/hover').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager))), import('./languageFeatures/implementations').then(provider => this._register(provider.register(selector, this.client))), - import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), + import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager, this.telemetryReporter))), import('./languageFeatures/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), import('./languageFeatures/linkedEditing').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))), From 60c8cb0be41b6f666418564013d1e39ac26d514d Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 23 Aug 2023 15:19:38 -0700 Subject: [PATCH 1133/1180] Re #183449. Roaming kernel history. --- .../notebookKernelHistoryServiceImpl.ts | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts index 7256ad1d404b7..0a19cda94bfe8 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { LinkedMap, Touch } from 'vs/base/common/map'; import { localize } from 'vs/nls'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; @@ -36,6 +36,9 @@ export class NotebookKernelHistoryService extends Disposable implements INoteboo this._loadState(); this._register(this._storageService.onWillSaveState(() => this._saveState())); + this._register(this._storageService.onDidChangeValue(StorageScope.WORKSPACE, NotebookKernelHistoryService.STORAGE_KEY, this._register(new DisposableStore()))(() => { + this._restoreState(); + })); } getKernels(notebook: INotebookTextModelLike): { selected: INotebookKernel | undefined; all: INotebookKernel[] } { @@ -79,12 +82,28 @@ export class NotebookKernelHistoryService extends Disposable implements INoteboo if (notEmpty) { const serialized = this._serialize(); - this._storageService.store(NotebookKernelHistoryService.STORAGE_KEY, JSON.stringify(serialized), StorageScope.WORKSPACE, StorageTarget.MACHINE); + this._storageService.store(NotebookKernelHistoryService.STORAGE_KEY, JSON.stringify(serialized), StorageScope.WORKSPACE, StorageTarget.USER); } else { this._storageService.remove(NotebookKernelHistoryService.STORAGE_KEY, StorageScope.WORKSPACE); } } + private _restoreState(): void { + const serialized = this._storageService.get(NotebookKernelHistoryService.STORAGE_KEY, StorageScope.WORKSPACE); + if (serialized) { + try { + for (const [viewType, kernels] of JSON.parse(serialized)) { + const linkedMap = this._mostRecentKernelsMap[viewType] ?? new LinkedMap(); + for (const entry of kernels.entries) { + linkedMap.set(entry, entry, Touch.AsOld); + } + } + } catch (e) { + console.error('Deserialize notebook kernel history failed', e); + } + } + } + private _loadState(): void { const serialized = this._storageService.get(NotebookKernelHistoryService.STORAGE_KEY, StorageScope.WORKSPACE); if (serialized) { From e4a2928d14b38a67e334a120d447ded29e0f562c Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 23 Aug 2023 15:47:35 -0700 Subject: [PATCH 1134/1180] bump distro (#191139) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 584247e9fa406..2e5dcf01a2eb8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "1591281180fd2cd18935e6847131d2d4213b7b69", + "distro": "56bfb9ce4a8d2298f475a1b8d9c7a7b5a72204f2", "author": { "name": "Microsoft Corporation" }, From b82a7222adc865e8a27b1b14c1fd11ab2900f23e Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 23 Aug 2023 15:49:45 -0700 Subject: [PATCH 1135/1180] Fix chat response file tree border radius (#191142) --- .../workbench/contrib/chat/browser/chatListRenderer.css | 8 -------- src/vs/workbench/contrib/chat/browser/media/chat.css | 8 ++++++-- 2 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 src/vs/workbench/contrib/chat/browser/chatListRenderer.css diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.css b/src/vs/workbench/contrib/chat/browser/chatListRenderer.css deleted file mode 100644 index 49c3ab7833ce2..0000000000000 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.css +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.interactive-response-progress-tree .monaco-tl-row:hover { - background-color: var(--vscode-list-hoverBackground); -} diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index ab5e3bd6c59fb..33b798459ea46 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -436,8 +436,6 @@ .interactive-response-progress-tree { margin: 16px 0px; - border-radius: 4px; - border: 1px solid var(--vscode-input-border, transparent); } .interactive-response-progress-tree.focused { @@ -458,3 +456,9 @@ align-items: start; gap: 6px; } + +.interactive-response-progress-tree .monaco-list .monaco-scrollable-element .monaco-list-rows { + border: 1px solid var(--vscode-input-border,transparent); + border-radius: 4px; + width: auto; +} From 9a69c2ab7ca5e81f513a00179b717a8b9bc2217a Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 23 Aug 2023 16:03:45 -0700 Subject: [PATCH 1136/1180] One Provider per Type (#191136) Simpler design due to feedback from Logan. --- .../browser/mainThreadAiRelatedInformation.ts | 11 ++++--- .../workbench/api/common/extHost.api.impl.ts | 4 +-- .../workbench/api/common/extHost.protocol.ts | 4 +-- .../api/common/extHostAiRelatedInformation.ts | 11 ++++--- .../common/aiRelatedInformation.ts | 12 ++++---- .../common/aiRelatedInformationService.ts | 29 +++++++++---------- .../vscode.proposed.aiRelatedInformation.d.ts | 27 +++++------------ 7 files changed, 41 insertions(+), 57 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts b/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts index b198f41be47c9..e254b5f4149fc 100644 --- a/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts +++ b/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts @@ -7,9 +7,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; import { ExtHostAiRelatedInformationShape, ExtHostContext, MainContext, MainThreadAiRelatedInformationShape } from 'vs/workbench/api/common/extHost.protocol'; import { RelatedInformationType } from 'vs/workbench/api/common/extHostTypes'; -import { IAiRelatedInformationProvider, IAiRelatedInformationService } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; +import { IAiRelatedInformationProvider, IAiRelatedInformationService, RelatedInformationResult } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; -import { RelatedInformationResult } from 'vscode'; @extHostNamedCustomer(MainContext.MainThreadAiRelatedInformation) export class MainThreadAiRelatedInformation extends Disposable implements MainThreadAiRelatedInformationShape { @@ -29,13 +28,13 @@ export class MainThreadAiRelatedInformation extends Disposable implements MainTh return this._aiRelatedInformationService.getRelatedInformation(query, types, CancellationToken.None); } - $registerAiRelatedInformationProvider(handle: number, types: RelatedInformationType[]): void { + $registerAiRelatedInformationProvider(handle: number, type: RelatedInformationType): void { const provider: IAiRelatedInformationProvider = { - provideAiRelatedInformation: (query, types, token) => { - return this._proxy.$provideAiRelatedInformation(handle, query, types, token); + provideAiRelatedInformation: (query, token) => { + return this._proxy.$provideAiRelatedInformation(handle, query, token); }, }; - this._registrations.set(handle, this._aiRelatedInformationService.registerAiRelatedInformationProvider(types, provider)); + this._registrations.set(handle, this._aiRelatedInformationService.registerAiRelatedInformationProvider(type, provider)); } $unregisterAiRelatedInformationProvider(handle: number): void { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index f9803e1476f3c..acdb35b1b1e25 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1332,9 +1332,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension, 'aiRelatedInformation'); return extHostAiRelatedInformation.getRelatedInformation(extension, query, types); }, - registerRelatedInformationProvider(types: vscode.RelatedInformationType[], provider: vscode.RelatedInformationProvider) { + registerRelatedInformationProvider(type: vscode.RelatedInformationType, provider: vscode.RelatedInformationProvider) { checkProposedApiEnabled(extension, 'aiRelatedInformation'); - return extHostAiRelatedInformation.registerRelatedInformationProvider(extension, types, provider); + return extHostAiRelatedInformation.registerRelatedInformationProvider(extension, type, provider); }, registerEmbeddingVectorProvider(model: string, provider: vscode.EmbeddingVectorProvider) { checkProposedApiEnabled(extension, 'aiRelatedInformation'); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 93826ca0f5f02..37e0b6c9ba944 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1675,12 +1675,12 @@ export interface MainThreadSemanticSimilarityShape extends IDisposable { } export interface ExtHostAiRelatedInformationShape { - $provideAiRelatedInformation(handle: number, query: string, types: RelatedInformationType[], token: CancellationToken): Promise; + $provideAiRelatedInformation(handle: number, query: string, token: CancellationToken): Promise; } export interface MainThreadAiRelatedInformationShape { $getAiRelatedInformation(query: string, types: RelatedInformationType[]): Promise; - $registerAiRelatedInformationProvider(handle: number, types: RelatedInformationType[]): void; + $registerAiRelatedInformationProvider(handle: number, type: RelatedInformationType): void; $unregisterAiRelatedInformationProvider(handle: number): void; } diff --git a/src/vs/workbench/api/common/extHostAiRelatedInformation.ts b/src/vs/workbench/api/common/extHostAiRelatedInformation.ts index 9dc39e42ae1cd..4cb934e1b1e28 100644 --- a/src/vs/workbench/api/common/extHostAiRelatedInformation.ts +++ b/src/vs/workbench/api/common/extHostAiRelatedInformation.ts @@ -5,7 +5,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ExtHostAiRelatedInformationShape, IMainContext, MainContext, MainThreadAiRelatedInformationShape } from 'vs/workbench/api/common/extHost.protocol'; -import type { CancellationToken, RelatedInformationProvider, RelatedInformationResult, RelatedInformationType } from 'vscode'; +import type { CancellationToken, RelatedInformationProvider, RelatedInformationType, RelatedInformationResult } from 'vscode'; import { Disposable } from 'vs/workbench/api/common/extHostTypes'; export class ExtHostRelatedInformation implements ExtHostAiRelatedInformationShape { @@ -18,7 +18,7 @@ export class ExtHostRelatedInformation implements ExtHostAiRelatedInformationSha this._proxy = mainContext.getProxy(MainContext.MainThreadAiRelatedInformation); } - async $provideAiRelatedInformation(handle: number, query: string, types: RelatedInformationType[], token: CancellationToken): Promise { + async $provideAiRelatedInformation(handle: number, query: string, token: CancellationToken): Promise { if (this._relatedInformationProviders.size === 0) { throw new Error('No semantic similarity providers registered'); } @@ -28,8 +28,7 @@ export class ExtHostRelatedInformation implements ExtHostAiRelatedInformationSha throw new Error('Semantic similarity provider not found'); } - // TODO: should this return undefined or an empty array? - const result = await provider.provideRelatedInformation(query, types, token) ?? []; + const result = await provider.provideRelatedInformation(query, token) ?? []; return result; } @@ -37,11 +36,11 @@ export class ExtHostRelatedInformation implements ExtHostAiRelatedInformationSha return this._proxy.$getAiRelatedInformation(query, types); } - registerRelatedInformationProvider(extension: IExtensionDescription, types: RelatedInformationType[], provider: RelatedInformationProvider): Disposable { + registerRelatedInformationProvider(extension: IExtensionDescription, type: RelatedInformationType, provider: RelatedInformationProvider): Disposable { const handle = this._nextHandle; this._nextHandle++; this._relatedInformationProviders.set(handle, provider); - this._proxy.$registerAiRelatedInformationProvider(handle, types); + this._proxy.$registerAiRelatedInformationProvider(handle, type); return new Disposable(() => { this._proxy.$unregisterAiRelatedInformationProvider(handle); this._relatedInformationProviders.delete(handle); diff --git a/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts index a8bddf2c1e4be..f3b7d9a090fc8 100644 --- a/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts +++ b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts @@ -16,29 +16,31 @@ export enum RelatedInformationType { SettingInformation = 4 } -export interface RelatedInformationResult { +interface RelatedInformationBaseResult { type: RelatedInformationType; weight: number; } -export interface CommandInformationResult extends RelatedInformationResult { +export interface CommandInformationResult extends RelatedInformationBaseResult { type: RelatedInformationType.CommandInformation; command: string; } -export interface SettingInformationResult extends RelatedInformationResult { +export interface SettingInformationResult extends RelatedInformationBaseResult { type: RelatedInformationType.SettingInformation; setting: string; } +export type RelatedInformationResult = CommandInformationResult | SettingInformationResult; + export interface IAiRelatedInformationService { readonly _serviceBrand: undefined; isEnabled(): boolean; getRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): Promise; - registerAiRelatedInformationProvider(types: RelatedInformationType[], provider: IAiRelatedInformationProvider): IDisposable; + registerAiRelatedInformationProvider(type: RelatedInformationType, provider: IAiRelatedInformationProvider): IDisposable; } export interface IAiRelatedInformationProvider { - provideAiRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): Promise; + provideAiRelatedInformation(query: string, token: CancellationToken): Promise; } diff --git a/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts index e0309ff37d164..7168c3b4eede1 100644 --- a/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts +++ b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts @@ -24,24 +24,21 @@ export class AiRelatedInformationService implements IAiRelatedInformationService return this._providers.size > 0; } - registerAiRelatedInformationProvider(types: RelatedInformationType[], provider: IAiRelatedInformationProvider): IDisposable { - for (const type of types) { - const providers = this._providers.get(type) ?? []; - providers.push(provider); - this._providers.set(type, providers); - } + registerAiRelatedInformationProvider(type: RelatedInformationType, provider: IAiRelatedInformationProvider): IDisposable { + const providers = this._providers.get(type) ?? []; + providers.push(provider); + this._providers.set(type, providers); + return { dispose: () => { - for (const type of types) { - const providers = this._providers.get(type) ?? []; - const index = providers.indexOf(provider); - if (index !== -1) { - providers.splice(index, 1); - } - if (providers.length === 0) { - this._providers.delete(type); - } + const providers = this._providers.get(type) ?? []; + const index = providers.indexOf(provider); + if (index !== -1) { + providers.splice(index, 1); + } + if (providers.length === 0) { + this._providers.delete(type); } } }; @@ -78,7 +75,7 @@ export class AiRelatedInformationService implements IAiRelatedInformationService for (const provider of providers) { cancellablePromises.push(createCancelablePromise(async t => { try { - const result = await provider.provideAiRelatedInformation(query, types, t); + const result = await provider.provideAiRelatedInformation(query, t); // double filter just in case return result.filter(r => types.includes(r.type)); } catch (e) { diff --git a/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts b/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts index d3916c50608d3..e5e28653cec62 100644 --- a/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts +++ b/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts @@ -7,13 +7,6 @@ declare module 'vscode' { // https://github.com/microsoft/vscode/issues/190909 - export interface SearchResult { - // from Andrea - preview: string; - resource: Uri; - location: Range; - } - export enum RelatedInformationType { SymbolInformation = 1, CommandInformation = 2, @@ -21,33 +14,27 @@ declare module 'vscode' { SettingInformation = 4 } - export interface RelatedInformationResult { + interface RelatedInformationBaseResult { type: RelatedInformationType; weight: number; } - export interface SymbolInformationResult extends RelatedInformationResult { - type: RelatedInformationType.SymbolInformation; - symbolInformation: SymbolInformation; - } + // TODO: Symbols and Search - export interface CommandInformationResult extends RelatedInformationResult { + export interface CommandInformationResult extends RelatedInformationBaseResult { type: RelatedInformationType.CommandInformation; command: string; } - export interface SettingInformationResult extends RelatedInformationResult { + export interface SettingInformationResult extends RelatedInformationBaseResult { type: RelatedInformationType.SettingInformation; setting: string; } - export interface SearchInformationResult extends RelatedInformationResult { - type: RelatedInformationType.SearchInformation; - searchResult: SearchResult; - } + export type RelatedInformationResult = CommandInformationResult | SettingInformationResult; export interface RelatedInformationProvider { - provideRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): ProviderResult; + provideRelatedInformation(query: string, token: CancellationToken): ProviderResult; } export interface EmbeddingVectorProvider { @@ -56,7 +43,7 @@ declare module 'vscode' { export namespace ai { export function getRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): Thenable; - export function registerRelatedInformationProvider(types: RelatedInformationType[], provider: RelatedInformationProvider): Disposable; + export function registerRelatedInformationProvider(type: RelatedInformationType, provider: RelatedInformationProvider): Disposable; export function registerEmbeddingVectorProvider(model: string, provider: EmbeddingVectorProvider): Disposable; } } From ba35c622b06307173c04184e0e270673d750a4d2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 23 Aug 2023 16:26:51 -0700 Subject: [PATCH 1137/1180] Allow InteractiveProgressContent to return a markdown string (#191145) This allows enabling of specific command uris in responses --- src/vs/workbench/api/browser/mainThreadChat.ts | 7 ++++--- .../workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostChat.ts | 4 ++++ .../contrib/chat/browser/chatListRenderer.ts | 9 +++++---- .../workbench/contrib/chat/common/chatModel.ts | 18 +++++++++++------- .../contrib/chat/common/chatService.ts | 2 +- .../contrib/chat/common/chatServiceImpl.ts | 2 +- .../vscode.proposed.interactive.d.ts | 2 +- 8 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadChat.ts b/src/vs/workbench/api/browser/mainThreadChat.ts index ddeba6f997b57..6b45f16279627 100644 --- a/src/vs/workbench/api/browser/mainThreadChat.ts +++ b/src/vs/workbench/api/browser/mainThreadChat.ts @@ -5,6 +5,7 @@ import { DeferredPromise } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; +import { IMarkdownString } from 'vs/base/common/htmlContent'; import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; import { revive } from 'vs/base/common/marshalling'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -19,13 +20,13 @@ import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/ext export class MainThreadChat extends Disposable implements MainThreadChatShape { private readonly _providerRegistrations = this._register(new DisposableMap()); - private readonly _activeRequestProgressCallbacks = new Map (DeferredPromise | void)>(); + private readonly _activeRequestProgressCallbacks = new Map (DeferredPromise | void)>(); private readonly _stateEmitters = new Map>(); private readonly _proxy: ExtHostChatShape; private _responsePartHandlePool = 0; - private readonly _activeResponsePartPromises = new Map>(); + private readonly _activeResponsePartPromises = new Map>(); constructor( extHostContext: IExtHostContext, @@ -134,7 +135,7 @@ export class MainThreadChat extends Disposable implements MainThreadChatShape { if ('placeholder' in progress) { const responsePartId = `${id}_${++this._responsePartHandlePool}`; - const deferredContentPromise = new DeferredPromise(); + const deferredContentPromise = new DeferredPromise(); this._activeResponsePartPromises.set(responsePartId, deferredContentPromise); this._activeRequestProgressCallbacks.get(id)?.({ ...progress, resolvedContent: deferredContentPromise.p }); return this._responsePartHandlePool; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 37e0b6c9ba944..e4964fb5670a0 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1216,7 +1216,7 @@ export interface IChatResponseProgressFileTreeData { children?: IChatResponseProgressFileTreeData[]; } -export type IChatResponseProgressDto = { content: string } | { requestId: string } | { placeholder: string } | { treeData: IChatResponseProgressFileTreeData }; +export type IChatResponseProgressDto = { content: string | IMarkdownString } | { requestId: string } | { placeholder: string } | { treeData: IChatResponseProgressFileTreeData }; export interface MainThreadChatShape extends IDisposable { $registerChatProvider(handle: number, id: string): Promise; diff --git a/src/vs/workbench/api/common/extHostChat.ts b/src/vs/workbench/api/common/extHostChat.ts index db4f90727ba5e..9aa2c625cc9ac 100644 --- a/src/vs/workbench/api/common/extHostChat.ts +++ b/src/vs/workbench/api/common/extHostChat.ts @@ -232,6 +232,10 @@ export class ExtHostChat implements ExtHostChatShape { const [progressHandle, progressContent] = res; this._proxy.$acceptResponseProgress(handle, sessionId, progressContent, progressHandle ?? undefined); }); + } else if ('content' in progress) { + this._proxy.$acceptResponseProgress(handle, sessionId, { + content: typeof progress.content === 'string' ? progress.content : typeConvert.MarkdownString.from(progress.content) + }); } else { this._proxy.$acceptResponseProgress(handle, sessionId, progress); } diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index dad24e99b6060..e6ec6bd3ae881 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -316,12 +316,12 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer, element: ChatTreeItem, index: number, templateData: IChatListItemTemplate) { const fillInIncompleteTokens = isResponseVM(element) && (!element.isComplete || element.isCanceled || element.errorDetails?.responseIsFiltered || element.errorDetails?.responseIsIncomplete); dom.clearNode(templateData.value); let fileTreeIndex = 0; - for (const data of markdownValue) { + for (const data of value) { const result = 'value' in data ? this.renderMarkdown(data, element, templateData.elementDisposables, templateData, fillInIncompleteTokens) : this.renderTreeData(data, element, templateData.elementDisposables, templateData, fileTreeIndex++); @@ -577,8 +577,9 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer; - updateContent(responsePart: string | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void; + updateContent(responsePart: string | IMarkdownString | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void; asString(): string; } @@ -125,17 +125,21 @@ export class Response implements IResponse { return this._responseRepr; } - updateContent(responsePart: string | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void { - if (typeof responsePart === 'string') { + updateContent(responsePart: string | IMarkdownString | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void { + if (typeof responsePart === 'string' || isMarkdownString(responsePart)) { const responsePartLength = this._responseParts.length - 1; const lastResponsePart = this._responseParts[responsePartLength]; if (lastResponsePart.isPlaceholder === true || isCompleteInteractiveProgressTreeData(lastResponsePart)) { // The last part is resolving or a tree data item, start a new part - this._responseParts.push({ string: new MarkdownString(responsePart) }); + this._responseParts.push({ string: typeof responsePart === 'string' ? new MarkdownString(responsePart) : responsePart }); } else { // Combine this part with the last, non-resolving string part - this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart) }; + if (isMarkdownString(responsePart)) { + this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart.value, responsePart) }; + } else { + this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart, lastResponsePart.string) }; + } } this._updateRepr(quiet); @@ -250,7 +254,7 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel this._id = 'response_' + ChatResponseModel.nextId++; } - updateContent(responsePart: string | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean) { + updateContent(responsePart: string | IMarkdownString | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean) { this._response.updateContent(responsePart, quiet); } diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 2812120dccdd6..9039dfb51509e 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -52,7 +52,7 @@ export interface IChatResponseProgressFileTreeData { } export type IChatProgress = - { content: string } | { requestId: string } | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent: Promise }; + { content: string | IMarkdownString } | { requestId: string } | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent: Promise }; export interface IPersistedChatState { } export interface IChatProvider { diff --git a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts index ae621f87f693a..bd759fd4c9491 100644 --- a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts @@ -450,7 +450,7 @@ export class ChatService extends Disposable implements IChatService { gotProgress = true; if ('content' in progress) { - this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`); + this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${typeof progress.content === 'string' ? progress.content.length : progress.content.value.length} chars`); } else if ('placeholder' in progress) { this.trace('sendRequest', `Provider returned placeholder for session ${model.sessionId}, ${progress.placeholder}`); } else if (isCompleteInteractiveProgressTreeData(progress)) { diff --git a/src/vscode-dts/vscode.proposed.interactive.d.ts b/src/vscode-dts/vscode.proposed.interactive.d.ts index 382afeb82776b..8ec16060be1a5 100644 --- a/src/vscode-dts/vscode.proposed.interactive.d.ts +++ b/src/vscode-dts/vscode.proposed.interactive.d.ts @@ -121,7 +121,7 @@ declare module 'vscode' { } export interface InteractiveProgressContent { - content: string; + content: string | MarkdownString; } export interface InteractiveProgressId { From f7a7d9488fe56fba0851a9f53ab203a5136a799c Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 23 Aug 2023 16:47:31 -0700 Subject: [PATCH 1138/1180] cli: serve-web listener improvements (#191146) - Allow listening on a socket path (required manually implementing the Accept trait), fixes #191043 - Parse the host syntax correctly, fixes #191067 --- cli/src/async_pipe.rs | 55 ++++++++++++++++++++++++++++++- cli/src/commands/args.rs | 3 ++ cli/src/commands/serve_web.rs | 62 +++++++++++++++++++++-------------- 3 files changed, 94 insertions(+), 26 deletions(-) diff --git a/cli/src/async_pipe.rs b/cli/src/async_pipe.rs index 6c7c918967af6..e9b710c1d6815 100644 --- a/cli/src/async_pipe.rs +++ b/cli/src/async_pipe.rs @@ -6,6 +6,8 @@ use crate::{constants::APPLICATION_NAME, util::errors::CodeError}; use async_trait::async_trait; use std::path::{Path, PathBuf}; +use std::pin::Pin; +use std::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite}; use tokio::net::TcpListener; use uuid::Uuid; @@ -44,7 +46,7 @@ cfg_if::cfg_if! { } else { use tokio::{time::sleep, io::ReadBuf}; use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions, NamedPipeClient, NamedPipeServer}; - use std::{time::Duration, pin::Pin, task::{Context, Poll}, io}; + use std::{time::Duration, io}; use pin_project::pin_project; #[pin_project(project = AsyncPipeProj)] @@ -174,6 +176,57 @@ cfg_if::cfg_if! { } } +impl AsyncPipeListener { + pub fn into_pollable(self) -> PollableAsyncListener { + PollableAsyncListener { + listener: Some(self), + write_fut: tokio_util::sync::ReusableBoxFuture::new(make_accept_fut(None)), + } + } +} + +pub struct PollableAsyncListener { + listener: Option, + write_fut: tokio_util::sync::ReusableBoxFuture< + 'static, + (AsyncPipeListener, Result), + >, +} + +async fn make_accept_fut( + data: Option, +) -> (AsyncPipeListener, Result) { + match data { + Some(mut l) => { + let c = l.accept().await; + (l, c) + } + None => unreachable!("this future should not be pollable in this state"), + } +} + +impl hyper::server::accept::Accept for PollableAsyncListener { + type Conn = AsyncPipe; + type Error = CodeError; + + fn poll_accept( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + if let Some(l) = self.listener.take() { + self.write_fut.set(make_accept_fut(Some(l))) + } + + match self.write_fut.poll(cx) { + Poll::Ready((l, cnx)) => { + self.listener = Some(l); + Poll::Ready(Some(cnx)) + } + Poll::Pending => Poll::Pending, + } + } +} + /// Gets a random name for a pipe/socket on the paltform pub fn get_socket_name() -> PathBuf { cfg_if::cfg_if! { diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index cce01c52fd930..bfa1c6f2da4ed 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -185,6 +185,9 @@ pub struct ServeWebArgs { /// Host to listen on, defaults to 'localhost' #[clap(long)] pub host: Option, + // The path to a socket file for the server to listen to. + #[clap(long)] + pub socket_path: Option, /// Port to listen on. If 0 is passed a random free port is picked. #[clap(long, default_value_t = 8000)] pub port: u16, diff --git a/cli/src/commands/serve_web.rs b/cli/src/commands/serve_web.rs index b2bf4d431e402..4a3af432444b9 100644 --- a/cli/src/commands/serve_web.rs +++ b/cli/src/commands/serve_web.rs @@ -16,7 +16,9 @@ use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::pin; use tokio::process::Command; -use crate::async_pipe::{get_socket_name, get_socket_rw_stream, AsyncPipe}; +use crate::async_pipe::{ + get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe, +}; use crate::constants::VSCODE_CLI_QUALITY; use crate::download_cache::DownloadCache; use crate::log; @@ -53,43 +55,53 @@ const RELEASE_CACHE_SECS: u64 = 60 * 60; /// while new clients get new VS Code Server versions. pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result { legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; - let mut addr: SocketAddr = match &args.host { - Some(h) => h.parse().map_err(CodeError::InvalidHostAddress)?, - None => SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0), - }; - addr.set_port(args.port); let platform: crate::update_service::Platform = PreReqChecker::new().verify().await?; if !args.without_connection_token { // Ensure there's a defined connection token, since if multiple server versions // are excuted, they will need to have a single shared token. - let connection_token = args - .connection_token - .clone() - .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()); - ctx.log.result(format!( - "Web UI available at http://{}?tkn={}", - addr, connection_token, - )); - args.connection_token = Some(connection_token); - } else { - ctx.log - .result(format!("Web UI available at http://{}", addr)); - args.connection_token = None; + args.connection_token = Some( + args.connection_token + .clone() + .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()), + ); } - let cm = ConnectionManager::new(&ctx, platform, args); - let make_svc = make_service_fn(move |_conn| { + let cm = ConnectionManager::new(&ctx, platform, args.clone()); + let make_svc = move || { let cm = cm.clone(); - let log = ctx.log.clone(); + let log = cm.log.clone(); let service = service_fn(move |req| handle(cm.clone(), log.clone(), req)); async move { Ok::<_, Infallible>(service) } - }); + }; + + 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()) + .serve(make_service_fn(|_| make_svc())) + .await + } else { + let addr: SocketAddr = match &args.host { + Some(h) => { + SocketAddr::new(h.parse().map_err(CodeError::InvalidHostAddress)?, args.port) + } + None => SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), args.port), + }; - let server = Server::bind(&addr).serve(make_svc); + let mut listening = format!("Web UI available at http://{}", addr); + if let Some(ct) = args.connection_token { + listening.push_str(&format!("?tkn={}", ct)); + } + ctx.log.result(listening); + + Server::bind(&addr) + .serve(make_service_fn(|_| make_svc())) + .await + }; - server.await.map_err(CodeError::CouldNotListenOnInterface)?; + r.map_err(CodeError::CouldNotListenOnInterface)?; Ok(0) } From e23be75182cabbf88bb2662d55c5c34c1f9a50f4 Mon Sep 17 00:00:00 2001 From: Ole Date: Thu, 24 Aug 2023 01:55:41 +0200 Subject: [PATCH 1139/1180] Increase shortcut consistency of web with electron. (#191061) On electron, nothing changes. On web, * "Focus Application Menu" changes from F10 to Alt+F10 (this action only exists on web) * "Debugger: Step over" changes from Alt+F10 to F10 like on electron While #183510 already added the F10 binding for the debugger also on web, it did not actually have any effect, because of a conflict with F10 for "Focus Application Menu" on web. This change was agreed upon in #190180 due to the relatively low usage of "Open Application Menu" in the interest of more overall consistency. Fixes #190180. --- src/vs/workbench/browser/parts/titlebar/menubarControl.ts | 4 ++-- src/vs/workbench/contrib/debug/browser/debugCommands.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index e96e773a916a8..ec47bd48bca0c 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -32,7 +32,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la import { isFullscreen } from 'vs/base/browser/browser'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; -import { KeyCode } from 'vs/base/common/keyCodes'; +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IsMacNativeContext, IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -440,7 +440,7 @@ export class CustomMenubarControl extends MenubarControl { id: `workbench.actions.menubar.focus`, title: { value: localize('focusMenu', "Focus Application Menu"), original: 'Focus Application Menu' }, keybinding: { - primary: KeyCode.F10, + primary: KeyMod.Alt | KeyCode.F10, weight: KeybindingWeight.WorkbenchContrib, when: IsWebContext }, diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 9515ab1ad73f8..1fecc75d4f9a3 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -474,7 +474,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: STEP_OVER_ID, weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.F10, - secondary: isWeb ? [(KeyMod.Alt | KeyCode.F10)] : undefined, // Keep Alt-F10 for web for backwards-compatibility when: CONTEXT_DEBUG_STATE.isEqualTo('stopped'), handler: async (accessor: ServicesAccessor, _: string, context: CallStackContext | unknown) => { const contextKeyService = accessor.get(IContextKeyService); From a0377f0c51dbb2d3188565cdf35e89929f864e65 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 23 Aug 2023 20:42:18 -0700 Subject: [PATCH 1140/1180] Fix #189809. Update tree options paddingBottom. (#191143) --- src/vs/base/browser/ui/tree/abstractTree.ts | 2 +- src/vs/platform/list/browser/listService.ts | 4 ++-- src/vs/workbench/contrib/files/browser/views/explorerView.ts | 2 +- src/vs/workbench/contrib/search/browser/searchView.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 3591193bab95a..70199a8164c80 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1218,7 +1218,7 @@ export interface IAbstractTreeOptions extends IAbstractTr readonly collapseByDefault?: boolean; // defaults to false readonly filter?: ITreeFilter; readonly dnd?: ITreeDragAndDrop; - readonly additionalScrollHeight?: number; + readonly paddingBottom?: number; readonly findWidgetEnabled?: boolean; readonly findWidgetStyles?: IFindWidgetStyles; readonly defaultFindVisibility?: TreeVisibility | ((e: T) => TreeVisibility); diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 7c5a1eb9cd6b4..6b698bc17f63f 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -1145,7 +1145,7 @@ function workbenchTreeDataPreamble(treeRenderIndentGuidesKey); return { @@ -1162,7 +1162,7 @@ function workbenchTreeDataPreamble(treeExpandMode) === 'doubleClick'), contextViewProvider: contextViewService as IContextViewProvider, diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 76b81a7ed4232..55039bcddd075 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -450,7 +450,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { } return false; }, - additionalScrollHeight: ExplorerDelegate.ITEM_HEIGHT, + paddingBottom: ExplorerDelegate.ITEM_HEIGHT, overrideStyles: { listBackground: SIDE_BAR_BACKGROUND } diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 4cdc0341049a9..b87d13478160f 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -860,7 +860,7 @@ export class SearchView extends ViewPane { overrideStyles: { listBackground: this.getBackgroundColor() }, - additionalScrollHeight: SearchDelegate.ITEM_HEIGHT + paddingBottom: SearchDelegate.ITEM_HEIGHT })); this._register(this.tree.onContextMenu(e => this.onContextMenu(e))); const updateHasSomeCollapsible = () => this.toggleCollapseStateDelayer.trigger(() => this.hasSomeCollapsibleResultKey.set(this.hasSomeCollapsible())); From d6330cc2a58af3e2658f6acdd88ab1263e4d0d1c Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 23 Aug 2023 20:43:36 -0700 Subject: [PATCH 1141/1180] Update cached map --- .../browser/services/notebookKernelHistoryServiceImpl.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts index 0a19cda94bfe8..7901ccc3e16e9 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts @@ -97,6 +97,8 @@ export class NotebookKernelHistoryService extends Disposable implements INoteboo for (const entry of kernels.entries) { linkedMap.set(entry, entry, Touch.AsOld); } + + this._mostRecentKernelsMap[viewType] = linkedMap; } } catch (e) { console.error('Deserialize notebook kernel history failed', e); From 94956b4c3fb38badce912cae3d5a531502669885 Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 23 Aug 2023 20:55:52 -0700 Subject: [PATCH 1142/1180] Fix #189673. Tracking original output id that is reused. --- .../contrib/notebook/browser/notebook.contribution.ts | 4 ++-- .../common/model/notebookCellOutputTextModel.ts | 11 +++++++++++ .../contrib/notebook/common/notebookCommon.ts | 4 ++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 8bbe932cb1f10..2ef3dfb4e8e97 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -455,7 +455,7 @@ class CellInfoContentProvider { let result: { content: string; mode: ILanguageSelection } | undefined = undefined; const mode = this._languageService.createById('json'); - const op = cell.outputs.find(op => op.outputId === data.outputId); + const op = cell.outputs.find(op => op.outputId === data.outputId || op.alternativeOutputId === data.outputId); const streamOutputData = this.parseStreamOutput(op); if (streamOutputData) { result = streamOutputData; @@ -491,7 +491,7 @@ class CellInfoContentProvider { } const ref = await this._notebookModelResolverService.resolve(data.notebook); - const cell = ref.object.notebook.cells.find(cell => !!cell.outputs.find(op => op.outputId === data.outputId)); + const cell = ref.object.notebook.cells.find(cell => !!cell.outputs.find(op => op.outputId === data.outputId || op.alternativeOutputId === data.outputId)); if (!cell) { ref.dispose(); diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts index 85ed20571d1c6..2e2ad62c97e2b 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts @@ -25,6 +25,15 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp return this._rawOutput.outputId; } + /** + * Alternative output id that's reused when the output is updated. + */ + private _alternativeOutputId: string; + + get alternativeOutputId(): string { + return this._alternativeOutputId; + } + private _versionId = 0; get versionId() { @@ -35,6 +44,8 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp private _rawOutput: IOutputDto ) { super(); + + this._alternativeOutputId = this._rawOutput.outputId; } replaceData(rawData: IOutputDto) { diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index e01a5c37361fa..8d06fb4cec314 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -214,6 +214,10 @@ export interface ICellOutput { outputs: IOutputItemDto[]; metadata?: Record; outputId: string; + /** + * Alternative output id that's reused when the output is updated. + */ + alternativeOutputId: string; onDidChangeData: Event; replaceData(items: IOutputDto): void; appendData(items: IOutputItemDto[]): void; From c4b5dff6088ecaffbb8d3f0bdcf26d937bd4c117 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 09:35:08 +0200 Subject: [PATCH 1143/1180] fix #189798 (#191090) --- .../preferences/browser/settingsTreeModels.ts | 2 +- .../browser/configurationService.ts | 2 +- .../test/browser/configurationService.test.ts | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index bcd2604c8d717..180f990b5a5b9 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -273,7 +273,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { } private getTargetToInspect(setting: ISetting): SettingsTarget { - if (!this.userDataProfileService.currentProfile.isDefault) { + if (!this.userDataProfileService.currentProfile.isDefault && !this.userDataProfileService.currentProfile.useDefaultFlags?.settings) { if (setting.scope === ConfigurationScope.APPLICATION) { return ConfigurationTarget.APPLICATION; } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index bc40358f62fac..d2c05378c9c99 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -47,7 +47,7 @@ import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/envir import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { - return userDataProfile.isDefault + return (userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings) ? hasRemote ? LOCAL_MACHINE_SCOPES : undefined : hasRemote ? LOCAL_MACHINE_PROFILE_SCOPES : PROFILE_SCOPES; } diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index e0613cac0c707..72084f75018c3 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -1774,6 +1774,22 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue2'); })); + test('switch to non default profile using settings from default profile', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "applicationValue", "configurationService.profiles.testSetting": "userValue" }')); + await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "profileValue", "configurationService.profiles.testSetting": "profileValue" }')); + await testObject.reloadConfiguration(); + + const profile = toUserDataProfile('custom3', 'custom3', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache'), { useDefaultFlags: { settings: true } }, instantiationService.get(IUserDataProfilesService).defaultProfile); + await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "applicationValue2", "configurationService.profiles.testSetting": "profileValue2" }')); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await userDataProfileService.updateCurrentProfile(profile); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.applicationSetting', 'configurationService.profiles.testSetting']); + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting'), 'applicationValue2'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue2'); + })); + test('In non-default profile, changing application settings shall include only application scope settings in the change event', () => runWithFakedTimers({ useFakeTimers: true }, async () => { await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{}')); await testObject.reloadConfiguration(); From 42ff46c8806112de0d04ef92c8fbd7ffaf820055 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 24 Aug 2023 10:35:07 +0200 Subject: [PATCH 1144/1180] Hovering over an editor tab will "drop a white shadow" on the text (fix #189625) (#191165) --- .../workbench/browser/parts/editor/media/tabstitlecontrol.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index 398e3058b2e3a..17e17c1a758c6 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -297,6 +297,10 @@ padding-right: 5px; /* with tab sizing shrink/fixed and badges, we want a right-padding because the close button is hidden */ } +.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.tab-actions-left):not(.tab-actions-off) .tab-label { + padding-right: 5px; /* ensure that the gradient does not show when tab actions show https://github.com/microsoft/vscode/issues/189625*/ +} + .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sticky-compact:not(.has-icon) .monaco-icon-label { text-align: center; /* ensure that sticky-compact tabs without icon have label centered */ } From 7ef754c2f623aa662526e611c67e8e1a97e6753a Mon Sep 17 00:00:00 2001 From: Alpha Romer Coma <400829150120@r3-1.deped.gov.ph> Date: Thu, 24 Aug 2023 08:37:25 +0000 Subject: [PATCH 1145/1180] Fix supported markdown-lint violations in markdown files (#190750) docs: fix supported markdownlint violations --- .devcontainer/README.md | 5 +- .devcontainer/prebuilt/README.md | 45 +++++++++-------- CONTRIBUTING.md | 2 +- README.md | 8 +-- SECURITY.md | 14 +++--- build/monaco/README-npm.md | 1 + extensions/git-base/README.md | 9 ++-- extensions/git/README.md | 8 +-- extensions/javascript/syntaxes/Readme.md | 2 + extensions/json-language-features/README.md | 2 +- .../json-language-features/server/README.md | 29 +++++++---- .../markdown-language-features/README.md | 2 +- .../server/README.md | 50 +++++++++---------- extensions/media-preview/README.md | 1 - extensions/npm/README.md | 4 +- extensions/php-language-features/README.md | 2 +- extensions/simple-browser/README.md | 3 +- .../typescript-basics/syntaxes/Readme.md | 1 + .../web/README.md | 48 +++++++++--------- .../test/colorize-fixtures/test.md | 2 +- src/vscode-dts/README.md | 9 ++-- test/README.md | 1 + test/integration/browser/README.md | 2 +- test/monaco/README.md | 8 +-- test/smoke/Audit.md | 10 ++-- test/smoke/README.md | 4 +- test/unit/README.md | 4 +- 27 files changed, 146 insertions(+), 130 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 6522e98aac95e..a5bde90d52746 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -19,13 +19,14 @@ This dev container includes configuration for a development container for workin > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Due to the size of the repository we strongly recommend cloning it on a Linux filesystem for better bind mount performance. On macOS we recommend using a Docker volume (press F1 and select **Dev Containers: Clone Repository in Container Volume...**) and on Windows we recommend using a WSL folder: + - Make sure you are running a recent WSL version to get X11 and Wayland support. - Use the WSL extension for VS Code to open the cloned folder in WSL. - Press F1 and select **Dev Containers: Reopen in Container**. Next: **[Try it out!](#try-it)** -## Try it! +## Try it To start working with Code - OSS, follow these steps: @@ -50,6 +51,6 @@ Next, let's try debugging. Enjoy! -# Notes +## Notes The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`. diff --git a/.devcontainer/prebuilt/README.md b/.devcontainer/prebuilt/README.md index 82e731230c0d6..2ca4619ce1365 100644 --- a/.devcontainer/prebuilt/README.md +++ b/.devcontainer/prebuilt/README.md @@ -14,21 +14,21 @@ If you already have VS Code and Docker installed, you can click the badge above 2. **Important**: Docker needs at least **4 Cores and 8 GB of RAM** to run a full build with **9 GB of RAM** being recommended. If you are on macOS, or are using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item and going to **Preferences/Settings > Resources > Advanced**. - > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. + > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. 3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension. - ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) + ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) - > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. + > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Press Ctrl/Cmd + Shift + P or F1 and select **Dev Containers: Clone Repository in Container Volume...**. - > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem. + > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem. 5. Type `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box and press Enter. -6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password. +6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here. @@ -54,41 +54,42 @@ Next: **[Try it out!](#try-it)** ### Using VS Code with GitHub Codespaces -You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/). Here's how to do it. +You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer][def]. Here's how to do it. -1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). +1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). - > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. + > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. 2. After the VS Code is up and running, press Ctrl/Cmd + Shift + P or F1, choose **Codespaces: Create New Codespace**, and use the following settings: - - `microsoft/vscode` for the repository. - - Select any branch (e.g. **main**) - you can select a different one later. - - Choose **Standard** (4-core, 8GB) as the size. -4. After you have connected to the codespace, you can use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password. +- `microsoft/vscode` for the repository. +- Select any branch (e.g. **main**) - you can select a different one later. +- Choose **Standard** (4-core, 8GB) as the size. + +3. After you have connected to the codespace, you can use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. > **Tip:** You may also need change your VNC client's **Picture Quality** setting to **High** to get a full color desktop. -5. Anything you start in VS Code, or the integrated terminal, will appear here. +4. Anything you start in VS Code, or the integrated terminal, will appear here. Next: **[Try it out!](#try-it)** -## Try it! +## Try it This container uses the [Fluxbox](http://fluxbox.org/) window manager to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed. -> **Note:** You can also set the resolution from the command line by typing `set-resolution`. + > **Note:** You can also set the resolution from the command line by typing `set-resolution`. To start working with Code - OSS, follow these steps: 1. In your local VS Code client, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands: - ```bash - yarn install - bash scripts/code.sh - ``` + ```bash + yarn install + bash scripts/code.sh + ``` -2. After the build is complete, open a web browser or a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to the desktop environment as described in the quick start and enter `vscode` as the password. +2. After the build is complete, open a web browser or a [VNC Viewer][def] to connect to the desktop environment as described in the quick start and enter `vscode` as the password. 3. You should now see Code - OSS! @@ -98,8 +99,10 @@ Next, let's try debugging. 2. Go to your local VS Code client, and use the **Run / Debug** view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5). - > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `scripts/code.sh` first will set up Electron which will usually solve timeout issues. + > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `scripts/code.sh` first will set up Electron which will usually solve timeout issues. 3. After a bit, Code - OSS will appear with the debugger attached! Enjoy! + +[def]: https://www.realvnc.com/en/connect/download/viewer/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b96e077aa67ea..f17fa84364568 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,6 +104,6 @@ If you believe the bot got something wrong, please open a new issue and let us k If you are interested in writing code to fix issues, please see [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) in the wiki. -# Thank You! +## Thank You Your contributions to open source, large or small, make great projects like this possible. Thank you for taking the time to contribute. diff --git a/README.md b/README.md index 0c7c6236c42c6..61df8fc6bb44e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Visual Studio Code - Open Source ("Code - OSS") + [![Feature Requests](https://img.shields.io/github/issues/microsoft/vscode/feature-request.svg)](https://github.com/microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc) [![Bugs](https://img.shields.io/github/issues/microsoft/vscode/bug.svg)](https://github.com/microsoft/vscode/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Abug) [![Gitter](https://img.shields.io/badge/chat-on%20gitter-yellow.svg)](https://gitter.im/Microsoft/vscode) @@ -60,9 +61,10 @@ VS Code includes a set of built-in extensions located in the [extensions](extens This repository includes a Visual Studio Code Dev Containers / GitHub Codespaces development container. -- For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows. - - If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. -- For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command. +* For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows. + * If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. + +* For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command. Docker / the Codespace should have at least **4 Cores and 6 GB of RAM (8 GB recommended)** to run full build. See the [development container README](.devcontainer/README.md) for more information. diff --git a/SECURITY.md b/SECURITY.md index a050f362c1528..4fa5946a867c6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -18,13 +18,13 @@ You should receive a response within 24 hours. If for some reason you do not, pl Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue +* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. diff --git a/build/monaco/README-npm.md b/build/monaco/README-npm.md index ca5592e0fe1f6..ec8eb5a40376e 100644 --- a/build/monaco/README-npm.md +++ b/build/monaco/README-npm.md @@ -10,4 +10,5 @@ The Monaco Editor is the code editor that powers [VS Code](https://github.com/mi This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/microsoft/vscode). ## License + [MIT](https://github.com/microsoft/vscode/blob/main/LICENSE.txt) diff --git a/extensions/git-base/README.md b/extensions/git-base/README.md index ff5bcc321c7e2..d6f0b7c128b21 100644 --- a/extensions/git-base/README.md +++ b/extensions/git-base/README.md @@ -14,7 +14,8 @@ The Git extension exposes an API, reachable by any other extension. 2. Include `git-base.d.ts` in your extension's compilation. 3. Get a hold of the API with the following snippet: - ```ts - const gitBaseExtension = vscode.extensions.getExtension('vscode.git-base').exports; - const git = gitBaseExtension.getAPI(1); - ``` + ```ts + const gitBaseExtension = vscode.extensions.getExtension('vscode.git-base').exports; + const git = gitBaseExtension.getAPI(1); + + ``` diff --git a/extensions/git/README.md b/extensions/git/README.md index a20f320753424..2a6678de93339 100644 --- a/extensions/git/README.md +++ b/extensions/git/README.md @@ -14,7 +14,7 @@ The Git extension exposes an API, reachable by any other extension. 2. Include `git.d.ts` in your extension's compilation. 3. Get a hold of the API with the following snippet: - ```ts - const gitExtension = vscode.extensions.getExtension('vscode.git').exports; - const git = gitExtension.getAPI(1); - ``` \ No newline at end of file + ```ts + const gitExtension = vscode.extensions.getExtension('vscode.git').exports; + const git = gitExtension.getAPI(1); + ``` diff --git a/extensions/javascript/syntaxes/Readme.md b/extensions/javascript/syntaxes/Readme.md index bc29199fd73e7..b7db3a6a4c9bf 100644 --- a/extensions/javascript/syntaxes/Readme.md +++ b/extensions/javascript/syntaxes/Readme.md @@ -1,10 +1,12 @@ The file `JavaScript.tmLanguage.json` is derived from [TypeScriptReact.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage). To update to the latest version: + - `cd extensions/typescript` and run `npm run update-grammars` - don't forget to run the integration tests at `./scripts/test-integration.sh` The script does the following changes: + - fileTypes .tsx -> .js & .jsx - scopeName scope.tsx -> scope.js - update all rule names .tsx -> .js diff --git a/extensions/json-language-features/README.md b/extensions/json-language-features/README.md index 2ff5e6e57d312..3de3d11081a6e 100644 --- a/extensions/json-language-features/README.md +++ b/extensions/json-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension. \ No newline at end of file +See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension. diff --git a/extensions/json-language-features/server/README.md b/extensions/json-language-features/server/README.md index e9875ba59779a..10956439e320a 100644 --- a/extensions/json-language-features/server/README.md +++ b/extensions/json-language-features/server/README.md @@ -11,6 +11,7 @@ The JSON Language server provides language-specific smarts for editing, validati ### Server capabilities The JSON language server supports requests on documents of language id `json` and `jsonc`. + - `json` documents are parsed and validated following the [JSON specification](https://tools.ietf.org/html/rfc7159). - `jsonc` documents additionally accept single line (`//`) and multi-line comments (`/* ... */`). JSONC is a VSCode specific file format, intended for VSCode configuration files, without any aspirations to define a new common file format. @@ -25,12 +26,12 @@ The server implements the following capabilities of the language server protocol - Semantic Selection for semantic selection for one or multiple cursor positions. - [Goto Definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) for $ref references in JSON schemas - [Diagnostics (Validation)](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics) are pushed for all open documents - - syntax errors - - structural validation based on the document's [JSON schema](http://json-schema.org/). + - syntax errors + - structural validation based on the document's [JSON schema](http://json-schema.org/). In order to load JSON schemas, the JSON server uses NodeJS `http` and `fs` modules. For all other features, the JSON server only relies on the documents and settings provided by the client through the LSP. -### Client requirements: +### Client requirements The JSON language server expects the client to only send requests and notifications for documents of language id `json` and `jsonc`. @@ -56,8 +57,8 @@ Clients may send a `workspace/didChangeConfiguration` notification to notify the The server supports the following settings: - http - - `proxy`: The URL of the proxy server to use when fetching schema. When undefined or empty, no proxy is used. - - `proxyStrictSSL`: Whether the proxy server certificate should be verified against the list of supplied CAs. + - `proxy`: The URL of the proxy server to use when fetching schema. When undefined or empty, no proxy is used. + - `proxyStrictSSL`: Whether the proxy server certificate should be verified against the list of supplied CAs. - json - `format` @@ -72,6 +73,7 @@ The server supports the following settings: - `resultLimit`: The max number of color decorators and outline symbols to be computed (for performance reasons) - `jsonFoldingLimit`: The max number of folding ranges to be computed for json documents (for performance reasons) - `jsoncFoldingLimit`: The max number of folding ranges to be computed for jsonc documents (for performance reasons) + ```json { "http": { @@ -103,6 +105,7 @@ The server supports the following settings: [JSON schemas](http://json-schema.org/) are essential for code assist, hovers, color decorators to work and are required for structural validation. To find the schema for a given JSON document, the server uses the following mechanisms: + - JSON documents can define the schema URL using a `$schema` property - The settings define a schema association based on the documents URL. Settings can either associate a schema URL to a file or path pattern, and they can directly provide a schema. - Additionally, schema associations can also be provided by a custom 'schemaAssociations' configuration call. @@ -115,9 +118,9 @@ The `initializationOptions.handledSchemaProtocols` initialization option defines ```ts let clientOptions: LanguageClientOptions = { - initializationOptions: { - handledSchemaProtocols: ['file'] // language server should only try to load file URLs - } + initializationOptions: { + handledSchemaProtocols: ['file'] // language server should only try to load file URLs + } ... } ``` @@ -132,6 +135,7 @@ If `handledSchemaProtocols` is not set, the JSON language server will load the f Requests for schemas with URLs not handled by the server are forwarded to the client through an LSP request. This request is a JSON language server-specific, non-standardized, extension to the LSP. Request: + - method: 'vscode/content' - params: `string` - The schema URL to request. - response: `string` - The content of the schema with the given URL @@ -146,6 +150,7 @@ The server will, as a response, clear the schema content from the cache and relo In addition to the settings, schemas associations can also be provided through a notification from the client to the server. This notification is a JSON language server-specific, non-standardized, extension to the LSP. Notification: + - method: 'json/schemaAssociations' - params: `ISchemaAssociations` or `ISchemaAssociation[]` defined as follows @@ -183,11 +188,14 @@ interface ISchemaAssociation { } ``` + `ISchemaAssociations` - - keys: a file names or file path (separated by `/`). `*` can be used as a wildcard. - - values: An array of schema URLs + +- keys: a file names or file path (separated by `/`). `*` can be used as a wildcard. +- values: An array of schema URLs Notification: + - method: 'json/schemaContent' - params: `string` the URL of the schema that has changed. @@ -226,6 +234,7 @@ The source code of the JSON language server can be found in the [VSCode reposito File issues and pull requests in the [VSCode GitHub Issues](https://github.com/microsoft/vscode/issues). See the document [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) on how to build and run from source. Most of the functionality of the server is located in libraries: + - [jsonc-parser](https://github.com/microsoft/node-jsonc-parser) contains the JSON parser and scanner. - [vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice) contains the implementation of all features as a re-usable library. - [vscode-languageserver-node](https://github.com/microsoft/vscode-languageserver-node) contains the implementation of language server for NodeJS. diff --git a/extensions/markdown-language-features/README.md b/extensions/markdown-language-features/README.md index e80e9e886bb95..2052521da84b8 100644 --- a/extensions/markdown-language-features/README.md +++ b/extensions/markdown-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [Markdown in Visual Studio Code](https://code.visualstudio.com/docs/languages/markdown) to learn about the features of this extension. \ No newline at end of file +See [Markdown in Visual Studio Code](https://code.visualstudio.com/docs/languages/markdown) to learn about the features of this extension. diff --git a/extensions/markdown-language-features/server/README.md b/extensions/markdown-language-features/server/README.md index 1fd38302195ff..4114d2698bf6a 100644 --- a/extensions/markdown-language-features/server/README.md +++ b/extensions/markdown-language-features/server/README.md @@ -6,7 +6,6 @@ The Markdown language server powers VS Code's built-in markdown support, providi This server uses the [Markdown Language Service](https://github.com/microsoft/vscode-markdown-languageservice) to implement almost all of the language features. You can use that library if you need a library for working with Markdown instead of a full language server. - ## Server capabilities - [Completions](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) for Markdown links. @@ -31,14 +30,13 @@ This server uses the [Markdown Language Service](https://github.com/microsoft/vs - [Code Actions](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction) - - Organize link definitions source action. - - Extract link to definition refactoring. + - Organize link definitions source action. + - Extract link to definition refactoring. - Updating links when a file is moved / renamed. Uses a custom `markdown/getEditForFileRenames` message. - [Pull diagnostics (validation)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics) for links. - ## Client requirements ### Initialization options @@ -53,27 +51,27 @@ Clients may send a `workspace/didChangeConfiguration` notification to notify the The server supports the following settings: - `markdown` - - `suggest` - - `paths` - - `enabled` — Enable/disable path suggestions. - - - `occurrencesHighlight` - - `enabled` — Enable/disable highlighting of link occurrences. - - - `validate` - - `enabled` — Enable/disable all validation. - - `referenceLinks` - - `enabled` — Enable/disable validation of reference links: `[text][ref]` - - `fragmentLinks` - - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` - - `fileLinks` - - `enabled` — Enable/disable validation of links to file in the workspace. - - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. Use `inherit` to inherit the `fragmentLinks` setting. - - `ignoredLinks` — Array of glob patterns for files that should not be validated. - - `unusedLinkDefinitions` - - `enabled` — Enable/disable validation of unused link definitions. - - `duplicateLinkDefinitions` - - `enabled` — Enable/disable validation of duplicated link definitions. + - `suggest` + - `paths` + - `enabled` — Enable/disable path suggestions. + + - `occurrencesHighlight` + - `enabled` — Enable/disable highlighting of link occurrences. + + - `validate` + - `enabled` — Enable/disable all validation. + - `referenceLinks` + - `enabled` — Enable/disable validation of reference links: `[text][ref]` + - `fragmentLinks` + - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` + - `fileLinks` + - `enabled` — Enable/disable validation of links to file in the workspace. + - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. Use `inherit` to inherit the `fragmentLinks` setting. + - `ignoredLinks` — Array of glob patterns for files that should not be validated. + - `unusedLinkDefinitions` + - `enabled` — Enable/disable validation of unused link definitions. + - `duplicateLinkDefinitions` + - `enabled` — Enable/disable validation of duplicated link definitions. ### Custom requests @@ -109,7 +107,6 @@ Delete a previously created file watcher. Get a list of all markdown files in the workspace. - ## Contribute The source code of the Markdown language server can be found in the [VSCode repository](https://github.com/microsoft/vscode) at [extensions/markdown-language-features/server](https://github.com/microsoft/vscode/tree/master/extensions/markdown-language-features/server). @@ -132,4 +129,3 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the [MIT](https://github.com/microsoft/vscode/blob/master/LICENSE.txt) License. - diff --git a/extensions/media-preview/README.md b/extensions/media-preview/README.md index 48428a684bfc6..8163e01714331 100644 --- a/extensions/media-preview/README.md +++ b/extensions/media-preview/README.md @@ -16,7 +16,6 @@ This extension provides basic preview for images, audio and video files. - `.webp` - `.avif` - ### Supported audio formats - `.mp3` diff --git a/extensions/npm/README.md b/extensions/npm/README.md index 82730c7e82a67..296bf03f73e0c 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -28,7 +28,7 @@ The extension supports running a script as a task from a folder in the Explorer. ### Others -The extension fetches data from https://registry.npmjs.org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies. +The extension fetches data from and to provide auto-completion and information on hover features on npm dependencies. ## Settings @@ -40,5 +40,3 @@ The extension fetches data from https://registry.npmjs.org and https://registry. - `npm.scriptExplorerAction` - The default click action: `open` or `run`, the default is `open`. - `npm.enableRunFromFolder` - Enable running npm scripts from the context menu of folders in Explorer, the default is `false`. - `npm.scriptCodeLens.enable` - Enable/disable the code lenses to run a script, the default is `false`. - - diff --git a/extensions/php-language-features/README.md b/extensions/php-language-features/README.md index c00be6a964e78..e0d28f5254fc3 100644 --- a/extensions/php-language-features/README.md +++ b/extensions/php-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [PHP in Visual Studio Code](https://code.visualstudio.com/docs/languages/php) to learn about the features of this extension. \ No newline at end of file +See [PHP in Visual Studio Code](https://code.visualstudio.com/docs/languages/php) to learn about the features of this extension. diff --git a/extensions/simple-browser/README.md b/extensions/simple-browser/README.md index b4ecf7a4ad661..5121dc86e8933 100644 --- a/extensions/simple-browser/README.md +++ b/extensions/simple-browser/README.md @@ -2,5 +2,4 @@ **Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled. -Provides a very basic browser preview using an iframe embedded in a [webview](). This extension is primarily meant to be used by other extensions for showing simple web content. - +Provides a very basic browser preview using an iframe embedded in a [webviewW](). This extension is primarily meant to be used by other extensions for showing simple web content. diff --git a/extensions/typescript-basics/syntaxes/Readme.md b/extensions/typescript-basics/syntaxes/Readme.md index 2f9c2b95ee24c..fa05c28d970bd 100644 --- a/extensions/typescript-basics/syntaxes/Readme.md +++ b/extensions/typescript-basics/syntaxes/Readme.md @@ -1,6 +1,7 @@ The file `TypeScript.tmLanguage.json` and `TypeScriptReact.tmLanguage.json` are derived from [TypeScript.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScript.tmLanguage) and [TypeScriptReact.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage). To update to the latest version: + - `cd extensions/typescript` and run `npm run update-grammars` - don't forget to run the integration tests at `./scripts/test-integration.sh` diff --git a/extensions/typescript-language-features/web/README.md b/extensions/typescript-language-features/web/README.md index 9cae35b8cf39f..a9c19b5d72a68 100644 --- a/extensions/typescript-language-features/web/README.md +++ b/extensions/typescript-language-features/web/README.md @@ -1,4 +1,5 @@ # vscode-wasm-typescript + Language server host for typescript using vscode's sync-api in the browser ## TODOs @@ -22,33 +23,33 @@ Language server host for typescript using vscode's sync-api in the browser - LATER: Turns out you can skip the existing server by depending on tsserverlibrary instead of tsserver. - [x] figure out a webpack-native way to generate tsserver.web.js if possible - [x] path rewriting is pretty loosey-goosey; likely to be incorrect some of the time - - invert the logic from TypeScriptServiceClient.normalizedPath for requests - - invert the function from webServer.ts for responses (maybe) - - something with getWorkspaceRootForResource (or anything else that checks `resouce.scheme`) + - invert the logic from TypeScriptServiceClient.normalizedPath for requests + - invert the function from webServer.ts for responses (maybe) + - something with getWorkspaceRootForResource (or anything else that checks `resouce.scheme`) - [x] put files one level down from virtual root - [x] fill in missing environment files like lib.dom.d.ts - - toResource's isWeb branch *probably* knows where to find this, just need to put it in the virtual FS - - I guess during setup in serverProcess.browser.ts. - - Not sure whether it needs to have the data or just a fs entry. - - Wait, I don't know how files get added to the FS normally. + - toResource's isWeb branch *probably* knows where to find this, just need to put it in the virtual FS + - I guess during setup in serverProcess.browser.ts. + - Not sure whether it needs to have the data or just a fs entry. + - Wait, I don't know how files get added to the FS normally. - [x] cancellation should only retain one cancellation checker - - the one that matches the current request id - - but that means tracking (or retrieving from tsserver) the request id (aka seq?) - - and correctly setting/resetting it on the cancellation token too. - - I looked at the tsserver code. I think the web case is close to the single-pipe node case, + - the one that matches the current request id + - but that means tracking (or retrieving from tsserver) the request id (aka seq?) + - and correctly setting/resetting it on the cancellation token too. + - I looked at the tsserver code. I think the web case is close to the single-pipe node case, so I just require that requestId is set in order to call the *current* cancellation checker. - - Any incoming message with a cancellation checker will overwrite the current one. + - Any incoming message with a cancellation checker will overwrite the current one. - [x] Cancellation code in vscode is suspiciously prototypey. - - Specifically, it adds the vscode-wasm cancellation to original cancellation code, but should actually switch to the former for web only. - - looks like `isWeb()` is a way to check for being on the web + - Specifically, it adds the vscode-wasm cancellation to original cancellation code, but should actually switch to the former for web only. + - looks like `isWeb()` is a way to check for being on the web - [x] create multiple watchers - - on-demand instead of watching everything and checking on watch firing + - on-demand instead of watching everything and checking on watch firing - [x] get file watching to work - - it could *already* work, I just don't know how to test it - - look at extensions/markdown-language-features/src/client/fileWatchingManager.ts to see if I can use that - - later: it is OK. its main difference is that you can watch files in not-yet-created directories, and it maintains + - it could *already* work, I just don't know how to test it + - look at extensions/markdown-language-features/src/client/fileWatchingManager.ts to see if I can use that + - later: it is OK. its main difference is that you can watch files in not-yet-created directories, and it maintains a web of directory watches that then check whether the file is eventually created. - - even later: well, it works even though it is similar to my code. + - even later: well, it works even though it is similar to my code. I'm not sure what is different. - [x] copy fileWatchingManager.ts to web/ ; there's no sharing code between extensions - [x] Find out scheme the web actually uses instead of vscode-test-web (or switch over entirely to isWeb) @@ -106,6 +107,7 @@ Language server host for typescript using vscode's sync-api in the browser - so I can just redo whatever that did and it'll be fine ### Done + - [x] need to update 0.2 -> 0.7.* API (once it's working properly) - [x] including reshuffling the webpack hack if needed - [x] need to use the settings recommended by Sheetal @@ -113,7 +115,7 @@ Language server host for typescript using vscode's sync-api in the browser - [x] sync-api-client says fs is rooted at memfs:/sample-folder; the protocol 'memfs:' is confusing our file parsing I think - [x] nothing ever seems to find tsconfig.json - [x] messages aren't actually coming through, just the message from the first request - - fixed by simplifying the listener setup for now + - fixed by simplifying the listener setup for now - [x] once messages work, you can probably log by postMessage({ type: 'log', body: "some logging text" }) - [x] implement realpath, modifiedtime, resolvepath, then turn semantic mode on - [x] file watching implemented with saved map of filename to callback, and forwarding @@ -125,6 +127,7 @@ Language server host for typescript using vscode's sync-api in the browser ## Notes messages received by extension AND host use paths like ^/memfs/ts-nul-authority/sample-folder/file.ts + - problem: pretty sure the extension doesn't know what to do with that: it's not putting down error spans in file.ts - question: why is the extension requesting quickinfo in that URI format? And it works! (probably because the result is a tooltip, not an in-file span) - problem: weird concatenations with memfs:/ in the middle @@ -140,15 +143,14 @@ but readFile is getting called with things like memfs:/sample-folder/memfs:/type watchDirectory with /sample-folder/^ and directoryExists with /sample-folder/^/memfs/ts-nul-authority/sample-folder/workspaces/ watchFile with /sample-folder/memfs:/sample-folder/memfs:/lib.es2020.full.d.ts -### LATER: +### LATER OK, so the paths that tsserver has look like this: ^/scheme/mount/whatever.ts but the paths the filesystem has look like this: scheme:/whatever.ts (not sure about 'mount', that's only when cloning from the fs) so you have to shave off the scheme that the host combined with the path and put on the scheme that the vfs is using. -### LATER 2: +### LATER 2 Some commands ask for getExecutingFilePath or getCurrentDirectory and cons up a path themselves. This works, because URI.from({ scheme, path }) matches what the fs has in it Problem: In *some* messages (all?), vscode then refers to /x.ts and ^/vscode-test-web/mount/x.ts (or ^/memfs/ts-nul-authority/x.ts) - diff --git a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md index 28f3590536e5f..309aa6de7935c 100644 --- a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md +++ b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md @@ -103,4 +103,4 @@ Pop * Multiple definitions and terms are possible * Definitions can include multiple paragraphs too -*[ABBR]: Markdown plus abbreviations (produces an tag) \ No newline at end of file +*[ABBR]: Markdown plus abbreviations (produces an tag) diff --git a/src/vscode-dts/README.md b/src/vscode-dts/README.md index a69e5eb65e124..9b3640d920887 100644 --- a/src/vscode-dts/README.md +++ b/src/vscode-dts/README.md @@ -1,18 +1,17 @@ -## vscode-dts +# vscode-dts This is the place for the stable API and for API proposals. - -### Consume a proposal +## Consume a proposal 1. find a proposal you are interested in 1. add its name to your extensions `package.json#enabledApiProposals` property 1. run `npx vscode-dts dev` to download the `d.ts` files into your project 1. don't forget that extension using proposed API cannot be published -1. learn more here: https://code.visualstudio.com/api/advanced-topics/using-proposed-api +1. learn more here: -### Add a new proposal +## Add a new proposal 1. create a _new_ file in this directory, its name must follow this pattern `vscode.proposed.[a-zA-Z]+.d.ts` 1. creating the proposal-file will automatically update `src/vs/workbench/services/extensions/common/extensionsApiProposals.ts` (make sure to run `yarn watch`) diff --git a/test/README.md b/test/README.md index 80cf9d929122e..1e4d114dce5b0 100644 --- a/test/README.md +++ b/test/README.md @@ -3,6 +3,7 @@ ## Contents This folder contains the various test runners for VSCode. Please refer to the documentation within for how to run them: + * `unit`: our suite of unit tests ([README](unit/README.md)) * `integration`: our suite of API tests ([README](integration/browser/README.md)) * `smoke`: our suite of automated UI tests ([README](smoke/README.md)) diff --git a/test/integration/browser/README.md b/test/integration/browser/README.md index 34107241f8e6a..8b25994564d02 100644 --- a/test/integration/browser/README.md +++ b/test/integration/browser/README.md @@ -21,7 +21,7 @@ All integration tests run in a browser instance as specified by the command line Add the `--debug` flag to see a browser window with the tests running. -**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests (https://playwright.dev/docs/debug#verbose-api-logs) +**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests () ## Debug diff --git a/test/monaco/README.md b/test/monaco/README.md index 68bb7051ce816..e55338934f293 100644 --- a/test/monaco/README.md +++ b/test/monaco/README.md @@ -4,10 +4,10 @@ This directory contains scripts that are used to smoke test the Monaco Editor di ## Setup & Bundle - $test/monaco> yarn - $test/monaco> yarn run bundle + $test/monaco> yarn + $test/monaco> yarn run bundle ## Compile and run tests - $test/monaco> yarn run compile - $test/monaco> yarn test + $test/monaco> yarn run compile + $test/monaco> yarn test diff --git a/test/smoke/Audit.md b/test/smoke/Audit.md index 4ec76567e9c39..fd8913b44e2e9 100644 --- a/test/smoke/Audit.md +++ b/test/smoke/Audit.md @@ -1,13 +1,15 @@ # VS Code Smoke Tests Failures History + This file contains a history of smoke test failures which could be avoided if particular techniques were used in the test (e.g. binding test elements with HTML5 `data-*` attribute). To better understand what can be employed in smoke test to ensure its stability, it is important to understand patterns that led to smoke test breakage. This markdown is a result of work on [this issue](https://github.com/microsoft/vscode/issues/27906). -# Log +## Log + 1. This following change led to the smoke test failure because DOM element's attribute `a[title]` was changed: - [eac49a3](https://github.com/microsoft/vscode/commit/eac49a321b84cb9828430e9dcd3f34243a3480f7) + [eac49a3](https://github.com/microsoft/vscode/commit/eac49a321b84cb9828430e9dcd3f34243a3480f7) - This attribute was used in the smoke test to grab the contents of SCM part in status bar: - [0aec2d6](https://github.com/microsoft/vscode/commit/0aec2d6838b5e65cc74c33b853ffbd9fa191d636) + This attribute was used in the smoke test to grab the contents of SCM part in status bar: + [0aec2d6](https://github.com/microsoft/vscode/commit/0aec2d6838b5e65cc74c33b853ffbd9fa191d636) 2. To be continued... diff --git a/test/smoke/README.md b/test/smoke/README.md index ffef4c28339c9..9b5eb6282b4ea 100644 --- a/test/smoke/README.md +++ b/test/smoke/README.md @@ -2,7 +2,7 @@ Make sure you are on **Node v12.x**. -### Quick Overview +## Quick Overview ```bash # Build extensions in the VS Code repo (if needed) @@ -57,7 +57,7 @@ xattr -d com.apple.quarantine - `-f PATTERN` (alias `-g PATTERN`) filters the tests to be run. You can also use pretty much any mocha argument; - `--headless` will run playwright in headless mode when `--web` is used. -**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests (https://playwright.dev/docs/debug#verbose-api-logs), for example to `pw:browser`. +**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests (), for example to `pw:browser`. ### Develop diff --git a/test/unit/README.md b/test/unit/README.md index 58d569d571f96..154f1cf0ad097 100644 --- a/test/unit/README.md +++ b/test/unit/README.md @@ -33,10 +33,10 @@ Unit tests from layers `common` and `browser` are run inside `chromium`, `webkit The following command will create a `coverage` folder in the `.build` folder at the root of the workspace: -**OS X and Linux** +### OS X and Linux ./scripts/test.sh --coverage -**Windows** +### Windows scripts\test --coverage From 76ab868e1c01ee0c01116bfe50b6d3e7ee098c88 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 24 Aug 2023 11:18:24 +0200 Subject: [PATCH 1146/1180] review comment --- .../browser/stickyScrollController.ts | 1 + .../browser/stickyScrollWidget.ts | 20 +++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts index 5764622526da7..53a7aa18f3c4b 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts @@ -430,6 +430,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _renderStickyScroll() { const model = this._editor.getModel(); if (!model || model.isTooLargeForTokenization()) { + this._stickyScrollWidget.setState(undefined); return; } const stickyLineVersion = this._stickyLineCandidateProvider.getVersionId(); diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 79e9f479add12..607dcb730685f 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -99,9 +99,11 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return this._lineNumbers; } - setState(state: StickyScrollWidgetState): void { - dom.clearNode(this._lineNumbersDomNode); - dom.clearNode(this._linesDomNode); + setState(state: StickyScrollWidgetState | undefined): void { + this._clearStickyWidget(); + if (!state) { + return; + } this._stickyLines = []; const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); const futureWidgetHeight = state.startLineNumbers.length * editorLineHeight + state.lastLineRelativePosition; @@ -129,6 +131,12 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._rootDomNode.style.width = `${layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth}px`; } + private _clearStickyWidget() { + dom.clearNode(this._lineNumbersDomNode); + dom.clearNode(this._linesDomNode); + this._rootDomNode.style.display = 'none'; + } + private _renderRootNode(): void { if (!this._editor._getViewModel()) { @@ -145,7 +153,11 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); const widgetHeight: number = this._lineNumbers.length * editorLineHeight + this._lastLineRelativePosition; - this._rootDomNode.style.display = widgetHeight > 0 ? 'block' : 'none'; + if (widgetHeight === 0) { + this._clearStickyWidget(); + return; + } + this._rootDomNode.style.display = 'block'; this._lineNumbersDomNode.style.height = `${widgetHeight}px`; this._linesDomNodeScrollable.style.height = `${widgetHeight}px`; this._rootDomNode.style.height = `${widgetHeight}px`; From 65068af4f74187ca06e763f93ddee46d10511002 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 11:28:16 +0200 Subject: [PATCH 1147/1180] Fixes #191144 --- .../browser/parts/editor/editorCommands.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 044bd29da9e9e..77c8985611a82 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -361,6 +361,13 @@ function registerDiffEditorCommands(): void { handler: accessor => navigateInDiffEditor(accessor, true) }); + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: GOTO_NEXT_CHANGE, + title: { value: localize('compare.nextChange', "Go to Next Change"), original: 'Go to Next Change' }, + } + }); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: GOTO_PREVIOUS_CHANGE, weight: KeybindingWeight.WorkbenchContrib, @@ -369,6 +376,13 @@ function registerDiffEditorCommands(): void { handler: accessor => navigateInDiffEditor(accessor, false) }); + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: GOTO_PREVIOUS_CHANGE, + title: { value: localize('compare.previousChange', "Go to Previous Change"), original: 'Go to Previous Change' }, + } + }); + function getActiveTextDiffEditor(accessor: ServicesAccessor): TextDiffEditor | undefined { const editorService = accessor.get(IEditorService); From eac8efd2cd1ff9dfa1bc40e7c24c7cafe20f4523 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 11:56:40 +0200 Subject: [PATCH 1148/1180] fix #189339 (#191187) --- src/vs/workbench/browser/parts/views/treeView.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index c5dc8bf57e396..62ca965951c16 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -613,7 +613,7 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { // Pass Focus to Viewer this.tree.domFocus(); - } else if (this.tree) { + } else if (this.tree && this.treeContainer && !this.treeContainer.classList.contains('hide')) { this.tree.domFocus(); } else { this.domNode.focus(); @@ -1017,6 +1017,9 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { this.domNode.setAttribute('tabindex', '0'); } else if (this.treeContainer) { this.treeContainer.classList.remove('hide'); + if (this.domNode === DOM.getActiveElement()) { + this.focus(); + } this.domNode.removeAttribute('tabindex'); } } From 681cd1b481c17b556123f3fafbd4bba8a3d366c3 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 12:01:19 +0200 Subject: [PATCH 1149/1180] Fixes https://github.com/microsoft/vscode/issues/187889 --- .../inlineCompletions/browser/inlineCompletionsController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts index 51b2d4fc56265..094393e32c5b2 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts @@ -117,7 +117,7 @@ export class InlineCompletionsController extends Disposable { this._register(editor.onDidChangeCursorPosition(e => transaction(tx => { /** @description onDidChangeCursorPosition */ this.updateObservables(tx, VersionIdChangeReason.Other); - if (e.reason === CursorChangeReason.Explicit) { + if (e.reason === CursorChangeReason.Explicit || e.source === 'api') { this.model.get()?.stop(tx); } }))); From 92b1178b552431333feba64a270a514055e96ccc Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 12:37:34 +0200 Subject: [PATCH 1150/1180] Fixes #190325 --- .../diffEditorWidget2/accessibleDiffViewer.ts | 5 +-- src/vs/editor/common/core/offsetRange.ts | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts index d66333e1aec86..32f45d8518655 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts @@ -18,6 +18,7 @@ import { applyStyle } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { DiffReview } from 'vs/editor/browser/widget/diffReview'; import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; 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'; @@ -163,7 +164,7 @@ class ViewModel extends Disposable { const groups = this.groups.get(); if (!groups || groups.length <= 1) { return; } subtransaction(tx, tx => { - this._currentGroupIdx.set((this._currentGroupIdx.get() + groups.length + delta) % groups.length, tx); + this._currentGroupIdx.set(OffsetRange.ofLength(groups.length).clipCyclic(this._currentGroupIdx.get() + delta), tx); this._currentElementIdx.set(0, tx); }); } @@ -175,7 +176,7 @@ class ViewModel extends Disposable { const group = this.currentGroup.get(); if (!group || group.lines.length <= 1) { return; } transaction(tx => { - this._currentElementIdx.set((this._currentElementIdx.get() + group.lines.length + delta) % group.lines.length, tx); + this._currentElementIdx.set(OffsetRange.ofLength(group.lines.length).clip(this._currentElementIdx.get() + delta), tx); }); } diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts index d4129b1c532d5..27e60bca2df63 100644 --- a/src/vs/editor/common/core/offsetRange.ts +++ b/src/vs/editor/common/core/offsetRange.ts @@ -34,6 +34,10 @@ export class OffsetRange { return new OffsetRange(start, endExclusive); } + public static ofLength(length: number): OffsetRange { + return new OffsetRange(0, length); + } + constructor(public readonly start: number, public readonly endExclusive: number) { if (start > endExclusive) { throw new BugIndicatingError(`Invalid range: ${this.toString()}`); @@ -102,6 +106,36 @@ export class OffsetRange { public slice(arr: T[]): T[] { return arr.slice(this.start, this.endExclusive); } + + /** + * Returns the given value if it is contained in this instance, otherwise the closest value that is contained. + * The range must not be empty. + */ + public clip(value: number): number { + if (this.isEmpty) { + throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`); + } + return Math.max(this.start, Math.min(this.endExclusive - 1, value)); + } + + /** + * Returns `r := value + k * length` such that `r` is contained in this range. + * The range must not be empty. + * + * E.g. `[5, 10).clipCyclic(10) === 5`, `[5, 10).clipCyclic(11) === 6` and `[5, 10).clipCyclic(4) === 9`. + */ + public clipCyclic(value: number): number { + if (this.isEmpty) { + throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`); + } + if (value < this.start) { + return this.endExclusive - ((this.start - value) % this.length); + } + if (value >= this.endExclusive) { + return this.start + ((value - this.start) % this.length); + } + return value; + } } export class OffsetRangeSet { From 7b7f33106a88a315be47f4db1cd5358833f1a371 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 14:16:31 +0200 Subject: [PATCH 1151/1180] fix #189872 (#191206) --- .../contrib/extensions/browser/fileBasedRecommendations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts b/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts index b3417372e48f3..b886e41733869 100644 --- a/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts +++ b/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts @@ -281,7 +281,7 @@ export class FileBasedRecommendations extends ExtensionRecommendations { const language = model.getLanguageId(); const languageName = this.languageService.getLanguageName(language); if (importantRecommendations.size && - this.promptRecommendedExtensionForFileType(languageName && isImportantRecommendationForLanguage && language !== PLAINTEXT_LANGUAGE_ID ? localize('languageName', "{0} language", languageName) : basename(uri), language, [...importantRecommendations])) { + this.promptRecommendedExtensionForFileType(languageName && isImportantRecommendationForLanguage && language !== PLAINTEXT_LANGUAGE_ID ? localize('languageName', "the {0} language", languageName) : basename(uri), language, [...importantRecommendations])) { return; } } From 1e8ccdc0ff61b62177be63644c5526252b961e9b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 14:25:39 +0200 Subject: [PATCH 1152/1180] #189481 scope to web (#191204) --- .../browser/userDataSyncWorkbenchService.ts | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index 0668f9e3b6a5b..d509a21c76c5b 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -171,17 +171,19 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } private async initialize(): Promise { - const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); - if (this.currentSessionId === undefined && authenticationSession?.id) { - if (this.environmentService.options?.settingsSyncOptions?.authenticationProvider && this.environmentService.options.settingsSyncOptions.enabled) { - this.currentSessionId = authenticationSession.id; - } + if (isWeb) { + const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); + if (this.currentSessionId === undefined && authenticationSession?.id) { + if (this.environmentService.options?.settingsSyncOptions?.authenticationProvider && this.environmentService.options.settingsSyncOptions.enabled) { + this.currentSessionId = authenticationSession.id; + } - // Backward compatibility - else if (this.useWorkbenchSessionId) { - this.currentSessionId = authenticationSession.id; + // Backward compatibility + else if (this.useWorkbenchSessionId) { + this.currentSessionId = authenticationSession.id; + } + this.useWorkbenchSessionId = false; } - this.useWorkbenchSessionId = false; } await this.update(); From cafcb59c16b5fcb2ae2db76cea0ba2596df8b7db Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 14:32:29 +0200 Subject: [PATCH 1153/1180] fix #190228 (#191207) --- .../workbench/contrib/extensions/browser/extensionEditor.ts | 6 ++---- .../contrib/extensions/browser/media/extensionEditor.css | 4 ---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 0eb852277abf1..cbd45d0ebeb18 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -855,12 +855,10 @@ 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 <= 6) { + } else if (manifest.extensionPack!.length < 5) { 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 174b332538b3c..575e6870b54ca 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css @@ -517,10 +517,6 @@ 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 0050133a605178b015565e3b02c2e418d2fe8e3b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 14:47:28 +0200 Subject: [PATCH 1154/1180] fix #189574 (#191209) --- .../common/abstractExtensionManagementService.ts | 2 +- .../contrib/extensions/browser/extensions.contribution.ts | 2 +- .../contrib/extensions/browser/extensionsWorkbenchService.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index 829a9b679c9d2..bcbc16146d7c7 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -154,7 +154,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } async toggleAppliationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise { - if (isApplicationScopedExtension(extension.manifest)) { + if (isApplicationScopedExtension(extension.manifest) || extension.isBuiltin) { return extension; } diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 78f7de871fa2e..3d40bfa801d0c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -1421,7 +1421,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi menu: { id: MenuId.ExtensionContext, group: '2_configure', - when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate()), + when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate(), ContextKeyExpr.has('isBuiltinExtension').negate()), order: 3 }, run: async (accessor: ServicesAccessor, id: string) => { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 96659a5f22864..154696503e33e 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -1622,7 +1622,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } async toggleApplyExtensionToAllProfiles(extension: IExtension): Promise { - if (!extension.local || isApplicationScopedExtension(extension.local.manifest)) { + if (!extension.local || isApplicationScopedExtension(extension.local.manifest) || extension.isBuiltin) { return; } await this.extensionManagementService.toggleAppliationScope(extension.local, this.userDataProfileService.currentProfile.extensionsResource); From 1e822ef3f504b3940b26b1a1de1941ea06dafe48 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 24 Aug 2023 15:00:47 +0200 Subject: [PATCH 1155/1180] fix #190363 (#191210) --- .../browser/userDataProfileImportExportService.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts index cea4e9de5f832..9dc107dd7fbfd 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts @@ -324,14 +324,15 @@ export class UserDataProfileImportExportService extends Disposable implements IU let result: { name: string; items: ReadonlyArray } | undefined; disposables.add(Event.any(quickPick.onDidCustom, quickPick.onDidAccept)(() => { - if (!quickPick.value) { - quickPick.validationMessage = localize('name required', "Provide a name for the new profile"); + const name = quickPick.value.trim(); + if (!name) { + quickPick.validationMessage = localize('name required', "Profile name is required and must be a non-empty value."); quickPick.severity = Severity.Error; } if (quickPick.validationMessage) { return; } - result = { name: quickPick.value, items: quickPick.selectedItems }; + result = { name, items: quickPick.selectedItems }; quickPick.hide(); quickPick.severity = Severity.Ignore; quickPick.validationMessage = undefined; From e64b9487bfa0aa84ae43aad57a0555a3cf20ef8f Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 13:00:54 +0200 Subject: [PATCH 1156/1180] Fixes #189039 --- .../browser/widget/diffEditorWidget2/diffEditorEditors.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts index ee764c81aedf3..877f79ce430d4 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts @@ -50,6 +50,8 @@ export class DiffEditorEditors extends Disposable { /** @description update editor options */ _options.editorOptions.read(reader); + this._options.renderSideBySide.read(reader); + this.modified.updateOptions(this._adjustOptionsForRightHandSide(reader, changeSummary)); this.original.updateOptions(this._adjustOptionsForLeftHandSide(reader, changeSummary)); })); @@ -93,7 +95,11 @@ export class DiffEditorEditors extends Disposable { result.wordWrapOverride1 = 'off'; result.wordWrapOverride2 = 'off'; result.stickyScroll = { enabled: false }; + + // Disable unicode highlighting for the original side in inline mode, as they are not shown anyway. + result.unicodeHighlight = { nonBasicASCII: false, ambiguousCharacters: false, invisibleCharacters: false }; } else { + result.unicodeHighlight = this._options.editorOptions.get().unicodeHighlight; result.wordWrapOverride1 = this._options.diffWordWrap.get(); } if (changedOptions.originalAriaLabel) { From 06f6caff51dafa6e9a855e4e747085047ecb8f4b Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 11:03:02 +0200 Subject: [PATCH 1157/1180] Renames smart to legacy, standard to advanced --- src/vs/editor/browser/editorBrowser.ts | 2 +- src/vs/editor/browser/services/editorWorkerService.ts | 2 +- src/vs/editor/browser/widget/diffEditorWidget.ts | 2 +- .../widget/diffEditorWidget2/diffEditorViewModel.ts | 4 ++-- .../browser/widget/diffEditorWidget2/diffEditorWidget2.ts | 2 +- src/vs/editor/browser/widget/diffNavigator.ts | 2 +- src/vs/editor/browser/widget/diffReview.ts | 2 +- ...dLinesDiffComputer.ts => advancedLinesDiffComputer.ts} | 2 +- src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts | 2 +- ...artLinesDiffComputer.ts => legacyLinesDiffComputer.ts} | 2 +- src/vs/editor/common/diff/linesDiffComputers.ts | 8 ++++---- src/vs/editor/common/services/editorSimpleWorker.ts | 2 +- src/vs/editor/common/services/editorWorker.ts | 2 +- src/vs/editor/test/common/diff/diffComputer.test.ts | 2 +- .../test/common/services/testEditorWorkerService.ts | 2 +- src/vs/editor/test/node/diffing/diffingFixture.test.ts | 6 +++--- src/vs/editor/test/node/diffing/lineRangeMapping.test.ts | 2 +- src/vs/workbench/api/browser/mainThreadEditors.ts | 2 +- src/vs/workbench/api/common/extHost.protocol.ts | 2 +- .../workbench/contrib/notebook/common/notebookCommon.ts | 2 +- .../workbench/contrib/scm/browser/dirtydiffDecorator.ts | 2 +- 21 files changed, 27 insertions(+), 27 deletions(-) rename src/vs/editor/common/diff/{standardLinesDiffComputer.ts => advancedLinesDiffComputer.ts} (99%) rename src/vs/editor/common/diff/{smartLinesDiffComputer.ts => legacyLinesDiffComputer.ts} (99%) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index ae6cfd542d332..1ea2dff1bb61a 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -15,7 +15,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { IWordAtPosition } from 'vs/editor/common/core/wordHelper'; import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/cursorEvents'; -import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { GlyphMarginLane, ICursorStateComputer, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration, ITextModel, PositionAffinity } from 'vs/editor/common/model'; import { InjectedText } from 'vs/editor/common/modelLineProjectionData'; diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index 6757066169ff7..993fe8e813ca9 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -24,7 +24,7 @@ import { canceled, onUnexpectedError } from 'vs/base/common/errors'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +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 { LineRange } from 'vs/editor/common/core/lineRange'; diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 4eae29a335efc..e1a43acbaf6a6 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -40,7 +40,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { StringBuilder } from 'vs/editor/common/core/stringBuilder'; -import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 8dea4d6cc5691..7927623f49b36 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -11,7 +11,7 @@ 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 { StandardLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { AdvancedLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/advancedLinesDiffComputer'; 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'; @@ -162,7 +162,7 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo debouncer.cancel(); contentChangedSignal.read(reader); documentDiffProviderOptionChanged.read(reader); - readHotReloadableExport(StandardLinesDiffComputer, reader); + readHotReloadableExport(AdvancedLinesDiffComputer, reader); this._isDiffUpToDate.set(false, undefined); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 5bc2b098e2b72..280c2bb7b9ae1 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -30,7 +30,7 @@ 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 { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +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'; import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; diff --git a/src/vs/editor/browser/widget/diffNavigator.ts b/src/vs/editor/browser/widget/diffNavigator.ts index 0f34a1e59601b..1edce99edf63c 100644 --- a/src/vs/editor/browser/widget/diffNavigator.ts +++ b/src/vs/editor/browser/widget/diffNavigator.ts @@ -10,7 +10,7 @@ import * as objects from 'vs/base/common/objects'; import { IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { ICursorPositionChangedEvent } from 'vs/editor/common/cursorEvents'; import { Range } from 'vs/editor/common/core/range'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; diff --git a/src/vs/editor/browser/widget/diffReview.ts b/src/vs/editor/browser/widget/diffReview.ts index ea813d85aa529..268d41d2f3b11 100644 --- a/src/vs/editor/browser/widget/diffReview.ts +++ b/src/vs/editor/browser/widget/diffReview.ts @@ -19,7 +19,7 @@ import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget'; import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { ILanguageIdCodec } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; diff --git a/src/vs/editor/common/diff/standardLinesDiffComputer.ts b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts similarity index 99% rename from src/vs/editor/common/diff/standardLinesDiffComputer.ts rename to src/vs/editor/common/diff/advancedLinesDiffComputer.ts index 20279a9fe68c5..61fd21d9c2908 100644 --- a/src/vs/editor/common/diff/standardLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts @@ -17,7 +17,7 @@ import { optimizeSequenceDiffs, removeRandomLineMatches, removeRandomMatches, sm import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm'; import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping, LinesDiff, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -export class StandardLinesDiffComputer implements ILinesDiffComputer { +export class AdvancedLinesDiffComputer implements ILinesDiffComputer { private readonly dynamicProgrammingDiffing = new DynamicProgrammingDiffing(); private readonly myersDiffingAlgorithm = new MyersDiffAlgorithm(); diff --git a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts index c79d557e40913..cef14d466c843 100644 --- a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts +++ b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts @@ -5,7 +5,7 @@ import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { ISequence, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; -import { LineSequence, LinesSliceCharSequence } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LineSequence, LinesSliceCharSequence } from 'vs/editor/common/diff/advancedLinesDiffComputer'; export function optimizeSequenceDiffs(sequence1: ISequence, sequence2: ISequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { let result = sequenceDiffs; diff --git a/src/vs/editor/common/diff/smartLinesDiffComputer.ts b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts similarity index 99% rename from src/vs/editor/common/diff/smartLinesDiffComputer.ts rename to src/vs/editor/common/diff/legacyLinesDiffComputer.ts index fe7fdcdc5bfb7..5ea6524a41ee7 100644 --- a/src/vs/editor/common/diff/smartLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts @@ -13,7 +13,7 @@ import { LineRange } from 'vs/editor/common/core/lineRange'; const MINIMUM_MATCHING_CHARACTER_LENGTH = 3; -export class SmartLinesDiffComputer implements ILinesDiffComputer { +export class LegacyLinesDiffComputer implements ILinesDiffComputer { computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff { const diffComputer = new DiffComputer(originalLines, modifiedLines, { maxComputationTime: options.maxComputationTimeMs, diff --git a/src/vs/editor/common/diff/linesDiffComputers.ts b/src/vs/editor/common/diff/linesDiffComputers.ts index 415c72e8f04bd..727b91455b79d 100644 --- a/src/vs/editor/common/diff/linesDiffComputers.ts +++ b/src/vs/editor/common/diff/linesDiffComputers.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SmartLinesDiffComputer } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; export const linesDiffComputers = { - getLegacy: () => new SmartLinesDiffComputer(), - getAdvanced: () => new StandardLinesDiffComputer(), + getLegacy: () => new LegacyLinesDiffComputer(), + getAdvanced: () => new AdvancedLinesDiffComputer(), }; diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 2c26721fd47b1..ca8364f62d3a4 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -20,7 +20,7 @@ import { createMonacoBaseAPI } from 'vs/editor/common/services/editorBaseApi'; 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/smartLinesDiffComputer'; +import { DiffComputer, IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers'; import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects'; diff --git a/src/vs/editor/common/services/editorWorker.ts b/src/vs/editor/common/services/editorWorker.ts index 9038e313a9c5c..9e1cca8a460de 100644 --- a/src/vs/editor/common/services/editorWorker.ts +++ b/src/vs/editor/common/services/editorWorker.ts @@ -6,7 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { IRange } from 'vs/editor/common/core/range'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IInplaceReplaceSupportResult, TextEdit } from 'vs/editor/common/languages'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/editor/test/common/diff/diffComputer.test.ts b/src/vs/editor/test/common/diff/diffComputer.test.ts index a8eb52b07c18e..aca599dc6e50d 100644 --- a/src/vs/editor/test/common/diff/diffComputer.test.ts +++ b/src/vs/editor/test/common/diff/diffComputer.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Constants } from 'vs/base/common/uint'; import { Range } from 'vs/editor/common/core/range'; -import { DiffComputer, ICharChange, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { DiffComputer, ICharChange, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; diff --git a/src/vs/editor/test/common/services/testEditorWorkerService.ts b/src/vs/editor/test/common/services/testEditorWorkerService.ts index 640a3e4b59676..e6693d821e99d 100644 --- a/src/vs/editor/test/common/services/testEditorWorkerService.ts +++ b/src/vs/editor/test/common/services/testEditorWorkerService.ts @@ -8,7 +8,7 @@ import { IRange } from 'vs/editor/common/core/range'; import { DiffAlgorithmName, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker'; import { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; export class TestEditorWorkerService implements IEditorWorkerService { diff --git a/src/vs/editor/test/node/diffing/diffingFixture.test.ts b/src/vs/editor/test/node/diffing/diffingFixture.test.ts index 59173290fc8cb..a04f2edf9d87b 100644 --- a/src/vs/editor/test/node/diffing/diffingFixture.test.ts +++ b/src/vs/editor/test/node/diffing/diffingFixture.test.ts @@ -9,8 +9,8 @@ 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 { SmartLinesDiffComputer } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; suite('diff fixtures', () => { setup(() => { @@ -38,7 +38,7 @@ suite('diff fixtures', () => { const secondContent = readFileSync(join(folderPath, secondFileName), 'utf8').replaceAll('\r\n', '\n').replaceAll('\r', '\n'); const secondContentLines = secondContent.split(/\n/); - const diffingAlgo = diffingAlgoName === 'legacy' ? new SmartLinesDiffComputer() : new StandardLinesDiffComputer(); + const diffingAlgo = diffingAlgoName === 'legacy' ? new LegacyLinesDiffComputer() : new AdvancedLinesDiffComputer(); const ignoreTrimWhitespace = folder.indexOf('trimws') >= 0; const diff = diffingAlgo.computeDiff(firstContentLines, secondContentLines, { ignoreTrimWhitespace, maxComputationTimeMs: Number.MAX_SAFE_INTEGER, computeMoves: false }); diff --git a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts index 5cda2c947945c..f0d0802912daa 100644 --- a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts +++ b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts @@ -6,7 +6,7 @@ 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/standardLinesDiffComputer'; +import { getLineRangeMapping } from 'vs/editor/common/diff/advancedLinesDiffComputer'; suite('lineRangeMapping', () => { test('1', () => { diff --git a/src/vs/workbench/api/browser/mainThreadEditors.ts b/src/vs/workbench/api/browser/mainThreadEditors.ts index 552241c27d748..b5e8bb0ef56fd 100644 --- a/src/vs/workbench/api/browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadEditors.ts @@ -23,7 +23,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { IEditorControl } from 'vs/workbench/common/editor'; import { getCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index e4964fb5670a0..82646f45caca7 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -19,7 +19,7 @@ import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; import * as languages from 'vs/editor/common/languages'; diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index e01a5c37361fa..90a0451aae13a 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -15,7 +15,7 @@ import { basename } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; import { ISplice } from 'vs/base/common/sequence'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { Command, WorkspaceEditMetadata } from 'vs/editor/common/languages'; import { IReadonlyTextBuffer } from 'vs/editor/common/model'; diff --git a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts index 41ac8d05a2bc1..589c0e5e99d1f 100644 --- a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts +++ b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts @@ -50,7 +50,7 @@ import { ThemeIcon } from 'vs/base/common/themables'; import { onUnexpectedError } from 'vs/base/common/errors'; import { TextCompareEditorActiveContext } from 'vs/workbench/common/contextkeys'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { Color } from 'vs/base/common/color'; import { ResourceMap } from 'vs/base/common/map'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; From 905931a8683a6e4e51e15ce4f116aae976752eb7 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 11:29:53 +0200 Subject: [PATCH 1158/1180] 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 ff4febe8ce66b..89c884f18a01f 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -107,7 +107,7 @@ export interface ICommandHandler { #include(vs/editor/common/core/editOperation): ISingleEditOperation #include(vs/editor/common/core/wordHelper): IWordAtPosition #includeAll(vs/editor/common/model): IScrollEvent -#include(vs/editor/common/diff/smartLinesDiffComputer): IChange, ICharChange, ILineChange +#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 From 1f9f663d1d0329e8e8b6e79bc73d3f237e5a87b8 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 13:13:28 +0200 Subject: [PATCH 1159/1180] Fixes #189327 --- .../diffEditorWidget2/diffEditorViewModel.ts | 13 +++++++++++-- .../widget/workerBasedDocumentDiffProvider.ts | 15 +++++++++++++-- src/vs/editor/common/diff/documentDiffProvider.ts | 3 ++- src/vs/monaco.d.ts | 2 +- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 7927623f49b36..a41ba6a99094f 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { RunOnceScheduler } from 'vs/base/common/async'; -import { Disposable } from 'vs/base/common/lifecycle'; +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 { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange'; @@ -19,6 +19,7 @@ import { combineTextEditInfos } from 'vs/editor/common/model/bracketPairsTextMod 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); @@ -64,6 +65,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo this._hoveredMovedText.set(movedText, undefined); } + private readonly _cancellationTokenSource = new CancellationTokenSource(); + constructor( public readonly model: IDiffEditorModel, private readonly _options: DiffEditorOptions, @@ -71,6 +74,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ) { super(); + this._register(toDisposable(() => this._cancellationTokenSource.cancel())); + const contentChangedSignal = observableSignal('contentChangedSignal'); const debouncer = this._register(new RunOnceScheduler(() => contentChangedSignal.trigger(undefined), 200)); @@ -182,7 +187,11 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ignoreTrimWhitespace: this._options.ignoreTrimWhitespace.read(reader), maxComputationTimeMs: this._options.maxComputationTimeMs.read(reader), computeMoves: this._options.showMoves.read(reader), - }); + }, this._cancellationTokenSource.token); + + if (this._cancellationTokenSource.token.isCancellationRequested) { + return; + } result = applyOriginalEdits(result, originalTextEditInfos, model.original, model.modified) ?? result; result = applyModifiedEdits(result, modifiedTextEditInfos, model.original, model.modified) ?? result; diff --git a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts index cca1f5ab297c1..648ba44763c21 100644 --- a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts +++ b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -34,9 +35,9 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I this.diffAlgorithmOnDidChangeSubscription?.dispose(); } - async computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise { + async computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise { if (typeof this.diffAlgorithm !== 'string') { - return this.diffAlgorithm.computeDiff(original, modified, options); + return this.diffAlgorithm.computeDiff(original, modified, options, cancellationToken); } // This significantly speeds up the case when the original file is empty @@ -95,6 +96,16 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I timedOut: result?.quitEarly ?? true, }); + if (cancellationToken.isCancellationRequested) { + // Text models might be disposed! + return { + changes: [], + identical: false, + quitEarly: true, + moves: [], + }; + } + if (!result) { throw new Error('no diff result available'); } diff --git a/src/vs/editor/common/diff/documentDiffProvider.ts b/src/vs/editor/common/diff/documentDiffProvider.ts index ad707d114b5ad..02907dddca3f8 100644 --- a/src/vs/editor/common/diff/documentDiffProvider.ts +++ b/src/vs/editor/common/diff/documentDiffProvider.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; import { ITextModel } from 'vs/editor/common/model'; @@ -14,7 +15,7 @@ export interface IDocumentDiffProvider { /** * Computes the diff between the text models `original` and `modified`. */ - computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise; + computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise; /** * Is fired when settings of the diff algorithm change that could alter the result of the diffing computation. diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 544197938c258..2d030c3fa23f1 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2374,7 +2374,7 @@ declare namespace monaco.editor { /** * Computes the diff between the text models `original` and `modified`. */ - computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise; + computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise; /** * Is fired when settings of the diff algorithm change that could alter the result of the diffing computation. * Any user of this provider should recompute the diff when this event is fired. From 4d9f1fc9c92bde758245ed28aa3a8389d5f4d745 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 14:37:09 +0200 Subject: [PATCH 1160/1180] Fixes CI --- src/vs/editor/browser/widget/diffEditorWidget.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index e1a43acbaf6a6..5588ae6f5ec27 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -11,6 +11,7 @@ import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor import { IBoundarySashes, ISashEvent, IVerticalSashLayoutProvider, Orientation, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; import * as assert from 'vs/base/common/assert'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; import { Color } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -1186,7 +1187,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE ignoreTrimWhitespace: this._options.ignoreTrimWhitespace, maxComputationTimeMs: this._options.maxComputationTime, computeMoves: false, - }).then(result => { + }, CancellationToken.None).then(result => { if (currentToken === this._diffComputationToken && currentOriginalModel === this._originalEditor.getModel() && currentModifiedModel === this._modifiedEditor.getModel() From 94ad4e5e1fb341c48ebda57b786e5785f0338e85 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 08:13:35 -0700 Subject: [PATCH 1161/1180] address feedback --- .../terminal.accessibility.contribution.ts | 10 +---- .../browser/terminalAccessibleWidget.ts | 40 +++++++++---------- 2 files changed, 21 insertions(+), 29 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 4eb13c439a680..96b9602e45d4f 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 @@ -48,7 +48,7 @@ class TextAreaSyncContribution extends DisposableStore implements ITerminalContr } registerTerminalContribution(TextAreaSyncContribution.ID, TextAreaSyncContribution); -export class AccessibleBufferContribution extends DisposableStore implements ITerminalContribution { +class AccessibleBufferContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.accessible-buffer'; private _xterm: IXtermTerminal & { raw: Terminal } | undefined; static get(instance: ITerminalInstance): AccessibleBufferContribution | null { @@ -220,13 +220,7 @@ registerTerminalAction({ precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), run: async (c) => { const instance = c.service.activeInstance || await c.service.createTerminal({ location: TerminalLocation.Panel }); - if (!instance) { - return; - } - const contribution = instance.getContribution('terminal.accessible-buffer'); - if (contribution) { - contribution.hide(); - } + instance.getContribution(AccessibleBufferContribution.ID)?.hide(); instance.focus(true); } }); diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index 77fd61739349c..f25793c1da9cb 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -40,16 +40,16 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { protected _listeners: IDisposable[] = []; - private readonly _focusedContextKey?: IContextKey; - private readonly _focusedLastLineContextKey?: IContextKey; + private readonly _focusedContextKey: IContextKey; + private readonly _focusedLastLineContextKey: IContextKey; private readonly _focusTracker?: dom.IFocusTracker; constructor( private readonly _className: string, protected readonly _instance: Pick, protected readonly _xterm: Pick & { raw: Terminal }, - private _focusContextKey: RawContextKey | undefined, - private _focusLastLineContextKey: RawContextKey | undefined, + private rawFocusContextKey: RawContextKey, + private rawFocusLastLineContextKey: RawContextKey, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IModelService private readonly _modelService: IModelService, @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -89,23 +89,21 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._element.replaceChildren(this._editorContainer); this._xtermElement.insertAdjacentElement('beforebegin', this._element); - if (this._focusContextKey && this._focusLastLineContextKey) { - this._focusTracker = this.add(dom.trackFocus(this._editorContainer)); - this._focusedContextKey = this._focusContextKey.bindTo(this._contextKeyService); - this._focusedLastLineContextKey = this._focusLastLineContextKey.bindTo(this._contextKeyService); - this.add(this._focusTracker.onDidFocus(() => { - this._focusedContextKey?.set(true); - this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); - })); - this.add(this._focusTracker.onDidBlur(() => { - this._focusedContextKey?.reset(); - this._focusedLastLineContextKey?.reset(); - })); - this._editorWidget.onDidChangeCursorPosition(() => { - console.log(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); - this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); - }); - } + this._focusTracker = this.add(dom.trackFocus(this._editorContainer)); + this._focusedContextKey = this.rawFocusContextKey.bindTo(this._contextKeyService); + this._focusedLastLineContextKey = this.rawFocusLastLineContextKey.bindTo(this._contextKeyService); + this.add(this._focusTracker.onDidFocus(() => { + this._focusedContextKey?.set(true); + this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + })); + this.add(this._focusTracker.onDidBlur(() => { + this._focusedContextKey?.reset(); + this._focusedLastLineContextKey?.reset(); + })); + this._editorWidget.onDidChangeCursorPosition(() => { + console.log(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + }); this.add(Event.runAndSubscribe(this._xterm.raw.onResize, () => this.layout())); this.add(this._configurationService.onDidChangeConfiguration(e => { From d1173ce59c051da9dd551a16b31d628d20a267be Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 08:28:10 -0700 Subject: [PATCH 1162/1180] rm private --- .../accessibility/browser/terminalAccessibleWidget.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index f25793c1da9cb..b95d8814f1eb9 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -48,8 +48,8 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { private readonly _className: string, protected readonly _instance: Pick, protected readonly _xterm: Pick & { raw: Terminal }, - private rawFocusContextKey: RawContextKey, - private rawFocusLastLineContextKey: RawContextKey, + rawFocusContextKey: RawContextKey, + rawFocusLastLineContextKey: RawContextKey, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IModelService private readonly _modelService: IModelService, @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -90,8 +90,8 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._xtermElement.insertAdjacentElement('beforebegin', this._element); this._focusTracker = this.add(dom.trackFocus(this._editorContainer)); - this._focusedContextKey = this.rawFocusContextKey.bindTo(this._contextKeyService); - this._focusedLastLineContextKey = this.rawFocusLastLineContextKey.bindTo(this._contextKeyService); + this._focusedContextKey = rawFocusContextKey.bindTo(this._contextKeyService); + this._focusedLastLineContextKey = rawFocusLastLineContextKey.bindTo(this._contextKeyService); this.add(this._focusTracker.onDidFocus(() => { this._focusedContextKey?.set(true); this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); From 52771a40c46c2c6e982acf211c7337e7d4b36079 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 08:34:39 -0700 Subject: [PATCH 1163/1180] reuse var --- .../accessibility/browser/terminalAccessibleBuffer.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index 0835367c86e5b..f8fc9a2c500e6 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -110,8 +110,9 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } private _getCommandsWithEditorLine(): ICommandWithEditorLine[] | undefined { - const commands = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.commands; - const currentCommand = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.currentCommand; + const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); + const commands = capability?.commands; + const currentCommand = capability?.currentCommand; if (!commands?.length) { return; } From c0655c7c1725ad4c3494686f7be925838810f97d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 09:05:28 -0700 Subject: [PATCH 1164/1180] fix #188329 --- .../browser/terminal.accessibility.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 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 96b9602e45d4f..0efe30d072dc0 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 @@ -117,8 +117,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.CtrlCmd | KeyCode.UpArrow, + secondary: [KeyMod.Alt | KeyCode.F2], weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, TerminalContextKeys.focus, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } From f52b2d78e9f4a2b564a465fb0ba9e63f7622b513 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 09:09:59 -0700 Subject: [PATCH 1165/1180] Revert "fix #188329" This reverts commit c0655c7c1725ad4c3494686f7be925838810f97d. --- .../browser/terminal.accessibility.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 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 0efe30d072dc0..96b9602e45d4f 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 @@ -117,8 +117,8 @@ registerTerminalAction({ precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), keybinding: [ { - primary: KeyMod.CtrlCmd | KeyCode.UpArrow, - secondary: [KeyMod.Alt | KeyCode.F2], + primary: KeyMod.Shift | KeyCode.Tab, + secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow, KeyMod.Alt | KeyCode.F2], weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, TerminalContextKeys.focus, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } From 3bed7cfbdbde8c3370e040b9c8b8d9462a0c23b3 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 16:57:19 +0200 Subject: [PATCH 1166/1180] Fixes #190422 --- .../inlineCompletions/browser/commands.ts | 3 +- .../browser/inlineCompletionsHintsWidget.css | 2 +- .../browser/inlineCompletionsHintsWidget.ts | 56 ++++++++++++++----- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts index 799433568e0a0..ac7535f923173 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts @@ -148,7 +148,8 @@ export class AcceptInlineCompletion extends EditorAction { InlineCompletionContextKeys.inlineSuggestionVisible, EditorContextKeys.tabMovesFocus.toNegated(), InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize, - SuggestContext.Visible.toNegated() + SuggestContext.Visible.toNegated(), + EditorContextKeys.hoverFocused.toNegated(), ), } }); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css index 642e6c51d7aa9..196307cc49e53 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css @@ -29,7 +29,7 @@ padding: 2px 3px; } -.monaco-editor .inlineSuggestionsHints .custom-actions .action-item:nth-child(2) a { +.monaco-editor .inlineSuggestionsHints .availableSuggestionCount a { display: flex; min-width: 19px; justify-content: center; diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts index eb9aa10b05cc8..0cde6e9a9b5f8 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { h } from 'vs/base/browser/dom'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { KeybindingLabel, unthemedKeybindingLabelOptions } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { equals } from 'vs/base/common/arrays'; @@ -112,10 +112,7 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC public readonly suppressMouseDown = false; private readonly nodes = h('div.inlineSuggestionsHints', { className: this.withBorder ? '.withBorder' : '' }, [ - h('div', { style: { display: 'flex' } }, [ - h('div@actionBar', { className: 'custom-actions' }), - h('div@toolBar'), - ]) + h('div@toolBar'), ]); private createCommandAction(commandId: string, label: string, iconClassName: string): Action { @@ -173,21 +170,29 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC ) { super(); - const actionBar = this._register(new ActionBar(this.nodes.actionBar)); - - actionBar.push(this.previousAction, { icon: true, label: false }); - actionBar.push(this.availableSuggestionCountAction); - actionBar.push(this.nextAction, { icon: true, label: false }); - this.toolBar = this._register(instantiationService.createInstance(CustomizedMenuWorkbenchToolBar, this.nodes.toolBar, MenuId.InlineSuggestionToolbar, { menuOptions: { renderShortTitle: true }, toolbarOptions: { primaryGroup: g => g.startsWith('primary') }, actionViewItemProvider: (action, options) => { - return action instanceof MenuItemAction ? instantiationService.createInstance(StatusBarViewItem, action, undefined) : undefined; + if (action instanceof MenuItemAction) { + return instantiationService.createInstance(StatusBarViewItem, action, undefined); + } + if (action === this.availableSuggestionCountAction) { + const a = new ActionViewItemWithClassName(undefined, action, { label: true, icon: false }); + a.setClass('availableSuggestionCount'); + return a; + } + return undefined; }, telemetrySource: 'InlineSuggestionToolbar', })); + this.toolBar.setPrependedPrimaryActions([ + this.previousAction, + this.availableSuggestionCountAction, + this.nextAction, + ]); + this._register(this.toolBar.onDidChangeDropdownVisibility(e => { InlineSuggestionHintsContentWidget._dropDownVisible = e; })); @@ -270,6 +275,21 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC } } +class ActionViewItemWithClassName extends ActionViewItem { + private _className: string | undefined = undefined; + + setClass(className: string | undefined): void { + this._className = className; + } + + override render(container: HTMLElement): void { + super.render(container); + if (this._className) { + container.classList.add(this._className); + } + } +} + class StatusBarViewItem extends MenuEntryActionViewItem { protected override updateLabel() { const kb = this._keybindingService.lookupKeybinding(this._action.id, this._contextKeyService); @@ -291,6 +311,7 @@ class StatusBarViewItem extends MenuEntryActionViewItem { export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { private readonly menu = this._store.add(this.menuService.createMenu(this.menuId, this.contextKeyService, { emitEventsForSubmenuChanges: true })); private additionalActions: IAction[] = []; + private prependedPrimaryActions: IAction[] = []; constructor( container: HTMLElement, @@ -319,12 +340,21 @@ export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { ); secondary.push(...this.additionalActions); + primary.unshift(...this.prependedPrimaryActions); this.setActions(primary, secondary); } + setPrependedPrimaryActions(actions: IAction[]): void { + if (equals(this.prependedPrimaryActions, actions, (a, b) => a === b)) { + return; + } + + this.prependedPrimaryActions = actions; + this.updateToolbar(); + } + setAdditionalSecondaryActions(actions: IAction[]): void { if (equals(this.additionalActions, actions, (a, b) => a === b)) { - // don't update if the actions are the same return; } From 3fbf0442d354acd412eaee43ef8ba90bfd9ac4cb Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 24 Aug 2023 09:44:27 -0700 Subject: [PATCH 1167/1180] tunnels: fix forgotten event listener (#191228) Was accidentally removed removed during a PR comment followup Fixes #190859 --- src/vs/platform/tunnel/node/tunnelService.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/platform/tunnel/node/tunnelService.ts b/src/vs/platform/tunnel/node/tunnelService.ts index 0894400360dfb..f28dc9e22715d 100644 --- a/src/vs/platform/tunnel/node/tunnelService.ts +++ b/src/vs/platform/tunnel/node/tunnelService.ts @@ -19,6 +19,7 @@ import { IAddressProvider, IConnectionOptions, connectRemoteAgentTunnel } from ' import { IRemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService'; import { ISignService } from 'vs/platform/sign/common/sign'; import { AbstractTunnelService, ISharedTunnelsService, ITunnelProvider, ITunnelService, RemoteTunnel, TunnelPrivacyId, isAllInterfaces, isLocalhost, isPortPrivileged, isTunnelProvider } from 'vs/platform/tunnel/common/tunnel'; +import { VSBuffer } from 'vs/base/common/buffer'; async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost: string, tunnelRemoteHost: string, tunnelRemotePort: number, tunnelLocalPort?: number): Promise { let readyTunnel: NodeRemoteTunnel | undefined; @@ -159,6 +160,7 @@ export class NodeRemoteTunnel extends Disposable implements RemoteTunnel { remoteSocket.onClose(() => localSocket.destroy()); remoteSocket.onEnd(() => localSocket.end()); remoteSocket.onData(d => localSocket.write(d.buffer)); + localSocket.on('data', d => remoteSocket.write(VSBuffer.wrap(d))); localSocket.resume(); } From 6acb0ecd042d3db44604497e3ab82644bd0787e7 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 18:53:22 +0200 Subject: [PATCH 1168/1180] Fixes #188070 --- .../threadedBackgroundTokenizerFactory.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts b/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts index b121441fd7831..9558ffdd75e64 100644 --- a/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts +++ b/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts @@ -63,7 +63,7 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable { const controllerContainer = this._getWorkerProxy().then((workerProxy) => { if (store.isDisposed || !workerProxy) { return undefined; } - const controllerContainer = { controller: undefined as undefined | TextMateWorkerTokenizerController }; + const controllerContainer = { controller: undefined as undefined | TextMateWorkerTokenizerController, worker: this._worker }; store.add(keepAliveWhenAttached(textModel, () => { const controller = new TextMateWorkerTokenizerController(textModel, workerProxy, this._languageService.languageIdCodec, tokenStore, this._configurationService, maxTokenizationLineLength); controllerContainer.controller = controller; @@ -82,10 +82,12 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable { store.dispose(); }, requestTokens: async (startLineNumber, endLineNumberExclusive) => { - const controller = (await controllerContainer)?.controller; - if (controller) { - // If there is no controller, the model has been detached in the meantime - controller.requestTokens(startLineNumber, endLineNumberExclusive); + const container = await controllerContainer; + + // If there is no controller, the model has been detached in the meantime. + // Only request the proxy object if the worker is the same! + if (container?.controller && container.worker === this._worker) { + container.controller.requestTokens(startLineNumber, endLineNumberExclusive); } }, reportMismatchingTokens: (lineNumber) => { From c520db561ce3ffbb9d9507f0a61f4cd375609c17 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 10:52:37 -0700 Subject: [PATCH 1169/1180] fix #189864 --- .../browser/accessibilityContributions.ts | 2 +- .../accessibility/browser/accessibleView.ts | 25 ++++++++++--------- .../browser/accessibleViewActions.ts | 4 +-- .../browser/actions/chatAccessibilityHelp.ts | 2 +- .../browser/accessibility/accessibility.css | 2 +- .../codeEditor/browser/diffEditorHelper.ts | 2 +- .../notebook/browser/notebookAccessibility.ts | 2 +- .../browser/terminalAccessibilityHelp.ts | 16 ++++++------ 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts index 1baf82143d41e..cfab22c7cc3ce 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts @@ -101,7 +101,7 @@ class AccessibilityHelpProvider implements IAccessibleContentProvider { } else { content.push(this._descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOffMsg, AccessibilityHelpNLS.tabFocusModeOffMsgNoKb)); } - return content.join('\n'); + return content.join('\n\n'); } } diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 68302f41952af..617c87028f86a 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -3,13 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { EventType, addDisposableListener } from 'vs/base/browser/dom'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { alert } from 'vs/base/browser/ui/aria/aria'; +import { IAction } from 'vs/base/common/actions'; +import { Codicon } from 'vs/base/common/codicons'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { marked } from 'vs/base/common/marked/marked'; import { isMacintosh } from 'vs/base/common/platform'; +import { ThemeIcon } from 'vs/base/common/themables'; import { URI } from 'vs/base/common/uri'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions'; @@ -20,6 +24,7 @@ import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings'; import { CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeActionController'; import { localize } from 'vs/nls'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { WorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -31,14 +36,9 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; -import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; import { AccessibilityVerbositySettingId, accessibilityHelpIsShown, accessibleViewCurrentProviderId, accessibleViewGoToSymbolSupported, accessibleViewIsShown, accessibleViewSupportsNavigation, accessibleViewVerbosityEnabled } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; +import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; -import { IAction } from 'vs/base/common/actions'; -import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { Codicon } from 'vs/base/common/codicons'; -import { ThemeIcon } from 'vs/base/common/themables'; -import { addDisposableListener, EventType } from 'vs/base/browser/dom'; const enum DIMENSIONS { MAX_WIDTH = 600 @@ -108,6 +108,7 @@ class AccessibleView extends Disposable { private _editorContainer: HTMLElement; private _currentProvider: IAccessibleContentProvider | undefined; private readonly _toolbar: WorkbenchToolBar; + private _currentContent: string | undefined; constructor( @IOpenerService private readonly _openerService: IOpenerService, @@ -217,10 +218,10 @@ class AccessibleView extends Disposable { } getSymbols(): IAccessibleViewSymbol[] | undefined { - if (!this._currentProvider) { + if (!this._currentProvider || !this._currentContent) { return; } - const tokens = this._currentProvider.options.language && this._currentProvider.options.language !== 'markdown' ? this._currentProvider.getSymbols?.() : marked.lexer(this._currentProvider.provideContent()); + const tokens = this._currentProvider.options.language && this._currentProvider.options.language !== 'markdown' ? this._currentProvider.getSymbols?.() : marked.lexer(this._currentContent); if (!tokens) { return; } @@ -299,7 +300,7 @@ class AccessibleView extends Disposable { } this._updateContextKeys(provider, true); const value = this._configurationService.getValue(provider.verbositySettingKey); - const readMoreLink = provider.options.readMoreUrl ? localize("openDoc", "\nPress H now to open a browser window with more information related to accessibility.\n") : ''; + const readMoreLink = provider.options.readMoreUrl ? localize("openDoc", "\n\nPress H now to open a browser window with more information related to accessibility.\n\n") : ''; let disableHelpHint = ''; if (provider.options.type === AccessibleViewType.Help && !!value) { disableHelpHint = this._getDisableVerbosityHint(provider.verbositySettingKey); @@ -321,9 +322,9 @@ class AccessibleView extends Disposable { } } - const fragment = message + provider.provideContent() + readMoreLink + disableHelpHint + localize('exit-tip', '\nExit this dialog via the Escape key.'); + this._currentContent = message + provider.provideContent() + readMoreLink + disableHelpHint + localize('exit-tip', '\n\nExit this dialog via the Escape key.'); - this._getTextModel(URI.from({ path: `accessible-view-${provider.verbositySettingKey}`, scheme: 'accessible-view', fragment })).then((model) => { + this._getTextModel(URI.from({ path: `accessible-view-${provider.verbositySettingKey}`, scheme: 'accessible-view', fragment: this._currentContent })).then((model) => { if (!model) { return; } @@ -424,7 +425,7 @@ class AccessibleView extends Disposable { if (!this._currentProvider) { return false; } - return this._currentProvider.options.language === 'markdown' || this._currentProvider.options.language === undefined || !!this._currentProvider.getSymbols; + return this._currentProvider.options.type === AccessibleViewType.Help || this._currentProvider.options.language === 'markdown' || this._currentProvider.options.language === undefined || !!this._currentProvider.getSymbols; } public showAccessibleViewHelp(): void { diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts index c62bcf7782b55..9133dc3fd8219 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts @@ -84,7 +84,7 @@ class AccessibleViewGoToSymbolAction extends Action2 { constructor() { super({ id: AccessibilityCommandId.GoToSymbol, - precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewGoToSymbolSupported), + precondition: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewGoToSymbolSupported), keybinding: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyO, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Period], @@ -95,7 +95,7 @@ class AccessibleViewGoToSymbolAction extends Action2 { commandPalette, { ...accessibleViewMenu, - when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation), + when: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewGoToSymbolSupported), } ], title: localize('editor.action.accessibleViewGoToSymbol', "Go To Symbol in Accessible View") diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts index f8c40b935f7bf..e277b37202187 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts @@ -45,7 +45,7 @@ export function getAccessibilityHelpText(accessor: ServicesAccessor, type: 'pane content.push(localize('inlineChat.toolbar', "Use tab to reach conditional parts like commands, status, message responses and more.")); } content.push(localize('chat.audioCues', "Audio cues can be changed via settings with a prefix of audioCues.chat. By default, if a request takes more than 4 seconds, you will hear an audio cue indicating that progress is still occurring.")); - return content.join('\n'); + return content.join('\n\n'); } function descriptionForCommand(commandId: string, msg: string, noKbMsg: string, keybindingService: IKeybindingService): string { diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css index 25fcb4b03d824..2e0a1c517537a 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css @@ -11,7 +11,7 @@ border: 2px solid var(--vscode-focusBorder); border-radius: 6px; margin-top: -1px; - z-index: 2550; + z-index: 2540; } .accessible-view-container .actions-container { diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index 1e0d06ff9b886..22148696b724c 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -107,7 +107,7 @@ function createScreenReaderHelp(): IDisposable { localize('msg1', "You are in a diff editor."), localize('msg2', "Press {0} or {1} to view the next or previous diff in the diff review mode that is optimized for screen readers.", next, previous), localize('msg3', "To control which audio cues should be played, the following settings can be configured: {0}.", keys.join(', ')), - ].join('\n'), + ].join('\n\n'), onClose: () => { codeEditor.focus(); }, diff --git a/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts b/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts index 790e9e8bdc395..a019db5693e98 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts @@ -34,7 +34,7 @@ export function getAccessibilityHelpText(accessor: ServicesAccessor): string { content.push(localize('notebook.changeCellType', 'The Change Cell to Code/Markdown commands are used to switch between cell types.')); - return content.join('\n'); + return content.join('\n\n'); } function descriptionForCommand(commandId: string, msg: string, noKbMsg: string, keybindingService: IKeybindingService): string { diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts index d3a0e3a592c33..2504d461fb225 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts @@ -75,18 +75,20 @@ export class TerminalAccessibleContentProvider extends Disposable implements IAc content.push(localize('commandPromptMigration', "Consider using powershell instead of command prompt for an improved experience")); } if (this._hasShellIntegration) { - content.push(localize('shellIntegration', "The terminal has a feature called shell integration that offers an enhanced experience and provides useful commands for screen readers such as:")); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToNextCommand, localize('goToNextCommand', 'Go to Next Command ({0})'), localize('goToNextCommandNoKb', 'Go to Next Command is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToPreviousCommand, localize('goToPreviousCommand', 'Go to Previous Command ({0})'), localize('goToPreviousCommandNoKb', 'Go to Previous Command is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.NavigateAccessibleBuffer, localize('navigateAccessibleBuffer', 'Navigate Accessible Buffer ({0})'), localize('navigateAccessibleBufferNoKb', 'Navigate Accessible Buffer is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('runRecentCommand', 'Run Recent Command ({0})'), localize('runRecentCommandNoKb', 'Run Recent Command is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.GoToRecentDirectory, localize('goToRecentDirectory', 'Go to Recent Directory ({0})'), localize('goToRecentDirectoryNoKb', 'Go to Recent Directory is currently not triggerable by a keybinding.'))); + const shellIntegrationCommandList = []; + shellIntegrationCommandList.push(localize('shellIntegration', "The terminal has a feature called shell integration that offers an enhanced experience and provides useful commands for screen readers such as:")); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToNextCommand, localize('goToNextCommand', 'Go to Next Command ({0})'), localize('goToNextCommandNoKb', 'Go to Next Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToPreviousCommand, localize('goToPreviousCommand', 'Go to Previous Command ({0})'), localize('goToPreviousCommandNoKb', 'Go to Previous Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.NavigateAccessibleBuffer, localize('navigateAccessibleBuffer', 'Navigate Accessible Buffer ({0})'), localize('navigateAccessibleBufferNoKb', 'Navigate Accessible Buffer is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('runRecentCommand', 'Run Recent Command ({0})'), localize('runRecentCommandNoKb', 'Run Recent Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.GoToRecentDirectory, localize('goToRecentDirectory', 'Go to Recent Directory ({0})'), localize('goToRecentDirectoryNoKb', 'Go to Recent Directory is currently not triggerable by a keybinding.'))); + content.push(shellIntegrationCommandList.join('\n')); } else { content.push(this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('goToRecentDirectoryNoShellIntegration', 'The Go to Recent Directory command ({0}) enables screen readers to easily navigate to a directory that has been used in the terminal.'), localize('goToRecentDirectoryNoKbNoShellIntegration', 'The Go to Recent Directory command enables screen readers to easily navigate to a directory that has been used in the terminal and is currently not triggerable by a keybinding.'))); } 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('accessibilitySettings', 'Access accessibility settings such as `terminal.integrated.tabFocusMode` via the Preferences: Open Accessibility Settings command.')); - return content.join('\n'); + return content.join('\n\n'); } } From ac0d0a89c83d38cc090c70d3b9059239f4fd223f Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 24 Aug 2023 10:53:05 -0700 Subject: [PATCH 1170/1180] cli: adopt latest devtunnels for ipv6 forwarding support (#191236) --- cli/Cargo.lock | 2 +- cli/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/Cargo.lock b/cli/Cargo.lock index a67cc7cf3bd9e..34627da135bbf 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -2471,7 +2471,7 @@ dependencies = [ [[package]] name = "tunnels" version = "0.1.0" -source = "git+https://github.com/microsoft/dev-tunnels?rev=2621784a9ad72aa39500372391332a14bad581a3#2621784a9ad72aa39500372391332a14bad581a3" +source = "git+https://github.com/microsoft/dev-tunnels?rev=3141ad7be00e18c4231f7c4fb6c11f9219ac49af#3141ad7be00e18c4231f7c4fb6c11f9219ac49af" dependencies = [ "async-trait", "chrono", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 18f18069c1fc0..50fad68a8a46a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -34,7 +34,7 @@ serde_bytes = "0.11.9" chrono = { version = "0.4.26", features = ["serde", "std", "clock"], default-features = false } gethostname = "0.4.3" libc = "0.2.144" -tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "2621784a9ad72aa39500372391332a14bad581a3", default-features = false, features = ["connections"] } +tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "3141ad7be00e18c4231f7c4fb6c11f9219ac49af", default-features = false, features = ["connections"] } keyring = { version = "2.0.3", default-features = false, features = ["linux-secret-service-rt-tokio-crypto-openssl"] } dialoguer = "0.10.4" hyper = { version = "0.14.26", features = ["server", "http1", "runtime"] } From 7c205af18101b8b0a3325de3cda08792f8120715 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 10:57:28 -0700 Subject: [PATCH 1171/1180] make sure go to symbol works for help menu default actions --- .../contrib/accessibility/browser/accessibleView.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 617c87028f86a..fd562e9e1896f 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -258,7 +258,10 @@ class AccessibleView extends Disposable { } showSymbol(provider: IAccessibleContentProvider, symbol: IAccessibleViewSymbol): void { - const index = provider.provideContent().split('\n').findIndex(line => line.includes(symbol.info.split('\n')[0]) || (symbol.firstListItem && line.includes(symbol.firstListItem))) ?? -1; + if (!this._currentContent) { + return; + } + const index = this._currentContent.split('\n').findIndex(line => line.includes(symbol.info.split('\n')[0]) || (symbol.firstListItem && line.includes(symbol.firstListItem))) ?? -1; if (index >= 0) { this.show(provider); this._editorWidget.revealLine(index + 1); From ff5ec02d95db113257519757b168dfa8c841c7db Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 11:05:40 -0700 Subject: [PATCH 1172/1180] move setting of context key to fix issue on first invocation --- .../workbench/contrib/accessibility/browser/accessibleView.ts | 2 +- .../contrib/codeEditor/browser/accessibility/accessibility.css | 2 +- 2 files 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 fd562e9e1896f..33deac7073825 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -301,7 +301,6 @@ class AccessibleView extends Disposable { this._currentProvider = provider; this._accessibleViewCurrentProviderId.set(provider.verbositySettingKey.replaceAll('accessibility.verbosity.', '')); } - this._updateContextKeys(provider, true); const value = this._configurationService.getValue(provider.verbositySettingKey); const readMoreLink = provider.options.readMoreUrl ? localize("openDoc", "\n\nPress H now to open a browser window with more information related to accessibility.\n\n") : ''; let disableHelpHint = ''; @@ -326,6 +325,7 @@ class AccessibleView extends Disposable { } this._currentContent = message + provider.provideContent() + readMoreLink + disableHelpHint + localize('exit-tip', '\n\nExit this dialog via the Escape key.'); + this._updateContextKeys(provider, true); this._getTextModel(URI.from({ path: `accessible-view-${provider.verbositySettingKey}`, scheme: 'accessible-view', fragment: this._currentContent })).then((model) => { if (!model) { diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css index 2e0a1c517537a..25fcb4b03d824 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css @@ -11,7 +11,7 @@ border: 2px solid var(--vscode-focusBorder); border-radius: 6px; margin-top: -1px; - z-index: 2540; + z-index: 2550; } .accessible-view-container .actions-container { From 7a860fb4f5288dabd2b2dc88570a0800a963b322 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 24 Aug 2023 11:43:01 -0700 Subject: [PATCH 1173/1180] Fix tests --- .../test/browser/notebookKernelHistory.test.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts index bb7e0967612ff..52eadf224ae70 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts @@ -18,7 +18,7 @@ import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/no import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { IMenu, IMenuService } from 'vs/platform/actions/common/actions'; import { NotebookKernelHistoryService } from 'vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl'; -import { IStorageService, IWillSaveStateEvent, StorageScope } from 'vs/platform/storage/common/storage'; +import { IApplicationStorageValueChangeEvent, IProfileStorageValueChangeEvent, IStorageService, IStorageValueChangeEvent, IWillSaveStateEvent, IWorkspaceStorageValueChangeEvent, StorageScope } from 'vs/platform/storage/common/storage'; import { INotebookLoggingService } from 'vs/workbench/contrib/notebook/common/notebookLoggingService'; suite('NotebookKernelHistoryService', () => { @@ -70,6 +70,12 @@ suite('NotebookKernelHistoryService', () => { instantiationService.stub(IStorageService, new class extends mock() { override onWillSaveState: Event = Event.None; + override onDidChangeValue(scope: StorageScope.WORKSPACE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.PROFILE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.APPLICATION, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope, key: string | undefined, disposable: DisposableStore): Event { + return Event.None; + } override get(key: string, scope: StorageScope, fallbackValue: string): string; override get(key: string, scope: StorageScope, fallbackValue?: string | undefined): string | undefined; override get(key: unknown, scope: unknown, fallbackValue?: unknown): string | undefined { @@ -119,6 +125,12 @@ suite('NotebookKernelHistoryService', () => { instantiationService.stub(IStorageService, new class extends mock() { override onWillSaveState: Event = Event.None; + override onDidChangeValue(scope: StorageScope.WORKSPACE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.PROFILE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.APPLICATION, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope, key: string | undefined, disposable: DisposableStore): Event { + return Event.None; + } override get(key: string, scope: StorageScope, fallbackValue: string): string; override get(key: string, scope: StorageScope, fallbackValue?: string | undefined): string | undefined; override get(key: unknown, scope: unknown, fallbackValue?: unknown): string | undefined { From 794400449fb70a6ff317410152d5997fdac35c35 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 24 Aug 2023 11:55:43 -0700 Subject: [PATCH 1174/1180] fix #191238 --- .../contrib/accessibility/browser/accessibleView.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 33deac7073825..506af0bfe1512 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -187,6 +187,7 @@ class AccessibleView extends Disposable { if (!showAccessibleViewHelp) { this._currentProvider = undefined; this._accessibleViewCurrentProviderId.reset(); + this._updateContextKeys(provider!, false); } } }; @@ -267,6 +268,7 @@ class AccessibleView extends Disposable { this._editorWidget.revealLine(index + 1); this._editorWidget.setSelection({ startLineNumber: index + 1, startColumn: 1, endLineNumber: index + 1, endColumn: 1 }); } + this._updateContextKeys(provider, true); } disableHint(): void { @@ -280,10 +282,10 @@ class AccessibleView extends Disposable { private _updateContextKeys(provider: IAccessibleContentProvider, shown: boolean): void { if (provider.options.type === AccessibleViewType.Help) { this._accessiblityHelpIsShown.set(shown); - this._accessibleViewIsShown.set(!shown); + this._accessibleViewIsShown.reset(); } else { this._accessibleViewIsShown.set(shown); - this._accessiblityHelpIsShown.set(!shown); + this._accessiblityHelpIsShown.reset(); } if (provider.next && provider.previous) { this._accessibleViewSupportsNavigation.set(true); From ecb0c80fc1da718cabb863409897d941bf18aa49 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Thu, 24 Aug 2023 12:53:41 -0700 Subject: [PATCH 1175/1180] Bump extension telemetry module (#191237) * Bump extension telemetry module * Fix webpack --- extensions/git/package.json | 2 +- extensions/git/yarn.lock | 393 ++++++++++++----- extensions/github-authentication/package.json | 2 +- extensions/github-authentication/yarn.lock | 395 ++++++++++++----- extensions/github/package.json | 2 +- extensions/github/yarn.lock | 398 +++++++++++++----- .../markdown-language-features/package.json | 2 +- .../markdown-language-features/yarn.lock | 376 ++++++++++++----- extensions/media-preview/package.json | 2 +- extensions/media-preview/yarn.lock | 395 ++++++++++++----- extensions/merge-conflict/package.json | 2 +- extensions/merge-conflict/yarn.lock | 395 ++++++++++++----- .../microsoft-authentication/package.json | 2 +- extensions/microsoft-authentication/yarn.lock | 395 ++++++++++++----- extensions/shared.webpack.config.js | 2 + extensions/simple-browser/package.json | 2 +- extensions/simple-browser/yarn.lock | 395 ++++++++++++----- .../typescript-language-features/package.json | 2 +- .../typescript-language-features/yarn.lock | 383 ++++++++++++----- 19 files changed, 2641 insertions(+), 904 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index d7d241e0aab60..105491916ca65 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -3005,7 +3005,7 @@ }, "dependencies": { "@joaomoreno/unique-names-generator": "^5.1.0", - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "@vscode/iconv-lite-umd": "0.7.0", "byline": "^5.0.0", "file-type": "16.5.4", diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 6be6a6b4e4374..bb3a09d947c0b 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/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,71 +80,105 @@ dependencies: tslib "^2.2.0" +"@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: + "@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" + "@joaomoreno/unique-names-generator@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@joaomoreno/unique-names-generator/-/unique-names-generator-5.1.0.tgz#d577d425aed794c44c0e8863cddd5dea349f74f3" integrity sha512-KEVThTpUIKPb7dBKJ9mJ3WYnD1mJZZsEinCSp9CVEPlWbDagurFv1RKRjvvujrLfJzsGc0HkBHS9W8Bughao4A== -"@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== +"@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.9" + "@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" @@ -131,39 +190,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" + +"@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/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== +"@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== "@tokenizer/token@^0.3.0": version "0.3.0" @@ -202,26 +296,41 @@ resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== +"@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== + "@types/which@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/which/-/which-3.0.0.tgz#849afdd9fdcb0b67339b9cfc80fa6ea4e0253fc5" integrity sha512-ASCxdbsrwNfSMXALlC3Decif9rwDMu+80KGp5zI2RLRotfMsTv7fHL8W8VDp24wymzDyIFudhUeSCugrgRFfHQ== -"@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== +"@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" "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== +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" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -229,22 +338,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" @@ -271,6 +382,11 @@ byline@^5.0.0: resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= +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" @@ -295,7 +411,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== @@ -307,17 +423,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" @@ -344,6 +460,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" @@ -366,11 +494,28 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +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" + inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +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" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -381,6 +526,13 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -393,11 +545,21 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +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== + peek-readable@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" @@ -424,6 +586,24 @@ readable-web-to-node-stream@^3.0.0: dependencies: readable-stream "^3.6.0" +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" + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -434,7 +614,14 @@ semver@^5.3.0, semver@^5.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -459,6 +646,11 @@ strtok3@^6.2.4: "@tokenizer/token" "^0.3.0" peek-readable "^4.1.0" +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== + token-types@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.0.tgz#b66bc3d67420c6873222a424eee64a744f4c2f13" @@ -493,3 +685,8 @@ which@3.0.1: integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== dependencies: isexe "^2.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/github-authentication/package.json b/extensions/github-authentication/package.json index f5e3c95e6dd83..4855716e08e06 100644 --- a/extensions/github-authentication/package.json +++ b/extensions/github-authentication/package.json @@ -60,7 +60,7 @@ }, "dependencies": { "node-fetch": "2.6.7", - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "vscode-tas-client": "^0.1.47" }, "devDependencies": { diff --git a/extensions/github-authentication/yarn.lock b/extensions/github-authentication/yarn.lock index 858f60ddaffa0..da5f5631576c3 100644 --- a/extensions/github-authentication/yarn.lock +++ b/extensions/github-authentication/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" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-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-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/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@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/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/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@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-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" "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@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" "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.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-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@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@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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" + +"@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/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== +"@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" @@ -183,15 +277,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" @@ -200,22 +309,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" @@ -244,6 +355,11 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +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" @@ -268,7 +384,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== @@ -280,17 +396,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -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" @@ -322,6 +438,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" @@ -339,6 +467,30 @@ 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" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -351,6 +503,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" +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" @@ -363,12 +520,42 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +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== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -378,6 +565,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== + tas-client@0.1.45: version "0.1.45" resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.45.tgz#83bbf73f8458a0f527f9a389f7e1c37f63a64a76" @@ -419,3 +611,8 @@ whatwg-url@^5.0.0: dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/github/package.json b/extensions/github/package.json index ec02df2ec850e..afbb7253f7f9e 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -183,7 +183,7 @@ "@octokit/graphql-schema": "14.4.0", "@octokit/rest": "19.0.4", "tunnel": "^0.0.6", - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { "@types/node": "18.x" diff --git a/extensions/github/yarn.lock b/extensions/github/yarn.lock index f562d36c972e0..ab4275a38b9c0 100644 --- a/extensions/github/yarn.lock +++ b/extensions/github/yarn.lock @@ -17,32 +17,50 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.11.0.tgz#fc0e8f56caac08a9d4ac91c07a6c5a360ea31c82" - integrity sha512-nB4KXl6qAyJmBVLWA7SakT4tzpYZTCk4pvRBeI+Ye0WYSOrlTqlMhc4MSS/8atD3ufeYWdkN380LLoXlUUzThw== +"@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== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-auth" "^1.4.0" "@azure/core-tracing" "^1.0.1" - "@azure/core-util" "^1.3.0" + "@azure/core-util" "^1.0.0" "@azure/logger" "^1.0.0" form-data "^4.0.0" http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" 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.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.3.2.tgz#3f8cfda1e87fac0ce84f8c1a42fcd6d2a986632d" - integrity sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ== +"@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", "@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" @@ -54,66 +72,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.12", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.12.tgz#f5f56626bd0385a357fae6f730eea347be02ce64" - integrity sha512-cHpxZZ+pbtOyqFMFB/c1COpaOE3VPFU6phYVHVvOA9DvoeMZfI/Xrxaj7B/vfq4MmkiE7nOAPhv5ZRn+i6OogA== +"@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.14" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-post-js@^3.2.8": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.12.tgz#60f6ff48ba48c88880c1bceb376711cdd34f87ea" - integrity sha512-vhIVYg4FzBfwtM8tBqDUq3xU+cFu6SQ7biuJHtQpd5PVjDgvAovVOMRF1khsZE/k2rttRRBpmBgNEqG3Ptoysw== +"@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/1ds-core-js" "3.2.12" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.14.tgz#daabd8a418d9b70a318c0126518e000dd6f67fa0" - integrity sha512-z1AG6lqV3ACtdUXnT0Ubj48BAZ8K01sFsYdWgroSXpw2lYUlXAzdx3tK8zpaqEXSEhok8CWTZki7aunHzkZHSw== +"@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/applicationinsights-common" "2.8.14" - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" + "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-common@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.14.tgz#7d082295f862a189c80aa98b3f4aaec926546051" - integrity sha512-1xjJvyyRN7tb5ahOTkEGGsvw8zvqmS714y3+1m7ooKHFfxO0wX+eYOU/kke74BCY0nJ/pocB/6hjWZOgwvbHig== +"@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" "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@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" "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.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-core-js" "2.8.14" "@microsoft/applicationinsights-shims" "2.0.2" "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-core-js@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.14.tgz#80e3d9d42102e741494726d78ac923098bad7132" - integrity sha512-XacWUHdjSHMUwdngMZBp0oiCBifD56CQK2Egu2PiBiF4xu2AO2yNCtWSXsQX2g5OkEhVwaEjfa/aH3WbpYxB1g== +"@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@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.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.14.tgz#8c43bcad2e12f25eb00a9aaad0182371507b21b9" - integrity sha512-R2mzg5NmCtLloq3lPQFmnlvjrPIqm3mWNYVy5ELJuOPZ7S6j9y7s4yHOzfXynmOziiQd+0q1j9pTth9aP9vo0g== +"@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: + "@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" "2.8.14" - "@microsoft/applicationinsights-common" "2.8.14" - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@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" @@ -125,6 +177,25 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== +"@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: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@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: + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@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== + "@octokit/auth-token@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.1.tgz#88bc2baf5d706cb258474e722a720a8365dff2ec" @@ -255,39 +326,50 @@ dependencies: "@octokit/openapi-types" "^17.1.0" -"@opentelemetry/api@^1.0.4": +"@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.14.0", "@opentelemetry/core@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.14.0.tgz#64e876b29cb736c984d54164cd47433f513eafd3" - integrity sha512-MnMZ+sxsnlzloeuXL2nm5QcNczt/iO82UOeQQDHhV83F2fP3sgntW2evvtoxJki0MBLxEsh5ADD7PR/Hn5uzjw== +"@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/semantic-conventions" "1.15.2" + +"@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: - "@opentelemetry/semantic-conventions" "1.14.0" + "@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.14.0": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.14.0.tgz#d6b0a4e71c2706d33c8c6ec7a7b8fea6ad27ddea" - integrity sha512-qRfWIgBxxl3z47E036Aey0Lj2ZjlFb27Q7Xnj1y1z/P293RXJZGLtcfn/w8JF7v1Q2hs3SDGxz7Wb9Dko1YUQA== +"@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.14.0" - "@opentelemetry/semantic-conventions" "1.14.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.14.0.tgz#831af08f002228a11e577ff860eb6059c8b80fb7" - integrity sha512-NzRGt3PS+HPKfQYMb6Iy8YYc5OKA73qDwci/6ujOIvyW9vcqBJSWbjZ8FeLEAmuatUB5WrRhEKu9b0sIiIYTrQ== +"@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.14.0" - "@opentelemetry/resources" "1.14.0" - "@opentelemetry/semantic-conventions" "1.14.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.14.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.14.0.tgz#6a729b7f372ce30f77a3f217c09bc216f863fccb" - integrity sha512-rJfCY8rCWz3cb4KI6pEofnytvMPuj3YLQwoscCCYZ5DkdiPjo15IQ0US7+mjcWy9H3fcZIzf2pbJZ7ck/h4tug== +"@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" @@ -299,15 +381,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" @@ -316,22 +413,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" @@ -358,6 +457,11 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +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" @@ -382,7 +486,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== @@ -399,17 +503,17 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -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" @@ -427,6 +531,11 @@ 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== + graphql-tag@^2.10.3: version "2.12.6" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" @@ -439,6 +548,13 @@ graphql@^16.0.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== +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" @@ -456,11 +572,35 @@ 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" + is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -473,6 +613,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +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" @@ -492,12 +637,42 @@ once@^1.4.0: dependencies: wrappy "1" +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== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -507,6 +682,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== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -532,6 +712,11 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -549,3 +734,8 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 78c71ce9138bf..9743845b8d971 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -726,7 +726,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "dompurify": "^3.0.5", "highlight.js": "^11.8.0", "markdown-it": "^12.3.2", diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index 8a47f870e93e1..36b5aebfed8ff 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-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: + "@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.9" + "@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== + +"@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: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@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== +"@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/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@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/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== +"@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/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@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== +"@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: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@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/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/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" @@ -207,6 +301,11 @@ resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== +"@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== + "@types/trusted-types@*": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" @@ -222,21 +321,31 @@ resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@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== +"@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" "@vscode/l10n@^0.0.10": version "0.0.10" resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.10.tgz#9c513107c690c0dd16e3ec61e453743de15ebdb0" integrity sha512-E1OCmDcDWa0Ya7vtSjp/XfHFGqYJfh+YPC1RkATU71fTac+j1JjCcB3qwSzmlKAighx2WxhLlfhS0RwAN++PFQ== +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" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -244,22 +353,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" argparse@^2.0.1: version "2.0.1" @@ -299,6 +410,11 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +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" @@ -328,7 +444,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== @@ -340,17 +456,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" dompurify@^3.0.5: version "3.0.5" @@ -378,6 +494,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" + highlight.js@^11.8.0: version "11.8.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.8.0.tgz#966518ea83257bae2e7c9a48596231856555bb65" @@ -400,6 +528,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" + linkify-it@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" @@ -459,6 +604,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +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== + morphdom@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/morphdom/-/morphdom-2.6.1.tgz#e868e24f989fa3183004b159aed643e628b4306e" @@ -469,24 +619,47 @@ ms@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== + picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +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.5: +semver@^7.3.5, 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== @@ -496,6 +669,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" diff --git a/extensions/media-preview/package.json b/extensions/media-preview/package.json index 3107d9d60bf17..6c1b46220b9cf 100644 --- a/extensions/media-preview/package.json +++ b/extensions/media-preview/package.json @@ -126,7 +126,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "vscode-uri": "^3.0.6" }, "repository": { diff --git a/extensions/media-preview/yarn.lock b/extensions/media-preview/yarn.lock index 971c4c2c50acf..36b652d7d7b88 100644 --- a/extensions/media-preview/yarn.lock +++ b/extensions/media-preview/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" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-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-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/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@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/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/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@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-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" "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@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" "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.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-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@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@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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,54 +185,104 @@ 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== + +"@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: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@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== +"@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/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@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/semantic-conventions" "1.15.2" -"@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== +"@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.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@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== +"@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.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@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/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" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@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" @@ -182,22 +291,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" @@ -219,6 +330,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +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" @@ -243,7 +359,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== @@ -255,17 +371,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" @@ -283,6 +399,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" @@ -300,6 +428,30 @@ 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" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -312,17 +464,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +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== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -332,6 +519,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" @@ -346,3 +538,8 @@ vscode-uri@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.6.tgz#5e6e2e1a4170543af30151b561a41f71db1d6f91" integrity sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/merge-conflict/package.json b/extensions/merge-conflict/package.json index 00a7136cff250..751e85c3da254 100644 --- a/extensions/merge-conflict/package.json +++ b/extensions/merge-conflict/package.json @@ -166,7 +166,7 @@ } }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { "@types/node": "18.x" diff --git a/extensions/merge-conflict/yarn.lock b/extensions/merge-conflict/yarn.lock index f07c9a1370132..d214c5e444709 100644 --- a/extensions/merge-conflict/yarn.lock +++ b/extensions/merge-conflict/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" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-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-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/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@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/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/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@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-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" "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@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" "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.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-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@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@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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.3.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.3.0.tgz#27c6f776ac3c1c616651e506a89f438a0ed6a055" - integrity sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ== +"@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.8.0", "@opentelemetry/core@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.8.0.tgz#cca18594dd48ded6dc0d08c7e789c79af0315934" - integrity sha512-6SDjwBML4Am0AQmy7z1j6HGrWDgeK8awBRUvl1PGw6HayViMk4QpnUXvv4HTHisecgVBy43NE/cstWprm8tIfw== +"@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: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@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: + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@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/semantic-conventions" "1.8.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/resources@1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.8.0.tgz#260be9742cf7bceccc0db928d8ca8d64391acfe3" - integrity sha512-KSyMH6Jvss/PFDy16z5qkCK0ERlpyqixb1xwb73wLMvVq+j7i89lobDjw3JkpCcd1Ws0J6jAI4fw28Zufj2ssg== +"@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: - "@opentelemetry/core" "1.8.0" - "@opentelemetry/semantic-conventions" "1.8.0" + "@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.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.8.0.tgz#70713aab90978a16dea188c8335209f857be7384" - integrity sha512-iH41m0UTddnCKJzZx3M85vlhKzRcmT48pUeBbnzsGrq4nIay1oWVHKM5nhB5r8qRDGvd/n7f/YLCXClxwM0tvA== +"@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.8.0" - "@opentelemetry/resources" "1.8.0" - "@opentelemetry/semantic-conventions" "1.8.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.8.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.8.0.tgz#fe2aa90e6df050a11cd57f5c0f47b0641fd2cad3" - integrity sha512-TYh1MRcm4JnvpqtqOwT9WYaBYY4KERHdToxs/suDTLviGRsQkIjS5yYROTYTSJQUnYLOn/TuOh5GoMwfLSU+Ew== +"@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" @@ -224,6 +335,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +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" @@ -248,7 +364,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== @@ -260,17 +376,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" @@ -288,6 +404,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" @@ -305,6 +433,30 @@ 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" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -317,17 +469,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +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== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -337,6 +524,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" @@ -346,3 +538,8 @@ uuid@^8.3.0: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/microsoft-authentication/package.json b/extensions/microsoft-authentication/package.json index c0ed977db77d6..8747c4a1df8f8 100644 --- a/extensions/microsoft-authentication/package.json +++ b/extensions/microsoft-authentication/package.json @@ -118,7 +118,7 @@ "dependencies": { "node-fetch": "2.6.7", "@azure/ms-rest-azure-env": "^2.0.0", - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "repository": { "type": "git", diff --git a/extensions/microsoft-authentication/yarn.lock b/extensions/microsoft-authentication/yarn.lock index 1332269496699..68b4aa00b84ab 100644 --- a/extensions/microsoft-authentication/yarn.lock +++ b/extensions/microsoft-authentication/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" @@ -60,66 +85,100 @@ resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz#45809f89763a480924e21d3c620cd40866771625" integrity sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw== -"@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" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-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-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/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@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/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/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@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-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" "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@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" "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.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-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@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@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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" @@ -131,39 +190,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" + +"@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/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== +"@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" @@ -202,20 +296,35 @@ dependencies: "@types/node" "*" +"@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== + "@types/uuid@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== -"@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== +"@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" @@ -224,22 +333,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" @@ -261,6 +372,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +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" @@ -285,7 +401,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== @@ -297,17 +413,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -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" @@ -334,6 +450,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" @@ -351,6 +479,30 @@ 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" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -363,6 +515,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" +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" @@ -375,12 +532,42 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +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== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -390,6 +577,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== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -417,3 +609,8 @@ whatwg-url@^5.0.0: dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 5a9ccd93d30fc..cd9aef4967718 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -60,6 +60,7 @@ function withNodeDefaults(/**@type WebpackConfig & { context: string }*/extConfi externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist, 'applicationinsights-native-metrics': 'commonjs applicationinsights-native-metrics', // ignored because we don't ship native module + '@azure/functions-core': 'commonjs azure/functions-core', // optioinal dependency of appinsights that we don't use '@opentelemetry/tracing': 'commonjs @opentelemetry/tracing', // ignored because we don't ship this module '@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation', // ignored because we don't ship this module '@azure/opentelemetry-instrumentation-azure-sdk': 'commonjs @azure/opentelemetry-instrumentation-azure-sdk', // ignored because we don't ship this module @@ -143,6 +144,7 @@ function withBrowserDefaults(/**@type WebpackConfig & { context: string }*/extCo externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist, 'applicationinsights-native-metrics': 'commonjs applicationinsights-native-metrics', // ignored because we don't ship native module + '@azure/functions-core': 'commonjs azure/functions-core', // optioinal dependency of appinsights that we don't use '@opentelemetry/tracing': 'commonjs @opentelemetry/tracing', // ignored because we don't ship this module '@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation', // ignored because we don't ship this module '@azure/opentelemetry-instrumentation-azure-sdk': 'commonjs @azure/opentelemetry-instrumentation-azure-sdk', // ignored because we don't ship this module diff --git a/extensions/simple-browser/package.json b/extensions/simple-browser/package.json index 79abe8e57cd92..e86b8de070b68 100644 --- a/extensions/simple-browser/package.json +++ b/extensions/simple-browser/package.json @@ -66,7 +66,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { "@types/vscode-webview": "^1.57.0", diff --git a/extensions/simple-browser/yarn.lock b/extensions/simple-browser/yarn.lock index e57ce16ff4408..d6ce34c9e21c0 100644 --- a/extensions/simple-browser/yarn.lock +++ b/extensions/simple-browser/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" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-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-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/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@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/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/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@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-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" "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@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" "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.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-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@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@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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,59 +185,109 @@ 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== + +"@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: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@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== +"@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/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@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/semantic-conventions" "1.15.2" -"@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== +"@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.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@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== +"@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.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@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/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" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@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== + "@types/vscode-webview@^1.57.0": version "1.57.0" resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@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== +"@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" @@ -224,6 +335,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +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" @@ -248,7 +364,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== @@ -260,17 +376,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" @@ -288,6 +404,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" @@ -305,6 +433,30 @@ 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" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -317,17 +469,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +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== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -337,6 +524,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" @@ -351,3 +543,8 @@ vscode-codicons@^0.0.14: version "0.0.14" resolved "https://registry.yarnpkg.com/vscode-codicons/-/vscode-codicons-0.0.14.tgz#e0d05418e2e195564ff6f6a2199d70415911c18f" integrity sha512-6CEH5KT9ct5WMw7n5dlX7rB8ya4CUI2FSq1Wk36XaW+c5RglFtAanUV0T+gvZVVFhl/WxfjTvFHq06Hz9c1SLA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index d855af70e68df..e3c9a7f870ddf 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -33,7 +33,7 @@ "Programming Languages" ], "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "jsonc-parser": "^3.2.0", "semver": "7.5.2", "vscode-tas-client": "^0.1.63", diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index 1b011de04497f..eedf2d9c58027 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-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" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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-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-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/1ds-core-js" "3.2.8" + "@microsoft/applicationinsights-core-js" "2.8.15" "@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/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/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" + "@microsoft/1ds-core-js" "3.2.13" + "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@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-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" "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@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" "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.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-core-js" "2.8.9" "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" -"@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@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" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@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== + +"@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: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@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== +"@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/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@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/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== +"@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/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@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== +"@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: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@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/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/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" @@ -175,15 +269,20 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== -"@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" "@vscode/sync-api-client@^0.7.2": version "0.7.2" @@ -206,6 +305,16 @@ "@vscode/sync-api-common" "0.7.2" vscode-uri "3.0.3" +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" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -213,22 +322,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" @@ -257,6 +368,11 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +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" @@ -281,7 +397,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== @@ -293,17 +409,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" @@ -326,6 +442,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" @@ -343,6 +471,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" + jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" @@ -367,11 +512,39 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +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@7.5.2: version "7.5.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" @@ -384,7 +557,14 @@ semver@^5.3.0, semver@^5.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +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.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -394,6 +574,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== + tas-client@0.1.58: version "0.1.58" resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.58.tgz#67d66bf0e27df5276ebc751105e6ad47791c36d8" From ee8edc4dc9e6cae4f879bd6ad9e05a9ab40e07ee Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 22:32:45 +0200 Subject: [PATCH 1176/1180] Better moved code detection. --- src/vs/editor/common/diff/advancedLinesDiffComputer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/diff/advancedLinesDiffComputer.ts b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts index 61fd21d9c2908..a7d9605d78c14 100644 --- a/src/vs/editor/common/diff/advancedLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts @@ -311,7 +311,7 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive; const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0; - if (currentMoveAfterLast && originalDist <= 1 && modifiedDist <= 1) { + if (currentMoveAfterLast && originalDist + modifiedDist <= 2) { joinedMoves[joinedMoves.length - 1] = last.join(current); continue; } From 9e2cd079528bea00be8aabb16df1323683bb382d Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 22:38:58 +0200 Subject: [PATCH 1177/1180] Use text instead of icon for moved code compare button --- .../browser/widget/diffEditorWidget2/movedBlocksLines.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts index 6a5316decbad4..f52c55e389ff5 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -325,6 +325,7 @@ class MovedBlockOverlayWidget extends ViewZoneOverlayWidget { const isActive = this._diffModel.movedTextToCompare.read(reader) === _move; actionCompare.checked = isActive; })); - actionBar.push(actionCompare, { icon: true, label: false }); + + actionBar.push(actionCompare, { icon: false, label: true }); } } From 506e14d8db23cad93f15781ec2405780cab4d35a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 22:55:21 +0200 Subject: [PATCH 1178/1180] Fixes #191255 --- .../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 f52c55e389ff5..c4144924bcede 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -145,7 +145,7 @@ export class MovedBlocksLinesPart extends Disposable { lines.sort(tieBreakComparators( compareBy(l => l.fromWithoutScroll > l.toWithoutScroll, booleanComparator), - compareBy(l => -l.fromWithoutScroll, numberComparator) + compareBy(l => l.fromWithoutScroll > l.toWithoutScroll ? l.fromWithoutScroll : -l.toWithoutScroll, numberComparator) )); const layout = LinesLayout.compute(lines.map(l => l.range)); From 27eb58d046191d391bbf99a18398fdebe39e7996 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Thu, 24 Aug 2023 14:54:28 -0700 Subject: [PATCH 1179/1180] Add `preserveInput` for quick search and remove col:line (#191260) Fixes #191258 Fixes #191253 --- .../quickTextSearch/textSearchQuickAccess.ts | 14 ++++++++++---- .../contrib/search/browser/search.contribution.ts | 7 ++++++- src/vs/workbench/services/search/common/search.ts | 3 +++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts index d01ad5ad73bbf..6324613fbfd17 100644 --- a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts @@ -15,9 +15,9 @@ 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 { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { IWorkbenchQuickAccessConfiguration } from 'vs/workbench/browser/quickaccess'; import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { IViewsService } from 'vs/workbench/common/views'; import { searchDetailsIcon, searchOpenInFileIcon } from 'vs/workbench/contrib/search/browser/searchIcons'; @@ -78,16 +78,23 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider().workbench?.editor; const searchConfig = this._configurationService.getValue().search; - const quickAccessConfig = this._configurationService.getValue().workbench.quickOpen; return { openEditorPinned: !editorConfig?.enablePreviewFromQuickOpen || !editorConfig?.enablePreview, - preserveInput: quickAccessConfig.preserveInput, + preserveInput: searchConfig.experimental.quickAccess.preserveInput, maxResults: searchConfig.maxResults, smartCase: searchConfig.smartCase, }; } + get defaultFilterValue(): DefaultQuickAccessFilterValue | undefined { + if (this.configuration.preserveInput) { + return DefaultQuickAccessFilterValue.LAST; + } + + return undefined; + } + private doSearch(contentPattern: string, token: CancellationToken): { syncResults: FileMatch[]; asyncResults: Promise; @@ -195,7 +202,6 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { await this.handleAccept(fileMatch, { diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 2f9b6d54d73b8..a2f41a98fac6c 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -376,7 +376,12 @@ configurationRegistry.registerConfiguration({ type: 'boolean', description: nls.localize('search.experimental.closedNotebookResults', "Show notebook editor rich content results for closed notebooks. Please refresh your search results after changing this setting."), default: false - } + }, + 'search.experimental.quickAccess.preserveInput': { + 'type': 'boolean', + 'description': nls.localize('search.experimental.quickAccess.preserveInput', "Controls whether the last typed input to Quick Search should be restored when opening it the next time."), + 'default': false + }, } }); diff --git a/src/vs/workbench/services/search/common/search.ts b/src/vs/workbench/services/search/common/search.ts index caded264a85a2..6935850b67155 100644 --- a/src/vs/workbench/services/search/common/search.ts +++ b/src/vs/workbench/services/search/common/search.ts @@ -414,6 +414,9 @@ export interface ISearchConfigurationProperties { defaultViewMode: ViewMode; experimental: { closedNotebookRichContentResults: boolean; + quickAccess: { + preserveInput: boolean; + }; }; } From 885ebcd9b44968dbad137ff21102a39341cba303 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 22:25:19 +0200 Subject: [PATCH 1180/1180] Fixes #185781 --- .../diffEditorWidget2/diffEditorWidget2.ts | 8 +- .../widget/diffEditorWidget2/outlineModel.ts | 384 ++++++++++++++++++ .../diffEditorWidget2/unchangedRanges.ts | 104 ++++- 3 files changed, 480 insertions(+), 16 deletions(-) create mode 100644 src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 280c2bb7b9ae1..b8c42ae717f70 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -157,7 +157,9 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(autorunWithStore((reader, store) => { /** @description UnchangedRangesFeature */ - this.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options)); + this.unchangedRangesFeature = store.add( + this._instantiationService.createInstance(readHotReloadableExport(UnchangedRangesFeature, reader), this._editors, this._diffModel, this._options) + ); })); this._register(autorunWithStore((reader, store) => { @@ -178,7 +180,9 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(autorunWithStore((reader, store) => { /** @description OverviewRulerPart */ - store.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors, + store.add(this._instantiationService.createInstance( + readHotReloadableExport(OverviewRulerPart, reader), + this._editors, this.elements.root, this._diffModel, this._rootSizeObserver.width, diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts new file mode 100644 index 0000000000000..cd12277b82cf9 --- /dev/null +++ b/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts @@ -0,0 +1,384 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { binarySearch, coalesceInPlace, equals } from 'vs/base/common/arrays'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { onUnexpectedExternalError } from 'vs/base/common/errors'; +import { Iterable } from 'vs/base/common/iterator'; +import { commonPrefixLength } from 'vs/base/common/strings'; +import { URI } from 'vs/base/common/uri'; +import { IPosition, Position } from 'vs/editor/common/core/position'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { DocumentSymbol, DocumentSymbolProvider } from 'vs/editor/common/languages'; +import { ITextModel } from 'vs/editor/common/model'; +import { MarkerSeverity } from 'vs/platform/markers/common/markers'; + +// TODO@hediet: These classes are copied from outlineModel.ts because of layering issues. +// Because these classes just depend on the DocumentSymbolProvider (which is in the core editor), +// they should be moved to the core editor as well. + +export abstract class TreeElement { + + abstract id: string; + abstract children: Map; + abstract parent: TreeElement | undefined; + + remove(): void { + this.parent?.children.delete(this.id); + } + + static findId(candidate: DocumentSymbol | string, container: TreeElement): string { + // complex id-computation which contains the origin/extension, + // the parent path, and some dedupe logic when names collide + let candidateId: string; + if (typeof candidate === 'string') { + candidateId = `${container.id}/${candidate}`; + } else { + candidateId = `${container.id}/${candidate.name}`; + if (container.children.get(candidateId) !== undefined) { + candidateId = `${container.id}/${candidate.name}_${candidate.range.startLineNumber}_${candidate.range.startColumn}`; + } + } + + let id = candidateId; + for (let i = 0; container.children.get(id) !== undefined; i++) { + id = `${candidateId}_${i}`; + } + + return id; + } + + static getElementById(id: string, element: TreeElement): TreeElement | undefined { + if (!id) { + return undefined; + } + const len = commonPrefixLength(id, element.id); + if (len === id.length) { + return element; + } + if (len < element.id.length) { + return undefined; + } + for (const [, child] of element.children) { + const candidate = TreeElement.getElementById(id, child); + if (candidate) { + return candidate; + } + } + return undefined; + } + + static size(element: TreeElement): number { + let res = 1; + for (const [, child] of element.children) { + res += TreeElement.size(child); + } + return res; + } + + static empty(element: TreeElement): boolean { + return element.children.size === 0; + } +} + +export interface IOutlineMarker { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + severity: MarkerSeverity; +} + +export class OutlineElement extends TreeElement { + + children = new Map(); + marker: { count: number; topSev: MarkerSeverity } | undefined; + + constructor( + readonly id: string, + public parent: TreeElement | undefined, + readonly symbol: DocumentSymbol + ) { + super(); + } +} + +export class OutlineGroup extends TreeElement { + + children = new Map(); + + constructor( + readonly id: string, + public parent: TreeElement | undefined, + readonly label: string, + readonly order: number, + ) { + super(); + } + + getItemEnclosingPosition(position: IPosition): OutlineElement | undefined { + return position ? this._getItemEnclosingPosition(position, this.children) : undefined; + } + + private _getItemEnclosingPosition(position: IPosition, children: Map): OutlineElement | undefined { + for (const [, item] of children) { + if (!item.symbol.range || !Range.containsPosition(item.symbol.range, position)) { + continue; + } + return this._getItemEnclosingPosition(position, item.children) || item; + } + return undefined; + } + + updateMarker(marker: IOutlineMarker[]): void { + for (const [, child] of this.children) { + this._updateMarker(marker, child); + } + } + + private _updateMarker(markers: IOutlineMarker[], item: OutlineElement): void { + item.marker = undefined; + + // find the proper start index to check for item/marker overlap. + const idx = binarySearch(markers, item.symbol.range, Range.compareRangesUsingStarts); + let start: number; + if (idx < 0) { + start = ~idx; + if (start > 0 && Range.areIntersecting(markers[start - 1], item.symbol.range)) { + start -= 1; + } + } else { + start = idx; + } + + const myMarkers: IOutlineMarker[] = []; + let myTopSev: MarkerSeverity | undefined; + + for (; start < markers.length && Range.areIntersecting(item.symbol.range, markers[start]); start++) { + // remove markers intersecting with this outline element + // and store them in a 'private' array. + const marker = markers[start]; + myMarkers.push(marker); + (markers as Array)[start] = undefined; + if (!myTopSev || marker.severity > myTopSev) { + myTopSev = marker.severity; + } + } + + // Recurse into children and let them match markers that have matched + // this outline element. This might remove markers from this element and + // therefore we remember that we have had markers. That allows us to render + // the dot, saying 'this element has children with markers' + for (const [, child] of item.children) { + this._updateMarker(myMarkers, child); + } + + if (myTopSev) { + item.marker = { + count: myMarkers.length, + topSev: myTopSev + }; + } + + coalesceInPlace(markers); + } +} + +export class OutlineModel extends TreeElement { + + static create(registry: LanguageFeatureRegistry, textModel: ITextModel, token: CancellationToken): Promise { + + const cts = new CancellationTokenSource(token); + const result = new OutlineModel(textModel.uri); + const provider = registry.ordered(textModel); + const promises = provider.map((provider, index) => { + + const id = TreeElement.findId(`provider_${index}`, result); + const group = new OutlineGroup(id, result, provider.displayName ?? 'Unknown Outline Provider', index); + + + return Promise.resolve(provider.provideDocumentSymbols(textModel, cts.token)).then(result => { + for (const info of result || []) { + OutlineModel._makeOutlineElement(info, group); + } + return group; + }, err => { + onUnexpectedExternalError(err); + return group; + }).then(group => { + if (!TreeElement.empty(group)) { + result._groups.set(id, group); + } else { + group.remove(); + } + }); + }); + + const listener = registry.onDidChange(() => { + const newProvider = registry.ordered(textModel); + if (!equals(newProvider, provider)) { + cts.cancel(); + } + }); + + return Promise.all(promises).then(() => { + if (cts.token.isCancellationRequested && !token.isCancellationRequested) { + return OutlineModel.create(registry, textModel, token); + } else { + return result._compact(); + } + }).finally(() => { + listener.dispose(); + }); + } + + private static _makeOutlineElement(info: DocumentSymbol, container: OutlineGroup | OutlineElement): void { + const id = TreeElement.findId(info, container); + const res = new OutlineElement(id, container, info); + if (info.children) { + for (const childInfo of info.children) { + OutlineModel._makeOutlineElement(childInfo, res); + } + } + container.children.set(res.id, res); + } + + static get(element: TreeElement | undefined): OutlineModel | undefined { + while (element) { + if (element instanceof OutlineModel) { + return element; + } + element = element.parent; + } + return undefined; + } + + readonly id = 'root'; + readonly parent = undefined; + + protected _groups = new Map(); + children = new Map(); + + protected constructor(readonly uri: URI) { + super(); + + this.id = 'root'; + this.parent = undefined; + } + + private _compact(): this { + let count = 0; + for (const [key, group] of this._groups) { + if (group.children.size === 0) { // empty + this._groups.delete(key); + } else { + count += 1; + } + } + if (count !== 1) { + // + this.children = this._groups; + } else { + // adopt all elements of the first group + const group = Iterable.first(this._groups.values())!; + for (const [, child] of group.children) { + child.parent = this; + this.children.set(child.id, child); + } + } + return this; + } + + merge(other: OutlineModel): boolean { + if (this.uri.toString() !== other.uri.toString()) { + return false; + } + if (this._groups.size !== other._groups.size) { + return false; + } + this._groups = other._groups; + this.children = other.children; + return true; + } + + getItemEnclosingPosition(position: IPosition, context?: OutlineElement): OutlineElement | undefined { + + let preferredGroup: OutlineGroup | undefined; + if (context) { + let candidate = context.parent; + while (candidate && !preferredGroup) { + if (candidate instanceof OutlineGroup) { + preferredGroup = candidate; + } + candidate = candidate.parent; + } + } + + let result: OutlineElement | undefined = undefined; + for (const [, group] of this._groups) { + result = group.getItemEnclosingPosition(position); + if (result && (!preferredGroup || preferredGroup === group)) { + break; + } + } + return result; + } + + getItemById(id: string): TreeElement | undefined { + return TreeElement.getElementById(id, this); + } + + updateMarker(marker: IOutlineMarker[]): void { + // sort markers by start range so that we can use + // outline element starts for quicker look up + marker.sort(Range.compareRangesUsingStarts); + + for (const [, group] of this._groups) { + group.updateMarker(marker.slice(0)); + } + } + + getTopLevelSymbols(): DocumentSymbol[] { + const roots: DocumentSymbol[] = []; + for (const child of this.children.values()) { + if (child instanceof OutlineElement) { + roots.push(child.symbol); + } else { + roots.push(...Iterable.map(child.children.values(), child => child.symbol)); + } + } + return roots.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range)); + } + + asListOfDocumentSymbols(): DocumentSymbol[] { + const roots = this.getTopLevelSymbols(); + const bucket: DocumentSymbol[] = []; + OutlineModel._flattenDocumentSymbols(bucket, roots, ''); + return bucket.sort((a, b) => + Position.compare(Range.getStartPosition(a.range), Range.getStartPosition(b.range)) || Position.compare(Range.getEndPosition(b.range), Range.getEndPosition(a.range)) + ); + } + + private static _flattenDocumentSymbols(bucket: DocumentSymbol[], entries: DocumentSymbol[], overrideContainerLabel: string): void { + for (const entry of entries) { + bucket.push({ + kind: entry.kind, + tags: entry.tags, + name: entry.name, + detail: entry.detail, + containerName: entry.containerName || overrideContainerLabel, + range: entry.range, + selectionRange: entry.selectionRange, + children: undefined, // we flatten it... + }); + + // Recurse over children + if (entry.children) { + OutlineModel._flattenDocumentSymbols(bucket, entry.children, entry.name); + } + } + } +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index 7272f56b11fdd..b3ac905331d52 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -4,34 +4,49 @@ *--------------------------------------------------------------------------------------------*/ import { $, addDisposableListener, h, reset } from 'vs/base/browser/dom'; -import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { renderIcon, renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { compareBy, numberComparator, reverseOrder } from 'vs/base/common/arrays'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; +import { Event } from 'vs/base/common/event'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, derived, derivedWithStore, observableFromEvent, transaction } from 'vs/base/common/observable'; +import { IObservable, IReader, autorun, autorunWithStore, derived, derivedWithStore, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { isDefined } from 'vs/base/common/types'; import { ICodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions'; import { DiffEditorViewModel, UnchangedRegion } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; +import { OutlineModel } from 'vs/editor/browser/widget/diffEditorWidget2/outlineModel'; import { PlaceholderViewZone, ViewZoneOverlayWidget, applyObservableDecorations, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; 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 { Range } from 'vs/editor/common/core/range'; import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; -import { IModelDecorationOptions, IModelDeltaDecoration } from 'vs/editor/common/model'; +import { SymbolKind, SymbolKinds } from 'vs/editor/common/languages'; +import { IModelDecorationOptions, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { localize } from 'vs/nls'; export class UnchangedRangesFeature extends Disposable { private _isUpdatingViewZones = false; public get isUpdatingViewZones(): boolean { return this._isUpdatingViewZones; } + private readonly _modifiedModel = observableFromEvent(this._editors.modified.onDidChangeModel, () => this._editors.modified.getModel()); + + private readonly _modifiedOutlineSource = derivedWithStore('modified outline source', (reader, store) => { + const m = this._modifiedModel.read(reader); + if (!m) { return undefined; } + return store.add(new OutlineSource(this._languageFeaturesService, m)); + }); + constructor( private readonly _editors: DiffEditorEditors, private readonly _diffModel: IObservable, private readonly _options: DiffEditorOptions, + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, ) { super(); @@ -66,6 +81,9 @@ export class UnchangedRangesFeature extends Disposable { const modViewZones: IViewZone[] = []; const sideBySide = this._options.renderSideBySide.read(reader); + const modifiedOutlineSource = this._modifiedOutlineSource.read(reader); + if (!modifiedOutlineSource) { return { origViewZones, modViewZones }; } + const curUnchangedRegions = unchangedRegions.read(reader); for (const r of curUnchangedRegions) { if (r.shouldHideControls(reader)) { @@ -76,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, !sideBySide)); + store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, !sideBySide, modifiedOutlineSource)); } { 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, false)); + store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, false, modifiedOutlineSource)); } } @@ -177,6 +195,57 @@ export class UnchangedRangesFeature extends Disposable { } } +class DisposableCancellationTokenSource extends CancellationTokenSource { + public override dispose() { + super.dispose(true); + } +} + +class OutlineSource extends Disposable { + private readonly _currentModel = observableValue('current model', undefined); + + constructor( + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, + private readonly _textModel: ITextModel, + ) { + super(); + + const documentSymbolProviderChanged = observableSignalFromEvent( + 'documentSymbolProvider.onDidChange', + this._languageFeaturesService.documentSymbolProvider.onDidChange + ); + + const textModelChanged = observableSignalFromEvent( + '_textModel.onDidChangeContent', + Event.debounce(e => this._textModel.onDidChangeContent(e), () => undefined, 100) + ); + + this._register(autorunWithStore(async (reader, store) => { + documentSymbolProviderChanged.read(reader); + textModelChanged.read(reader); + + const src = store.add(new DisposableCancellationTokenSource()); + const model = await OutlineModel.create( + this._languageFeaturesService.documentSymbolProvider, + this._textModel, + src.token, + ); + if (store.isDisposed) { return; } + + this._currentModel.set(model, undefined); + })); + } + + public getBreadcrumbItems(startRange: LineRange, reader: IReader): { name: string; kind: SymbolKind }[] { + const m = this._currentModel.read(reader); + if (!m) { return []; } + const symbols = m.asListOfDocumentSymbols() + .filter(s => startRange.contains(s.range.startLineNumber) && !startRange.contains(s.range.endLineNumber)); + symbols.sort(reverseOrder(compareBy(s => s.range.endLineNumber - s.range.startLineNumber, numberComparator))); + return symbols.map(s => ({ name: s.name, kind: s.kind })); + } +} + 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') }), @@ -194,6 +263,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { _viewZone: PlaceholderViewZone, private readonly _unchangedRegion: UnchangedRegion, private readonly hide: boolean, + private readonly _modifiedOutlineSource: OutlineSource, ) { const root = h('div.diff-hidden-lines-widget'); super(_editor, _viewZone, root.root); @@ -296,19 +366,25 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { children.push($('span', { title: linesHiddenText }, linesHiddenText)); } - // TODO@hediet implement breadcrumbs for collapsed regions - /* - if (_unchangedRegion.originalLineNumber === 48) { - children.push($('span', undefined, '\u00a0|\u00a0')); - children.push($('span', { title: 'test' }, ...renderLabelWithIcons('$(symbol-class) DiffEditorWidget2'))); - } else if (_unchangedRegion.originalLineNumber === 88) { + const range = this._unchangedRegion.getHiddenModifiedRange(reader); + const items = this._modifiedOutlineSource.getBreadcrumbItems(range, reader); + + if (items.length > 0) { children.push($('span', undefined, '\u00a0|\u00a0')); - children.push($('span', { title: 'test' }, ...renderLabelWithIcons('$(symbol-constructor) constructor'))); + + let isFirst = true; + for (const item of items) { + if (!isFirst) { + children.push($('span', {}, ' ', renderIcon(Codicon.chevronRight), ' ')); + } + + const icon = SymbolKinds.toIcon(item.kind); + children.push($('span', {}, renderIcon(icon), ' ', item.name)); + isFirst = false; + } } - */ reset(this._nodes.others, ...children); - })); } }