Merge branch 'main' into joh/swc

This commit is contained in:
Johannes
2022-05-25 12:29:28 +02:00
159 changed files with 1894 additions and 930 deletions
+1
View File
@@ -14,6 +14,7 @@ export interface ITelemetryData {
}
export type WorkbenchActionExecutedClassification = {
owner: 'bpasero';
id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
+4
View File
@@ -37,6 +37,10 @@ export class VSDataTransfer {
this._data.set(mimeType, value);
}
public delete(mimeType: string) {
this._data.delete(mimeType);
}
public setString(mimeType: string, stringOrPromise: string | Promise<string>) {
this.set(mimeType, {
asString: async () => stringOrPromise,
@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { LanguagePackService } from 'vs/platform/languagePacks/node/languagePacks';
export class LocalizationsUpdater extends Disposable {
constructor(
@ILocalizationsService private readonly localizationsService: LocalizationsService
@ILanguagePackService private readonly localizationsService: LanguagePackService
) {
super();
@@ -46,8 +46,8 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { MessagePortMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { LanguagePackService } from 'vs/platform/languagePacks/node/languagePacks';
import { ConsoleLogger, ILoggerService, ILogService, MultiplexLogService } from 'vs/platform/log/common/log';
import { FollowerLogService, LoggerChannelClient, LogLevelChannelClient } from 'vs/platform/log/common/logIpc';
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
@@ -311,7 +311,7 @@ class SharedProcessMain extends Disposable {
services.set(IExtensionTipsService, new SyncDescriptor(ExtensionTipsService));
// Localizations
services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService));
services.set(ILanguagePackService, new SyncDescriptor(LanguagePackService));
// Diagnostics
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService));
@@ -360,9 +360,9 @@ class SharedProcessMain extends Disposable {
const channel = new ExtensionManagementChannel(accessor.get(IExtensionManagementService), () => null);
this.server.registerChannel('extensions', channel);
// Localizations
const localizationsChannel = ProxyChannel.fromService(accessor.get(ILocalizationsService));
this.server.registerChannel('localizations', localizationsChannel);
// Language Packs
const languagePacksChannel = ProxyChannel.fromService(accessor.get(ILanguagePackService));
this.server.registerChannel('languagePacks', languagePacksChannel);
// Diagnostics
const diagnosticsChannel = ProxyChannel.fromService(accessor.get(IDiagnosticsService));
+1 -1
View File
@@ -1105,7 +1105,7 @@ export class CodeApplication extends Disposable {
code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of shared process crash to understand the nature of the crash better.' };
visible: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether shared process window was visible or not.' };
shuttingdown: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether the application is shutting down when the crash happens.' };
owner: 'bpaser';
owner: 'bpasero';
comment: 'Event which fires whenever an error occurs in the shared process';
};
+3 -3
View File
@@ -36,8 +36,8 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { LanguagePackService } from 'vs/platform/languagePacks/node/languagePacks';
import { ConsoleLogger, getLogLevel, ILogger, ILogService, LogLevel, MultiplexLogService } from 'vs/platform/log/common/log';
import { SpdLogLogger } from 'vs/platform/log/node/spdlogLog';
import { FilePolicyService } from 'vs/platform/policy/common/filePolicyService';
@@ -161,7 +161,7 @@ class CliMain extends Disposable {
services.set(IExtensionManagementCLIService, new SyncDescriptor(ExtensionManagementCLIService));
// Localizations
services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService));
services.set(ILanguagePackService, new SyncDescriptor(LanguagePackService));
// Telemetry
const appenders: AppInsightsAppender[] = [];
+28
View File
@@ -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.
*--------------------------------------------------------------------------------------------*/
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
import { URI } from 'vs/base/common/uri';
export function toVSDataTransfer(dataTransfer: DataTransfer) {
const vsDataTransfer = new VSDataTransfer();
for (const item of dataTransfer.items) {
const type = item.type;
if (item.kind === 'string') {
const asStringValue = new Promise<string>(resolve => item.getAsString(resolve));
vsDataTransfer.setString(type, asStringValue);
} else if (item.kind === 'file') {
const file = item.getAsFile() as null | (File & { path?: string });
if (file) {
const uri = file.path ? URI.parse(file.path) : undefined;
vsDataTransfer.setFile(type, file.name, uri, async () => {
return new Uint8Array(await file.arrayBuffer());
});
}
}
}
return vsDataTransfer;
}
@@ -338,6 +338,7 @@ export abstract class EditorAction extends EditorCommand {
protected reportTelemetry(accessor: ServicesAccessor, editor: ICodeEditor) {
type EditorActionInvokedClassification = {
owner: 'alexdima';
name: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
+9
View File
@@ -721,6 +721,15 @@ export interface CodeActionProvider {
_getAdditionalMenuItems?(context: CodeActionContext, actions: readonly CodeAction[]): Command[];
}
/**
* @internal
*/
export interface DocumentPasteEditProvider {
prepareDocumentPaste?(model: model.ITextModel, selection: Selection, dataTransfer: VSDataTransfer, token: CancellationToken): Promise<undefined | VSDataTransfer>;
provideDocumentPasteEdits(model: model.ITextModel, selection: Selection, dataTransfer: VSDataTransfer, token: CancellationToken): Promise<WorkspaceEdit | SnippetTextEdit | undefined>;
}
/**
* Represents a parameter of a callable-signature. A parameter can
* have a label and a doc-comment.
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const ILanguageFeaturesService = createDecorator<ILanguageFeaturesService>('ILanguageFeaturesService');
@@ -25,6 +25,8 @@ export interface ILanguageFeaturesService {
readonly codeActionProvider: LanguageFeatureRegistry<CodeActionProvider>;
readonly documentPasteEditProvider: LanguageFeatureRegistry<DocumentPasteEditProvider>;
readonly renameProvider: LanguageFeatureRegistry<RenameProvider>;
readonly documentFormattingEditProvider: LanguageFeatureRegistry<DocumentFormattingEditProvider>;
@@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri';
import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
@@ -41,6 +41,7 @@ export class LanguageFeaturesService implements ILanguageFeaturesService {
readonly documentRangeSemanticTokensProvider = new LanguageFeatureRegistry<DocumentRangeSemanticTokensProvider>(this._score.bind(this));
readonly documentSemanticTokensProvider = new LanguageFeatureRegistry<DocumentSemanticTokensProvider>(this._score.bind(this));
readonly documentOnDropEditProvider = new LanguageFeatureRegistry<DocumentOnDropEditProvider>(this._score.bind(this));
readonly documentPasteEditProvider = new LanguageFeatureRegistry<DocumentPasteEditProvider>(this._score.bind(this));
private _notebookTypeResolver?: NotebookInfoResolver;
@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { editorConfigurationBaseNode } from 'vs/editor/common/config/editorConfigurationSchema';
import { CopyPasteController } from 'vs/editor/contrib/copyPaste/browser/copyPasteController';
import * as nls from 'vs/nls';
import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform';
registerEditorContribution(CopyPasteController.ID, CopyPasteController);
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
...editorConfigurationBaseNode,
properties: {
'editor.experimental.pasteActions.enabled': {
type: 'boolean',
scope: ConfigurationScope.LANGUAGE_OVERRIDABLE,
description: nls.localize('pasteActions', "Enable/disable running edits from extensions on paste."),
default: false,
},
}
});
@@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { addDisposableListener } from 'vs/base/browser/dom';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
import { Disposable } from 'vs/base/common/lifecycle';
import { Mimes } from 'vs/base/common/mime';
import { generateUuid } from 'vs/base/common/uuid';
import { toVSDataTransfer } from 'vs/editor/browser/dnd';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IBulkEditService, ResourceEdit, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
import { Selection } from 'vs/editor/common/core/selection';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { DocumentPasteEditProvider, SnippetTextEdit, WorkspaceEdit } from 'vs/editor/common/languages';
import { ITextModel } from 'vs/editor/common/model';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { CodeEditorStateFlag, EditorStateCancellationTokenSource } from 'vs/editor/contrib/editorState/browser/editorState';
import { performSnippetEdit } from 'vs/editor/contrib/snippet/browser/snippetController2';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
const vscodeClipboardMime = 'application/vnd.code.copyId';
class DefaultPasteEditProvider implements DocumentPasteEditProvider {
async provideDocumentPasteEdits(model: ITextModel, selection: Selection, dataTransfer: VSDataTransfer, _token: CancellationToken): Promise<WorkspaceEdit | undefined> {
const textDataTransfer = dataTransfer.get(Mimes.text) ?? dataTransfer.get('text');
if (textDataTransfer) {
const text = await textDataTransfer.asString();
return {
edits: [new ResourceTextEdit(model.uri, { range: selection, text })]
};
}
return undefined;
}
}
export class CopyPasteController extends Disposable implements IEditorContribution {
public static readonly ID = 'editor.contrib.copyPasteActionController';
public static get(editor: ICodeEditor): CopyPasteController {
return editor.getContribution<CopyPasteController>(CopyPasteController.ID)!;
}
private readonly _editor: ICodeEditor;
private _currentClipboardItem: undefined | {
readonly handle: string;
readonly dataTransferPromise: CancelablePromise<VSDataTransfer>;
};
constructor(
editor: ICodeEditor,
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
@IClipboardService private readonly _clipboardService: IClipboardService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService,
) {
super();
this._editor = editor;
this._languageFeaturesService.documentPasteEditProvider.register('*', new DefaultPasteEditProvider());
const container = editor.getContainerDomNode();
this._register(addDisposableListener(container, 'copy', (e: ClipboardEvent) => {
if (!e.clipboardData) {
return;
}
const model = editor.getModel();
const selection = this._editor.getSelection();
if (!model || !selection) {
return;
}
if (!this.arePasteActionsEnabled(model)) {
return;
}
const providers = this._languageFeaturesService.documentPasteEditProvider.ordered(model).filter(x => !!x.prepareDocumentPaste);
if (!providers.length) {
return;
}
const dataTransfer = toVSDataTransfer(e.clipboardData);
// Save off a handle pointing to data that VS Code maintains.
const handle = generateUuid();
e.clipboardData.setData(vscodeClipboardMime, handle);
const promise = createCancelablePromise(async token => {
const results = await Promise.all(providers.map(provider => {
return provider.prepareDocumentPaste!(model, selection, dataTransfer, token);
}));
for (const result of results) {
result?.forEach((value, key) => {
dataTransfer.set(key, value);
});
}
return dataTransfer;
});
this._currentClipboardItem?.dataTransferPromise.cancel();
this._currentClipboardItem = { handle: handle, dataTransferPromise: promise };
}));
this._register(addDisposableListener(container, 'paste', async (e: ClipboardEvent) => {
const selection = this._editor.getSelection();
if (!e.clipboardData || !selection || !editor.hasModel()) {
return;
}
const model = editor.getModel();
if (!this.arePasteActionsEnabled(model)) {
return;
}
const originalDocVersion = model.getVersionId();
const providers = this._languageFeaturesService.documentPasteEditProvider.ordered(model);
if (!providers.length) {
return;
}
const handle = e.clipboardData?.getData(vscodeClipboardMime);
if (typeof handle !== 'string') {
return;
}
e.preventDefault();
e.stopImmediatePropagation();
const tokenSource = new EditorStateCancellationTokenSource(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Selection);
try {
const dataTransfer = toVSDataTransfer(e.clipboardData);
if (handle && this._currentClipboardItem?.handle === handle) {
const toMergeDataTransfer = await this._currentClipboardItem.dataTransferPromise;
toMergeDataTransfer.forEach((value, key) => {
dataTransfer.set(key, value);
});
}
if (!dataTransfer.has(Mimes.uriList)) {
const resources = await this._clipboardService.readResources();
if (resources.length) {
const value = resources.join('\n');
dataTransfer.set(Mimes.uriList, {
value,
asString: async () => value,
asFile: () => undefined,
});
}
}
dataTransfer.delete(vscodeClipboardMime);
for (const provider of providers) {
const edit = await provider.provideDocumentPasteEdits(model, selection, dataTransfer, tokenSource.token);
if (originalDocVersion !== model.getVersionId()) {
return;
}
if (edit) {
if ((edit as WorkspaceEdit).edits) {
await this._bulkEditService.apply(ResourceEdit.convert(edit as WorkspaceEdit), { editor });
} else {
performSnippetEdit(editor, edit as SnippetTextEdit);
}
return;
}
}
} finally {
tokenSource.dispose();
}
}, true));
}
public arePasteActionsEnabled(model: ITextModel): boolean {
return this._configurationService.getValue('editor.experimental.pasteActions.enabled', {
resource: model.uri
});
}
}
@@ -121,10 +121,8 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
.map(input => input.resource!.toString());
if (editorData.length) {
const added = new VSDataTransfer();
const str = distinct(editorData).join('\n');
added.setString(Mimes.uriList.toLowerCase(), str);
return added;
textEditorDataTransfer.setString(Mimes.uriList.toLowerCase(), str);
}
}
@@ -188,3 +186,4 @@ class DefaultOnDropProvider implements DocumentOnDropEditProvider {
registerEditorContribution(DropIntoEditorController.ID, DropIntoEditorController);
@@ -451,11 +451,11 @@ export class SuggestController implements IEditorContribution {
type AcceptedSuggestionClassification = {
owner: 'jrieken';
comment: 'Information accepting completion items';
providerId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comments: 'Provider of the completions item' };
basenameHash: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comments: 'Hash of the basename of the file into which the completion was inserted' };
fileExtension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'File extension of the file into which the completion was inserted' };
languageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'Language type of the file into which the completion was inserted' };
kind: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'The completion item kind' };
providerId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'Provider of the completions item' };
basenameHash: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'Hash of the basename of the file into which the completion was inserted' };
fileExtension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'File extension of the file into which the completion was inserted' };
languageId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Language type of the file into which the completion was inserted' };
kind: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The completion item kind' };
};
// _debugDisplayName looks like `vscode.css-language-features(/-:)`, where the last bit is the trigger chars
// normalize it to just the extension ID and lowercase
+1
View File
@@ -15,6 +15,7 @@ import 'vs/editor/contrib/clipboard/browser/clipboard';
import 'vs/editor/contrib/codeAction/browser/codeActionContributions';
import 'vs/editor/contrib/codelens/browser/codelensController';
import 'vs/editor/contrib/colorPicker/browser/colorContributions';
import 'vs/editor/contrib/copyPaste/browser/copyPasteContribution';
import 'vs/editor/contrib/comment/browser/comment';
import 'vs/editor/contrib/contextmenu/browser/contextmenu';
import 'vs/editor/contrib/cursorUndo/browser/cursorUndo';
@@ -536,8 +536,10 @@ export class DiagnosticsService implements IDiagnosticsService {
try {
const stats = await collectWorkspaceStats(folder, ['node_modules', '.git']);
type WorkspaceStatsClassification = {
'workspace.id': { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
rendererSessionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
owner: 'lramos15';
comment: 'Metadata related to the workspace';
'workspace.id': { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A UUID given to a workspace to identify it.' };
rendererSessionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The ID of the session' };
};
type WorkspaceStatsEvent = {
'workspace.id': string | undefined;
@@ -548,9 +550,11 @@ export class DiagnosticsService implements IDiagnosticsService {
rendererSessionId: workspace.rendererSessionId
});
type WorkspaceStatsFileClassification = {
rendererSessionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
type: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
count: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
owner: 'lramos15';
comment: 'Helps us gain insights into what type of files are being used in a workspace';
rendererSessionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The ID of the session.' };
type: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The type of file' };
count: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'How many types of that file are present' };
};
type WorkspaceStatsFileEvent = {
rendererSessionId: string;
+1 -1
View File
@@ -7,7 +7,7 @@ import { getClientArea, getTopLeftOffset } from 'vs/base/browser/dom';
import { coalesce } from 'vs/base/common/arrays';
import { language, locale } from 'vs/base/common/platform';
import { IElement, ILocaleInfo, ILocalizedStrings, IWindowDriver } from 'vs/platform/driver/common/driver';
import localizedStrings from 'vs/platform/localizations/common/localizedStrings';
import localizedStrings from 'vs/platform/languagePacks/common/localizedStrings';
export class BrowserWindowDriver implements IWindowDriver {
@@ -616,6 +616,7 @@ export function reportTelemetry(telemetryService: ITelemetryService, eventName:
const errorcode = error ? error instanceof ExtensionManagementError ? error.code : ExtensionManagementErrorCode.Internal : undefined;
/* __GDPR__
"extensionGallery:install" : {
"owner": "sandy081",
"success": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"durationSinceUpdate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
@@ -628,6 +629,7 @@ export function reportTelemetry(telemetryService: ITelemetryService, eventName:
*/
/* __GDPR__
"extensionGallery:uninstall" : {
"owner": "sandy081",
"success": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"errorcode": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
@@ -638,6 +640,7 @@ export function reportTelemetry(telemetryService: ITelemetryService, eventName:
*/
/* __GDPR__
"extensionGallery:update" : {
"owner": "sandy081",
"success": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"errorcode": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
@@ -235,6 +235,7 @@ const DefaultQueryState: IQueryState = {
};
type GalleryServiceQueryClassification = {
owner: 'sandy081';
readonly filterTypes: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
readonly flags: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
readonly sortBy: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
@@ -272,6 +273,7 @@ type GalleryServiceQueryEvent = QueryTelemetryData & {
};
type GalleryServiceAdditionalQueryClassification = {
owner: 'sandy081';
readonly duration: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; 'isMeasurement': true };
readonly count: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
@@ -992,6 +994,7 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
const startTime = new Date().getTime();
/* __GDPR__
"galleryService:downloadVSIX" : {
"owner": "sandy081",
"duration": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"${include}": [
"${GalleryExtensionTelemetryData}"
@@ -1124,6 +1127,7 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
const message = getErrorMessage(err);
type GalleryServiceCDNFallbackClassification = {
owner: 'sandy081';
url: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
message: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
@@ -27,6 +27,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
type ExeExtensionRecommendationsClassification = {
owner: 'sandy081';
extensionId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
exeName: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
};
@@ -12,6 +12,9 @@ export const IExtensionHostStarter = createDecorator<IExtensionHostStarter>('ext
export const ipcExtensionHostStarterChannelName = 'extensionHostStarter';
export interface IExtensionHostProcessOptions {
responseWindowId: number;
responseChannel: string;
responseNonce: string;
env: { [key: string]: string | undefined };
detached: boolean;
execArgv: string[] | undefined;
@@ -27,8 +30,9 @@ export interface IExtensionHostStarter {
onDynamicError(id: string): Event<{ error: SerializedError }>;
onDynamicExit(id: string): Event<{ code: number; signal: string }>;
createExtensionHost(): Promise<{ id: string }>;
start(id: string, opts: IExtensionHostProcessOptions): Promise<{ pid: number }>;
canUseUtilityProcess(): Promise<boolean>;
createExtensionHost(useUtilityProcess: boolean): Promise<{ id: string }>;
start(id: string, opts: IExtensionHostProcessOptions): Promise<void>;
enableInspectPort(id: string): Promise<boolean>;
kill(id: string): Promise<void>;
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { canceled, SerializedError, transformErrorForSerialization } from 'vs/base/common/errors';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { IExtensionHostProcessOptions, IExtensionHostStarter } from 'vs/platform/extensions/common/extensionHostStarter';
import { Emitter, Event } from 'vs/base/common/event';
import { ILogService } from 'vs/platform/log/common/log';
@@ -17,20 +17,40 @@ import { FileAccess } from 'vs/base/common/network';
import { mixin } from 'vs/base/common/objects';
import * as platform from 'vs/base/common/platform';
import { cwd } from 'vs/base/common/process';
import type { EventEmitter } from 'events';
import * as electron from 'electron';
declare namespace UtilityProcessProposedApi {
interface UtilityProcessOptions {
serviceName?: string | undefined;
execArgv?: string[] | undefined;
env?: NodeJS.ProcessEnv | undefined;
}
export class UtilityProcess extends EventEmitter {
readonly pid?: number | undefined;
constructor(modulePath: string, args?: string[] | undefined, options?: UtilityProcessOptions);
postMessage(channel: string, message: any, transfer?: Electron.MessagePortMain[]): void;
kill(signal?: number | string): boolean;
on(event: 'exit', listener: (code: number) => void): this;
on(event: 'spawn', listener: () => void): this;
}
}
const UtilityProcess = <typeof UtilityProcessProposedApi.UtilityProcess>((electron as any).UtilityProcess);
const canUseUtilityProcess = (typeof UtilityProcess !== 'undefined');
export class ExtensionHostStarter implements IDisposable, IExtensionHostStarter {
_serviceBrand: undefined;
private static _lastId: number = 0;
protected readonly _extHosts: Map<string, ExtensionHostProcess>;
protected readonly _extHosts: Map<string, ExtensionHostProcess | UtilityExtensionHostProcess>;
private _shutdown = false;
constructor(
@ILogService private readonly _logService: ILogService,
@ILifecycleMainService lifecycleMainService: ILifecycleMainService
) {
this._extHosts = new Map<string, ExtensionHostProcess>();
this._extHosts = new Map<string, ExtensionHostProcess | UtilityExtensionHostProcess>();
// On shutdown: gracefully await extension host shutdowns
lifecycleMainService.onWillShutdown((e) => {
@@ -43,7 +63,7 @@ export class ExtensionHostStarter implements IDisposable, IExtensionHostStarter
// Intentionally not killing the extension host processes
}
private _getExtHost(id: string): ExtensionHostProcess {
private _getExtHost(id: string): ExtensionHostProcess | UtilityExtensionHostProcess {
const extHostProcess = this._extHosts.get(id);
if (!extHostProcess) {
throw new Error(`Unknown extension host!`);
@@ -71,12 +91,24 @@ export class ExtensionHostStarter implements IDisposable, IExtensionHostStarter
return this._getExtHost(id).onExit;
}
async createExtensionHost(): Promise<{ id: string }> {
async canUseUtilityProcess(): Promise<boolean> {
return canUseUtilityProcess;
}
async createExtensionHost(useUtilityProcess: boolean): Promise<{ id: string }> {
if (this._shutdown) {
throw canceled();
}
const id = String(++ExtensionHostStarter._lastId);
const extHost = new ExtensionHostProcess(id, this._logService);
let extHost: UtilityExtensionHostProcess | ExtensionHostProcess;
if (useUtilityProcess) {
if (!canUseUtilityProcess) {
throw new Error(`Cannot use UtilityProcess!`);
}
extHost = new UtilityExtensionHostProcess(id, this._logService);
} else {
extHost = new ExtensionHostProcess(id, this._logService);
}
this._extHosts.set(id, extHost);
extHost.onExit(({ pid, code, signal }) => {
this._logService.info(`Extension host with pid ${pid} exited with code: ${code}, signal: ${signal}.`);
@@ -88,7 +120,7 @@ export class ExtensionHostStarter implements IDisposable, IExtensionHostStarter
return { id };
}
async start(id: string, opts: IExtensionHostProcessOptions): Promise<{ pid: number }> {
async start(id: string, opts: IExtensionHostProcessOptions): Promise<void> {
if (this._shutdown) {
throw canceled();
}
@@ -160,7 +192,7 @@ class ExtensionHostProcess extends Disposable {
super();
}
start(opts: IExtensionHostProcessOptions): { pid: number } {
start(opts: IExtensionHostProcessOptions): void {
if (platform.isCI) {
this._logService.info(`Calling fork to start extension host...`);
}
@@ -199,8 +231,130 @@ class ExtensionHostProcess extends Disposable {
this._hasExited = true;
this._onExit.fire({ pid, code, signal });
});
return { pid };
}
enableInspectPort(): boolean {
if (!this._process) {
return false;
}
this._logService.info(`Enabling inspect port on extension host with pid ${this._process.pid}.`);
interface ProcessExt {
_debugProcess?(n: number): any;
}
if (typeof (<ProcessExt>process)._debugProcess === 'function') {
// use (undocumented) _debugProcess feature of node
(<ProcessExt>process)._debugProcess!(this._process.pid!);
return true;
} else if (!platform.isWindows) {
// use KILL USR1 on non-windows platforms (fallback)
this._process.kill('SIGUSR1');
return true;
} else {
// not supported...
return false;
}
}
kill(): void {
if (!this._process) {
return;
}
this._logService.info(`Killing extension host with pid ${this._process.pid}.`);
this._process.kill();
}
async waitForExit(maxWaitTimeMs: number): Promise<void> {
if (!this._process) {
return;
}
const pid = this._process.pid;
this._logService.info(`Waiting for extension host with pid ${pid} to exit.`);
await Promise.race([Event.toPromise(this.onExit), timeout(maxWaitTimeMs)]);
if (!this._hasExited) {
// looks like we timed out
this._logService.info(`Extension host with pid ${pid} did not exit within ${maxWaitTimeMs}ms.`);
this._process.kill();
}
}
}
class UtilityExtensionHostProcess extends Disposable {
readonly onStdout = Event.None;
readonly onStderr = Event.None;
readonly onError = Event.None;
readonly _onMessage = this._register(new Emitter<any>());
readonly onMessage = this._onMessage.event;
readonly _onExit = this._register(new Emitter<{ pid: number; code: number; signal: string }>());
readonly onExit = this._onExit.event;
private _process: UtilityProcessProposedApi.UtilityProcess | null = null;
private _hasExited: boolean = false;
constructor(
public readonly id: string,
@ILogService private readonly _logService: ILogService,
) {
super();
}
start(opts: IExtensionHostProcessOptions): void {
const responseWindow = electron.BrowserWindow.fromId(opts.responseWindowId);
if (!responseWindow || responseWindow.isDestroyed() || responseWindow.webContents.isDestroyed()) {
this._logService.info(`Refusing to create new Extension Host UtilityProcess because requesting window cannot be found...`);
return;
}
const serviceName = `extensionHost${this.id}`;
const modulePath = FileAccess.asFileUri('bootstrap-fork.js', require).fsPath;
const args: string[] = ['--type=extensionHost', '--skipWorkspaceStorageLock'];
const execArgv: string[] = opts.execArgv || [];
const env: { [key: string]: any } = { ...opts.env };
// Make sure all values are strings, otherwise the process will not start
for (const key of Object.keys(env)) {
env[key] = String(env[key]);
}
this._logService.info(`Creating new UtilityProcess to start extension host...`);
this._process = new UtilityProcess(modulePath, args, { serviceName, env, execArgv });
this._process.on('spawn', () => {
this._logService.info(`Utility process emits spawn!`);
});
this._process.on('exit', (code: number) => {
this._logService.info(`Utility process emits exit!`);
this._hasExited = true;
this._onExit.fire({ pid: this._process!.pid!, code, signal: '' });
});
const listener = (event: electron.Event, details: electron.Details) => {
if (details.type !== 'Utility') {
return;
}
// Despite the fact that we pass the argument `seviceName`,
// the details have a field called `name` where this value appears
if (details.name === serviceName) {
this._logService.info(`Utility process emits exit!`);
this._hasExited = true;
this._onExit.fire({ pid: this._process!.pid!, code: details.exitCode, signal: '' });
}
};
electron.app.on('child-process-gone', listener);
this._register(toDisposable(() => {
electron.app.off('child-process-gone', listener);
}));
const { port1, port2 } = new electron.MessageChannelMain();
this._process.postMessage('port', null, [port2]);
responseWindow.webContents.postMessage(opts.responseChannel, opts.responseNonce, [port1]);
}
enableInspectPort(): boolean {
@@ -16,6 +16,7 @@ import { createFileSystemProviderError, FileChangeType, IFileDeleteOptions, IFil
import { DBClosedError, IndexedDB } from 'vs/base/browser/indexedDB';
export type IndexedDBFileSystemProviderErrorDataClassification = {
owner: 'sandy081';
readonly scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
readonly operation: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
readonly code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' };
@@ -0,0 +1,12 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const ILanguagePackService = createDecorator<ILanguagePackService>('languagePackService');
export interface ILanguagePackService {
readonly _serviceBrand: undefined;
getInstalledLanguages(): Promise<string[]>;
}
@@ -13,7 +13,8 @@ import { Promises } from 'vs/base/node/pfs';
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
import { IExtensionIdentifier, IExtensionManagementService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ILocalizationsService, isValidLocalization } from 'vs/platform/localizations/common/localizations';
import { ILocalizationContribution } from 'vs/platform/extensions/common/extensions';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { ILogService } from 'vs/platform/log/common/log';
interface ILanguagePack {
@@ -25,7 +26,7 @@ interface ILanguagePack {
translations: { [id: string]: string };
}
export class LocalizationsService extends Disposable implements ILocalizationsService {
export class LanguagePackService extends Disposable implements ILanguagePackService {
declare readonly _serviceBrand: undefined;
@@ -48,7 +49,7 @@ export class LocalizationsService extends Disposable implements ILocalizationsSe
});
}
async getLanguageIds(): Promise<string[]> {
async getInstalledLanguages(): Promise<string[]> {
const languagePacks = await this.cache.getLanguagePacks();
// Contributed languages are those installed via extension packs, so does not include English
const languages = ['en', ...Object.keys(languagePacks)];
@@ -174,3 +175,27 @@ class LanguagePacksCache extends Disposable {
});
}
}
function isValidLocalization(localization: ILocalizationContribution): boolean {
if (typeof localization.languageId !== 'string') {
return false;
}
if (!Array.isArray(localization.translations) || localization.translations.length === 0) {
return false;
}
for (const translation of localization.translations) {
if (typeof translation.id !== 'string') {
return false;
}
if (typeof translation.path !== 'string') {
return false;
}
}
if (localization.languageName && typeof localization.languageName !== 'string') {
return false;
}
if (localization.localizedLanguageName && typeof localization.localizedLanguageName !== 'string') {
return false;
}
return true;
}
@@ -1,37 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ILocalizationContribution } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const ILocalizationsService = createDecorator<ILocalizationsService>('localizationsService');
export interface ILocalizationsService {
readonly _serviceBrand: undefined;
getLanguageIds(): Promise<string[]>;
}
export function isValidLocalization(localization: ILocalizationContribution): boolean {
if (typeof localization.languageId !== 'string') {
return false;
}
if (!Array.isArray(localization.translations) || localization.translations.length === 0) {
return false;
}
for (const translation of localization.translations) {
if (typeof translation.id !== 'string') {
return false;
}
if (typeof translation.path !== 'string') {
return false;
}
}
if (localization.languageName && typeof localization.languageName !== 'string') {
return false;
}
if (localization.localizedLanguageName && typeof localization.localizedLanguageName !== 'string') {
return false;
}
return true;
}
@@ -84,8 +84,10 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf
return configurationService.onDidChangeConfiguration(event => {
if (event.source !== ConfigurationTarget.DEFAULT) {
type UpdateConfigurationClassification = {
configurationSource: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
configurationKeys: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
owner: 'lramos15, sbatten';
comment: 'Event which fires when user updates telemetry configuration';
configurationSource: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'What configuration file was updated i.e user or workspace' };
configurationKeys: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'What configuration keys were updated' };
};
type UpdateConfigurationEvent = {
configurationSource: string;
@@ -144,7 +144,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
private _handleVSCodeSequence(data: string): boolean {
const didHandle = this._doHandleVSCodeSequence(data);
if (!this._hasUpdatedTelemetry && didHandle) {
this._telemetryService?.publicLog2<{ classification: 'SystemMetaData'; purpose: 'FeatureInsight' }>('terminal/shellIntegrationActivationSucceeded');
this._telemetryService?.publicLog2<{}, { owner: 'meganrogge'; comment: 'Indicates shell integration was activated' }>('terminal/shellIntegrationActivationSucceeded');
this._hasUpdatedTelemetry = true;
if (this._activationTimeout !== undefined) {
clearTimeout(this._activationTimeout);
@@ -232,7 +232,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
private async _ensureCapabilitiesOrAddFailureTelemetry(): Promise<void> {
this._activationTimeout = setTimeout(() => {
if (!this.capabilities.get(TerminalCapability.CommandDetection) && !this.capabilities.get(TerminalCapability.CwdDetection)) {
this._telemetryService?.publicLog2<{ classification: 'SystemMetaData'; purpose: 'FeatureInsight' }>('terminal/shellIntegrationActivationTimeout');
this._telemetryService?.publicLog2<{}, { owner: 'meganrogge'; comment: 'Indicates shell integration activation did not occur within 10 seconds' }>('terminal/shellIntegrationActivationTimeout');
this._logService.warn('Shell integration failed to add capabilities within 10 seconds');
}
this._hasUpdatedTelemetry = true;
@@ -19,6 +19,7 @@ export function createUpdateURL(platform: string, quality: string, productServic
}
export type UpdateNotAvailableClassification = {
owner: 'joaomoreno';
explicit: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
@@ -92,6 +92,7 @@ export class DarwinUpdateService extends AbstractUpdateService {
}
type UpdateDownloadedClassification = {
owner: 'joaomoreno';
version: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
this.telemetryService.publicLog2<{ version: String }, UpdateDownloadedClassification>('update:downloaded', { version: update.version });
@@ -29,6 +29,7 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'
import { Change, getLastSyncResourceUri, IRemoteUserData, IResourcePreview as IBaseResourcePreview, ISyncData, ISyncResourceHandle, ISyncResourcePreview as IBaseSyncResourcePreview, IUserData, IUserDataInitializer, IUserDataManifest, IUserDataSyncBackupStoreService, IUserDataSyncConfiguration, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, IUserDataSyncUtilService, MergeState, PREVIEW_DIR_NAME, SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_CONFIGURATION_SCOPE, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
type SyncSourceClassification = {
owner: 'sandy081';
source?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
@@ -22,10 +22,12 @@ import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/use
import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines';
type AutoSyncClassification = {
owner: 'sandy081';
sources: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
type AutoSyncErrorClassification = {
owner: 'sandy081';
code: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
service: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
@@ -194,7 +196,7 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
// Reset
if (everywhere) {
this.telemetryService.publicLog2('sync/turnOffEveryWhere');
this.telemetryService.publicLog2<{}, { owner: 'sandy081' }>('sync/turnOffEveryWhere');
await this.userDataSyncService.reset();
} else {
await this.userDataSyncService.resetLocal();
@@ -12,6 +12,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ALL_SYNC_RESOURCES, getEnablementKey, IUserDataSyncEnablementService, IUserDataSyncStoreManagementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
type SyncEnablementClassification = {
owner: 'sandy081';
enabled?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
@@ -28,6 +28,7 @@ import { TasksSynchroniser } from 'vs/platform/userDataSync/common/tasksSync';
import { ALL_SYNC_RESOURCES, Change, createSyncHeaders, IManualSyncTask, IResourcePreview, ISyncResourceHandle, ISyncResourcePreview, ISyncTask, IUserDataManifest, IUserDataSyncConfiguration, IUserDataSyncEnablementService, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncService, IUserDataSyncStoreManagementService, IUserDataSyncStoreService, MergeState, SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, UserDataSyncStoreError, USER_DATA_SYNC_CONFIGURATION_SCOPE } from 'vs/platform/userDataSync/common/userDataSync';
type SyncErrorClassification = {
owner: 'sandy081';
code: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
service: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
serverCode?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
@@ -28,8 +28,8 @@ import { SpdLogLogger } from 'vs/platform/log/node/spdlogLog';
import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IServerEnvironmentService, ServerEnvironmentService, ServerParsedArgs } from 'vs/server/node/serverEnvironmentService';
import { ExtensionManagementCLIService } from 'vs/platform/extensionManagement/common/extensionManagementCLIService';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { LanguagePackService } from 'vs/platform/languagePacks/node/languagePacks';
import { getErrorMessage } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
import { isAbsolute, join } from 'vs/base/common/path';
@@ -104,7 +104,7 @@ class CliMain extends Disposable {
services.set(IExtensionsScannerService, new SyncDescriptor(ExtensionsScannerService));
services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
services.set(IExtensionManagementCLIService, new SyncDescriptor(ExtensionManagementCLIService));
services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService));
services.set(ILanguagePackService, new SyncDescriptor(LanguagePackService));
return new InstantiationService(services);
}
@@ -757,10 +757,10 @@ export async function createServer(address: string | net.AddressInfo | null, arg
type ServerStartClassification = {
owner: 'alexdima';
comment: 'The server has started up';
startTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' };
startedTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' };
codeLoadedTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' };
readyTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' };
startTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The time the server started at.' };
startedTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The time the server began listening for connections.' };
codeLoadedTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The time which the code loaded on the server' };
readyTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The time when the server was completely ready' };
};
type ServerStartEvent = {
startTime: number;
+3 -3
View File
@@ -35,8 +35,8 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { LanguagePackService } from 'vs/platform/languagePacks/node/languagePacks';
import { AbstractLogger, DEFAULT_LOG_LEVEL, getLogLevel, ILogService, LogLevel, LogService, MultiplexLogService } from 'vs/platform/log/common/log';
import { LogLevelChannel } from 'vs/platform/log/common/logIpc';
import { SpdLogLogger } from 'vs/platform/log/node/spdlogLog';
@@ -159,7 +159,7 @@ export async function setupServerServices(connectionToken: ServerConnectionToken
services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
const instantiationService: IInstantiationService = new InstantiationService(services);
services.set(ILocalizationsService, instantiationService.createInstance(LocalizationsService));
services.set(ILanguagePackService, instantiationService.createInstance(LanguagePackService));
const extensionManagementCLIService = instantiationService.createInstance(ExtensionManagementCLIService);
services.set(IExtensionManagementCLIService, extensionManagementCLIService);
@@ -5,6 +5,7 @@
import { VSBuffer } from 'vs/base/common/buffer';
import { CancellationToken } from 'vs/base/common/cancellation';
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
import { CancellationError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
@@ -23,14 +24,13 @@ import { ITextModel } from 'vs/editor/common/model';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { decodeSemanticTokensDto } from 'vs/editor/common/services/semanticTokensDto';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
import { DataTransferCache } from 'vs/workbench/api/common/shared/dataTransferCache';
import * as callh from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
import * as search from 'vs/workbench/contrib/search/common/search';
import * as typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape, reviveWorkspaceEditDto } from '../common/extHost.protocol';
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceEditDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape, reviveWorkspaceEditDto } from '../common/extHost.protocol';
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
export class MainThreadLanguageFeatures extends Disposable implements MainThreadLanguageFeaturesShape {
@@ -366,6 +366,47 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
this._registrations.set(handle, this._languageFeaturesService.codeActionProvider.register(selector, provider));
}
// --- copy paste action provider
$registerPasteEditProvider(handle: number, selector: IDocumentFilterDto[], supportsCopy: boolean): void {
const provider: languages.DocumentPasteEditProvider = {
prepareDocumentPaste: supportsCopy
? async (model: ITextModel, selection: Selection, dataTransfer: VSDataTransfer, token: CancellationToken): Promise<VSDataTransfer | undefined> => {
const dataTransferDto = await typeConvert.DataTransfer.toDataTransferDTO(dataTransfer);
if (token.isCancellationRequested) {
return undefined;
}
const result = await this._proxy.$prepareDocumentPaste(handle, model.uri, selection, dataTransferDto, token);
if (!result) {
return undefined;
}
const dataTransferOut = new VSDataTransfer();
result.items.forEach(([type, item]) => {
dataTransferOut.setString(type, item.asString);
});
return dataTransferOut;
}
: undefined,
provideDocumentPasteEdits: async (model: ITextModel, selection: Selection, dataTransfer: VSDataTransfer, token: CancellationToken) => {
const d = await typeConvert.DataTransfer.toDataTransferDTO(dataTransfer);
const result = await this._proxy.$providePasteEdits(handle, model.uri, selection, d, token);
if (!result) {
return;
} else if ((result as IWorkspaceEditDto).edits) {
return reviveWorkspaceEditDto(result as IWorkspaceEditDto);
} else {
return result as languages.SnippetTextEdit;
}
}
};
this._registrations.set(handle, this._languageFeaturesService.documentPasteEditProvider.register(selector, provider));
}
// --- formatting
$registerDocumentFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void {
@@ -421,6 +421,16 @@ export class MainThreadSCM implements MainThreadSCMShape {
repository.input.placeholder = placeholder;
}
$setInputBoxEnablement(sourceControlHandle: number, enabled: boolean): void {
const repository = this._repositories.get(sourceControlHandle);
if (!repository) {
return;
}
repository.input.enabled = enabled;
}
$setInputBoxVisibility(sourceControlHandle: number, visible: boolean): void {
const repository = this._repositories.get(sourceControlHandle);
@@ -37,14 +37,14 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews);
}
async $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean; canSelectMany: boolean; dropMimeTypes: string[]; dragMimeTypes: string[]; hasHandleDrag: boolean; hasHandleDrop: boolean }): Promise<void> {
async $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean; canSelectMany: boolean; dropMimeTypes: string[]; dragMimeTypes: string[]; hasHandleDrag: boolean; hasHandleDrop: boolean; supportsFileDataTransfers: boolean }): Promise<void> {
this.logService.trace('MainThreadTreeViews#$registerTreeViewDataProvider', treeViewId, options);
this.extensionService.whenInstalledExtensionsRegistered().then(() => {
const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService);
this._dataProviders.set(treeViewId, dataProvider);
const dndController = (options.hasHandleDrag || options.hasHandleDrop)
? new TreeViewDragAndDropController(treeViewId, options.dropMimeTypes, options.dragMimeTypes, options.hasHandleDrag, this._proxy) : undefined;
? new TreeViewDragAndDropController(treeViewId, options.dropMimeTypes, options.dragMimeTypes, options.hasHandleDrag, options.supportsFileDataTransfers, this._proxy) : undefined;
const viewer = this.getTreeView(treeViewId);
if (viewer) {
// Order is important here. The internal tree isn't created until the dataProvider is set.
@@ -201,6 +201,7 @@ class TreeViewDragAndDropController implements ITreeViewDragAndDropController {
readonly dropMimeTypes: string[],
readonly dragMimeTypes: string[],
readonly hasWillDrop: boolean,
readonly supportsFileDataTransfers: boolean,
private readonly _proxy: ExtHostTreeViewsShape) { }
async handleDrop(dataTransfer: VSDataTransfer, targetTreeItem: ITreeItem | undefined, token: CancellationToken,
@@ -457,6 +457,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable {
return extHostLanguageFeatures.registerCodeActionProvider(extension, checkSelector(selector), provider, metadata);
},
registerDocumentPasteEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentPasteEditProvider): vscode.Disposable {
checkProposedApiEnabled(extension, 'documentPaste');
return extHostLanguageFeatures.registerDocumentPasteEditProvider(extension, checkSelector(selector), provider);
},
registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider);
},
@@ -524,7 +528,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters);
},
registerInlineCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider): vscode.Disposable {
checkProposedApiEnabled(extension, 'inlineCompletions');
if (provider.handleDidShowCompletionItem) {
checkProposedApiEnabled(extension, 'inlineCompletionsAdditions');
}
@@ -258,7 +258,7 @@ export interface MainThreadTextEditorsShape extends IDisposable {
}
export interface MainThreadTreeViewsShape extends IDisposable {
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean; canSelectMany: boolean; dropMimeTypes: readonly string[]; dragMimeTypes: readonly string[]; hasHandleDrag: boolean; hasHandleDrop: boolean }): Promise<void>;
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean; canSelectMany: boolean; dropMimeTypes: readonly string[]; dragMimeTypes: readonly string[]; hasHandleDrag: boolean; hasHandleDrop: boolean; supportsFileDataTransfers: boolean }): Promise<void>;
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise<void>;
$reveal(treeViewId: string, itemInfo: { item: ITreeItem; parentChain: ITreeItem[] } | undefined, options: IRevealOptions): Promise<void>;
$setMessage(treeViewId: string, message: string): void;
@@ -372,6 +372,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerLinkedEditingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], metadata: ICodeActionProviderMetadataDto, displayName: string, supportsResolve: boolean): void;
$registerPasteEditProvider(handle: number, selector: IDocumentFilterDto[], supportsCopy: boolean): void;
$registerDocumentFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void;
$registerRangeFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void;
$registerOnTypeFormattingSupport(handle: number, selector: IDocumentFilterDto[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void;
@@ -1187,6 +1188,7 @@ export interface MainThreadSCMShape extends IDisposable {
$setInputBoxValue(sourceControlHandle: number, value: string): void;
$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
$setInputBoxEnablement(sourceControlHandle: number, enabled: boolean): void;
$setInputBoxVisibility(sourceControlHandle: number, visible: boolean): void;
$showValidationMessage(sourceControlHandle: number, message: string | IMarkdownString, type: InputValidationType): void;
$setValidationProviderIsEnabled(sourceControlHandle: number, enabled: boolean): void;
@@ -1729,6 +1731,8 @@ export interface ExtHostLanguageFeaturesShape {
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: languages.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined>;
$resolveCodeAction(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<IWorkspaceEditDto | undefined>;
$releaseCodeActions(handle: number, cacheId: number): void;
$prepareDocumentPaste(handle: number, uri: UriComponents, range: IRange, dataTransfer: DataTransferDTO, token: CancellationToken): Promise<DataTransferDTO | undefined>;
$providePasteEdits(handle: number, uri: UriComponents, range: IRange, dataTransfer: DataTransferDTO, token: CancellationToken): Promise<IWorkspaceEditDto | Dto<languages.SnippetTextEdit> | undefined>;
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: languages.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: languages.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: languages.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
@@ -424,6 +424,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) {
const event = getTelemetryActivationEvent(extensionDescription, reason);
type ExtensionActivationTimesClassification = {
owner: 'jrieken';
outcome: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
} & TelemetryActivationEventFragment & ExtensionActivationTimesFragment;
@@ -447,7 +448,9 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> {
const event = getTelemetryActivationEvent(extensionDescription, reason);
type ActivatePluginClassification = {} & TelemetryActivationEventFragment;
type ActivatePluginClassification = {
owner: 'jrieken';
} & TelemetryActivationEventFragment;
this._mainThreadTelemetryProxy.$publicLog2<TelemetryActivationEvent, ActivatePluginClassification>('activatePlugin', event);
const entryPoint = this._getEntryPoint(extensionDescription);
if (!entryPoint) {
@@ -7,7 +7,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
import { mixin } from 'vs/base/common/objects';
import type * as vscode from 'vscode';
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit, Location, InlineCompletionTriggerKindNew, InlineCompletionTriggerKind } from 'vs/workbench/api/common/extHostTypes';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit, Location, InlineCompletionTriggerKindNew, InlineCompletionTriggerKind, WorkspaceEdit } from 'vs/workbench/api/common/extHostTypes';
import { ISingleEditOperation } from 'vs/editor/common/core/editOperation';
import * as languages from 'vs/editor/common/languages';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
@@ -31,7 +31,7 @@ import { IdGenerator } from 'vs/base/common/idGenerator';
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
import { Cache } from './cache';
import { StopWatch } from 'vs/base/common/stopwatch';
import { isCancellationError } from 'vs/base/common/errors';
import { isCancellationError, NotImplementedError } from 'vs/base/common/errors';
import { raceCancellationError } from 'vs/base/common/async';
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { Dto } from 'vs/workbench/services/extensions/common/proxyIdentifier';
@@ -485,6 +485,52 @@ class CodeActionAdapter {
}
}
class DocumentPasteEditProvider {
constructor(
private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape,
private readonly _documents: ExtHostDocuments,
private readonly _provider: vscode.DocumentPasteEditProvider,
private readonly _handle: number,
) { }
async prepareDocumentPaste(resource: URI, range: IRange, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.DataTransferDTO | undefined> {
if (!this._provider.prepareDocumentPaste) {
return undefined;
}
const doc = this._documents.getDocument(resource);
const vscodeRange = typeConvert.Range.to(range);
const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, () => {
throw new NotImplementedError();
});
await this._provider.prepareDocumentPaste(doc, vscodeRange, dataTransfer, token);
return typeConvert.DataTransfer.toDataTransferDTO(dataTransfer);
}
async providePasteEdits(requestId: number, resource: URI, range: IRange, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<undefined | extHostProtocol.IWorkspaceEditDto | Dto<languages.SnippetTextEdit>> {
const doc = this._documents.getDocument(resource);
const vscodeRange = typeConvert.Range.to(range);
const dataTransfer = typeConvert.DataTransfer.toDataTransfer(dataTransferDto, async (index) => {
return (await this._proxy.$resolveDocumentOnDropFileData(this._handle, requestId, index)).buffer;
});
const edit = await this._provider.provideDocumentPasteEdits(doc, vscodeRange, dataTransfer, token);
if (!edit) {
return;
}
if (edit instanceof WorkspaceEdit) {
return typeConvert.WorkspaceEdit.from(edit);
} else {
return typeConvert.SnippetTextEdit.from(edit as vscode.SnippetTextEdit);
}
}
}
class DocumentFormattingAdapter {
constructor(
@@ -1769,7 +1815,7 @@ class DocumentOnDropEditAdapter {
}
type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentPasteEditProvider | DocumentFormattingAdapter
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
| CompletionsAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter
| TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter
@@ -2413,6 +2459,23 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
Promise.resolve(adapter.provideDocumentOnDropEdits(requestId, URI.revive(resource), position, dataTransferDto, token)), undefined, undefined);
}
// --- copy/paste actions
registerDocumentPasteEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentPasteEditProvider): vscode.Disposable {
const handle = this._nextHandle();
this._adapter.set(handle, new AdapterData(new DocumentPasteEditProvider(this._proxy, this._documents, provider, handle), extension));
this._proxy.$registerPasteEditProvider(handle, this._transformDocumentSelector(selector), !!provider.prepareDocumentPaste);
return this._createDisposable(handle);
}
$prepareDocumentPaste(handle: number, resource: UriComponents, range: IRange, dataTransfer: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.DataTransferDTO | undefined> {
return this._withAdapter(handle, DocumentPasteEditProvider, adapter => adapter.prepareDocumentPaste(URI.revive(resource), range, dataTransfer, token), undefined, token);
}
$providePasteEdits(handle: number, resource: UriComponents, range: IRange, dataTransferDto: extHostProtocol.DataTransferDTO, token: CancellationToken): Promise<extHostProtocol.IWorkspaceEditDto | Dto<languages.SnippetTextEdit> | undefined> {
return this._withAdapter(handle, DocumentPasteEditProvider, adapter => adapter.providePasteEdits(0, URI.revive(resource), range, dataTransferDto, token), undefined, token);
}
// --- configuration
private static _serializeRegExp(regExp: RegExp): extHostProtocol.IRegExpDto {
@@ -249,6 +249,7 @@ class KeytarNodeModuleFactory implements INodeModuleFactory {
public load(_request: string, parent: URI): any {
const ext = this._extensionPaths.findSubstr(parent);
type ShimmingKeytarClassification = {
owner: 'jrieken';
extension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
this._mainThreadTelemetry.$publicLog2<{ extension: string }, ShimmingKeytarClassification>('shimming.keytar', { extension: ext?.identifier.value ?? 'unknown_extension' });
@@ -346,6 +347,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
return;
}
type ShimmingOpenClassification = {
owner: 'jrieken';
extension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
this._mainThreadTelemetry.$publicLog2<{ extension: string }, ShimmingOpenClassification>('shimming.open', { extension: this._extensionId });
@@ -356,6 +358,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
return;
}
type ShimmingOpenCallNoForwardClassification = {
owner: 'jrieken';
extension: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
this._mainThreadTelemetry.$publicLog2<{ extension: string }, ShimmingOpenCallNoForwardClassification>('shimming.open.call.noForward', { extension: this._extensionId });
+23 -1
View File
@@ -249,6 +249,25 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
this.#proxy.$setValidationProviderIsEnabled(this._sourceControlHandle, !!fn);
}
private _enabled: boolean = true;
get enabled(): boolean {
checkProposedApiEnabled(this._extension, 'scmInput');
return this._enabled;
}
set enabled(enabled: boolean) {
checkProposedApiEnabled(this._extension, 'scmInput');
enabled = !!enabled;
if (this._enabled === enabled) {
return;
}
this._enabled = enabled;
this.#proxy.$setInputBoxEnablement(this._sourceControlHandle, enabled);
}
private _visible: boolean = true;
get visible(): boolean {
@@ -722,7 +741,10 @@ export class ExtHostSCM implements ExtHostSCMShape {
this.logService.trace('ExtHostSCM#createSourceControl', extension.identifier.value, id, label, rootUri);
type TEvent = { extensionId: string };
type TMeta = { extensionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' } };
type TMeta = {
owner: 'joaomoreno';
extensionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
this._telemetry.$publicLog2<TEvent, TMeta>('api/scm/createSourceControl', {
extensionId: extension.identifier.value,
});
+1 -1
View File
@@ -24,7 +24,7 @@ import { Schemas } from 'vs/base/common/network';
import * as Platform from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
import { USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/taskService';
import { USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/tasks';
import { NotSupportedError } from 'vs/base/common/errors';
export interface IExtHostTask extends ExtHostTaskShape {
@@ -24,7 +24,7 @@ import { IMarkdownString } from 'vs/base/common/htmlContent';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { Command } from 'vs/editor/common/languages';
import { ITreeViewsService, TreeviewsService } from 'vs/workbench/services/views/common/treeViewsService';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
type TreeItemHandle = string;
@@ -92,7 +92,8 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
const dragMimeTypes = options.dragAndDropController?.dragMimeTypes ?? [];
const hasHandleDrag = !!options.dragAndDropController?.handleDrag;
const hasHandleDrop = !!options.dragAndDropController?.handleDrop;
const registerPromise = this._proxy.$registerTreeViewDataProvider(viewId, { showCollapseAll: !!options.showCollapseAll, canSelectMany: !!options.canSelectMany, dropMimeTypes, dragMimeTypes, hasHandleDrag, hasHandleDrop });
const supportsFileDataTransfers = isProposedApiEnabled(extension, 'dataTransferFiles');
const registerPromise = this._proxy.$registerTreeViewDataProvider(viewId, { showCollapseAll: !!options.showCollapseAll, canSelectMany: !!options.canSelectMany, dropMimeTypes, dragMimeTypes, hasHandleDrag, hasHandleDrop, supportsFileDataTransfers });
const treeView = this.createExtHostTreeView(viewId, options, extension);
return {
get onDidCollapseElement() { return treeView.onDidCollapseElement; },
@@ -23,6 +23,7 @@ import { IHostUtils } from 'vs/workbench/api/common/extHostExtensionService';
import { ProcessTimeRunOnceScheduler } from 'vs/base/common/async';
import { boolean } from 'vs/editor/common/config/editorOptions';
import { createURITransformer } from 'vs/workbench/api/node/uriTransformer';
import { MessagePortMain } from 'electron';
import 'vs/workbench/api/common/extHost.common.services';
import 'vs/workbench/api/node/extHost.node.services';
@@ -102,8 +103,37 @@ let onTerminate = function (reason: string) {
nativeExit();
};
function _createExtHostProtocol(): Promise<PersistentProtocol> {
if (process.env.VSCODE_EXTHOST_WILL_SEND_SOCKET) {
function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
if (process.env.VSCODE_WILL_SEND_MESSAGE_PORT) {
return new Promise<IMessagePassingProtocol>((resolve, reject) => {
const withPorts = (ports: MessagePortMain[]) => {
const port = ports[0];
const onMessage = new BufferedEmitter<VSBuffer>();
port.on('message', (e) => onMessage.fire(VSBuffer.wrap(e.data)));
port.on('close', () => {
onTerminate('renderer closed the MessagePort');
});
port.start();
resolve({
onMessage: onMessage.event,
send: message => port.postMessage(message.buffer)
});
};
if ((<any>global).vscodePorts) {
const ports = (<any>global).vscodePorts;
delete (<any>global).vscodePorts;
withPorts(ports);
} else {
(<any>global).vscodePortsCallback = withPorts;
}
});
} else if (process.env.VSCODE_EXTHOST_WILL_SEND_SOCKET) {
return new Promise<PersistentProtocol>((resolve, reject) => {
@@ -220,8 +250,10 @@ async function createExtHostProtocol(): Promise<IMessagePassingProtocol> {
}
}
drain(): Promise<void> {
return protocol.drain();
async drain(): Promise<void> {
if (protocol.drain) {
return protocol.drain();
}
}
};
}
@@ -75,7 +75,7 @@ suite('MainThreadHostTreeView', function () {
}
drain(): any { return null; }
}, new TestViewsService(), new TestNotificationService(), testExtensionService, new NullLogService());
mainThreadTreeViews.$registerTreeViewDataProvider(testTreeViewId, { showCollapseAll: false, canSelectMany: false, dropMimeTypes: [], dragMimeTypes: [], hasHandleDrag: false, hasHandleDrop: false });
mainThreadTreeViews.$registerTreeViewDataProvider(testTreeViewId, { showCollapseAll: false, canSelectMany: false, dropMimeTypes: [], dragMimeTypes: [], hasHandleDrag: false, hasHandleDrop: false, supportsFileDataTransfers: false });
await testExtensionService.whenInstalledExtensionsRegistered();
});
@@ -102,6 +102,7 @@ export class ViewContainerActivityAction extends ActivityAction {
private logAction(action: string) {
type ActivityBarActionClassification = {
owner: 'sbatten';
viewletId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
action: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
@@ -968,6 +968,7 @@ function registerCloseEditorCommands() {
]);
type WorkbenchEditorReopenClassification = {
owner: 'rebornix';
scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
ext: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
@@ -575,6 +575,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
/* __GDPR__
"editorOpened" : {
"owner": "bpasero",
"${include}": [
"${EditorTelemetryDescriptor}"
]
@@ -611,6 +612,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
/* __GDPR__
"editorClosed" : {
"owner": "bpasero",
"${include}": [
"${EditorTelemetryDescriptor}"
]
@@ -66,7 +66,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
import { ThemeSettings } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { ITreeViewsService } from 'vs/workbench/services/views/browser/treeViewsService';
import { CodeDataTransfers } from 'vs/platform/dnd/browser/dnd';
import { CodeDataTransfers, FileAdditionalNativeProperties } from 'vs/platform/dnd/browser/dnd';
export class TreeViewPane extends ViewPane {
@@ -1503,40 +1503,21 @@ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
}
const treeDataTransfer = new VSDataTransfer();
const uris: URI[] = [];
let itemsCount = Array.from(originalEvent.dataTransfer.items).reduce((previous, current) => {
if ((current.kind === 'string') || (current.kind === 'file')) {
return previous + 1;
}
return previous;
}, 0);
let treeSourceInfo: TreeDragSourceInfo | undefined;
let willDropUuid: string | undefined;
if (this.treeItemsTransfer.hasData(DraggedTreeItemsIdentifier.prototype)) {
willDropUuid = this.treeItemsTransfer.getData(DraggedTreeItemsIdentifier.prototype)![0].identifier;
}
await new Promise<void>(resolve => {
function decrementStringCount() {
itemsCount--;
if (itemsCount === 0) {
// Check if there are uris to add and add them
if (uris.length) {
treeDataTransfer.setString(Mimes.uriList, uris.map(uri => uri.toString()).join('\n'));
}
resolve();
}
}
if (!originalEvent.dataTransfer) {
return;
}
for (const dataItem of originalEvent.dataTransfer.items) {
const type = dataItem.type;
const kind = dataItem.kind;
const convertedType = this.convertKnownMimes(type, kind).type;
if ((INTERNAL_MIME_TYPES.indexOf(convertedType) < 0)
&& (convertedType === this.treeMimeType) || (dndController.dropMimeTypes.indexOf(convertedType) >= 0)) {
if (dataItem.kind === 'string') {
await Promise.all([...originalEvent.dataTransfer.items].map(async dataItem => {
const type = dataItem.type;
const kind = dataItem.kind;
const convertedType = this.convertKnownMimes(type, kind).type;
if ((INTERNAL_MIME_TYPES.indexOf(convertedType) < 0)
&& (convertedType === this.treeMimeType) || (dndController.dropMimeTypes.indexOf(convertedType) >= 0)) {
if (dataItem.kind === 'string') {
await new Promise<void>(resolve =>
dataItem.getAsString(dataValue => {
if (convertedType === this.treeMimeType) {
treeSourceInfo = JSON.parse(dataValue);
@@ -1545,20 +1526,27 @@ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
const converted = this.convertKnownMimes(type, kind, dataValue);
treeDataTransfer.setString(converted.type, converted.value + '');
}
decrementStringCount();
});
} else if (dataItem.kind === 'file') {
const dataValue = dataItem.getAsFile();
if (dataValue) {
uris.push(URI.file(dataValue.path));
resolve();
}));
} else if (dataItem.kind === 'file') {
const file = dataItem.getAsFile();
if (file) {
uris.push(URI.file(file.path));
const uri = (file as FileAdditionalNativeProperties).path ? URI.parse((file as FileAdditionalNativeProperties).path!) : undefined;
if (dndController.supportsFileDataTransfers) {
treeDataTransfer.setFile(type, file.name, uri, async () => {
return new Uint8Array(await file.arrayBuffer());
});
}
decrementStringCount();
}
} else if (dataItem.kind === 'string' || dataItem.kind === 'file') {
decrementStringCount();
}
}
});
}));
// Check if there are uris to add and add them
if (uris.length) {
treeDataTransfer.setString(Mimes.uriList, uris.map(uri => uri.toString()).join('\n'));
}
const additionalWillDropPromise = this.treeViewsDragAndDropService.removeDragOperationTransfer(willDropUuid);
if (!additionalWillDropPromise) {
@@ -51,6 +51,7 @@ export interface IViewPaneOptions extends IPaneOptions {
}
type WelcomeActionClassification = {
owner: 'sandy081';
viewId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
uri: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
@@ -821,6 +821,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
if (this.viewContainerModel.activeViewDescriptors.some(viewDescriptor => viewDescriptor.id === viewId)) {
const visible = !this.viewContainerModel.isVisible(viewId);
type ViewsToggleVisibilityClassification = {
owner: 'sandy081';
viewId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
visible: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
+1
View File
@@ -831,6 +831,7 @@ export interface ITreeViewDataProvider {
export interface ITreeViewDragAndDropController {
readonly dropMimeTypes: string[];
readonly dragMimeTypes: string[];
readonly supportsFileDataTransfers: boolean;
handleDrag(sourceTreeItemHandles: string[], operationUuid: string, token: CancellationToken): Promise<VSDataTransfer | undefined>;
handleDrop(elements: VSDataTransfer, target: ITreeItem | undefined, token: CancellationToken, operationUuid?: string, sourceTreeId?: string, sourceTreeItemHandles?: string[]): Promise<void>;
}
@@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import severity from 'vs/base/common/severity';
import { Event } from 'vs/base/common/event';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { Markers } from 'vs/workbench/contrib/markers/common/markers';
import { ITaskService, ITaskSummary } from 'vs/workbench/contrib/tasks/common/taskService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
@@ -76,7 +76,7 @@ export class DebugTaskRunner {
return TaskRunResult.Success;
}
if (onTaskErrors === 'showErrors') {
await this.viewsService.openView(Constants.MARKERS_VIEW_ID, true);
await this.viewsService.openView(Markers.MARKERS_VIEW_ID, true);
return Promise.resolve(TaskRunResult.Failure);
}
if (onTaskErrors === 'abort') {
@@ -113,7 +113,7 @@ export class DebugTaskRunner {
return TaskRunResult.Success;
}
await this.viewsService.openView(Constants.MARKERS_VIEW_ID, true);
await this.viewsService.openView(Markers.MARKERS_VIEW_ID, true);
return Promise.resolve(TaskRunResult.Failure);
} catch (err) {
const taskConfigureAction = this.taskService.configureAction();
@@ -541,6 +541,7 @@ CommandsRegistry.registerCommand({
if (ext || await tryInstallHexEditor(notifications, progressService, extensionService, commandService)) {
/* __GDPR__
"debug/didViewMemory" : {
"owner": "connor4312",
"debugType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
@@ -18,6 +18,7 @@ export class DebugTelemetry {
const extension = dbgr.getMainExtensionDescriptor();
/* __GDPR__
"debugSessionStart" : {
"owner": "connor4312",
"type": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"breakpointCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"exceptionBreakpoints": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
@@ -44,6 +45,7 @@ export class DebugTelemetry {
/* __GDPR__
"debugSessionStop" : {
"owner": "connor4312",
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"success": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"sessionLengthInSeconds": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
@@ -306,6 +306,7 @@ export class ExperimentService extends Disposable implements IExperimentService
const promises = rawExperiments.map(experiment => this.evaluateExperiment(experiment));
return Promise.all(promises).then(() => {
type ExperimentsClassification = {
owner: 'sbatten';
experiments: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
this.telemetryService.publicLog2<{ experiments: string[] }, ExperimentsClassification>('experiments', { experiments: this._experiments.map(e => e.id) });
@@ -16,6 +16,7 @@ import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRe
import { localize } from 'vs/nls';
type DynamicWorkspaceRecommendationsClassification = {
owner: 'sandy081';
count: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
cache: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
@@ -562,6 +562,7 @@ export class ExtensionEditor extends EditorPane {
}
/* __GDPR__
"extensionGallery:openExtension" : {
"owner": "sandy081",
"recommendationReason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"${include}": [
"${GalleryExtensionTelemetryData}"
@@ -644,6 +645,7 @@ export class ExtensionEditor extends EditorPane {
private setRecommendationText(extension: IExtension, template: IExtensionEditorTemplate): void {
const updateRecommendationText = (layout: boolean) => {
reset(template.recommendation);
const extRecommendations = this.extensionRecommendationsService.getAllRecommendationsWithReason();
if (extRecommendations[extension.identifier.id.toLowerCase()]) {
const reasonText = extRecommendations[extension.identifier.id.toLowerCase()].reasonText;
@@ -658,8 +660,8 @@ export class ExtensionEditor extends EditorPane {
this.layout(this.dimension);
}
};
reset(template.recommendation);
if (extension.deprecationInfo || extension.state === ExtensionState.Installed) {
reset(template.recommendation);
return;
}
updateRecommendationText(false);
@@ -27,12 +27,14 @@ import { EnablementState, IWorkbenchExtensionManagementService, IWorkbenchExtens
import { IExtensionIgnoredRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
type ExtensionRecommendationsNotificationClassification = {
owner: 'sandy081';
userReaction: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
extensionId?: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
source: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
type ExtensionWorkspaceRecommendationsNotificationClassification = {
owner: 'sandy081';
userReaction: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
};
@@ -29,6 +29,7 @@ import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/com
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
type IgnoreRecommendationClassification = {
owner: 'sandy081';
recommendationReason: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
extensionId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
};
@@ -233,6 +234,7 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
if (recommendationReason) {
/* __GDPR__
"extensionGallery:install:recommendations" : {
"owner": "sandy081",
"recommendationReason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"${include}": [
"${GalleryExtensionTelemetryData}"
@@ -13,7 +13,7 @@ import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
import { Event } from 'vs/base/common/event';
import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtension } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget, SyncIgnoredWidget, ExtensionHoverWidget, ExtensionActivationStatusWidget, PreReleaseBookmarkWidget, extensionVerifiedPublisherIconColor } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions';
@@ -118,6 +118,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const reloadAction = this.instantiationService.createInstance(ReloadAction);
const actions = [
this.instantiationService.createInstance(ExtensionStatusLabelAction),
this.instantiationService.createInstance(MigrateDeprecatedExtension, true),
this.instantiationService.createInstance(UpdateAction),
reloadAction,
this.instantiationService.createInstance(InstallDropdownAction),
@@ -61,6 +61,7 @@ import { isOfflineError } from 'vs/base/parts/request/common/request';
const FORCE_FEATURE_EXTENSIONS = ['vscode.git', 'vscode.git-base', 'vscode.search-result'];
type WorkspaceRecommendationsClassification = {
owner: 'sandy081';
count: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; 'isMeasurement': true };
};
@@ -57,6 +57,7 @@ interface InstalledExtensionsEvent {
readonly count: number;
}
interface ExtensionsLoadClassification extends GDPRClassification<InstalledExtensionsEvent> {
owner: 'digitarald';
readonly extensionIds: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
readonly count: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
}
@@ -1454,6 +1455,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (changed[i]) {
/* __GDPR__
"extension:enable" : {
"owner": "sandy081",
"${include}": [
"${GalleryExtensionTelemetryData}"
]
@@ -1461,6 +1463,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
*/
/* __GDPR__
"extension:disable" : {
"owner": "sandy081",
"${include}": [
"${GalleryExtensionTelemetryData}"
]
@@ -37,6 +37,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
type FileExtensionSuggestionClassification = {
owner: 'sandy081';
userReaction: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
fileExtension: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight' };
};
@@ -4,9 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
import { IHostService } from 'vs/workbench/services/host/browser/host';
@@ -17,27 +16,22 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IProductService } from 'vs/platform/product/common/productService';
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { ViewContainerLocation } from 'vs/workbench/common/views';
import { Action2, MenuId } from 'vs/platform/actions/common/actions';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
export class ConfigureLocaleAction extends Action {
public static readonly ID = 'workbench.action.configureLocale';
public static readonly LABEL = localize('configureLocale', "Configure Display Language");
constructor(id: string, label: string,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@ILocalizationsService private readonly localizationService: ILocalizationsService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
@IHostService private readonly hostService: IHostService,
@INotificationService private readonly notificationService: INotificationService,
@IPaneCompositePartService private readonly paneCompositeService: IPaneCompositePartService,
@IDialogService private readonly dialogService: IDialogService,
@IProductService private readonly productService: IProductService
) {
super(id, label);
export class ConfigureLocaleAction extends Action2 {
constructor() {
super({
id: 'workbench.action.configureLocale',
title: { original: 'Configure Display Language', value: localize('configureLocale', "Configure Display Language") },
menu: {
id: MenuId.CommandPalette
}
});
}
private async getLanguageOptions(): Promise<IQuickPickItem[]> {
const availableLanguages = await this.localizationService.getLanguageIds();
private async getLanguageOptions(localizationService: ILanguagePackService): Promise<IQuickPickItem[]> {
const availableLanguages = await localizationService.getInstalledLanguages();
availableLanguages.sort();
return availableLanguages
@@ -45,12 +39,22 @@ export class ConfigureLocaleAction extends Action {
.concat({ label: localize('installAdditionalLanguages', "Install Additional Languages...") });
}
public override async run(): Promise<void> {
const languageOptions = await this.getLanguageOptions();
public override async run(accessor: ServicesAccessor): Promise<void> {
const environmentService: IEnvironmentService = accessor.get(IEnvironmentService);
const languagePackService: ILanguagePackService = accessor.get(ILanguagePackService);
const quickInputService: IQuickInputService = accessor.get(IQuickInputService);
const jsonEditingService: IJSONEditingService = accessor.get(IJSONEditingService);
const hostService: IHostService = accessor.get(IHostService);
const notificationService: INotificationService = accessor.get(INotificationService);
const paneCompositeService: IPaneCompositePartService = accessor.get(IPaneCompositePartService);
const dialogService: IDialogService = accessor.get(IDialogService);
const productService: IProductService = accessor.get(IProductService);
const languageOptions = await this.getLanguageOptions(languagePackService);
const currentLanguageIndex = languageOptions.findIndex(l => l.label === language);
try {
const selectedLanguage = await this.quickInputService.pick(languageOptions,
const selectedLanguage = await quickInputService.pick(languageOptions,
{
canPickMany: false,
placeHolder: localize('chooseDisplayLanguage', "Select Display Language"),
@@ -58,7 +62,7 @@ export class ConfigureLocaleAction extends Action {
});
if (selectedLanguage === languageOptions[languageOptions.length - 1]) {
return this.paneCompositeService.openPaneComposite(EXTENSIONS_VIEWLET_ID, ViewContainerLocation.Sidebar, true)
return paneCompositeService.openPaneComposite(EXTENSIONS_VIEWLET_ID, ViewContainerLocation.Sidebar, true)
.then(viewlet => viewlet?.getViewPaneContainer())
.then(viewlet => {
const extensionsViewlet = viewlet as IExtensionsViewPaneContainer;
@@ -68,20 +72,20 @@ export class ConfigureLocaleAction extends Action {
}
if (selectedLanguage) {
await this.jsonEditingService.write(this.environmentService.argvResource, [{ path: ['locale'], value: selectedLanguage.label }], true);
const restart = await this.dialogService.confirm({
await jsonEditingService.write(environmentService.argvResource, [{ path: ['locale'], value: selectedLanguage.label }], true);
const restart = await dialogService.confirm({
type: 'info',
message: localize('relaunchDisplayLanguageMessage', "A restart is required for the change in display language to take effect."),
detail: localize('relaunchDisplayLanguageDetail', "Press the restart button to restart {0} and change the display language.", this.productService.nameLong),
detail: localize('relaunchDisplayLanguageDetail', "Press the restart button to restart {0} and change the display language.", productService.nameLong),
primaryButton: localize('restart', "&&Restart")
});
if (restart.confirmed) {
this.hostService.restart();
hostService.restart();
}
}
} catch (e) {
this.notificationService.error(e);
notificationService.error(e);
}
}
}
@@ -6,10 +6,7 @@
import { localize } from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { Disposable } from 'vs/base/common/lifecycle';
import { ConfigureLocaleAction } from 'vs/workbench/contrib/localizations/browser/localizationsActions';
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import * as platform from 'vs/base/common/platform';
@@ -21,15 +18,16 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { VIEWLET_ID as EXTENSIONS_VIEWLET_ID, IExtensionsViewPaneContainer } from 'vs/workbench/contrib/extensions/common/extensions';
import { minimumTranslatedStrings } from 'vs/workbench/contrib/localizations/browser/minimalTranslations';
import { minimumTranslatedStrings } from 'vs/workbench/contrib/localization/electron-sandbox/minimalTranslations';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { ViewContainerLocation } from 'vs/workbench/common/views';
import { registerAction2 } from 'vs/platform/actions/common/actions';
import { ConfigureLocaleAction } from 'vs/workbench/contrib/localization/browser/localizationsActions';
// Register action to configure locale and related settings
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ConfigureLocaleAction), 'Configure Display Language');
registerAction2(ConfigureLocaleAction);
const LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY = 'extensionsAssistant/languagePackSuggestionIgnore';
@@ -119,7 +117,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
const loc = manifest && manifest.contributes && manifest.contributes.localizations && manifest.contributes.localizations.filter(x => x.languageId.toLowerCase() === locale)[0];
const languageName = loc ? (loc.languageName || locale) : locale;
const languageDisplayName = loc ? (loc.localizedLanguageName || loc.languageName || locale) : locale;
const translationsFromPack: any = translation && translation.contents ? translation.contents['vs/workbench/contrib/localizations/browser/minimalTranslations'] : {};
const translationsFromPack: any = translation && translation.contents ? translation.contents['vs/workbench/contrib/localization/electron-sandbox/minimalTranslations'] : {};
const promptMessageKey = extensionToInstall ? 'installAndRestartMessage' : 'showLanguagePackExtensions';
const useEnglish = !translationsFromPack[promptMessageKey];
@@ -135,6 +133,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
const logUserReaction = (userReaction: string) => {
/* __GDPR__
"languagePackSuggestion:popup" : {
"owner": "TylerLeonhardt",
"userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
@@ -1,33 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { MarkersViewMode } from 'vs/workbench/contrib/markers/browser/markersView';
export default {
MARKERS_CONTAINER_ID: 'workbench.panel.markers',
MARKERS_VIEW_ID: 'workbench.panel.markers.view',
MARKERS_VIEW_STORAGE_ID: 'workbench.panel.markers',
MARKER_COPY_ACTION_ID: 'problems.action.copy',
MARKER_COPY_MESSAGE_ACTION_ID: 'problems.action.copyMessage',
RELATED_INFORMATION_COPY_MESSAGE_ACTION_ID: 'problems.action.copyRelatedInformationMessage',
FOCUS_PROBLEMS_FROM_FILTER: 'problems.action.focusProblemsFromFilter',
MARKERS_VIEW_FOCUS_FILTER: 'problems.action.focusFilter',
MARKERS_VIEW_CLEAR_FILTER_TEXT: 'problems.action.clearFilterText',
MARKERS_VIEW_SHOW_MULTILINE_MESSAGE: 'problems.action.showMultilineMessage',
MARKERS_VIEW_SHOW_SINGLELINE_MESSAGE: 'problems.action.showSinglelineMessage',
MARKER_OPEN_ACTION_ID: 'problems.action.open',
MARKER_OPEN_SIDE_ACTION_ID: 'problems.action.openToSide',
MARKER_SHOW_PANEL_ID: 'workbench.action.showErrorsWarnings',
MARKER_SHOW_QUICK_FIX: 'problems.action.showQuickFixes',
TOGGLE_MARKERS_VIEW_ACTION_ID: 'workbench.actions.view.toggleProblems',
MarkersViewModeContextKey: new RawContextKey<MarkersViewMode>('problemsViewMode', MarkersViewMode.Tree),
MarkersViewSmallLayoutContextKey: new RawContextKey<boolean>(`problemsView.smallLayout`, false),
MarkersTreeVisibilityContextKey: new RawContextKey<boolean>('problemsVisibility', false),
MarkerFocusContextKey: new RawContextKey<boolean>('problemFocus', false),
MarkerViewFilterFocusContextKey: new RawContextKey<boolean>('problemsFilterFocus', false),
RelatedInformationFocusContextKey: new RawContextKey<boolean>('relatedInformationFocus', false)
};
@@ -11,16 +11,16 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { localize } from 'vs/nls';
import { Marker, RelatedInformation, ResourceMarkers } from 'vs/workbench/contrib/markers/browser/markersModel';
import { MarkersView, MarkersViewMode } from 'vs/workbench/contrib/markers/browser/markersView';
import { MarkersView } from 'vs/workbench/contrib/markers/browser/markersView';
import { MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { Registry } from 'vs/platform/registry/common/platform';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { MarkersViewMode, Markers, MarkersContextKeys } from 'vs/workbench/contrib/markers/common/markers';
import Messages from 'vs/workbench/contrib/markers/browser/messages';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ActivityUpdater, IMarkersView } from 'vs/workbench/contrib/markers/browser/markers';
import { IMarkersView } from 'vs/workbench/contrib/markers/browser/markers';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/browser/statusbar';
import { IMarkerService, MarkerStatistics } from 'vs/platform/markers/common/markers';
import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation, IViewsRegistry, IViewsService } from 'vs/workbench/common/views';
@@ -31,53 +31,54 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
import { Codicon } from 'vs/base/common/codicons';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { ViewAction } from 'vs/workbench/browser/parts/views/viewPane';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: Constants.MARKER_OPEN_ACTION_ID,
id: Markers.MARKER_OPEN_ACTION_ID,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(Constants.MarkerFocusContextKey),
when: ContextKeyExpr.and(MarkersContextKeys.MarkerFocusContextKey),
primary: KeyCode.Enter,
mac: {
primary: KeyCode.Enter,
secondary: [KeyMod.CtrlCmd | KeyCode.DownArrow]
},
handler: (accessor, args: any) => {
const markersView = accessor.get(IViewsService).getActiveViewWithId<MarkersView>(Constants.MARKERS_VIEW_ID)!;
const markersView = accessor.get(IViewsService).getActiveViewWithId<MarkersView>(Markers.MARKERS_VIEW_ID)!;
markersView.openFileAtElement(markersView.getFocusElement(), false, false, true);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: Constants.MARKER_OPEN_SIDE_ACTION_ID,
id: Markers.MARKER_OPEN_SIDE_ACTION_ID,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(Constants.MarkerFocusContextKey),
when: ContextKeyExpr.and(MarkersContextKeys.MarkerFocusContextKey),
primary: KeyMod.CtrlCmd | KeyCode.Enter,
mac: {
primary: KeyMod.WinCtrl | KeyCode.Enter
},
handler: (accessor, args: any) => {
const markersView = accessor.get(IViewsService).getActiveViewWithId<MarkersView>(Constants.MARKERS_VIEW_ID)!;
const markersView = accessor.get(IViewsService).getActiveViewWithId<MarkersView>(Markers.MARKERS_VIEW_ID)!;
markersView.openFileAtElement(markersView.getFocusElement(), false, true, true);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: Constants.MARKER_SHOW_PANEL_ID,
id: Markers.MARKER_SHOW_PANEL_ID,
weight: KeybindingWeight.WorkbenchContrib,
when: undefined,
primary: undefined,
handler: async (accessor, args: any) => {
await accessor.get(IViewsService).openView(Constants.MARKERS_VIEW_ID);
await accessor.get(IViewsService).openView(Markers.MARKERS_VIEW_ID);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: Constants.MARKER_SHOW_QUICK_FIX,
id: Markers.MARKER_SHOW_QUICK_FIX,
weight: KeybindingWeight.WorkbenchContrib,
when: Constants.MarkerFocusContextKey,
when: MarkersContextKeys.MarkerFocusContextKey,
primary: KeyMod.CtrlCmd | KeyCode.Period,
handler: (accessor, args: any) => {
const markersView = accessor.get(IViewsService).getActiveViewWithId<MarkersView>(Constants.MARKERS_VIEW_ID)!;
const markersView = accessor.get(IViewsService).getActiveViewWithId<MarkersView>(Markers.MARKERS_VIEW_ID)!;
const focusedElement = markersView.getFocusElement();
if (focusedElement instanceof Marker) {
markersView.showQuickFixes(focusedElement);
@@ -125,17 +126,17 @@ const markersViewIcon = registerIcon('markers-view-icon', Codicon.warning, local
// markers view container
const VIEW_CONTAINER: ViewContainer = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({
id: Constants.MARKERS_CONTAINER_ID,
id: Markers.MARKERS_CONTAINER_ID,
title: Messages.MARKERS_PANEL_TITLE_PROBLEMS,
icon: markersViewIcon,
hideIfEmpty: true,
order: 0,
ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [Constants.MARKERS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]),
storageId: Constants.MARKERS_VIEW_STORAGE_ID,
ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [Markers.MARKERS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]),
storageId: Markers.MARKERS_VIEW_STORAGE_ID,
}, ViewContainerLocation.Panel, { donotRegisterOpenCommand: true });
Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry).registerViews([{
id: Constants.MARKERS_VIEW_ID,
id: Markers.MARKERS_VIEW_ID,
containerIcon: markersViewIcon,
name: Messages.MARKERS_PANEL_TITLE_PROBLEMS,
canToggleVisibility: false,
@@ -151,22 +152,21 @@ Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry).registerViews
// workbench
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchRegistry.registerWorkbenchContribution(ActivityUpdater, LifecyclePhase.Restored);
// actions
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: `workbench.actions.table.${Constants.MARKERS_VIEW_ID}.viewAsTree`,
id: `workbench.actions.table.${Markers.MARKERS_VIEW_ID}.viewAsTree`,
title: localize('viewAsTree', "View as Tree"),
menu: {
id: MenuId.ViewTitle,
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Constants.MARKERS_VIEW_ID), Constants.MarkersViewModeContextKey.isEqualTo(MarkersViewMode.Table)),
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Markers.MARKERS_VIEW_ID), MarkersContextKeys.MarkersViewModeContextKey.isEqualTo(MarkersViewMode.Table)),
group: 'navigation',
order: 3
},
icon: Codicon.listTree,
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
@@ -178,16 +178,16 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: `workbench.actions.table.${Constants.MARKERS_VIEW_ID}.viewAsTable`,
id: `workbench.actions.table.${Markers.MARKERS_VIEW_ID}.viewAsTable`,
title: localize('viewAsTable', "View as Table"),
menu: {
id: MenuId.ViewTitle,
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Constants.MARKERS_VIEW_ID), Constants.MarkersViewModeContextKey.isEqualTo(MarkersViewMode.Tree)),
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Markers.MARKERS_VIEW_ID), MarkersContextKeys.MarkersViewModeContextKey.isEqualTo(MarkersViewMode.Tree)),
group: 'navigation',
order: 3
},
icon: Codicon.listFlat,
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
@@ -206,15 +206,15 @@ registerAction2(class extends Action2 {
});
}
async run(accessor: ServicesAccessor): Promise<void> {
accessor.get(IViewsService).openView(Constants.MARKERS_VIEW_ID, true);
accessor.get(IViewsService).openView(Markers.MARKERS_VIEW_ID, true);
}
});
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
const when = ContextKeyExpr.and(FocusedViewContext.isEqualTo(Constants.MARKERS_VIEW_ID), Constants.MarkersTreeVisibilityContextKey, Constants.RelatedInformationFocusContextKey.toNegated());
const when = ContextKeyExpr.and(FocusedViewContext.isEqualTo(Markers.MARKERS_VIEW_ID), MarkersContextKeys.MarkersTreeVisibilityContextKey, MarkersContextKeys.RelatedInformationFocusContextKey.toNegated());
super({
id: Constants.MARKER_COPY_ACTION_ID,
id: Markers.MARKER_COPY_ACTION_ID,
title: { value: localize('copyMarker', "Copy"), original: 'Copy' },
menu: {
id: MenuId.ProblemsPanelContext,
@@ -226,7 +226,7 @@ registerAction2(class extends ViewAction<IMarkersView> {
primary: KeyMod.CtrlCmd | KeyCode.KeyC,
when
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -254,14 +254,14 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.MARKER_COPY_MESSAGE_ACTION_ID,
id: Markers.MARKER_COPY_MESSAGE_ACTION_ID,
title: { value: localize('copyMessage', "Copy Message"), original: 'Copy Message' },
menu: {
id: MenuId.ProblemsPanelContext,
when: Constants.MarkerFocusContextKey,
when: MarkersContextKeys.MarkerFocusContextKey,
group: 'navigation'
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -276,14 +276,14 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.RELATED_INFORMATION_COPY_MESSAGE_ACTION_ID,
id: Markers.RELATED_INFORMATION_COPY_MESSAGE_ACTION_ID,
title: { value: localize('copyMessage', "Copy Message"), original: 'Copy Message' },
menu: {
id: MenuId.ProblemsPanelContext,
when: Constants.RelatedInformationFocusContextKey,
when: MarkersContextKeys.RelatedInformationFocusContextKey,
group: 'navigation'
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -298,14 +298,14 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.FOCUS_PROBLEMS_FROM_FILTER,
id: Markers.FOCUS_PROBLEMS_FROM_FILTER,
title: localize('focusProblemsList', "Focus problems view"),
keybinding: {
when: Constants.MarkerViewFilterFocusContextKey,
when: MarkersContextKeys.MarkerViewFilterFocusContextKey,
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyMod.CtrlCmd | KeyCode.DownArrow
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -316,14 +316,14 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.MARKERS_VIEW_FOCUS_FILTER,
id: Markers.MARKERS_VIEW_FOCUS_FILTER,
title: localize('focusProblemsFilter', "Focus problems filter"),
keybinding: {
when: FocusedViewContext.isEqualTo(Constants.MARKERS_VIEW_ID),
when: FocusedViewContext.isEqualTo(Markers.MARKERS_VIEW_ID),
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyMod.CtrlCmd | KeyCode.KeyF
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -334,14 +334,14 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.MARKERS_VIEW_SHOW_MULTILINE_MESSAGE,
id: Markers.MARKERS_VIEW_SHOW_MULTILINE_MESSAGE,
title: { value: localize('show multiline', "Show message in multiple lines"), original: 'Problems: Show message in multiple lines' },
category: localize('problems', "Problems"),
menu: {
id: MenuId.CommandPalette,
when: ContextKeyExpr.has(getVisbileViewContextKey(Constants.MARKERS_VIEW_ID))
when: ContextKeyExpr.has(getVisbileViewContextKey(Markers.MARKERS_VIEW_ID))
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -352,14 +352,14 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.MARKERS_VIEW_SHOW_SINGLELINE_MESSAGE,
id: Markers.MARKERS_VIEW_SHOW_SINGLELINE_MESSAGE,
title: { value: localize('show singleline', "Show message in single line"), original: 'Problems: Show message in single line' },
category: localize('problems', "Problems"),
menu: {
id: MenuId.CommandPalette,
when: ContextKeyExpr.has(getVisbileViewContextKey(Constants.MARKERS_VIEW_ID))
when: ContextKeyExpr.has(getVisbileViewContextKey(Markers.MARKERS_VIEW_ID))
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -370,15 +370,15 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: Constants.MARKERS_VIEW_CLEAR_FILTER_TEXT,
id: Markers.MARKERS_VIEW_CLEAR_FILTER_TEXT,
title: localize('clearFiltersText', "Clear filters text"),
category: localize('problems', "Problems"),
keybinding: {
when: Constants.MarkerViewFilterFocusContextKey,
when: MarkersContextKeys.MarkerViewFilterFocusContextKey,
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyCode.Escape
},
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, markersView: IMarkersView): Promise<void> {
@@ -389,16 +389,16 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends ViewAction<IMarkersView> {
constructor() {
super({
id: `workbench.actions.treeView.${Constants.MARKERS_VIEW_ID}.collapseAll`,
id: `workbench.actions.treeView.${Markers.MARKERS_VIEW_ID}.collapseAll`,
title: localize('collapseAll', "Collapse All"),
menu: {
id: MenuId.ViewTitle,
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Constants.MARKERS_VIEW_ID), Constants.MarkersViewModeContextKey.isEqualTo(MarkersViewMode.Tree)),
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Markers.MARKERS_VIEW_ID), MarkersContextKeys.MarkersViewModeContextKey.isEqualTo(MarkersViewMode.Tree)),
group: 'navigation',
order: 2,
},
icon: Codicon.collapseAll,
viewId: Constants.MARKERS_VIEW_ID
viewId: Markers.MARKERS_VIEW_ID
});
}
async runInView(serviceAccessor: ServicesAccessor, view: IMarkersView): Promise<void> {
@@ -409,11 +409,11 @@ registerAction2(class extends ViewAction<IMarkersView> {
registerAction2(class extends Action2 {
constructor() {
super({
id: `workbench.actions.treeView.${Constants.MARKERS_VIEW_ID}.filter`,
id: `workbench.actions.treeView.${Markers.MARKERS_VIEW_ID}.filter`,
title: localize('filter', "Filter"),
menu: {
id: MenuId.ViewTitle,
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Constants.MARKERS_VIEW_ID), Constants.MarkersViewSmallLayoutContextKey.negate()),
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', Markers.MARKERS_VIEW_ID), MarkersContextKeys.MarkersViewSmallLayoutContextKey.negate()),
group: 'navigation',
order: 1,
},
@@ -425,16 +425,16 @@ registerAction2(class extends Action2 {
registerAction2(class extends Action2 {
constructor() {
super({
id: Constants.TOGGLE_MARKERS_VIEW_ACTION_ID,
id: Markers.TOGGLE_MARKERS_VIEW_ACTION_ID,
title: Messages.MARKERS_PANEL_TOGGLE_LABEL,
});
}
async run(accessor: ServicesAccessor): Promise<void> {
const viewsService = accessor.get(IViewsService);
if (viewsService.isViewVisible(Constants.MARKERS_VIEW_ID)) {
viewsService.closeView(Constants.MARKERS_VIEW_ID);
if (viewsService.isViewVisible(Markers.MARKERS_VIEW_ID)) {
viewsService.closeView(Markers.MARKERS_VIEW_ID);
} else {
viewsService.openView(Constants.MARKERS_VIEW_ID, true);
viewsService.openView(Markers.MARKERS_VIEW_ID, true);
}
}
});
@@ -514,3 +514,26 @@ class MarkersStatusBarContributions extends Disposable implements IWorkbenchCont
}
workbenchRegistry.registerWorkbenchContribution(MarkersStatusBarContributions, LifecyclePhase.Restored);
class ActivityUpdater extends Disposable implements IWorkbenchContribution {
private readonly activity = this._register(new MutableDisposable<IDisposable>());
constructor(
@IActivityService private readonly activityService: IActivityService,
@IMarkerService private readonly markerService: IMarkerService
) {
super();
this._register(this.markerService.onMarkerChanged(() => this.updateBadge()));
this.updateBadge();
}
private updateBadge(): void {
const { errors, warnings, infos } = this.markerService.getStatistics();
const total = errors + warnings + infos;
const message = localize('totalProblems', 'Total {0} Problems', total);
this.activity.value = this.activityService.showViewActivity(Markers.MARKERS_VIEW_ID, { badge: new NumberBadge(total, () => message) });
}
}
workbenchRegistry.registerWorkbenchContribution(ActivityUpdater, LifecyclePhase.Restored);
@@ -3,17 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable, MutableDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { localize } from 'vs/nls';
import Constants from './constants';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { MarkersFilters } from 'vs/workbench/contrib/markers/browser/markersViewActions';
import { Event } from 'vs/base/common/event';
import { IView } from 'vs/workbench/common/views';
import { MarkerElement, ResourceMarkers } from 'vs/workbench/contrib/markers/browser/markersModel';
import { MarkersViewMode } from 'vs/workbench/contrib/markers/browser/markersView';
import { MarkersViewMode } from 'vs/workbench/contrib/markers/common/markers';
export interface IMarkersView extends IView {
@@ -33,24 +27,3 @@ export interface IMarkersView extends IView {
setMultiline(multiline: boolean): void;
setViewMode(viewMode: MarkersViewMode): void;
}
export class ActivityUpdater extends Disposable implements IWorkbenchContribution {
private readonly activity = this._register(new MutableDisposable<IDisposable>());
constructor(
@IActivityService private readonly activityService: IActivityService,
@IMarkerService private readonly markerService: IMarkerService
) {
super();
this._register(this.markerService.onMarkerChanged(() => this.updateBadge()));
this.updateBadge();
}
private updateBadge(): void {
const { errors, warnings, infos } = this.markerService.getStatistics();
const total = errors + warnings + infos;
const message = localize('totalProblems', 'Total {0} Problems', total);
this.activity.value = this.activityService.showViewActivity(Constants.MARKERS_VIEW_ID, { badge: new NumberBadge(total, () => message) });
}
}
@@ -48,9 +48,8 @@ import { Codicon } from 'vs/base/common/codicons';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { Link } from 'vs/platform/opener/browser/link';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { MarkersViewMode } from 'vs/workbench/contrib/markers/browser/markersView';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { MarkersContextKeys, MarkersViewMode } from 'vs/workbench/contrib/markers/common/markers';
interface IResourceMarkersTemplateData {
resourceLabel: IResourceLabel;
@@ -718,7 +717,7 @@ export class MarkersViewModel extends Disposable {
this._multiline = multiline;
this._viewMode = viewMode;
this.viewModeContextKey = Constants.MarkersViewModeContextKey.bindTo(this.contextKeyService);
this.viewModeContextKey = MarkersContextKeys.MarkersViewModeContextKey.bindTo(this.contextKeyService);
this.viewModeContextKey.set(viewMode);
}
@@ -10,7 +10,6 @@ import * as dom from 'vs/base/browser/dom';
import { IAction, Action, Separator } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { Marker, ResourceMarkers, RelatedInformation, MarkerChangesEvent, MarkersModel, compareMarkersByUri, MarkerElement, MarkerTableItem } from 'vs/workbench/contrib/markers/browser/markersModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { MarkersFilterActionViewItem, MarkersFilters, IMarkersFiltersChangeEvent } from 'vs/workbench/contrib/markers/browser/markersViewActions';
@@ -59,6 +58,7 @@ import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/m
import { ResourceListDnDHandler } from 'vs/workbench/browser/dnd';
import { ITableContextMenuEvent, ITableEvent } from 'vs/base/browser/ui/table/table';
import { MarkersTable } from 'vs/workbench/contrib/markers/browser/markersTable';
import { Markers, MarkersContextKeys, MarkersViewMode } from 'vs/workbench/contrib/markers/common/markers';
function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterable<ITreeElement<MarkerElement>> {
return Iterable.map(resourceMarkers.markers, m => {
@@ -69,11 +69,6 @@ function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterab
});
}
export const enum MarkersViewMode {
Table = 'table',
Tree = 'tree'
}
export interface IProblemsWidget {
get contextKeyService(): IContextKeyService;
@@ -162,8 +157,8 @@ export class MarkersView extends ViewPane implements IMarkersView {
@IThemeService themeService: IThemeService,
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
this.smallLayoutContextKey = Constants.MarkersViewSmallLayoutContextKey.bindTo(this.contextKeyService);
this.panelState = new Memento(Constants.MARKERS_VIEW_STORAGE_ID, storageService).getMemento(StorageScope.WORKSPACE, StorageTarget.USER);
this.smallLayoutContextKey = MarkersContextKeys.MarkersViewSmallLayoutContextKey.bindTo(this.contextKeyService);
this.panelState = new Memento(Markers.MARKERS_VIEW_STORAGE_ID, storageService).getMemento(StorageScope.WORKSPACE, StorageTarget.USER);
this.markersModel = this._register(instantiationService.createInstance(MarkersModel));
this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState['multiline'], this.panelState['viewMode'] ?? this.getDefaultViewMode()));
@@ -419,8 +414,8 @@ export class MarkersView extends ViewPane implements IMarkersView {
this.widget = this.markersViewModel.viewMode === MarkersViewMode.Table ? this.createTable(parent) : this.createTree(parent);
this.widgetDisposables.add(this.widget);
const markerFocusContextKey = Constants.MarkerFocusContextKey.bindTo(this.widget.contextKeyService);
const relatedInformationFocusContextKey = Constants.RelatedInformationFocusContextKey.bindTo(this.widget.contextKeyService);
const markerFocusContextKey = MarkersContextKeys.MarkerFocusContextKey.bindTo(this.widget.contextKeyService);
const relatedInformationFocusContextKey = MarkersContextKeys.RelatedInformationFocusContextKey.bindTo(this.widget.contextKeyService);
this.widgetDisposables.add(this.widget.onDidChangeFocus(focus => {
markerFocusContextKey.set(focus.elements.some(e => e instanceof Marker));
relatedInformationFocusContextKey.set(focus.elements.some(e => e instanceof RelatedInformation));
@@ -915,7 +910,7 @@ class MarkersTree extends WorkbenchObjectTree<MarkerElement, FilterData> impleme
@IAccessibilityService accessibilityService: IAccessibilityService
) {
super(user, container, delegate, renderers, options, contextKeyService, listService, themeService, configurationService, keybindingService, accessibilityService);
this.visibilityContextKey = Constants.MarkersTreeVisibilityContextKey.bindTo(contextKeyService);
this.visibilityContextKey = MarkersContextKeys.MarkersTreeVisibilityContextKey.bindTo(contextKeyService);
}
collapseMarkers(): void {
@@ -11,7 +11,6 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import Messages from 'vs/workbench/contrib/markers/browser/messages';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { IThemeService, registerThemingParticipant, ICssStyleCollector, IColorTheme, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { toDisposable, Disposable } from 'vs/base/common/lifecycle';
@@ -31,6 +30,7 @@ import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { IMarkersView } from 'vs/workbench/contrib/markers/browser/markers';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { showHistoryKeybindingHint } from 'vs/platform/history/browser/historyWidgetKeybindingHint';
import { MarkersContextKeys } from 'vs/workbench/contrib/markers/common/markers';
export interface IMarkersFiltersChangeEvent {
filterText?: boolean;
@@ -260,7 +260,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
) {
super(null, action);
this.keybindingService = keybindingService;
this.focusContextKey = Constants.MarkerViewFilterFocusContextKey.bindTo(contextKeyService);
this.focusContextKey = MarkersContextKeys.MarkerViewFilterFocusContextKey.bindTo(contextKeyService);
this.delayedFilterUpdate = new Delayer<void>(400);
this._register(toDisposable(() => this.delayedFilterUpdate.cancel()));
this._register(markersView.onDidFocusFilter(() => this.focus()));
@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
export const enum MarkersViewMode {
Table = 'table',
Tree = 'tree'
}
export namespace Markers {
export const MARKERS_CONTAINER_ID = 'workbench.panel.markers';
export const MARKERS_VIEW_ID = 'workbench.panel.markers.view';
export const MARKERS_VIEW_STORAGE_ID = 'workbench.panel.markers';
export const MARKER_COPY_ACTION_ID = 'problems.action.copy';
export const MARKER_COPY_MESSAGE_ACTION_ID = 'problems.action.copyMessage';
export const RELATED_INFORMATION_COPY_MESSAGE_ACTION_ID = 'problems.action.copyRelatedInformationMessage';
export const FOCUS_PROBLEMS_FROM_FILTER = 'problems.action.focusProblemsFromFilter';
export const MARKERS_VIEW_FOCUS_FILTER = 'problems.action.focusFilter';
export const MARKERS_VIEW_CLEAR_FILTER_TEXT = 'problems.action.clearFilterText';
export const MARKERS_VIEW_SHOW_MULTILINE_MESSAGE = 'problems.action.showMultilineMessage';
export const MARKERS_VIEW_SHOW_SINGLELINE_MESSAGE = 'problems.action.showSinglelineMessage';
export const MARKER_OPEN_ACTION_ID = 'problems.action.open';
export const MARKER_OPEN_SIDE_ACTION_ID = 'problems.action.openToSide';
export const MARKER_SHOW_PANEL_ID = 'workbench.action.showErrorsWarnings';
export const MARKER_SHOW_QUICK_FIX = 'problems.action.showQuickFixes';
export const TOGGLE_MARKERS_VIEW_ACTION_ID = 'workbench.actions.view.toggleProblems';
}
export namespace MarkersContextKeys {
export const MarkersViewModeContextKey = new RawContextKey<MarkersViewMode>('problemsViewMode', MarkersViewMode.Tree);
export const MarkersViewSmallLayoutContextKey = new RawContextKey<boolean>(`problemsView.smallLayout`, false);
export const MarkersTreeVisibilityContextKey = new RawContextKey<boolean>('problemsVisibility', false);
export const MarkerFocusContextKey = new RawContextKey<boolean>('problemFocus', false);
export const MarkerViewFilterFocusContextKey = new RawContextKey<boolean>('problemsFilterFocus', false);
export const RelatedInformationFocusContextKey = new RawContextKey<boolean>('relatedInformationFocus', false);
}
@@ -245,6 +245,7 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti
mark(input.resource, 'editorLoaded');
type WorkbenchNotebookOpenClassification = {
owner: 'rebornix';
scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
ext: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
viewType: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
@@ -1130,6 +1130,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
});
}
type WorkbenchNotebookOpenClassification = {
owner: 'rebornix';
scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
ext: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
viewType: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
@@ -51,6 +51,7 @@ import { IEditorOptions } from 'vs/platform/editor/common/editor';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
type KeybindingEditorActionClassification = {
owner: 'sandy081';
action: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
command: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true };
};
@@ -122,7 +122,7 @@ export class SettingsTreeIndicatorsLabel {
updateDefaultOverrideIndicator(element: SettingsTreeSettingElement) {
this.defaultOverrideIndicatorElement.style.display = 'none';
const defaultValueSource = element.setting.defaultValueSource;
const defaultValueSource = element.defaultValueSource;
if (defaultValueSource) {
this.defaultOverrideIndicatorElement.style.display = 'inline';
if (typeof defaultValueSource !== 'string' && defaultValueSource.id !== element.setting.extensionInfo?.id) {
@@ -157,8 +157,8 @@ export function getIndicatorsLabelAriaLabel(element: SettingsTreeSettingElement,
}
// Add default override indicator text
if (element.setting.defaultValueSource) {
const defaultValueSource = element.setting.defaultValueSource;
if (element.defaultValueSource) {
const defaultValueSource = element.defaultValueSource;
if (typeof defaultValueSource !== 'string' && defaultValueSource.id !== element.setting.extensionInfo?.id) {
const extensionSource = defaultValueSource.displayName ?? defaultValueSource.id;
ariaLabelSections.push(localize('defaultOverriddenDetails', "Default setting value overridden by {0}", extensionSource));
@@ -1115,7 +1115,7 @@ export class SettingComplexRenderer extends AbstractSettingRenderer implements I
template.elementDisposables.add(template.button.onDidClick(() => {
if (isLanguageTagSetting) {
this._onApplyFilter.fire(`@${LANGUAGE_SETTING_TAG}:${plainKey}`);
this._onApplyFilter.fire(`@${LANGUAGE_SETTING_TAG}${plainKey}`);
} else {
this._onDidOpenSettings.fire(dataElement.setting.key);
}
@@ -18,7 +18,7 @@ import { FOLDER_SCOPES, WORKSPACE_SCOPES, REMOTE_MACHINE_SCOPES, LOCAL_MACHINE_S
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter } from 'vs/base/common/event';
import { ConfigurationScope, EditPresentationTypes, Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { ConfigurationScope, EditPresentationTypes, Extensions, IConfigurationRegistry, IExtensionInfo } from 'vs/platform/configuration/common/configurationRegistry';
import { ILanguageService } from 'vs/editor/common/languages/language';
import { Registry } from 'vs/platform/registry/common/platform';
@@ -129,6 +129,12 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
*/
defaultValue?: any;
/**
* The source of the default value to display.
* This value also accounts for extension-contributed language-specific default value overrides.
*/
defaultValueSource: string | IExtensionInfo | undefined;
/**
* Whether the setting is configured in the selected scope.
*/
@@ -146,7 +152,12 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
tags?: Set<string>;
overriddenScopeList: string[] = [];
/**
* For each language that contributes setting values or default overrides, we can see those values here.
*/
languageOverrideValues: Map<string, IConfigurationValue<unknown>> = new Map<string, IConfigurationValue<unknown>>();
description!: string;
valueType!: SettingValueType;
@@ -219,6 +230,10 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
}
}
// The user might have added, removed, or modified a language filter,
// so we reset the default value source to the non-language-specific default value source for now.
this.defaultValueSource = this.setting.nonLanguageSpecificDefaultValueSource;
if (inspected.policyValue) {
this.hasPolicyValue = true;
isConfigured = false; // The user did not manually configure the setting themselves.
@@ -236,7 +251,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
const registryValues = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationDefaultsOverrides();
const overrideValueSource = registryValues.get(`[${languageSelector}]`)?.valuesSources?.get(this.setting.key);
if (overrideValueSource) {
this.setting.defaultValueSource = overrideValueSource;
this.defaultValueSource = overrideValueSource;
}
} else {
this.scopeValue = isConfigured && inspected[targetSelector];
@@ -1862,6 +1862,13 @@ class SCMInputWidget extends Disposable {
this.repositoryDisposables.add(input.repository.provider.onDidChangeCommitTemplate(updateTemplate, this));
updateTemplate();
// Update input enablement
const updateEnablement = (enabled: boolean) => {
this.inputEditor.updateOptions({ readOnly: !enabled });
};
this.repositoryDisposables.add(input.onDidChangeEnablement(enabled => updateEnablement(enabled)));
updateEnablement(input.enabled);
// Save model
this.model = { input, textModel };
}
@@ -121,6 +121,9 @@ export interface ISCMInput {
validateInput: IInputValidator;
readonly onDidChangeValidateInput: Event<void>;
enabled: boolean;
readonly onDidChangeEnablement: Event<boolean>;
visible: boolean;
readonly onDidChangeVisibility: Event<boolean>;
@@ -38,6 +38,20 @@ class SCMInput implements ISCMInput {
private readonly _onDidChangePlaceholder = new Emitter<string>();
readonly onDidChangePlaceholder: Event<string> = this._onDidChangePlaceholder.event;
private _enabled = true;
get enabled(): boolean {
return this._enabled;
}
set enabled(enabled: boolean) {
this._enabled = enabled;
this._onDidChangeEnablement.fire(enabled);
}
private readonly _onDidChangeEnablement = new Emitter<boolean>();
readonly onDidChangeEnablement: Event<boolean> = this._onDidChangeEnablement.event;
private _visible = true;
get visible(): boolean {
@@ -1076,6 +1076,7 @@ export class SearchModel extends Disposable {
Promise.race([currentRequest, Event.toPromise(progressEmitter.event)]).finally(() => {
/* __GDPR__
"searchResultsFirstRender" : {
"owner": "roblourens",
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
@@ -1091,6 +1092,7 @@ export class SearchModel extends Disposable {
} finally {
/* __GDPR__
"searchResultsFinished" : {
"owner": "roblourens",
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
@@ -1119,6 +1121,7 @@ export class SearchModel extends Disposable {
/* __GDPR__
"searchResultsShown" : {
owner": "roblourens",
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"fileCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"options": { "${inline}": [ "${IPatternInfo}" ] },
@@ -139,7 +139,7 @@ export const openNewSearchEditor =
}
}
telemetryService.publicLog2('searchEditor/openNewSearchEditor');
telemetryService.publicLog2<{}, { owner: 'roblourens' }>('searchEditor/openNewSearchEditor');
const seedSearchStringFromSelection = _args.location === 'new' || configurationService.getValue<IEditorOptions>('editor').find!.seedSearchStringFromSelection;
const args: OpenSearchEditorArgs = { query: seedSearchStringFromSelection ? selected : undefined };
@@ -189,7 +189,7 @@ export const createEditorFromSearchResult =
const sortOrder = configurationService.getValue<ISearchConfigurationProperties>('search').sortOrder;
telemetryService.publicLog2('searchEditor/createEditorFromSearchResult');
telemetryService.publicLog2<{}, { owner: 'roblourens' }>('searchEditor/createEditorFromSearchResult');
const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true });
@@ -184,7 +184,7 @@ export class SearchEditorInput extends EditorInput {
override async saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise<EditorInput | undefined> {
const path = await this.fileDialogService.pickFileToSave(await this.suggestFileName(), options?.availableFileSystems);
if (path) {
this.telemetryService.publicLog2('searchEditor/saveSearchResults');
this.telemetryService.publicLog2<{}, { owner: 'roblourens' }>('searchEditor/saveSearchResults');
const toWrite = await this.serializeForDisk();
if (await this.textFileService.create([{ resource: path, value: toWrite, options: { overwrite: true } }])) {
this.setDirty(false);
@@ -66,6 +66,7 @@ class CESContribution extends Disposable implements IWorkbenchContribution {
const sendTelemetry = (userReaction: 'accept' | 'remindLater' | 'neverShowAgain' | 'cancelled') => {
/* __GDPR__
"cesSurvey:popup" : {
"owner": "digitarald",
"userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
@@ -141,7 +142,9 @@ class CESContribution extends Disposable implements IWorkbenchContribution {
}
}
/* __GDPR__
"cesSurvey:schedule" : { }
"cesSurvey:schedule" : {
"owner": "digitarald"
}
*/
this.telemetryService.publicLog('cesSurvey:schedule');
@@ -67,7 +67,7 @@ export class WorkspaceTags implements IWorkbenchContribution {
value = 'Unknown';
}
this.telemetryService.publicLog2<{ edition: string }, { edition: { classification: 'SystemMetaData'; purpose: 'BusinessInsight' } }>('windowsEdition', { edition: value });
this.telemetryService.publicLog2<{ edition: string }, { owner: 'sbatten'; edition: { classification: 'SystemMetaData'; purpose: 'BusinessInsight' } }>('windowsEdition', { edition: value });
}
private async getWorkspaceInformation(): Promise<IWorkspaceInformation> {
@@ -89,6 +89,7 @@ export class WorkspaceTags implements IWorkbenchContribution {
private reportWorkspaceTags(tags: Tags): void {
/* __GDPR__
"workspce.tags" : {
"owner": "lramos15",
"${include}": [
"${WorkspaceTags}"
]
@@ -116,6 +117,7 @@ export class WorkspaceTags implements IWorkbenchContribution {
set.forEach(item => list.push(item));
/* __GDPR__
"workspace.remotes" : {
"owner": "lramos15",
"domains" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
@@ -192,6 +194,7 @@ export class WorkspaceTags implements IWorkbenchContribution {
if (Object.keys(tags).length) {
/* __GDPR__
"workspace.azure" : {
"owner": "lramos15",
"${include}": [
"${AzureTags}"
]
@@ -36,7 +36,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IModelService } from 'vs/editor/common/services/model';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { Markers } from 'vs/workbench/contrib/markers/common/markers';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder, IWorkspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
@@ -52,9 +52,10 @@ import {
Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, TaskEvent,
TaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind,
TaskSorter, TaskIdentifier, KeyedTaskIdentifier, TASK_RUNNING_STATE, TaskRunSource,
KeyedTaskIdentifier as NKeyedTaskIdentifier, TaskDefinition, RuntimeType
KeyedTaskIdentifier as NKeyedTaskIdentifier, TaskDefinition, RuntimeType,
USER_TASKS_GROUP_KEY
} from 'vs/workbench/contrib/tasks/common/tasks';
import { ITaskService, ITaskProvider, ProblemMatcherRunOptions, CustomizationProperties, TaskFilter, WorkspaceFolderTaskResult, USER_TASKS_GROUP_KEY, CustomExecutionSupportedContext, ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService';
import { ITaskService, ITaskProvider, ProblemMatcherRunOptions, CustomizationProperties, TaskFilter, WorkspaceFolderTaskResult, CustomExecutionSupportedContext, ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService';
import { getTemplates as getTaskTemplates } from 'vs/workbench/contrib/tasks/common/taskTemplates';
import * as TaskConfig from '../common/taskConfiguration';
@@ -429,7 +430,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
});
CommandsRegistry.registerCommand('workbench.action.tasks.toggleProblems', () => this.commandService.executeCommand(Constants.TOGGLE_MARKERS_VIEW_ACTION_ID));
CommandsRegistry.registerCommand('workbench.action.tasks.toggleProblems', () => this.commandService.executeCommand(Markers.TOGGLE_MARKERS_VIEW_ACTION_ID));
CommandsRegistry.registerCommand('workbench.action.tasks.openUserTasks', async () => {
const resource = this.getResourceForKind(TaskSourceKind.User);
@@ -22,7 +22,7 @@ import { IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/marke
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IModelService } from 'vs/editor/common/services/model';
import { ProblemMatcher, ProblemMatcherRegistry /*, ProblemPattern, getResource */ } from 'vs/workbench/contrib/tasks/common/problemMatcher';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { Markers } from 'vs/workbench/contrib/markers/common/markers';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { ITerminalProfileResolverService, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
@@ -813,7 +813,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
let reveal = task.command.presentation!.reveal;
let revealProblems = task.command.presentation!.revealProblems;
if (revealProblems === RevealProblemKind.OnProblem) {
this.viewsService.openView(Constants.MARKERS_VIEW_ID, true);
this.viewsService.openView(Markers.MARKERS_VIEW_ID, true);
} else if (reveal === RevealKind.Silent) {
this.terminalService.setActiveInstance(terminal!);
this.terminalGroupService.showPanel(false);
@@ -956,7 +956,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
let revealProblems = task.command.presentation!.revealProblems;
let revealProblemPanel = terminal && (revealProblems === RevealProblemKind.OnProblem) && (startStopProblemMatcher.numberOfMatches > 0);
if (revealProblemPanel) {
this.viewsService.openView(Constants.MARKERS_VIEW_ID);
this.viewsService.openView(Markers.MARKERS_VIEW_ID);
} else if (terminal && (reveal === RevealKind.Silent) && ((exitCode !== 0) || (startStopProblemMatcher.numberOfMatches > 0) && startStopProblemMatcher.maxMarkerSeverity &&
(startStopProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error))) {
try {
@@ -991,7 +991,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
let showProblemPanel = task.command.presentation && (task.command.presentation.revealProblems === RevealProblemKind.Always);
if (showProblemPanel) {
this.viewsService.openView(Constants.MARKERS_VIEW_ID);
this.viewsService.openView(Markers.MARKERS_VIEW_ID);
} else if (task.command.presentation && (task.command.presentation.reveal === RevealKind.Always)) {
this.terminalService.setActiveInstance(terminal);
this.terminalGroupService.showPanel(task.command.presentation.focus);
@@ -23,7 +23,7 @@ import * as Tasks from './tasks';
import { TaskDefinitionRegistry } from './taskDefinitionRegistry';
import { ConfiguredInput } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { URI } from 'vs/base/common/uri';
import { USER_TASKS_GROUP_KEY, ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService';
import { ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService';
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
export const enum ShellQuoting {
@@ -1268,7 +1268,7 @@ export namespace GroupKind {
namespace TaskDependency {
function uriFromSource(context: ParseContext, source: TaskConfigSource): URI | string {
switch (source) {
case TaskConfigSource.User: return USER_TASKS_GROUP_KEY;
case TaskConfigSource.User: return Tasks.USER_TASKS_GROUP_KEY;
case TaskConfigSource.TasksJson: return context.workspaceFolder.uri;
default: return context.workspace && context.workspace.configuration ? context.workspace.configuration : context.workspaceFolder.uri;
}
@@ -2146,4 +2146,3 @@ export function parse(workspaceFolder: IWorkspaceFolder, workspace: IWorkspace |
export function createCustomTask(contributedTask: Tasks.ContributedTask, configuredProps: Tasks.ConfiguringTask | Tasks.CustomTask): Tasks.CustomTask {
return CustomTask.createCustomTask(contributedTask, configuredProps);
}
@@ -55,8 +55,6 @@ export interface WorkspaceFolderTaskResult extends WorkspaceTaskResult {
workspaceFolder: IWorkspaceFolder;
}
export const USER_TASKS_GROUP_KEY = 'settings';
export interface ITaskService {
readonly _serviceBrand: undefined;
onDidStateChange: Event<TaskEvent>;
@@ -17,9 +17,8 @@ import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDe
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
// TODO@jrieken HACK, HACK
// import { USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/taskService';
const USER_TASKS_GROUP_KEY = 'settings';
export const USER_TASKS_GROUP_KEY = 'settings';
export const TASK_RUNNING_STATE = new RawContextKey<boolean>('taskRunning', false, nls.localize('tasks.taskRunningContext', "Whether a task is currently running."));
export const TASKS_CATEGORY = { value: nls.localize('tasksCategory', "Tasks"), original: 'Tasks' };

Some files were not shown because too many files have changed in this diff Show More