mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-14 04:00:38 +01:00
Merge branch 'main' into joh/swc
This commit is contained in:
@@ -6,6 +6,7 @@ on:
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !github.event.pull_request.draft }}
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
|
||||
@@ -97,7 +97,7 @@ function writeControlFile(control) {
|
||||
fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2));
|
||||
}
|
||||
function getBuiltInExtensions() {
|
||||
log('Syncronizing built-in extensions...');
|
||||
log('Synchronizing built-in extensions...');
|
||||
log(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`);
|
||||
const control = readControlFile();
|
||||
const streams = [];
|
||||
|
||||
@@ -136,7 +136,7 @@ function writeControlFile(control: IControlFile): void {
|
||||
}
|
||||
|
||||
export function getBuiltInExtensions(): Promise<void> {
|
||||
log('Syncronizing built-in extensions...');
|
||||
log('Synchronizing built-in extensions...');
|
||||
log(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`);
|
||||
|
||||
const control = readControlFile();
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/localizations",
|
||||
"name": "vs/workbench/contrib/localization",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -416,6 +416,7 @@ export class CommandCenter {
|
||||
if (!url) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"owner": "lszomoru",
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
@@ -441,6 +442,7 @@ export class CommandCenter {
|
||||
if (!uris || uris.length === 0) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"owner": "lszomoru",
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
@@ -499,6 +501,7 @@ export class CommandCenter {
|
||||
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"owner": "lszomoru",
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"openFolder": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
|
||||
}
|
||||
@@ -518,6 +521,7 @@ export class CommandCenter {
|
||||
if (/already exists and is not an empty directory/.test(err && err.stderr || '')) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"owner": "lszomoru",
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
@@ -527,6 +531,7 @@ export class CommandCenter {
|
||||
} else {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"owner": "lszomoru",
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
@@ -2920,6 +2925,7 @@ export class CommandCenter {
|
||||
|
||||
/* __GDPR__
|
||||
"git.command" : {
|
||||
"owner": "lszomoru",
|
||||
"command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -192,7 +192,9 @@ export async function _activate(context: ExtensionContext): Promise<GitExtension
|
||||
outputChannelLogger.logWarning(err.message);
|
||||
|
||||
/* __GDPR__
|
||||
"git.missing" : {}
|
||||
"git.missing" : {
|
||||
"owner": "lszomoru"
|
||||
}
|
||||
*/
|
||||
telemetryReporter.sendTelemetryEvent('git.missing');
|
||||
|
||||
|
||||
@@ -1864,6 +1864,7 @@ export class Repository implements Disposable {
|
||||
if (didHitLimit) {
|
||||
/* __GDPR__
|
||||
"statusLimit" : {
|
||||
"owner": "lszomoru",
|
||||
"ignoreSubmodules": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"limit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"statusLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
|
||||
@@ -496,6 +496,7 @@ export class GitHubServer implements IGitHubServer {
|
||||
|
||||
/* __GDPR__
|
||||
"session" : {
|
||||
"owner": "TylerLeonhardt",
|
||||
"isEdu": { "classification": "NonIdentifiableDemographicInfo", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
@@ -530,6 +531,7 @@ export class GitHubServer implements IGitHubServer {
|
||||
|
||||
/* __GDPR__
|
||||
"ghe-session" : {
|
||||
"owner": "TylerLeonhardt",
|
||||
"version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
@@ -601,6 +603,7 @@ export class GitHubEnterpriseServer implements IGitHubServer {
|
||||
|
||||
/* __GDPR__
|
||||
"ghe-session" : {
|
||||
"owner": "TylerLeonhardt",
|
||||
"version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ module.exports = function () {
|
||||
queue.push(name);
|
||||
};
|
||||
|
||||
enqueue('es6');
|
||||
enqueue('es2020.full');
|
||||
|
||||
var result = [];
|
||||
while (queue.length > 0) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export function loadLibrary(name: string) {
|
||||
try {
|
||||
content = readFileSync(libPath).toString();
|
||||
} catch (e) {
|
||||
console.log(`Unable to load library ${name} at ${libPath}: ${e.message}`);
|
||||
console.log(`Unable to load library ${name} at ${libPath}`);
|
||||
content = '';
|
||||
}
|
||||
contents[name] = content;
|
||||
|
||||
@@ -19,7 +19,7 @@ import { getSemanticTokens, getSemanticTokenLegend } from './javascriptSemanticT
|
||||
const JS_WORD_REGEX = /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g;
|
||||
|
||||
function getLanguageServiceHost(scriptKind: ts.ScriptKind) {
|
||||
const compilerOptions: ts.CompilerOptions = { allowNonTsExtensions: true, allowJs: true, lib: ['lib.es6.d.ts'], target: ts.ScriptTarget.Latest, moduleResolution: ts.ModuleResolutionKind.Classic, experimentalDecorators: false };
|
||||
const compilerOptions: ts.CompilerOptions = { allowNonTsExtensions: true, allowJs: true, lib: ['lib.es2020.full.d.ts'], target: ts.ScriptTarget.Latest, moduleResolution: ts.ModuleResolutionKind.Classic, experimentalDecorators: false };
|
||||
|
||||
let currentTextDocument = TextDocument.create('init', 'javascript', 1, '');
|
||||
const jsLanguageService = import(/* webpackChunkName: "javascriptLibs" */ './javascriptLibs').then(libs => {
|
||||
@@ -52,7 +52,7 @@ function getLanguageServiceHost(scriptKind: ts.ScriptKind) {
|
||||
};
|
||||
},
|
||||
getCurrentDirectory: () => '',
|
||||
getDefaultLibFileName: (_options: ts.CompilerOptions) => 'es6',
|
||||
getDefaultLibFileName: (_options: ts.CompilerOptions) => 'es2020.full',
|
||||
readFile: (path: string, _encoding?: string | undefined): string | undefined => {
|
||||
if (path === currentTextDocument.uri) {
|
||||
return currentTextDocument.getText();
|
||||
@@ -66,6 +66,15 @@ function getLanguageServiceHost(scriptKind: ts.ScriptKind) {
|
||||
} else {
|
||||
return !!libs.loadLibrary(path);
|
||||
}
|
||||
},
|
||||
directoryExists: (path: string): boolean => {
|
||||
// typescript tries to first find libraries in node_modules/@types and node_modules/@typescript
|
||||
// there's no node_modules in our setup
|
||||
if (path.startsWith('node_modules')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
};
|
||||
return ts.createLanguageService(host);
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
"Programming Languages"
|
||||
],
|
||||
"enabledApiProposals": [
|
||||
"textEditorDrop"
|
||||
"textEditorDrop",
|
||||
"documentPaste"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onLanguage:markdown",
|
||||
@@ -414,6 +415,12 @@
|
||||
"markdownDescription": "%configuration.markdown.editor.drop.enabled%",
|
||||
"scope": "resource"
|
||||
},
|
||||
"markdown.experimental.editor.pasteLinks.enabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "%configuration.markdown.editor.pasteLinks.enabled%",
|
||||
"scope": "resource"
|
||||
},
|
||||
"markdown.experimental.validate.enabled": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
"configuration.markdown.links.openLocation.currentGroup": "Open links in the active editor group.",
|
||||
"configuration.markdown.links.openLocation.beside": "Open links beside the active editor.",
|
||||
"configuration.markdown.suggest.paths.enabled.description": "Enable/disable path suggestions for markdown links",
|
||||
"configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#workbench.experimental.editor.dropIntoEditor.enabled#`.",
|
||||
"configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#workbenck.experimental.editor.dropIntoEditor.enabled#`.",
|
||||
"configuration.markdown.editor.pasteLinks.enabled": "Enable/disable pasting files into a Markdown editor inserts Markdown links.",
|
||||
"configuration.markdown.experimental.validate.enabled.description": "Enable/disable all error reporting in Markdown files.",
|
||||
"configuration.markdown.experimental.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`. Requires enabling `#markdown.experimental.validate.enabled#`.",
|
||||
"configuration.markdown.experimental.validate.headerLinks.enabled.description": "Validate links to headers in Markdown files, e.g. `[link](#header)`. Requires enabling `#markdown.experimental.validate.enabled#`.",
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { CommandManager } from './commandManager';
|
||||
import * as commands from './commands/index';
|
||||
import { register as registerDiagnostics } from './languageFeatures/diagnostics';
|
||||
import { registerPasteProvider } from './languageFeatures/copyPaste';
|
||||
import { MdDefinitionProvider } from './languageFeatures/definitionProvider';
|
||||
import { register as registerDiagnostics } from './languageFeatures/diagnostics';
|
||||
import { MdLinkProvider } from './languageFeatures/documentLinkProvider';
|
||||
import { MdDocumentSymbolProvider } from './languageFeatures/documentSymbolProvider';
|
||||
import { registerDropIntoEditor } from './languageFeatures/dropIntoEditor';
|
||||
@@ -78,6 +79,7 @@ function registerMarkdownLanguageFeatures(
|
||||
MdPathCompletionProvider.register(selector, engine, linkProvider),
|
||||
registerDiagnostics(selector, engine, workspaceContents, linkProvider, commandManager),
|
||||
registerDropIntoEditor(selector),
|
||||
registerPasteProvider(selector),
|
||||
registerFindFileReferences(commandManager, referencesProvider),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { tryInsertUriList } from './dropIntoEditor';
|
||||
|
||||
export function registerPasteProvider(selector: vscode.DocumentSelector) {
|
||||
return vscode.languages.registerDocumentPasteEditProvider(selector, new class implements vscode.DocumentPasteEditProvider {
|
||||
|
||||
async provideDocumentPasteEdits(
|
||||
document: vscode.TextDocument,
|
||||
range: vscode.Range,
|
||||
dataTransfer: vscode.DataTransfer,
|
||||
token: vscode.CancellationToken,
|
||||
): Promise<vscode.SnippetTextEdit | undefined> {
|
||||
const enabled = vscode.workspace.getConfiguration('markdown', document).get('experimental.editor.pasteLinks.enabled', false);
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
return tryInsertUriList(document, range, dataTransfer, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -32,45 +32,45 @@ export function registerDropIntoEditor(selector: vscode.DocumentSelector) {
|
||||
}
|
||||
|
||||
const replacementRange = new vscode.Range(position, position);
|
||||
return this.tryInsertUriList(document, replacementRange, dataTransfer, token);
|
||||
}
|
||||
|
||||
private async tryInsertUriList(document: vscode.TextDocument, replacementRange: vscode.Range, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.SnippetTextEdit | undefined> {
|
||||
const urlList = await dataTransfer.get('text/uri-list')?.asString();
|
||||
if (!urlList || token.isCancellationRequested) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const uris: vscode.Uri[] = [];
|
||||
for (const resource of urlList.split('\n')) {
|
||||
try {
|
||||
uris.push(vscode.Uri.parse(resource));
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
if (!uris.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const snippet = new vscode.SnippetString();
|
||||
uris.forEach((uri, i) => {
|
||||
const mdPath = document.uri.scheme === uri.scheme
|
||||
? encodeURI(path.relative(URI.Utils.dirname(document.uri).fsPath, uri.fsPath).replace(/\\/g, '/'))
|
||||
: uri.toString(false);
|
||||
|
||||
const ext = URI.Utils.extname(uri).toLowerCase();
|
||||
snippet.appendText(imageFileExtensions.has(ext) ? '`);
|
||||
|
||||
if (i <= uris.length - 1 && uris.length > 1) {
|
||||
snippet.appendText(' ');
|
||||
}
|
||||
});
|
||||
|
||||
return new vscode.SnippetTextEdit(replacementRange, snippet);
|
||||
return tryInsertUriList(document, replacementRange, dataTransfer, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function tryInsertUriList(document: vscode.TextDocument, replacementRange: vscode.Range, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.SnippetTextEdit | undefined> {
|
||||
const urlList = await dataTransfer.get('text/uri-list')?.asString();
|
||||
if (!urlList || token.isCancellationRequested) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const uris: vscode.Uri[] = [];
|
||||
for (const resource of urlList.split('\n')) {
|
||||
try {
|
||||
uris.push(vscode.Uri.parse(resource));
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
if (!uris.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const snippet = new vscode.SnippetString();
|
||||
uris.forEach((uri, i) => {
|
||||
const mdPath = document.uri.scheme === uri.scheme
|
||||
? encodeURI(path.relative(URI.Utils.dirname(document.uri).fsPath, uri.fsPath).replace(/\\/g, '/'))
|
||||
: uri.toString(false);
|
||||
|
||||
const ext = URI.Utils.extname(uri).toLowerCase();
|
||||
snippet.appendText(imageFileExtensions.has(ext) ? '`);
|
||||
|
||||
if (i <= uris.length - 1 && uris.length > 1) {
|
||||
snippet.appendText(' ');
|
||||
}
|
||||
});
|
||||
|
||||
return new vscode.SnippetTextEdit(replacementRange, snippet);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"src/**/*",
|
||||
"../../src/vscode-dts/vscode.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.textEditorDrop.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts"
|
||||
"../../src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.documentPaste.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"license": "MIT",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "4.7.1-rc"
|
||||
"typescript": "4.7"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall.mjs"
|
||||
|
||||
@@ -554,6 +554,7 @@ class CompletionAcceptedCommand implements Command {
|
||||
if (item instanceof MyCompletionItem) {
|
||||
/* __GDPR__
|
||||
"completions.accept" : {
|
||||
"owner": "mjbvz",
|
||||
"isPackageJsonImport" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"isImportStatementCompletion" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"${include}": [
|
||||
@@ -820,6 +821,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider<
|
||||
) {
|
||||
/* __GDPR__
|
||||
"completions.execute" : {
|
||||
"owner": "mjbvz",
|
||||
"duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
|
||||
@@ -32,6 +32,7 @@ class OrganizeImportsCommand implements Command {
|
||||
public async execute(file: string, sortOnly = false): Promise<any> {
|
||||
/* __GDPR__
|
||||
"organizeImports.execute" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
]
|
||||
|
||||
@@ -37,6 +37,7 @@ class ApplyCodeActionCommand implements Command {
|
||||
): Promise<boolean> {
|
||||
/* __GDPR__
|
||||
"quickFix.execute" : {
|
||||
"owner": "mjbvz",
|
||||
"fixName" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
@@ -67,6 +68,7 @@ class ApplyFixAllCodeAction implements Command {
|
||||
public async execute(args: ApplyFixAllCodeAction_args): Promise<void> {
|
||||
/* __GDPR__
|
||||
"quickFixAll.execute" : {
|
||||
"owner": "mjbvz",
|
||||
"fixName" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
|
||||
@@ -36,6 +36,7 @@ class DidApplyRefactoringCommand implements Command {
|
||||
public async execute(args: DidApplyRefactoringCommand_Args): Promise<void> {
|
||||
/* __GDPR__
|
||||
"refactor.execute" : {
|
||||
"owner": "mjbvz",
|
||||
"action" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
|
||||
@@ -230,6 +230,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe
|
||||
if (!executeInfo.token || !executeInfo.token.isCancellationRequested) {
|
||||
/* __GDPR__
|
||||
"languageServiceErrorResponse" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}",
|
||||
"${TypeScriptRequestErrorProperties}"
|
||||
|
||||
@@ -388,6 +388,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
|
||||
/* __GDPR__
|
||||
"tsserver.spawned" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
],
|
||||
@@ -418,6 +419,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
|
||||
/* __GDPR__
|
||||
"tsserver.error" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
]
|
||||
@@ -443,6 +445,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
this.error(`TSServer exited with code: ${code}. Signal: ${signal}`);
|
||||
/* __GDPR__
|
||||
"tsserver.exitWithCode" : {
|
||||
"owner": "mjbvz",
|
||||
"code" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
|
||||
"signal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
|
||||
"${include}": [
|
||||
@@ -601,6 +604,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
|
||||
/* __GDPR__
|
||||
"serviceExited" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
]
|
||||
@@ -846,6 +850,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
private fatalError(command: string, error: unknown): void {
|
||||
/* __GDPR__
|
||||
"fatalError" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}",
|
||||
"${TypeScriptRequestErrorProperties}"
|
||||
@@ -977,6 +982,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
|
||||
/* __GDPR__
|
||||
"typingsInstalled" : {
|
||||
"owner": "mjbvz",
|
||||
"installedPackages" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"installSuccess": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
|
||||
"typingsInstallerVersion": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
|
||||
|
||||
@@ -49,6 +49,7 @@ class ExcludeHintItem {
|
||||
this._item.show();
|
||||
/* __GDPR__
|
||||
"js.hintProjectExcludes" : {
|
||||
"owner": "mjbvz",
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
]
|
||||
|
||||
@@ -42,10 +42,10 @@ node-gyp-build@^4.3.0:
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
|
||||
integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
|
||||
|
||||
typescript@4.7.1-rc:
|
||||
version "4.7.1-rc"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.1-rc.tgz#23a0517d36c56de887b4457f29e2d265647bbd7c"
|
||||
integrity sha512-EQd2NVelDe6ZVc2sO1CSpuSs+RHzY8c2n/kTNQAHw4um/eAXY+ZY4IKoUpNK0wO6C5hN+XcUXR7yqT8VbwwNIQ==
|
||||
typescript@4.7:
|
||||
version "4.7.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.2.tgz#1f9aa2ceb9af87cca227813b4310fff0b51593c4"
|
||||
integrity sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==
|
||||
|
||||
vscode-grammar-updater@^1.1.0:
|
||||
version "1.1.0"
|
||||
|
||||
Vendored
+18
@@ -37,6 +37,11 @@ if (process.env['VSCODE_PARENT_PID']) {
|
||||
terminateWhenParentTerminates();
|
||||
}
|
||||
|
||||
// Listen for message ports
|
||||
if (process.env['VSCODE_WILL_SEND_MESSAGE_PORT']) {
|
||||
listenForMessagePort();
|
||||
}
|
||||
|
||||
// Load AMD entry point
|
||||
require('./bootstrap-amd').load(process.env['VSCODE_AMD_ENTRYPOINT']);
|
||||
|
||||
@@ -264,4 +269,17 @@ function terminateWhenParentTerminates() {
|
||||
}
|
||||
}
|
||||
|
||||
function listenForMessagePort() {
|
||||
// We need to listen for the 'port' event as soon as possible,
|
||||
// otherwise we might miss the event. But we should also be
|
||||
// prepared in case the event arrives late.
|
||||
process.on('port', (e) => {
|
||||
if (global.vscodePortsCallback) {
|
||||
global.vscodePortsCallback(e.ports);
|
||||
} else {
|
||||
global.vscodePorts = e.ports;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface ITelemetryData {
|
||||
}
|
||||
|
||||
export type WorkbenchActionExecutedClassification = {
|
||||
owner: 'bpasero';
|
||||
id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
|
||||
from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' };
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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';
|
||||
|
||||
};
|
||||
|
||||
@@ -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[] = [];
|
||||
|
||||
@@ -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' };
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[]>;
|
||||
}
|
||||
+28
-3
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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' };
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
+2
@@ -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' };
|
||||
};
|
||||
|
||||
+33
-29
@@ -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
-7
@@ -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" }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user