From a6752decb4b3090ddc42488f59ee9b634a88036b Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Sun, 20 Nov 2016 23:16:28 +0100 Subject: [PATCH 01/30] Only resolve paths in REPL if path is relative --- .../parts/debug/electron-browser/replViewer.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts index 579cabe77a1..b60f45a73ac 100644 --- a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts +++ b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts @@ -95,10 +95,11 @@ export class ReplExpressionsRenderer implements IRenderer { private static FILE_LOCATION_PATTERNS: RegExp[] = [ // group 0: the full thing :) // group 1: absolute path - // group 2: line number - // group 3: column number + // group 2: the root slash/drive letter, if present + // group 3: line number + // group 4: column number // eg: at Context. (c:\Users\someone\Desktop\mocha-runner\test\test.js:26:11) - /(?:at |^|[\(<\'\"\[])(?:file:\/\/)?((?:(?:\/|[a-zA-Z]:)|[^\(\)<>\'\"\[\]:\s]+)(?:[\\/][^\(\)<>\'\"\[\]:]*)?):(\d+)(?::(\d+))?(?:$|[\)>\'\"\]])/ + /(?:at |^|[\(<\'\"\[])(?:file:\/\/)?((?:(\/|[a-zA-Z]:)|[^\(\)<>\'\"\[\]:\s]+)(?:[\\/][^\(\)<>\'\"\[\]:]*)?):(\d+)(?::(\d+))?(?:$|[\)>\'\"\]])/ ]; private static LINE_HEIGHT_PX = 18; @@ -346,7 +347,8 @@ export class ReplExpressionsRenderer implements IRenderer { const match = pattern.exec(text); let resource: uri = null; try { - resource = match && this.contextService.toResource(match[1]); + // If root slash / drive letter is present, resolve relative path + resource = match && (match[2] ? uri.file(match[1]) : this.contextService.toResource(match[1])); } catch (e) { } if (resource) { @@ -363,7 +365,7 @@ export class ReplExpressionsRenderer implements IRenderer { link.textContent = text.substr(match.index, match[0].length); link.title = isMacintosh ? nls.localize('fileLinkMac', "Click to follow (Cmd + click opens to the side)") : nls.localize('fileLink', "Click to follow (Ctrl + click opens to the side)"); linkContainer.appendChild(link); - link.onclick = (e) => this.onLinkClick(new StandardMouseEvent(e), resource, Number(match[2]), match[3] && Number(match[3])); + link.onclick = (e) => this.onLinkClick(new StandardMouseEvent(e), resource, Number(match[3]), match[4] && Number(match[4])); let textAfterLink = text.substr(match.index + match[0].length); if (textAfterLink) { From 1df29647211bf4a156f94883881d8d6c780c1ecc Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 23 Nov 2016 10:57:39 +0100 Subject: [PATCH 02/30] extfs.delSync and tests --- src/vs/base/node/extfs.ts | 18 ++++++++ src/vs/base/test/node/extfs/extfs.test.ts | 53 +++++++++++++++++++++++ src/vs/base/test/node/pfs.test.ts | 43 ++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index 4da39cd3277..58710111885 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -245,6 +245,24 @@ function rmRecursive(path: string, callback: (error: Error) => void): void { }); } +export function delSync(path: string): void { + try { + const stat = fs.lstatSync(path); + if (stat.isDirectory() && !stat.isSymbolicLink()) { + readdirSync(path).forEach(child => delSync(paths.join(path, child))); + fs.rmdirSync(path); + } else { + fs.unlinkSync(path); + } + } catch (err) { + if (err.code === 'ENOENT') { + return; // not found + } + + throw err; + } +} + export function mv(source: string, target: string, callback: (error: Error) => void): void { if (source === target) { return callback(null); diff --git a/src/vs/base/test/node/extfs/extfs.test.ts b/src/vs/base/test/node/extfs/extfs.test.ts index a487a8d9edb..fbcf7e4fe82 100644 --- a/src/vs/base/test/node/extfs/extfs.test.ts +++ b/src/vs/base/test/node/extfs/extfs.test.ts @@ -34,6 +34,59 @@ suite('Extfs', () => { }); // 493 = 0755 }); + test('delSync - swallows file not found error', function () { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const newDir = path.join(parentDir, 'extfs', id); + + extfs.delSync(newDir); + + assert.ok(!fs.existsSync(newDir)); + }); + + test('delSync - simple', function (done: () => void) { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const newDir = path.join(parentDir, 'extfs', id); + + extfs.mkdirp(newDir, 493, (error) => { + if (error) { + return onError(error, done); + } + + fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents'); + fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents'); + + extfs.delSync(newDir); + + assert.ok(!fs.existsSync(newDir)); + done(); + }); // 493 = 0755 + }); + + test('delSync - recursive folder structure', function (done: () => void) { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const newDir = path.join(parentDir, 'extfs', id); + + extfs.mkdirp(newDir, 493, (error) => { + if (error) { + return onError(error, done); + } + + fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents'); + fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents'); + + fs.mkdirSync(path.join(newDir, 'somefolder')); + fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents'); + + extfs.delSync(newDir); + + assert.ok(!fs.existsSync(newDir)); + done(); + }); // 493 = 0755 + }); + test('copy, move and delete', function (done: () => void) { const id = uuid.generateUuid(); const id2 = uuid.generateUuid(); diff --git a/src/vs/base/test/node/pfs.test.ts b/src/vs/base/test/node/pfs.test.ts index 3e48a052e87..3963c7eea49 100644 --- a/src/vs/base/test/node/pfs.test.ts +++ b/src/vs/base/test/node/pfs.test.ts @@ -101,4 +101,47 @@ suite('PFS', () => { }, error => onError(error, done)); }); }); + + test('rimraf - simple', function (done: () => void) { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const newDir = path.join(parentDir, 'extfs', id); + + extfs.mkdirp(newDir, 493, (error) => { + if (error) { + return onError(error, done); + } + + fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents'); + fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents'); + + pfs.rimraf(newDir).then(() => { + assert.ok(!fs.existsSync(newDir)); + done(); + }, error => onError(error, done)); + }); // 493 = 0755 + }); + + test('rimraf - recursive folder structure', function (done: () => void) { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const newDir = path.join(parentDir, 'extfs', id); + + extfs.mkdirp(newDir, 493, (error) => { + if (error) { + return onError(error, done); + } + + fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents'); + fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents'); + + fs.mkdirSync(path.join(newDir, 'somefolder')); + fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents'); + + pfs.rimraf(newDir).then(() => { + assert.ok(!fs.existsSync(newDir)); + done(); + }, error => onError(error, done)); + }); // 493 = 0755 + }); }); \ No newline at end of file From c00bf9ab3f56177d6b32932e17adf175fe93aa4e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 23 Nov 2016 11:08:29 +0100 Subject: [PATCH 03/30] Validate backup workspaces on startup --- src/vs/code/electron-main/lifecycle.ts | 5 - src/vs/code/electron-main/windows.ts | 5 - .../test/electron-main/servicesTestUtils.ts | 3 - src/vs/platform/backup/common/backup.ts | 16 --- .../backup/electron-main/backupMainService.ts | 122 +++++++++++------- .../electron-main/backupMainService.test.ts | 52 ++++++-- .../lifecycle/common/mainLifecycle.ts | 6 - 7 files changed, 116 insertions(+), 93 deletions(-) diff --git a/src/vs/code/electron-main/lifecycle.ts b/src/vs/code/electron-main/lifecycle.ts index 26ba280a546..f0e2949f774 100644 --- a/src/vs/code/electron-main/lifecycle.ts +++ b/src/vs/code/electron-main/lifecycle.ts @@ -27,9 +27,6 @@ export class LifecycleService implements ILifecycleMainService { private oneTimeListenerTokenGenerator: number; private _wasUpdated: boolean; - private _onBeforeUnload = new Emitter(); - onBeforeUnload: Event = this._onBeforeUnload.event; - private _onBeforeQuit = new Emitter(); onBeforeQuit: Event = this._onBeforeQuit.event; @@ -133,8 +130,6 @@ export class LifecycleService implements ILifecycleMainService { const oneTimeCancelEvent = 'vscode:cancel' + oneTimeEventToken; ipc.once(oneTimeOkEvent, () => { - this._onBeforeUnload.fire(vscodeWindow); - c(false); // no veto }); diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 20c3e799dd0..8f93c24586c 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -357,11 +357,6 @@ export class WindowsManager implements IWindowsMainService { if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath) { const workspacesWithBackups = this.backupService.getWorkspaceBackupPaths(); workspacesWithBackups.forEach(workspacePath => { - if (!fs.existsSync(workspacePath)) { - this.backupService.removeWorkspaceBackupPathSync(Uri.file(workspacePath)); - return; - } - const configuration = this.toConfiguration(openConfig, workspacePath); const browserWindow = this.openInBrowserWindow(configuration, true /* new window */); usedWindows.push(browserWindow); diff --git a/src/vs/code/test/electron-main/servicesTestUtils.ts b/src/vs/code/test/electron-main/servicesTestUtils.ts index 80065c7c62a..c891f9d17b4 100644 --- a/src/vs/code/test/electron-main/servicesTestUtils.ts +++ b/src/vs/code/test/electron-main/servicesTestUtils.ts @@ -11,9 +11,6 @@ import Event, { Emitter } from 'vs/base/common/event'; export class TestLifecycleService implements ILifecycleMainService { public _serviceBrand: any; - private _onBeforeUnload = new Emitter(); - onBeforeUnload: Event = this._onBeforeUnload.event; - private _onBeforeQuit = new Emitter(); onBeforeQuit: Event = this._onBeforeQuit.event; diff --git a/src/vs/platform/backup/common/backup.ts b/src/vs/platform/backup/common/backup.ts index 600cbc75b4c..3da562e5e67 100644 --- a/src/vs/platform/backup/common/backup.ts +++ b/src/vs/platform/backup/common/backup.ts @@ -28,20 +28,4 @@ export interface IBackupMainService { * @param workspaces The workspaces to add. */ pushWorkspaceBackupPathsSync(workspaces: Uri[]): void; - - /** - * Removes a workspace backup path being tracked for restoration. - * - * @param workspace The workspace to remove. - */ - removeWorkspaceBackupPathSync(workspace: Uri): void; - - /** - * Gets whether the workspace has backup(s) associated with it (ie. if the workspace backup - * directory exists). - * - * @param workspace The workspace to evaluate. - * @return Whether the workspace has backups. - */ - hasWorkspaceBackup(workspace: Uri): boolean; } diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts index d69bb9e51f6..0234c2a8725 100644 --- a/src/vs/platform/backup/electron-main/backupMainService.ts +++ b/src/vs/platform/backup/electron-main/backupMainService.ts @@ -3,14 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as crypto from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; +import * as crypto from 'crypto'; +import * as extfs from 'vs/base/node/extfs'; import Uri from 'vs/base/common/uri'; import { IBackupWorkspacesFormat, IBackupMainService } from 'vs/platform/backup/common/backup'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; -import { VSCodeWindow } from 'vs/code/electron-main/window'; export class BackupMainService implements IBackupMainService { @@ -19,86 +18,107 @@ export class BackupMainService implements IBackupMainService { protected backupHome: string; protected workspacesJsonPath: string; - private workspacesJsonContent: IBackupWorkspacesFormat; + private backups: IBackupWorkspacesFormat; constructor( - @IEnvironmentService environmentService: IEnvironmentService, - @ILifecycleMainService lifecycleService: ILifecycleMainService + @IEnvironmentService environmentService: IEnvironmentService ) { this.backupHome = environmentService.backupHome; this.workspacesJsonPath = environmentService.backupWorkspacesPath; - lifecycleService.onBeforeUnload(this.onBeforeUnloadWindow.bind(this)); - this.loadSync(); } - private onBeforeUnloadWindow(vscodeWindow: VSCodeWindow) { - if (vscodeWindow.openedWorkspacePath) { - // Clear out workspace from workspaces.json if it doesn't have any backups - const workspaceResource = Uri.file(vscodeWindow.openedWorkspacePath); - if (!this.hasWorkspaceBackup(workspaceResource)) { - this.removeWorkspaceBackupPathSync(workspaceResource); - } - } - } - public getWorkspaceBackupPaths(): string[] { - return this.workspacesJsonContent.folderWorkspaces; + return this.backups.folderWorkspaces; } public pushWorkspaceBackupPathsSync(workspaces: Uri[]): void { + let needsSaving = false; workspaces.forEach(workspace => { - // Hot exit is disabled for empty workspaces - if (!workspace) { - return; - } - - if (this.workspacesJsonContent.folderWorkspaces.indexOf(workspace.fsPath) === -1) { - this.workspacesJsonContent.folderWorkspaces.push(workspace.fsPath); + if (this.backups.folderWorkspaces.indexOf(workspace.fsPath) === -1) { + this.backups.folderWorkspaces.push(workspace.fsPath); + needsSaving = true; } }); - this.saveSync(); + + if (needsSaving) { + this.saveSync(); + } } - public removeWorkspaceBackupPathSync(workspace: Uri): void { - if (!this.workspacesJsonContent.folderWorkspaces) { + protected removeWorkspaceBackupPathSync(workspace: Uri): void { + if (!this.backups.folderWorkspaces) { return; } - const index = this.workspacesJsonContent.folderWorkspaces.indexOf(workspace.fsPath); + const index = this.backups.folderWorkspaces.indexOf(workspace.fsPath); if (index === -1) { return; } - this.workspacesJsonContent.folderWorkspaces.splice(index, 1); + this.backups.folderWorkspaces.splice(index, 1); this.saveSync(); } - public hasWorkspaceBackup(workspace: Uri): boolean { - return fs.existsSync(this.getWorkspaceBackupDirectory(workspace)); - } - - private getWorkspaceBackupDirectory(workspace: Uri): string { - const workspaceHash = crypto.createHash('md5').update(workspace.fsPath).digest('hex'); - return path.join(this.backupHome, workspaceHash); - } - protected loadSync(): void { + let backups: IBackupWorkspacesFormat; try { - this.workspacesJsonContent = JSON.parse(fs.readFileSync(this.workspacesJsonPath, 'utf8').toString()); // invalid JSON or permission issue can happen here + backups = JSON.parse(fs.readFileSync(this.workspacesJsonPath, 'utf8').toString()); // invalid JSON or permission issue can happen here } catch (error) { - this.workspacesJsonContent = Object.create(null); + backups = Object.create(null); } // Ensure folderWorkspaces is a string[] - if (this.workspacesJsonContent.folderWorkspaces) { - const fws = this.workspacesJsonContent.folderWorkspaces; + if (backups.folderWorkspaces) { + const fws = backups.folderWorkspaces; if (!Array.isArray(fws) || fws.some(f => typeof f !== 'string')) { - this.workspacesJsonContent = Object.create(null); + backups = Object.create(null); } } - if (!this.workspacesJsonContent.folderWorkspaces) { - this.workspacesJsonContent.folderWorkspaces = []; + if (!backups.folderWorkspaces) { + backups.folderWorkspaces = []; + } + + this.backups = backups; + + // Validate backup workspaces + this.validateBackupWorkspaces(backups); + } + + private validateBackupWorkspaces(backups: IBackupWorkspacesFormat): void { + const staleBackupWorkspaces: { workspacePath: string; backupPath: string; }[] = []; + + const backupWorkspaces = backups.folderWorkspaces; + backupWorkspaces.forEach(workspacePath => { + const backupPath = this.toBackupPath(workspacePath); + if (!this.hasBackupsSync(backupPath)) { + staleBackupWorkspaces.push({ workspacePath, backupPath }); + } + }); + + staleBackupWorkspaces.forEach(staleBackupWorkspace => { + const {backupPath, workspacePath} = staleBackupWorkspace; + extfs.delSync(backupPath); + this.removeWorkspaceBackupPathSync(Uri.file(workspacePath)); + }); + } + + private hasBackupsSync(backupPath): boolean { + try { + const backupSchemas = extfs.readdirSync(backupPath); + if (backupSchemas.length === 0) { + return false; // empty backups + } + + return backupSchemas.some(backupSchema => { + try { + return extfs.readdirSync(path.join(backupPath, backupSchema)).length > 0; + } catch (error) { + return false; // invalid folder + } + }); + } catch (error) { + return false; // backup path does not exist } } @@ -108,9 +128,15 @@ export class BackupMainService implements IBackupMainService { if (!fs.existsSync(this.backupHome)) { fs.mkdirSync(this.backupHome); } - fs.writeFileSync(this.workspacesJsonPath, JSON.stringify(this.workspacesJsonContent)); + fs.writeFileSync(this.workspacesJsonPath, JSON.stringify(this.backups)); } catch (ex) { console.error('Could not save workspaces.json', ex); } } + + protected toBackupPath(workspacePath: string): string { + const workspaceHash = crypto.createHash('md5').update(workspacePath).digest('hex'); + + return path.join(this.backupHome, workspaceHash); + } } diff --git a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts index cfef8bb01ed..390711d12d3 100644 --- a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts +++ b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts @@ -7,7 +7,6 @@ import * as assert from 'assert'; import * as platform from 'vs/base/common/platform'; -import crypto = require('crypto'); import fs = require('fs'); import os = require('os'); import path = require('path'); @@ -15,13 +14,12 @@ import extfs = require('vs/base/node/extfs'); import pfs = require('vs/base/node/pfs'); import Uri from 'vs/base/common/uri'; import { TestEnvironmentService } from 'vs/test/utils/servicesTestUtils'; -import { TestLifecycleService } from 'vs/code/test/electron-main/servicesTestUtils'; import { BackupMainService } from 'vs/platform/backup/electron-main/backupMainService'; import { IBackupWorkspacesFormat } from 'vs/platform/backup/common/backup'; class TestBackupMainService extends BackupMainService { constructor(backupHome: string, backupWorkspacesPath: string) { - super(TestEnvironmentService, new TestLifecycleService()); + super(TestEnvironmentService); this.backupHome = backupHome; this.workspacesJsonPath = backupWorkspacesPath; @@ -29,6 +27,18 @@ class TestBackupMainService extends BackupMainService { // Force a reload with the new paths this.loadSync(); } + + public removeWorkspaceBackupPathSync(workspace: Uri): void { + return super.removeWorkspaceBackupPathSync(workspace); + } + + public loadSync(): void { + super.loadSync(); + } + + public toBackupPath(workspacePath: string): string { + return super.toBackupPath(workspacePath); + } } suite('BackupMainService', () => { @@ -39,9 +49,7 @@ suite('BackupMainService', () => { const fooFile = Uri.file(platform.isWindows ? 'C:\\foo' : '/foo'); const barFile = Uri.file(platform.isWindows ? 'C:\\bar' : '/bar'); - const fooWorkspaceBackupDir = path.join(backupHome, crypto.createHash('md5').update(fooFile.fsPath).digest('hex')); - - let service: BackupMainService; + let service: TestBackupMainService; setup(done => { service = new TestBackupMainService(backupHome, backupWorkspacesPath); @@ -123,9 +131,33 @@ suite('BackupMainService', () => { }); }); - test('doesWorkspaceHaveBackups should return whether the workspace\'s backup exists', () => { - assert.equal(service.hasWorkspaceBackup(fooFile), false); - fs.mkdirSync(fooWorkspaceBackupDir); - assert.equal(service.hasWorkspaceBackup(fooFile), true); + test('service validates backup workspaces on startup and cleans up', done => { + + // 1) backup workspace path does not exist + service.pushWorkspaceBackupPathsSync([fooFile, barFile]); + service.loadSync(); + assert.equal(service.getWorkspaceBackupPaths().length, 0); + + // 2) backup workspace path exists with empty contents within + fs.mkdirSync(service.toBackupPath(fooFile.fsPath)); + fs.mkdirSync(service.toBackupPath(barFile.fsPath)); + service.pushWorkspaceBackupPathsSync([fooFile, barFile]); + service.loadSync(); + assert.equal(service.getWorkspaceBackupPaths().length, 0); + assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath))); + assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath))); + + // 3) backup workspace path exists with empty folders within + fs.mkdirSync(service.toBackupPath(fooFile.fsPath)); + fs.mkdirSync(service.toBackupPath(barFile.fsPath)); + fs.mkdirSync(path.join(service.toBackupPath(fooFile.fsPath), 'file')); + fs.mkdirSync(path.join(service.toBackupPath(barFile.fsPath), 'untitled')); + service.pushWorkspaceBackupPathsSync([fooFile, barFile]); + service.loadSync(); + assert.equal(service.getWorkspaceBackupPaths().length, 0); + assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath))); + assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath))); + + done(); }); }); \ No newline at end of file diff --git a/src/vs/platform/lifecycle/common/mainLifecycle.ts b/src/vs/platform/lifecycle/common/mainLifecycle.ts index 7d931021a13..19ff487cc78 100644 --- a/src/vs/platform/lifecycle/common/mainLifecycle.ts +++ b/src/vs/platform/lifecycle/common/mainLifecycle.ts @@ -19,12 +19,6 @@ export interface ILifecycleMainService { */ wasUpdated: boolean; - /** - * Fired before the window unloads. This can either happen as a matter of closing the - * window or when the window is being reloaded. - */ - onBeforeUnload: Event; - /** * Due to the way we handle lifecycle with eventing, the general app.on('before-quit') * event cannot be used because it can be called twice on shutdown. Instead the onBeforeQuit From 80f7791279f7202986cf1ba417da398690da9d77 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 23 Nov 2016 19:49:16 +0100 Subject: [PATCH 04/30] cleanup and shuffle some code --- src/vs/code/common/window.ts | 37 ------------------- src/vs/code/electron-main/lifecycle.ts | 29 +++++++++++++-- src/vs/code/electron-main/main.ts | 7 ++-- src/vs/code/electron-main/window.ts | 32 +++++++++++++++- src/vs/code/electron-main/windows.ts | 7 ++-- .../test/electron-main/servicesTestUtils.ts | 34 ----------------- .../lifecycle/common/mainLifecycle.ts | 33 ----------------- .../electron-main/auto-updater.win32.ts | 4 +- .../update/electron-main/updateService.ts | 4 +- 9 files changed, 67 insertions(+), 120 deletions(-) delete mode 100644 src/vs/code/common/window.ts delete mode 100644 src/vs/code/test/electron-main/servicesTestUtils.ts delete mode 100644 src/vs/platform/lifecycle/common/mainLifecycle.ts diff --git a/src/vs/code/common/window.ts b/src/vs/code/common/window.ts deleted file mode 100644 index b932e63f7c3..00000000000 --- a/src/vs/code/common/window.ts +++ /dev/null @@ -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. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -export enum ReadyState { - - /** - * This window has not loaded any HTML yet - */ - NONE, - - /** - * This window is loading HTML - */ - LOADING, - - /** - * This window is navigating to another HTML - */ - NAVIGATING, - - /** - * This window is done loading HTML - */ - READY -} - -export interface IVSCodeWindow { - id: number; - readyState: ReadyState; - win: Electron.BrowserWindow; - - send(channel: string, ...args: any[]): void; -} \ No newline at end of file diff --git a/src/vs/code/electron-main/lifecycle.ts b/src/vs/code/electron-main/lifecycle.ts index f0e2949f774..0ac4e630112 100644 --- a/src/vs/code/electron-main/lifecycle.ts +++ b/src/vs/code/electron-main/lifecycle.ts @@ -7,14 +7,37 @@ import { ipcMain as ipc, app } from 'electron'; import { TPromise, TValueCallback } from 'vs/base/common/winjs.base'; -import { ReadyState, IVSCodeWindow } from 'vs/code/common/window'; +import { ReadyState, IVSCodeWindow } from 'vs/code/electron-main/window'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/code/electron-main/log'; import { IStorageService } from 'vs/code/electron-main/storage'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; import Event, { Emitter } from 'vs/base/common/event'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -export class LifecycleService implements ILifecycleMainService { +export const ILifecycleService = createDecorator('lifecycleService'); + +export interface ILifecycleService { + _serviceBrand: any; + + /** + * Will be true if an update was applied. Will only be true for each update once. + */ + wasUpdated: boolean; + + /** + * Due to the way we handle lifecycle with eventing, the general app.on('before-quit') + * event cannot be used because it can be called twice on shutdown. Instead the onBeforeQuit + * handler in this module can be used and it is only called once on a shutdown sequence. + */ + onBeforeQuit: Event; + + ready(): void; + registerWindow(vscodeWindow: IVSCodeWindow): void; + unload(vscodeWindow: IVSCodeWindow): TPromise; + quit(fromUpdate?: boolean): TPromise; +} + +export class LifecycleService implements ILifecycleService { _serviceBrand: any; diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 092c680983f..62221630058 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -15,8 +15,7 @@ import { IWindowsMainService, WindowsManager } from 'vs/code/electron-main/windo import { IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsChannel } from 'vs/platform/windows/common/windowsIpc'; import { WindowsService } from 'vs/platform/windows/electron-main/windowsService'; -import { LifecycleService } from 'vs/code/electron-main/lifecycle'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; +import { LifecycleService, ILifecycleService } from 'vs/code/electron-main/lifecycle'; import { VSCodeMenu } from 'vs/code/electron-main/menus'; import { IUpdateService } from 'vs/platform/update/common/update'; import { UpdateChannel } from 'vs/platform/update/common/updateIpc'; @@ -82,7 +81,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo const instantiationService = accessor.get(IInstantiationService); const logService = accessor.get(ILogService); const environmentService = accessor.get(IEnvironmentService); - const lifecycleService = accessor.get(ILifecycleMainService); + const lifecycleService = accessor.get(ILifecycleService); const configurationService = accessor.get(IConfigurationService) as ConfigurationService; let windowsMainService: IWindowsMainService; @@ -424,7 +423,7 @@ function createServices(args): IInstantiationService { services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, args, process.execPath)); services.set(ILogService, new SyncDescriptor(MainLogService)); - services.set(ILifecycleMainService, new SyncDescriptor(LifecycleService)); + services.set(ILifecycleService, new SyncDescriptor(LifecycleService)); services.set(IStorageService, new SyncDescriptor(StorageService)); services.set(IConfigurationService, new SyncDescriptor(ConfigurationService)); services.set(IRequestService, new SyncDescriptor(RequestService)); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 05294f00d87..9fcd36b1b6a 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -18,7 +18,6 @@ import { parseArgs } from 'vs/platform/environment/node/argv'; import product from 'vs/platform/product'; import { getCommonHTTPHeaders } from 'vs/platform/environment/node/http'; import { IWindowSettings } from 'vs/platform/windows/common/windows'; -import { ReadyState, IVSCodeWindow } from 'vs/code/common/window'; export interface IWindowState { width?: number; @@ -91,6 +90,37 @@ export interface IWindowConfiguration extends ParsedArgs { filesToDiff?: IPath[]; } +export enum ReadyState { + + /** + * This window has not loaded any HTML yet + */ + NONE, + + /** + * This window is loading HTML + */ + LOADING, + + /** + * This window is navigating to another HTML + */ + NAVIGATING, + + /** + * This window is done loading HTML + */ + READY +} + +export interface IVSCodeWindow { + id: number; + readyState: ReadyState; + win: Electron.BrowserWindow; + + send(channel: string, ...args: any[]): void; +} + export class VSCodeWindow implements IVSCodeWindow { public static menuBarHiddenKey = 'menuBarHidden'; diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 299a1880091..7caa9b42e33 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -17,11 +17,10 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { trim } from 'vs/base/common/strings'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IStorageService } from 'vs/code/electron-main/storage'; -import { IPath, VSCodeWindow, IWindowConfiguration, IWindowState as ISingleWindowState, defaultWindowState } from 'vs/code/electron-main/window'; -import { ReadyState } from 'vs/code/common/window'; +import { IPath, VSCodeWindow, IWindowConfiguration, IWindowState as ISingleWindowState, defaultWindowState, ReadyState } from 'vs/code/electron-main/window'; import { ipcMain as ipc, app, screen, BrowserWindow, dialog } from 'electron'; import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/electron-main/paths'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; +import { ILifecycleService } from 'vs/code/electron-main/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/code/electron-main/log'; import { getPathLabel } from 'vs/base/common/labels'; @@ -154,7 +153,7 @@ export class WindowsManager implements IWindowsMainService { @ILogService private logService: ILogService, @IStorageService private storageService: IStorageService, @IEnvironmentService private environmentService: IEnvironmentService, - @ILifecycleMainService private lifecycleService: ILifecycleMainService, + @ILifecycleService private lifecycleService: ILifecycleService, @IBackupMainService private backupService: IBackupMainService, @IConfigurationService private configurationService: IConfigurationService, @ITelemetryService private telemetryService: ITelemetryService diff --git a/src/vs/code/test/electron-main/servicesTestUtils.ts b/src/vs/code/test/electron-main/servicesTestUtils.ts deleted file mode 100644 index c891f9d17b4..00000000000 --- a/src/vs/code/test/electron-main/servicesTestUtils.ts +++ /dev/null @@ -1,34 +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 { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; -import { IVSCodeWindow } from 'vs/code/common/window'; -import { TPromise } from 'vs/base/common/winjs.base'; -import Event, { Emitter } from 'vs/base/common/event'; - -export class TestLifecycleService implements ILifecycleMainService { - public _serviceBrand: any; - - private _onBeforeQuit = new Emitter(); - onBeforeQuit: Event = this._onBeforeQuit.event; - - public get wasUpdated(): boolean { - return false; - } - - public ready(): void { - } - - public registerWindow(vscodeWindow: IVSCodeWindow): void { - } - - public unload(vscodeWindow: IVSCodeWindow): TPromise { - return TPromise.as(false); - } - - public quit(fromUpdate?: boolean): TPromise { - return TPromise.as(false); - } -} \ No newline at end of file diff --git a/src/vs/platform/lifecycle/common/mainLifecycle.ts b/src/vs/platform/lifecycle/common/mainLifecycle.ts deleted file mode 100644 index 19ff487cc78..00000000000 --- a/src/vs/platform/lifecycle/common/mainLifecycle.ts +++ /dev/null @@ -1,33 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IVSCodeWindow } from 'vs/code/common/window'; -import { TPromise } from 'vs/base/common/winjs.base'; -import Event from 'vs/base/common/event'; - -export const ILifecycleMainService = createDecorator('lifecycleMainService'); - -export interface ILifecycleMainService { - _serviceBrand: any; - - /** - * Will be true if an update was applied. Will only be true for each update once. - */ - wasUpdated: boolean; - - /** - * Due to the way we handle lifecycle with eventing, the general app.on('before-quit') - * event cannot be used because it can be called twice on shutdown. Instead the onBeforeQuit - * handler in this module can be used and it is only called once on a shutdown sequence. - */ - onBeforeQuit: Event; - - ready(): void; - registerWindow(vscodeWindow: IVSCodeWindow): void; - unload(vscodeWindow: IVSCodeWindow): TPromise; - quit(fromUpdate?: boolean): TPromise; -} \ No newline at end of file diff --git a/src/vs/platform/update/electron-main/auto-updater.win32.ts b/src/vs/platform/update/electron-main/auto-updater.win32.ts index 3d498f70da1..a1526cfad65 100644 --- a/src/vs/platform/update/electron-main/auto-updater.win32.ts +++ b/src/vs/platform/update/electron-main/auto-updater.win32.ts @@ -15,7 +15,7 @@ import { mkdirp } from 'vs/base/node/extfs'; import { isString } from 'vs/base/common/types'; import { Promise, TPromise } from 'vs/base/common/winjs.base'; import { download, asJson } from 'vs/base/node/request'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; +import { ILifecycleService } from 'vs/code/electron-main/lifecycle'; import { IRequestService } from 'vs/platform/request/node/request'; import { IAutoUpdater } from 'vs/platform/update/common/update'; import product from 'vs/platform/product'; @@ -36,7 +36,7 @@ export class Win32AutoUpdaterImpl extends EventEmitter implements IAutoUpdater { private updatePackagePath: string = null; constructor( - @ILifecycleMainService private lifecycleService: ILifecycleMainService, + @ILifecycleService private lifecycleService: ILifecycleService, @IRequestService private requestService: IRequestService ) { super(); diff --git a/src/vs/platform/update/electron-main/updateService.ts b/src/vs/platform/update/electron-main/updateService.ts index 462d60ce292..0f27826a29d 100644 --- a/src/vs/platform/update/electron-main/updateService.ts +++ b/src/vs/platform/update/electron-main/updateService.ts @@ -16,7 +16,7 @@ import { fromEventEmitter } from 'vs/base/node/event'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Win32AutoUpdaterImpl } from './auto-updater.win32'; import { LinuxAutoUpdaterImpl } from './auto-updater.linux'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/common/mainLifecycle'; +import { ILifecycleService } from 'vs/code/electron-main/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import product from 'vs/platform/product'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -85,7 +85,7 @@ export class UpdateService implements IUpdateService { constructor( @IInstantiationService instantiationService: IInstantiationService, - @ILifecycleMainService private lifecycleService: ILifecycleMainService, + @ILifecycleService private lifecycleService: ILifecycleService, @IConfigurationService private configurationService: IConfigurationService, @ITelemetryService private telemetryService: ITelemetryService ) { From d93fbc2ba9e3c14514e995422afc66302669e134 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 25 Nov 2016 11:55:55 +0100 Subject: [PATCH 05/30] Fix #16057 --- .../workbench/parts/preferences/browser/preferencesEditor.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index a5ecac35a49..c52cfc6a013 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -163,7 +163,9 @@ export class PreferencesEditorContribution extends Disposable implements editorC .then(editorModel => { if (editorModel) { this.preferencesRenderer = this.createPreferencesRenderer(editorModel); - this.preferencesRenderer.render(); + if (this.preferencesRenderer) { + this.preferencesRenderer.render(); + } } }); } From 4ce7942258317b4161339c25cde745a10e96de5c Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Fri, 25 Nov 2016 12:24:25 +0100 Subject: [PATCH 06/30] update node-debug --- build/gulpfile.vscode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 35a04e7687e..bcb65664b2c 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -39,7 +39,7 @@ const nodeModules = ['electron', 'original-fs'] // Build const builtInExtensions = [ - { name: 'ms-vscode.node-debug', version: '1.8.4' }, + { name: 'ms-vscode.node-debug', version: '1.8.5' }, { name: 'ms-vscode.node-debug2', version: '1.8.1' } ]; From ac284764cd91a8e20e101bd4294723264193337f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 25 Nov 2016 13:10:48 +0100 Subject: [PATCH 07/30] Fix #16058 - Check for workspace existence --- .../preferences/browser/preferencesService.ts | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesService.ts b/src/vs/workbench/parts/preferences/browser/preferencesService.ts index 7153a12aa21..7f3e6f06de7 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesService.ts @@ -99,7 +99,8 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.getUserSettingsEditorModel(); } - if (this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE).fsPath === uri.fsPath) { + const workspaceSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE); + if (workspaceSettingsUri && workspaceSettingsUri.fsPath === uri.fsPath) { return this.getWorkspaceSettingsEditorModel(); } @@ -157,7 +158,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic .then(() => null); } - openEditableSettings(configurationTarget: ConfigurationTarget, showVisibleEditor: boolean = false): TPromise { + private openEditableSettings(configurationTarget: ConfigurationTarget, showVisibleEditor: boolean = false): TPromise { const emptySettingsContents = this.getEmptyEditableSettingsContent(configurationTarget); const settingsResource = this.getEditableSettingsURI(configurationTarget); if (showVisibleEditor) { @@ -176,24 +177,31 @@ export class PreferencesService extends Disposable implements IPreferencesServic } public copyConfiguration(configurationValue: IConfigurationValue): void { - this.telemetryService.publicLog('defaultSettingsActions.copySetting', { userConfigurationKeys: [configurationValue.key] }); - this.openEditableSettings(this.configurationTarget, true).then(editor => { - const editorControl = editor.getControl(); - const disposable = editorControl.onDidChangeModelContent(() => { - new Delayer(100).trigger((): any => { - editorControl.focus(); - editorControl.setSelection(this.getSelectionRange(configurationValue.key, editorControl.getModel())); + if (this.configurationTarget) { + this.telemetryService.publicLog('defaultSettingsActions.copySetting', { userConfigurationKeys: [configurationValue.key] }); + this.openEditableSettings(this.configurationTarget, true).then(editor => { + const editorControl = editor.getControl(); + const disposable = editorControl.onDidChangeModelContent(() => { + new Delayer(100).trigger((): any => { + editorControl.focus(); + editorControl.setSelection(this.getSelectionRange(configurationValue.key, editorControl.getModel())); + }); + disposable.dispose(); }); - disposable.dispose(); + this.configurationEditingService.writeConfiguration(this.configurationTarget, configurationValue) + .then(null, error => this.messageService.show(Severity.Error, error)); }); - this.configurationEditingService.writeConfiguration(this.configurationTarget, configurationValue) - .then(null, error => this.messageService.show(Severity.Error, error)); - }); + } } + private resolveSettingsEditorModel(configurationTarget: ConfigurationTarget): TPromise { - return this.textModelResolverService.createModelReference(this.getEditableSettingsURI(configurationTarget)) - .then(reference => this.onModelResolved(reference.object.textEditorModel, configurationTarget)); + const settingsUri = this.getEditableSettingsURI(configurationTarget); + if (settingsUri) { + return this.textModelResolverService.createModelReference(settingsUri) + .then(reference => this.onModelResolved(reference.object.textEditorModel, configurationTarget)); + } + return TPromise.wrap(null); } private onModelResolved(model: editorCommon.IModel, configurationTarget: ConfigurationTarget) { @@ -242,8 +250,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic case ConfigurationTarget.USER: return URI.file(this.environmentService.appSettingsPath); case ConfigurationTarget.WORKSPACE: - return this.contextService.toResource('.vscode/settings.json'); + if (this.contextService.getWorkspace()) { + return this.contextService.toResource('.vscode/settings.json'); + } } + return null; } private promptToOpenWorkspaceSettings() { @@ -306,8 +317,14 @@ export class PreferencesService extends Disposable implements IPreferencesServic } private getConfigurationTarget(resource: URI): ConfigurationTarget { - return resource.fsPath === this.getEditableSettingsURI(ConfigurationTarget.USER).fsPath ? ConfigurationTarget.USER : - resource.fsPath === this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE).fsPath ? ConfigurationTarget.WORKSPACE : null; + if (this.getEditableSettingsURI(ConfigurationTarget.USER).fsPath === resource.fsPath) { + return ConfigurationTarget.USER; + } + const workspaceSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE); + if (workspaceSettingsUri && workspaceSettingsUri.fsPath === resource.fsPath) { + return ConfigurationTarget.WORKSPACE; + } + return null; } private getSelectionRange(setting: string, model: editorCommon.IModel): editorCommon.IRange { From 78591a92cf800f0613a8027214bf878456aea667 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 12:42:29 +0100 Subject: [PATCH 08/30] onDidExtensionViewletsLoad => onReady --- .../workbench/browser/parts/activitybar/activitybarPart.ts | 6 +++--- src/vs/workbench/services/viewlet/browser/viewlet.ts | 6 +++++- .../workbench/services/viewlet/browser/viewletService.ts | 7 +++++-- src/vs/workbench/test/browser/services.test.ts | 5 ++++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 925aea17fb3..f5d57c3d822 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -41,6 +41,9 @@ export class ActivitybarPart extends Part implements IActivityService { this.activityActionItems = {}; this.compositeIdToActions = {}; + // Update viewlet switcher when external viewlets become ready + this.viewletService.onReady().then(() => this.refreshViewletSwitcher()); + this.registerListeners(); } @@ -52,9 +55,6 @@ export class ActivitybarPart extends Part implements IActivityService { // Deactivate viewlet action on close this.toUnbind.push(this.viewletService.onDidViewletClose(viewlet => this.onCompositeClosed(viewlet))); - // Update viewlet switcher when external viewlets become ready - this.toUnbind.push(this.viewletService.onDidExtensionViewletsLoad(() => this.refreshViewletSwitcher())); - // Update viewlet switcher on toggling of a viewlet this.toUnbind.push(this.viewletService.onDidViewletToggle(() => this.refreshViewletSwitcher())); } diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index 1e44558c75e..2a60840d3a2 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -17,7 +17,6 @@ export interface IViewletService { onDidViewletOpen: Event; onDidViewletClose: Event; - onDidExtensionViewletsLoad: Event; onDidViewletToggle: Event; /** @@ -25,6 +24,11 @@ export interface IViewletService { */ openViewlet(id: string, focus?: boolean): TPromise; + /** + * Allows to wait until all viewlets are ready, including contributed ones. + */ + onReady(): TPromise; + /** * Toggles a viewlet with the given identifier. */ diff --git a/src/vs/workbench/services/viewlet/browser/viewletService.ts b/src/vs/workbench/services/viewlet/browser/viewletService.ts index dc2b04fa0ef..7715c2d130a 100644 --- a/src/vs/workbench/services/viewlet/browser/viewletService.ts +++ b/src/vs/workbench/services/viewlet/browser/viewletService.ts @@ -31,7 +31,6 @@ export class ViewletService implements IViewletService { public get onDidViewletOpen(): Event { return this.sidebarPart.onDidViewletOpen; }; public get onDidViewletClose(): Event { return this.sidebarPart.onDidViewletClose; }; - public get onDidExtensionViewletsLoad(): Event { return this._onDidExtensionViewletsLoad.event; }; public get onDidViewletToggle(): Event { return this._onDidViewletToggle.event; }; constructor( @@ -49,6 +48,10 @@ export class ViewletService implements IViewletService { this.loadExtensionViewlets(); } + public onReady(): TPromise { + return this.extensionViewletsLoaded; + } + private loadExtensionViewlets(): void { this.extensionViewletsLoaded = new TPromise(c => { this.extensionViewletsLoadedPromiseComplete = c; @@ -78,7 +81,7 @@ export class ViewletService implements IViewletService { } // Extension viewlets need to be loaded first which can take time - return this.extensionViewletsLoaded.then(() => { + return this.onReady().then(() => { if (this.viewletRegistry.getViewlet(id)) { return this.sidebarPart.openViewlet(id, focus); } diff --git a/src/vs/workbench/test/browser/services.test.ts b/src/vs/workbench/test/browser/services.test.ts index a8f42e401a3..1d17ae4ab45 100644 --- a/src/vs/workbench/test/browser/services.test.ts +++ b/src/vs/workbench/test/browser/services.test.ts @@ -105,9 +105,12 @@ class TestViewletService implements IViewletService { onDidViewletOpen = this.onDidViewletOpenEmitter.event; onDidViewletClose = this.onDidViewletCloseEmitter.event; - onDidExtensionViewletsLoad = this.onDidExtletsLoadEmitter.event; onDidViewletToggle = this.onDidViewletToggleEmitter.event; + public onReady(): TPromise { + return TPromise.as(null); + } + public openViewlet(id: string, focus?: boolean): TPromise { return TPromise.as(null); } From 50718f4bfdc9140d0d321d5b52a6646fbbea4c88 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 13:22:33 +0100 Subject: [PATCH 09/30] add "additional viewlets" menu item when there are extension viewlets --- src/vs/code/electron-main/menus.ts | 35 +++++++++++++++++++ .../workbench/electron-browser/integration.ts | 9 ++++- .../browser/treeExplorer.contribution.ts | 34 ++++++++++++++++-- .../treeExplorerActions.contribution.ts | 2 +- .../services/viewlet/browser/viewlet.ts | 2 +- .../viewlet/browser/viewletService.ts | 2 +- .../workbench/test/browser/services.test.ts | 2 +- 7 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 4f085b57da3..b84a8c752ad 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -26,6 +26,11 @@ interface IResolvedKeybinding { binding: number; } +interface IExtensionViewlet { + id: string; + label: string; +} + interface IConfiguration extends IFilesConfiguration { workbench: { sideBar: { @@ -61,6 +66,8 @@ export class VSCodeMenu { private mapResolvedKeybindingToActionId: { [id: string]: string; }; private keybindingsResolved: boolean; + private extensionViewlets: IExtensionViewlet[]; + constructor( @IStorageService private storageService: IStorageService, @IUpdateService private updateService: IUpdateService, @@ -70,6 +77,7 @@ export class VSCodeMenu { @ITelemetryService private telemetryService: ITelemetryService ) { this.actionIdKeybindingRequests = []; + this.extensionViewlets = []; this.mapResolvedKeybindingToActionId = Object.create(null); this.mapLastKnownKeybindingToActionId = this.storageService.getItem<{ [id: string]: string; }>(VSCodeMenu.lastKnownKeybindingsMapStorageKey) || Object.create(null); @@ -133,6 +141,21 @@ export class VSCodeMenu { } }); + // Listen to extension viewlets + ipc.on('vscode:extensionViewlets', (event, rawExtensionViewlets) => { + let extensionViewlets: IExtensionViewlet[] = []; + try { + extensionViewlets = JSON.parse(rawExtensionViewlets); + } catch (error) { + // Should not happen + } + + if (extensionViewlets.length) { + this.extensionViewlets = extensionViewlets; + this.updateMenu(); + } + }); + // Update when auto save config changes this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config, true /* update menu if changed */)); @@ -517,6 +540,17 @@ export class VSCodeMenu { const integratedTerminal = this.createMenuItem(nls.localize({ key: 'miToggleIntegratedTerminal', comment: ['&& denotes a mnemonic'] }, "&&Integrated Terminal"), 'workbench.action.terminal.toggleTerminal'); const problems = this.createMenuItem(nls.localize({ key: 'miMarker', comment: ['&& denotes a mnemonic'] }, "&&Problems"), 'workbench.actions.view.problems'); + let additionalViewlets: Electron.MenuItem; + if (this.extensionViewlets.length) { + const additionalViewletsMenu = new Menu(); + + this.extensionViewlets.forEach(viewlet => { + additionalViewletsMenu.append(this.createMenuItem(viewlet.label, viewlet.id)); + }); + + additionalViewlets = new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miAdditionalViewlets', comment: ['&& denotes a mnemonic'] }, "Additional &&Viewlets")), submenu: additionalViewletsMenu, enabled: true }); + } + const commands = this.createMenuItem(nls.localize({ key: 'miCommandPalette', comment: ['&& denotes a mnemonic'] }, "&&Command Palette..."), 'workbench.action.showCommands'); const fullscreen = new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miToggleFullScreen', comment: ['&& denotes a mnemonic'] }, "Toggle &&Full Screen")), accelerator: this.getAccelerator('workbench.action.toggleFullScreen'), click: () => this.windowsService.getLastActiveWindow().toggleFullScreen(), enabled: this.windowsService.getWindowCount() > 0 }); @@ -569,6 +603,7 @@ export class VSCodeMenu { git, debug, extensions, + additionalViewlets, __separator__(), output, problems, diff --git a/src/vs/workbench/electron-browser/integration.ts b/src/vs/workbench/electron-browser/integration.ts index 16536594cf5..2adb99774fa 100644 --- a/src/vs/workbench/electron-browser/integration.ts +++ b/src/vs/workbench/electron-browser/integration.ts @@ -41,6 +41,7 @@ import URI from 'vs/base/common/uri'; import { ReloadWindowAction, ToggleDevToolsAction, ShowStartupPerformance, OpenRecentAction } from 'vs/workbench/electron-browser/actions'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { ipcRenderer as ipc, webFrame, remote } from 'electron'; @@ -76,7 +77,8 @@ export class ElectronIntegration { @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IEnvironmentService private environmentService: IEnvironmentService, - @IThemeService private themeService: IThemeService + @IThemeService private themeService: IThemeService, + @IViewletService private viewletService: IViewletService ) { } @@ -108,6 +110,11 @@ export class ElectronIntegration { }, () => errors.onUnexpectedError); }); + // Send over all extension viewlets when ready + this.viewletService.onReady().then(() => { + ipc.send('vscode:extensionViewlets', JSON.stringify(this.viewletService.getViewlets().filter(v => v.fromExtension).map(v => { return { id: v.id, label: v.name }; }))); + }); + ipc.on('vscode:reportError', (event, error) => { if (error) { const errorParsed = JSON.parse(error); diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts index 3fb501dd6ed..a4ad9948997 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts @@ -15,10 +15,14 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { ICustomTreeExplorerService } from 'vs/workbench/parts/explorers/common/customTreeExplorerService'; import { CustomTreeExplorerService } from 'vs/workbench/parts/explorers/browser/customTreeExplorerService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet'; +import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ToggleViewletAction } from 'vs/workbench/browser/viewlet'; import { ITreeExplorer } from 'vs/platform/extensionManagement/common/extensionManagement'; import { toCustomExplorerViewletId, toCustomExplorerViewletCSSClass, isValidViewletId } from 'vs/workbench/parts/explorers/common/treeExplorer'; import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; +import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; registerSingleton(ICustomTreeExplorerService, CustomTreeExplorerService); @@ -41,6 +45,18 @@ const explorerSchema: IJSONSchema = { } }; +export class OpenViewletAction extends ToggleViewletAction { + + constructor( + id: string, + label: string, + @IViewletService viewletService: IViewletService, + @IWorkbenchEditorService editorService: IWorkbenchEditorService + ) { + super(id, label, id, viewletService, editorService); + } +} + export class ExtensionExplorersContribtion implements IWorkbenchContribution { constructor() { @@ -61,6 +77,7 @@ export class ExtensionExplorersContribtion implements IWorkbenchContribution { continue; } + // Generate CSS to show the icon in the activity bar const getIconRule = (iconPath) => { return `background-image: url('${iconPath}')`; }; if (icon) { const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${toCustomExplorerViewletCSSClass(treeExplorerNodeProviderId)}`; @@ -69,12 +86,23 @@ export class ExtensionExplorersContribtion implements IWorkbenchContribution { createCSSRule(iconClass, getIconRule(iconPath)); } + const viewletId = toCustomExplorerViewletId(treeExplorerNodeProviderId); + + // Register action to open the viewlet + const registry = Registry.as(ActionExtensions.WorkbenchActions); + registry.registerWorkbenchAction( + new SyncActionDescriptor(OpenViewletAction, viewletId, localize('showViewlet', "Show {0}", treeLabel)), + 'View: Show {0}', + localize('view', "View") + ); + + // Register as viewlet Registry.as(ViewletExtensions.Viewlets).registerViewlet(new ViewletDescriptor( 'vs/workbench/parts/explorers/browser/treeExplorerViewlet', 'TreeExplorerViewlet', - toCustomExplorerViewletId(treeExplorerNodeProviderId), + viewletId, treeLabel, - toCustomExplorerViewletCSSClass(treeExplorerNodeProviderId), + viewletId, -1, // External viewlets are ordered by enabling sequence, so order here doesn't matter. true // from extension )); diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts index 7319a542c3a..41b8a19c081 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts @@ -31,7 +31,7 @@ export class ToggleExternalViewletAction extends Action { } run(): TPromise { - const extViewlets = this.viewletService.getAllViewlets().filter(viewlet => viewlet.fromExtension); + const extViewlets = this.viewletService.getViewlets().filter(viewlet => viewlet.fromExtension); const picks: IPickOpenEntry[] = []; diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index 2a60840d3a2..f8a6d419fb3 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -42,7 +42,7 @@ export interface IViewletService { /** * Returns all registered viewlets */ - getAllViewlets(): ViewletDescriptor[]; + getViewlets(): ViewletDescriptor[]; /** * Returns all viewlets that should be displayed, ordered by: diff --git a/src/vs/workbench/services/viewlet/browser/viewletService.ts b/src/vs/workbench/services/viewlet/browser/viewletService.ts index 7715c2d130a..c41a0328a9a 100644 --- a/src/vs/workbench/services/viewlet/browser/viewletService.ts +++ b/src/vs/workbench/services/viewlet/browser/viewletService.ts @@ -107,7 +107,7 @@ export class ViewletService implements IViewletService { return this.sidebarPart.getActiveViewlet(); } - public getAllViewlets(): ViewletDescriptor[] { + public getViewlets(): ViewletDescriptor[] { const builtInViewlets = this.getBuiltInViewlets(); return builtInViewlets.concat(this.extensionViewlets); diff --git a/src/vs/workbench/test/browser/services.test.ts b/src/vs/workbench/test/browser/services.test.ts index 1d17ae4ab45..8a853bb58c1 100644 --- a/src/vs/workbench/test/browser/services.test.ts +++ b/src/vs/workbench/test/browser/services.test.ts @@ -118,7 +118,7 @@ class TestViewletService implements IViewletService { public toggleViewlet(id: string): void { } - public getAllViewlets(): ViewletDescriptor[] { + public getViewlets(): ViewletDescriptor[] { return []; } From 2876e5670741bb177148837fa6178b805ef2c110 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 13:26:56 +0100 Subject: [PATCH 10/30] :lipstick: --- .../explorers/browser/treeExplorer.contribution.ts | 6 +++--- .../browser/treeExplorerActions.contribution.ts | 4 ++-- .../parts/explorers/browser/treeExplorerActions.ts | 4 ++-- .../workbench/parts/explorers/common/treeExplorer.ts | 12 ++++++------ .../explorers/media/treeExplorer.contribution.css | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts index a4ad9948997..d80b1eae006 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts @@ -17,7 +17,7 @@ import { CustomTreeExplorerService } from 'vs/workbench/parts/explorers/browser/ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ToggleViewletAction } from 'vs/workbench/browser/viewlet'; import { ITreeExplorer } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { toCustomExplorerViewletId, toCustomExplorerViewletCSSClass, isValidViewletId } from 'vs/workbench/parts/explorers/common/treeExplorer'; +import { toViewletId, toViewletCSSClass, isValidViewletId } from 'vs/workbench/parts/explorers/common/treeExplorer'; import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; @@ -80,13 +80,13 @@ export class ExtensionExplorersContribtion implements IWorkbenchContribution { // Generate CSS to show the icon in the activity bar const getIconRule = (iconPath) => { return `background-image: url('${iconPath}')`; }; if (icon) { - const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${toCustomExplorerViewletCSSClass(treeExplorerNodeProviderId)}`; + const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${toViewletCSSClass(treeExplorerNodeProviderId)}`; const iconPath = join(extension.description.extensionFolderPath, icon); createCSSRule(iconClass, getIconRule(iconPath)); } - const viewletId = toCustomExplorerViewletId(treeExplorerNodeProviderId); + const viewletId = toViewletId(treeExplorerNodeProviderId); // Register action to open the viewlet const registry = Registry.as(ActionExtensions.WorkbenchActions); diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts index 41b8a19c081..cab22de2e26 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts @@ -13,12 +13,12 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { Action } from 'vs/base/common/actions'; import { IQuickOpenService, IPickOpenEntry } from 'vs/workbench/services/quickopen/common/quickOpenService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { toCustomExplorerViewletActionId } from 'vs/workbench/parts/explorers/common/treeExplorer'; +import { toViewletActionId } from 'vs/workbench/parts/explorers/common/treeExplorer'; const registry = Registry.as(ActionExtensions.WorkbenchActions); export class ToggleExternalViewletAction extends Action { - public static ID = toCustomExplorerViewletActionId('toggle'); + public static ID = toViewletActionId('toggle'); public static LABEL = localize('treeExplorer.toggle', 'Toggle Custom Explorer'); constructor( diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.ts b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.ts index f70f88610d8..04103edf29f 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.ts @@ -8,12 +8,12 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { TreeExplorerView } from 'vs/workbench/parts/explorers/browser/views/treeExplorerView'; -import { toCustomExplorerViewletActionId } from 'vs/workbench/parts/explorers/common/treeExplorer'; +import { toViewletActionId } from 'vs/workbench/parts/explorers/common/treeExplorer'; export class RefreshViewExplorerAction extends Action { constructor(view: TreeExplorerView) { - super(toCustomExplorerViewletActionId('refresh'), nls.localize('refresh', "Refresh"), 'customExplorer-action toggle', true, () => { + super(toViewletActionId('refresh'), nls.localize('refresh', "Refresh"), 'extensionViewlet-action toggle', true, () => { view.updateInput(); return TPromise.as(null); }); diff --git a/src/vs/workbench/parts/explorers/common/treeExplorer.ts b/src/vs/workbench/parts/explorers/common/treeExplorer.ts index 4a809f7d3c9..aa781838fa0 100644 --- a/src/vs/workbench/parts/explorers/common/treeExplorer.ts +++ b/src/vs/workbench/parts/explorers/common/treeExplorer.ts @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -export function toCustomExplorerViewletId(viewletId: string): string { - return `workbench.view.customExplorer.${viewletId}`; +export function toViewletId(viewletId: string): string { + return `workbench.view.extension.${viewletId}`; } -export function toCustomExplorerViewletActionId(viewletId: string): string { - return `workbench.action.customExplorer.${viewletId}`; +export function toViewletActionId(viewletId: string): string { + return `workbench.action.extension.${viewletId}`; } -export function toCustomExplorerViewletCSSClass(viewletId: string): string { - return `customExplorer-${viewletId}`; +export function toViewletCSSClass(viewletId: string): string { + return `extensionViewlet-${viewletId}`; } export function isValidViewletId(viewletId: string): boolean { diff --git a/src/vs/workbench/parts/explorers/media/treeExplorer.contribution.css b/src/vs/workbench/parts/explorers/media/treeExplorer.contribution.css index d1cee1c5f40..35425359a07 100644 --- a/src/vs/workbench/parts/explorers/media/treeExplorer.contribution.css +++ b/src/vs/workbench/parts/explorers/media/treeExplorer.contribution.css @@ -3,12 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench .customExplorer-action.toggle { +.monaco-workbench .extensionViewlet-action.toggle { background: url('Refresh.svg') center center no-repeat; } -.vs-dark .monaco-workbench .customExplorer-action.toggle, -.hc-black .monaco-workbench .customExplorer-action.toggle { +.vs-dark .monaco-workbench .extensionViewlet-action.toggle, +.hc-black .monaco-workbench .extensionViewlet-action.toggle { background: url('Refresh_inverse.svg') center center no-repeat; } From 0e0c6d6d13eabc6f8388ffb3801b6a890314dc51 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 13:46:44 +0100 Subject: [PATCH 11/30] fix issue with extension viewlet visibility --- .../parts/activitybar/activitybarPart.ts | 14 ++-- .../electron-browser/workbench.main.ts | 1 - .../browser/treeExplorer.contribution.ts | 12 ++-- .../treeExplorerActions.contribution.ts | 68 ------------------- .../parts/explorers/common/treeExplorer.ts | 3 +- .../services/viewlet/browser/viewlet.ts | 18 ----- .../viewlet/browser/viewletService.ts | 47 ++----------- .../workbench/test/browser/services.test.ts | 15 ---- 8 files changed, 15 insertions(+), 163 deletions(-) delete mode 100644 src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index f5d57c3d822..95c8070cd64 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -42,7 +42,7 @@ export class ActivitybarPart extends Part implements IActivityService { this.compositeIdToActions = {}; // Update viewlet switcher when external viewlets become ready - this.viewletService.onReady().then(() => this.refreshViewletSwitcher()); + this.viewletService.onReady().then(() => this.updateViewletSwitcher()); this.registerListeners(); } @@ -54,9 +54,6 @@ export class ActivitybarPart extends Part implements IActivityService { // Deactivate viewlet action on close this.toUnbind.push(this.viewletService.onDidViewletClose(viewlet => this.onCompositeClosed(viewlet))); - - // Update viewlet switcher on toggling of a viewlet - this.toUnbind.push(this.viewletService.onDidViewletToggle(() => this.refreshViewletSwitcher())); } private onActiveCompositeChanged(composite: IComposite): void { @@ -102,14 +99,11 @@ export class ActivitybarPart extends Part implements IActivityService { ariaLabel: nls.localize('activityBarAriaLabel', "Active View Switcher") }); - this.fillViewletSwitcher(this.viewletService.getAllViewletsToDisplay()); + this.updateViewletSwitcher(); } - private refreshViewletSwitcher(): void { - this.fillViewletSwitcher(this.viewletService.getAllViewletsToDisplay()); - } - - private fillViewletSwitcher(viewlets: ViewletDescriptor[]) { + private updateViewletSwitcher() { + const viewlets = this.viewletService.getViewlets(); // Pull out viewlets no longer needed const newViewletIds = viewlets.map(v => v.id); diff --git a/src/vs/workbench/electron-browser/workbench.main.ts b/src/vs/workbench/electron-browser/workbench.main.ts index a4d8a983aae..83e25d0b005 100644 --- a/src/vs/workbench/electron-browser/workbench.main.ts +++ b/src/vs/workbench/electron-browser/workbench.main.ts @@ -65,7 +65,6 @@ import 'vs/workbench/parts/extensions/browser/extensionsQuickOpen'; import 'vs/workbench/parts/extensions/electron-browser/extensionsViewlet'; // can be packaged separately import 'vs/workbench/parts/explorers/browser/treeExplorer.contribution'; -import 'vs/workbench/parts/explorers/browser/treeExplorerActions.contribution'; import 'vs/workbench/parts/explorers/browser/treeExplorerViewlet'; // can be packaged separately import 'vs/workbench/parts/output/browser/output.contribution'; diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts index d80b1eae006..474caf43f57 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts @@ -77,17 +77,17 @@ export class ExtensionExplorersContribtion implements IWorkbenchContribution { continue; } + const viewletId = toViewletId(treeExplorerNodeProviderId); + const viewletCSSClass = toViewletCSSClass(treeExplorerNodeProviderId); + // Generate CSS to show the icon in the activity bar - const getIconRule = (iconPath) => { return `background-image: url('${iconPath}')`; }; if (icon) { - const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${toViewletCSSClass(treeExplorerNodeProviderId)}`; + const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${viewletCSSClass}`; const iconPath = join(extension.description.extensionFolderPath, icon); - createCSSRule(iconClass, getIconRule(iconPath)); + createCSSRule(iconClass, `background-image: url('${iconPath}')`); } - const viewletId = toViewletId(treeExplorerNodeProviderId); - // Register action to open the viewlet const registry = Registry.as(ActionExtensions.WorkbenchActions); registry.registerWorkbenchAction( @@ -102,7 +102,7 @@ export class ExtensionExplorersContribtion implements IWorkbenchContribution { 'TreeExplorerViewlet', viewletId, treeLabel, - viewletId, + viewletCSSClass, -1, // External viewlets are ordered by enabling sequence, so order here doesn't matter. true // from extension )); diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts deleted file mode 100644 index cab22de2e26..00000000000 --- a/src/vs/workbench/parts/explorers/browser/treeExplorerActions.contribution.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import { localize } from 'vs/nls'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { Registry } from 'vs/platform/platform'; -import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry'; -import { ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { Action } from 'vs/base/common/actions'; -import { IQuickOpenService, IPickOpenEntry } from 'vs/workbench/services/quickopen/common/quickOpenService'; -import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { toViewletActionId } from 'vs/workbench/parts/explorers/common/treeExplorer'; - -const registry = Registry.as(ActionExtensions.WorkbenchActions); - -export class ToggleExternalViewletAction extends Action { - public static ID = toViewletActionId('toggle'); - public static LABEL = localize('treeExplorer.toggle', 'Toggle Custom Explorer'); - - constructor( - id: string, - label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, - @IViewletService private viewletService: IViewletService - ) { - super(id, name); - } - - run(): TPromise { - const extViewlets = this.viewletService.getViewlets().filter(viewlet => viewlet.fromExtension); - - const picks: IPickOpenEntry[] = []; - - extViewlets.forEach(viewlet => { - const isEnabled = this.viewletService.isViewletEnabled(viewlet.id); - const actionLabel = isEnabled ? localize('disable', "Disable") : localize('enable', "Enable"); - picks.push({ - id: viewlet.id, - label: `${actionLabel} ${viewlet.name}`, - run: () => { - this.viewletService.toggleViewlet(viewlet.id); - if (isEnabled) { - // To disable, so open default viewlet - const defaultViewletId = (Registry.as(ViewletExtensions.Viewlets)).getDefaultViewletId(); - this.viewletService.openViewlet(defaultViewletId); - } else { - // To enable, so open the viewlet to be enabled - this.viewletService.openViewlet(viewlet.id); - } - } - }); - }); - - return TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */).then(() => { - this.quickOpenService.pick(picks, { placeHolder: 'Select Custom Explorer to toggle' }).done(); - }); - } -} - -registry.registerWorkbenchAction( - new SyncActionDescriptor(ToggleExternalViewletAction, ToggleExternalViewletAction.ID, ToggleExternalViewletAction.LABEL), - 'View: Toggle Custom Explorer', - localize('view', "View") -); diff --git a/src/vs/workbench/parts/explorers/common/treeExplorer.ts b/src/vs/workbench/parts/explorers/common/treeExplorer.ts index aa781838fa0..fad6a30fd85 100644 --- a/src/vs/workbench/parts/explorers/common/treeExplorer.ts +++ b/src/vs/workbench/parts/explorers/common/treeExplorer.ts @@ -17,6 +17,5 @@ export function toViewletCSSClass(viewletId: string): string { } export function isValidViewletId(viewletId: string): boolean { - // Only allow alphanumeric letters, `_` and `-`. - return /^[a-z0-9_-]+$/i.test(viewletId); + return /^[a-z0-9_-]+$/i.test(viewletId); // Only allow alphanumeric letters, `_` and `-`. } diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index f8a6d419fb3..b6ee280e5af 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -17,7 +17,6 @@ export interface IViewletService { onDidViewletOpen: Event; onDidViewletClose: Event; - onDidViewletToggle: Event; /** * Opens a viewlet with the given identifier and pass keyboard focus to it if specified. @@ -29,11 +28,6 @@ export interface IViewletService { */ onReady(): TPromise; - /** - * Toggles a viewlet with the given identifier. - */ - toggleViewlet(id: string): void; - /** * Returns the current active viewlet or null if none. */ @@ -43,16 +37,4 @@ export interface IViewletService { * Returns all registered viewlets */ getViewlets(): ViewletDescriptor[]; - - /** - * Returns all viewlets that should be displayed, ordered by: - * - Stock Viewlets: order attribute - * - External Viewlets: enabling sequence - */ - getAllViewletsToDisplay(): ViewletDescriptor[]; - - /** - * Checks if an extension is enabled - */ - isViewletEnabled(id: string): boolean; } \ No newline at end of file diff --git a/src/vs/workbench/services/viewlet/browser/viewletService.ts b/src/vs/workbench/services/viewlet/browser/viewletService.ts index c41a0328a9a..d0be7110208 100644 --- a/src/vs/workbench/services/viewlet/browser/viewletService.ts +++ b/src/vs/workbench/services/viewlet/browser/viewletService.ts @@ -7,44 +7,33 @@ import { TPromise, ValueCallback } from 'vs/base/common/winjs.base'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import Event, { Emitter } from 'vs/base/common/event'; +import Event from 'vs/base/common/event'; import { ISidebar } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; import { Registry } from 'vs/platform/platform'; import { ViewletDescriptor, ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet'; -import { IStorageService } from 'vs/platform/storage/common/storage'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; export class ViewletService implements IViewletService { - private static readonly ENABLED_EXTENSION_VIEWLETS = 'workbench.viewlet.enabledExtViewlets'; - public _serviceBrand: any; private sidebarPart: ISidebar; private viewletRegistry: ViewletRegistry; - private enabledExtensionViewletIds: string[]; + private extensionViewlets: ViewletDescriptor[]; private extensionViewletsLoaded: TPromise; private extensionViewletsLoadedPromiseComplete: ValueCallback; - private _onDidExtensionViewletsLoad = new Emitter(); - private _onDidViewletToggle = new Emitter(); public get onDidViewletOpen(): Event { return this.sidebarPart.onDidViewletOpen; }; public get onDidViewletClose(): Event { return this.sidebarPart.onDidViewletClose; }; - public get onDidViewletToggle(): Event { return this._onDidViewletToggle.event; }; constructor( sidebarPart: ISidebar, - @IStorageService private storageService: IStorageService, @IExtensionService private extensionService: IExtensionService ) { this.sidebarPart = sidebarPart; this.viewletRegistry = Registry.as(ViewletExtensions.Viewlets); - const enabledExtensionViewletsJson = this.storageService.get(ViewletService.ENABLED_EXTENSION_VIEWLETS); - this.enabledExtensionViewletIds = enabledExtensionViewletsJson ? JSON.parse(enabledExtensionViewletsJson) : []; - this.extensionViewlets = []; - this.loadExtensionViewlets(); } @@ -53,6 +42,8 @@ export class ViewletService implements IViewletService { } private loadExtensionViewlets(): void { + this.extensionViewlets = []; + this.extensionViewletsLoaded = new TPromise(c => { this.extensionViewletsLoadedPromiseComplete = c; }); @@ -66,8 +57,6 @@ export class ViewletService implements IViewletService { }); this.extensionViewletsLoadedPromiseComplete(void 0); - - this._onDidExtensionViewletsLoad.fire(); }); } @@ -91,18 +80,6 @@ export class ViewletService implements IViewletService { }); } - public toggleViewlet(id: string): void { - const index = this.enabledExtensionViewletIds.indexOf(id); - if (index === -1) { - this.enabledExtensionViewletIds.push(id); - } else { - this.enabledExtensionViewletIds.splice(index, 1); - } - - this.storageService.store(ViewletService.ENABLED_EXTENSION_VIEWLETS, JSON.stringify(this.enabledExtensionViewletIds)); - this._onDidViewletToggle.fire(); - } - public getActiveViewlet(): IViewlet { return this.sidebarPart.getActiveViewlet(); } @@ -113,22 +90,6 @@ export class ViewletService implements IViewletService { return builtInViewlets.concat(this.extensionViewlets); } - public getAllViewletsToDisplay(): ViewletDescriptor[] { - const builtInViewlets = this.getBuiltInViewlets(); - const enabledExtensionViewlets = this.extensionViewlets - .filter(v => this.enabledExtensionViewletIds.indexOf(v.id) !== -1) - .sort((v1, v2) => { - return this.enabledExtensionViewletIds.indexOf(v1.id) - this.enabledExtensionViewletIds.indexOf(v2.id); - }); - - return builtInViewlets.concat(enabledExtensionViewlets); - } - - public isViewletEnabled(id: string): boolean { - return this.enabledExtensionViewletIds.indexOf(id) !== -1; - } - - // Get an ordered list of all built in viewlets private getBuiltInViewlets(): ViewletDescriptor[] { return this.viewletRegistry.getViewlets() .filter(viewlet => !viewlet.fromExtension) diff --git a/src/vs/workbench/test/browser/services.test.ts b/src/vs/workbench/test/browser/services.test.ts index 8a853bb58c1..fdd5ecdd494 100644 --- a/src/vs/workbench/test/browser/services.test.ts +++ b/src/vs/workbench/test/browser/services.test.ts @@ -100,12 +100,9 @@ class TestViewletService implements IViewletService { onDidViewletOpenEmitter = new Emitter(); onDidViewletCloseEmitter = new Emitter(); - onDidExtletsLoadEmitter = new Emitter(); - onDidViewletToggleEmitter = new Emitter(); onDidViewletOpen = this.onDidViewletOpenEmitter.event; onDidViewletClose = this.onDidViewletCloseEmitter.event; - onDidViewletToggle = this.onDidViewletToggleEmitter.event; public onReady(): TPromise { return TPromise.as(null); @@ -115,28 +112,16 @@ class TestViewletService implements IViewletService { return TPromise.as(null); } - public toggleViewlet(id: string): void { - } - public getViewlets(): ViewletDescriptor[] { return []; } - public getAllViewletsToDisplay(): ViewletDescriptor[] { - return []; - } - public getActiveViewlet(): IViewlet { return activeViewlet; } - public isViewletEnabled(id: string): boolean { - return true; - } - public dispose() { } - } class TestPanelService implements IPanelService { From c6c30c3d87cf5fac136fe9a459169ad157aedebe Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 13:55:14 +0100 Subject: [PATCH 12/30] Infinite FileWatcher start->crash loop (fixes #16009) --- .../files/node/watcher/unix/watcherService.ts | 4 ++-- .../node/watcher/win32/csharpWatcherService.ts | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts index f092b62b671..3c792f5b63a 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts @@ -61,11 +61,11 @@ export class FileWatcher { // that the watcher process died and we want to restart it here. we only do it a max number of times if (!this.isDisposed) { if (this.restartCounter <= FileWatcher.MAX_RESTARTS) { - this.errorLogger('Watcher terminated unexpectedly and is restarted again...'); + this.errorLogger('[FileWatcher] terminated unexpectedly and is restarted again...'); this.restartCounter++; this.startWatching(); } else { - this.errorLogger('Watcher failed to start after retrying for some time, giving up. Please report this as a bug report!'); + this.errorLogger('[FileWatcher] failed to start after retrying for some time, giving up. Please report this as a bug report!'); } } }, this.errorLogger); diff --git a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts index afd86a19ee4..6c1cfbc0611 100644 --- a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts @@ -16,9 +16,12 @@ import { IRawFileChange } from 'vs/workbench/services/files/node/watcher/common' export class OutOfProcessWin32FolderWatcher { + private static MAX_RESTARTS = 5; + private static changeTypeMap: FileChangeType[] = [FileChangeType.UPDATED, FileChangeType.ADDED, FileChangeType.DELETED]; private handle: cp.ChildProcess; + private restartCounter: number; constructor( private watchedFolder: string, @@ -27,6 +30,8 @@ export class OutOfProcessWin32FolderWatcher { private errorCallback: (error: string) => void, private verboseLogging: boolean ) { + this.restartCounter = 0; + this.startWatcher(); } @@ -93,8 +98,15 @@ export class OutOfProcessWin32FolderWatcher { private onExit(code: any, signal: any): void { if (this.handle) { // exit while not yet being disposed is unexpected! - this.errorCallback('[FileWatcher] terminated unexpectedly (code: ' + code + ', signal: ' + signal + ')'); - this.startWatcher(); // restart + this.errorCallback(`[FileWatcher] terminated unexpectedly (code: ${code}, signal: ${signal})`); + + if (this.restartCounter <= OutOfProcessWin32FolderWatcher.MAX_RESTARTS) { + this.errorCallback('[FileWatcher] is restarted again...'); + this.restartCounter++; + this.startWatcher(); // restart + } else { + this.errorCallback('[FileWatcher] Watcher failed to start after retrying for some time, giving up. Please report this as a bug report!'); + } } } From 8856422b774ed4cda7732d96e41de8504ceb3f4c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 25 Nov 2016 14:43:42 +0100 Subject: [PATCH 13/30] more escaping tests, #16056 --- .../editor/contrib/snippet/test/common/snippetParser.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts b/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts index 9bbe999213f..bc4d54f2474 100644 --- a/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts +++ b/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts @@ -110,7 +110,11 @@ suite('SnippetParser', () => { test('Parser, escaping', () => { assertEscape('$', '$'); + assertEscape('\\\\$', '\\$'); assertEscape('{', '{'); + assertEscape('\\}', '}'); + assertEscape('\\abc', '\\abc'); + assertEscape('foo${f:\\}}bar', 'foo}bar'); assertEscape('\\{', '{'); assertEscape('\\', '\\'); assertEscape('\\{{', '{{'); From 96b0a0030e17c2674dfd4c0b6891da4313e6d019 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 14:47:02 +0100 Subject: [PATCH 14/30] another fix for #15735 --- .../services/history/browser/history.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 276364b05cb..c6a7d762d7b 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -271,7 +271,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic private static MAX_HISTORY_ITEMS = 200; private static MAX_STACK_ITEMS = 20; private static MAX_RECENTLY_CLOSED_EDITORS = 20; - private static MERGE_CURSOR_CHANGES_THRESHOLD = 100; + private static MERGE_EVENT_CHANGES_THRESHOLD = 100; private stack: IStackEntry[]; private index: number; @@ -494,7 +494,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic }; } - this.add(editor.input, options); + this.add(editor.input, options, true /* from event */); } } @@ -504,34 +504,34 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic return; // do not push same editor input again } - this.add(editor.input); + this.add(editor.input, void 0, true /* from event */); } - public add(input: IEditorInput, options?: ITextEditorOptions): void { + public add(input: IEditorInput, options?: ITextEditorOptions, fromEvent?: boolean): void { if (!this.blockStackChanges) { - this.addToStack(input, options); + this.addToStack(input, options, fromEvent); } } - private addToStack(input: IEditorInput, options?: ITextEditorOptions): void { + private addToStack(input: IEditorInput, options?: ITextEditorOptions, fromEvent?: boolean): void { // Overwrite an entry in the stack if we have a matching input that comes // with editor options to indicate that this entry is more specific. Also // prevent entries that have the exact same options. Finally, Overwrite - // entries if we detect that the change came in very fast which indicates - // that it was not coming in from a user change but rather rapid programmatic - // changes. We just take the last of the changes to not cause too many - // entries on the stack. + // entries if it came from an event and we detect that the change came in + // very fast which indicates that it was not coming in from a user change + // but rather rapid programmatic changes. We just take the last of the changes + // to not cause too many entries on the stack. let replace = false; if (this.stack[this.index]) { const currentEntry = this.stack[this.index]; - if (this.matches(input, currentEntry.input) && (this.sameOptions(currentEntry.options, options) || Date.now() - currentEntry.timestamp < HistoryService.MERGE_CURSOR_CHANGES_THRESHOLD)) { + if (this.matches(input, currentEntry.input) && (this.sameOptions(currentEntry.options, options) || (fromEvent && Date.now() - currentEntry.timestamp < HistoryService.MERGE_EVENT_CHANGES_THRESHOLD))) { replace = true; } } const stackInput = this.preferResourceInput(input); - const entry = { input: stackInput, options, timestamp: Date.now() }; + const entry = { input: stackInput, options, timestamp: fromEvent ? Date.now() : void 0 }; // If we are not at the end of history, we remove anything after if (this.stack.length > this.index + 1) { From 9a6907075832335bfb18db64fc0a8faf65bfaac7 Mon Sep 17 00:00:00 2001 From: Dirk Baeumer Date: Fri, 25 Nov 2016 14:56:11 +0100 Subject: [PATCH 15/30] Merge in translations --- .../extensions/typescript/package.i18n.json | 2 +- .../src/vs/code/electron-main/menus.i18n.json | 1 + .../browser/accessibility.i18n.json | 2 +- .../editor/node/textMate/TMSyntax.i18n.json | 2 +- .../common/abstractExtensionService.i18n.json | 2 +- .../parts/editor/editorActions.i18n.json | 3 ++- .../parts/editor/editorStatus.i18n.json | 2 +- .../electron-browser/crashReporter.i18n.json | 3 ++- .../parts/debug/common/debugModel.i18n.json | 1 + .../emmet/node/emmet.contribution.i18n.json | 2 +- .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../parts/feedback/browser/feedback.i18n.json | 2 +- .../browser/files.contribution.i18n.json | 1 + .../parts/git/browser/gitActions.i18n.json | 3 +-- .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../parts/html/browser/webview.i18n.json | 2 +- .../task.contribution.i18n.json | 2 +- .../themes.contribution.i18n.json | 2 +- .../electron-browser/watermark.i18n.json | 17 ++++++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../electron-browser/themeService.i18n.json | 2 +- .../browser/extensionsActions.i18n.json | 14 +++++++++++- .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../config/commonEditorConfig.i18n.json | 2 +- .../node/debugConfigurationManager.i18n.json | 11 +++++----- .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../terminalInstance.i18n.json | 2 +- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../src/vs/code/electron-main/menus.i18n.json | 1 + .../config/commonEditorConfig.i18n.json | 2 +- .../parts/editor/editorActions.i18n.json | 4 +++- .../electron-browser/actions.i18n.json | 1 + .../electron-browser/crashReporter.i18n.json | 3 ++- .../main.contribution.i18n.json | 1 + .../parts/debug/common/debugModel.i18n.json | 1 + .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../browser/files.contribution.i18n.json | 1 + .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../terminal.contribution.i18n.json | 1 + .../electron-browser/watermark.i18n.json | 22 +++++++++++++++++++ .../browser/textFileService.i18n.json | 8 +++++++ .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../out/features/bufferSyncSupport.i18n.json | 2 +- .../config/commonEditorConfig.i18n.json | 2 +- ...guageConfigurationExtensionPoint.i18n.json | 2 +- .../editor/node/textMate/TMSnippets.i18n.json | 2 +- .../editor/node/textMate/TMSyntax.i18n.json | 2 +- .../node/extensionGalleryService.i18n.json | 2 +- .../parts/editor/editorActions.i18n.json | 11 +++++----- .../parts/editor/editorCommands.i18n.json | 2 +- .../browser/parts/panel/panelPart.i18n.json | 2 +- .../parts/sidebar/sidebarPart.i18n.json | 2 +- .../electron-browser/shell.i18n.json | 2 +- .../debug/browser/debugActions.i18n.json | 4 ++-- .../debug/electron-browser/repl.i18n.json | 2 +- .../parts/debug/node/debugAdapter.i18n.json | 2 +- .../node/debugConfigurationManager.i18n.json | 3 +-- .../browser/extensionEditor.i18n.json | 2 +- .../browser/extensionsActions.i18n.json | 14 +++++++++++- .../parts/files/browser/fileActions.i18n.json | 4 ++-- .../browser/files.contribution.i18n.json | 2 +- .../gitWorkbenchContributions.i18n.json | 2 +- .../git/browser/views/huge/hugeView.i18n.json | 2 +- .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../task.contribution.i18n.json | 8 +++---- .../terminal.contribution.i18n.json | 2 +- .../terminalActions.i18n.json | 6 ++--- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ .../electron-browser/themeService.i18n.json | 8 +++---- .../browser/extensionsActions.i18n.json | 12 ++++++++++ .../git/electron-browser/gitActions.i18n.json | 8 ++++++- .../electron-browser/watermark.i18n.json | 13 +++++++++++ .../browser/textFileService.i18n.json | 6 +++++ 89 files changed, 435 insertions(+), 77 deletions(-) create mode 100644 i18n/chs/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/chs/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/cht/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/cht/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/deu/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/deu/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/esn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/esn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/fra/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/fra/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/ita/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/ita/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/jpn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/jpn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/kor/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/kor/src/vs/workbench/services/textfile/browser/textFileService.i18n.json create mode 100644 i18n/rus/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json create mode 100644 i18n/rus/src/vs/workbench/services/textfile/browser/textFileService.i18n.json diff --git a/i18n/chs/extensions/typescript/package.i18n.json b/i18n/chs/extensions/typescript/package.i18n.json index 9c7f6fbf86a..7401aa502e0 100644 --- a/i18n/chs/extensions/typescript/package.i18n.json +++ b/i18n/chs/extensions/typescript/package.i18n.json @@ -27,7 +27,7 @@ "typescript.tsdk.desc": "指定包含要使用的 tsserver 和 lib*.d.ts 文件的文件夹路径。", "typescript.tsdk_version.desc": "指定 tsserver 的版本。仅在未使用 npm 安装 tsserver 时需要。", "typescript.tsserver.experimentalAutoBuild": "启用实验性自动生成。要求安装 1.9 dev 或 2.x tsserver 版本并在更改后重启 VS Code。", - "typescript.tsserver.trace": "启用跟踪发送到 TS 服务器的消息。", + "typescript.tsserver.trace": "对发送到 TS 服务器的消息启用跟踪。", "typescript.useCodeSnippetsOnMethodSuggest.dec": "完成函数的参数签名。", "typescript.validate.enable": "启用/禁用 TypeScript 验证。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/code/electron-main/menus.i18n.json b/i18n/chs/src/vs/code/electron-main/menus.i18n.json index d6b990704dc..fa00d992721 100644 --- a/i18n/chs/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/chs/src/vs/code/electron-main/menus.i18n.json @@ -97,6 +97,7 @@ "miToggleDebugConsole": "调试控制台(&&B)", "miToggleDevTools": "切换开发人员工具(&&T)", "miToggleEditorLayout": "切换编辑器组布局(&&L)", + "miToggleFocusMode": "切换焦点模式", "miToggleFullScreen": "切换全屏(&&F)", "miToggleIntegratedTerminal": "集成终端(&&I)", "miToggleMenuBar": "切换菜单栏(&&B)", diff --git a/i18n/chs/src/vs/editor/contrib/accessibility/browser/accessibility.i18n.json b/i18n/chs/src/vs/editor/contrib/accessibility/browser/accessibility.i18n.json index b3f2e279f8c..92ac742ae78 100644 --- a/i18n/chs/src/vs/editor/contrib/accessibility/browser/accessibility.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/accessibility/browser/accessibility.i18n.json @@ -9,7 +9,7 @@ "outroMsg": "可以通过按 Esc 消除此工具提示并返回到编辑器。", "status": "状态:", "tabFocusModeOffMsg": "在当前编辑器中按 Tab 将插入制表符。通过按 {0} 切换此行为。", - "tabFocusModeOffMsgNoKb": "在当前编辑器中按 Tab 会将焦点移动到下一个可聚焦的元素。当前无法通过键绑定触发命令 {0}。", + "tabFocusModeOffMsgNoKb": "在当前编辑器中按 Tab 会插入制表符。当前无法通过键绑定触发命令 {0}。", "tabFocusModeOnMsg": "在当前编辑器中按 Tab 会将焦点移动到下一个可聚焦的元素。通过按 {0} 切换此行为。", "tabFocusModeOnMsgNoKb": "在当前编辑器中按 Tab 会将焦点移动到下一个可聚焦的元素。当前无法通过键绑定触发命令 {0}。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json index b764ac8d5b4..19d9992239b 100644 --- a/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.embeddedLanguages": "\"contributes.{0}.embeddedLanguages\" 中值无效。必须为从作用域名称到语言的对象映射。给定值: {1}", + "invalid.embeddedLanguages": "\"contributes.{0}.embeddedLanguages\" 中的值无效。必须为从作用域名称到语言的对象映射。提供的值: {1}", "invalid.injectTo": "\"contributes.{0}.injectTo\" 中的值无效。必须为语言范围名称数组。提供的值: {1}", "invalid.language": "“contributes.{0}.language”中存在未知的语言。提供的值: {1}", "invalid.path.0": "“contributes.{0}.path”中应为字符串。提供的值: {1}", diff --git a/i18n/chs/src/vs/platform/extensions/common/abstractExtensionService.i18n.json b/i18n/chs/src/vs/platform/extensions/common/abstractExtensionService.i18n.json index 2baf210a49a..2441121c6e5 100644 --- a/i18n/chs/src/vs/platform/extensions/common/abstractExtensionService.i18n.json +++ b/i18n/chs/src/vs/platform/extensions/common/abstractExtensionService.i18n.json @@ -7,5 +7,5 @@ "activationError": "激活扩展“{0}”失败: {1}。", "failedDep1": "无法激活扩展”{1}“。原因: 无法激活依赖关系”{0}“。", "failedDep2": "无法激活扩展”{0}“。原因: 依赖关系多于 10 级(最可能是依赖关系循环)。", - "unknownDep": "无法激活扩展”{1}“。原因:未知依赖关系”{0}“。" + "unknownDep": "无法激活扩展”{1}“。原因: 未知依赖关系“{0}”。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index ed8df50629c..5c3b2ece7ba 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -34,9 +34,10 @@ "navigateNext": "前进", "navigatePrevious": "后退", "openNextEditor": "打开下一个编辑器", - "openNextEditorInGroup": "打开组中下一个最近使用的编辑器", + "openNextRecentlyUsedEditorInGroup": "打开组中下一个最近使用的编辑器", "openPreviousEditor": "打开上一个编辑器", "openPreviousEditorInGroup": "打开组中上一个最近使用的编辑器", + "openPreviousRecentlyUsedEditorInGroup": "打开组中上一个最近使用的编辑器", "openToSide": "打开到侧边", "reopenClosedEditor": "重新打开已关闭的编辑器", "showAllEditors": "显示所有编辑器", diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/editorStatus.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/editorStatus.i18n.json index bd0697137a4..176e56de2b1 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/editorStatus.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/editorStatus.i18n.json @@ -32,7 +32,7 @@ "pickEncodingForSave": "选择用于保存的文件编码", "pickEndOfLine": "选择行尾序列", "pickLanguage": "选择语言模式", - "pickLanguageToConfigure": "选择语言模式与“{0}”关联", + "pickLanguageToConfigure": "选择要与“{0}”关联的语言模式", "reopenWithEncoding": "通过编码重新打开", "saveWithEncoding": "通过编码保存", "selectEOL": "选择行尾序列", diff --git a/i18n/chs/src/vs/workbench/electron-browser/crashReporter.i18n.json b/i18n/chs/src/vs/workbench/electron-browser/crashReporter.i18n.json index 711aa6b9cbc..0f10026b79e 100644 --- a/i18n/chs/src/vs/workbench/electron-browser/crashReporter.i18n.json +++ b/i18n/chs/src/vs/workbench/electron-browser/crashReporter.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "telemetry.enableCrashReporting": "启用要发送给 Microsoft 的故障报表。\n\t// 此选项需重启才可生效。" + "telemetry.enableCrashReporting": "启用要发送给 Microsoft 的故障报表。\n\t// 此选项需重启才可生效。", + "telemetryConfigurationTitle": "遥测" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/debug/common/debugModel.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/common/debugModel.i18n.json index bba1f7a3bd1..478308920fd 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/common/debugModel.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/common/debugModel.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "notAvailable": "不可用", "snapshotObj": "仅显示了此对象的基元值。", "startDebugFirst": "请启动调试会话以评估", "unknownSource": "未知源", diff --git a/i18n/chs/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json index f8fa18905ae..11749818a23 100644 --- a/i18n/chs/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "emmetConfigurationTitle": "Emmet", - "emmetExclude": "其中 emmet 缩写不应展开的语言数组。", + "emmetExclude": "emmet 缩写不应在其中展开的语言数组。", "emmetPreferences": "用于修改 Emmet 的某些操作和解决程序的首选项。", "emmetSyntaxProfiles": "为指定的语法定义配置文件或使用带有特定规则的配置文件。", "triggerExpansionOnTab": "启用后,按 TAB 键时,将展开 Emmet 缩写。" diff --git a/i18n/chs/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/chs/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 351ce39dd77..dc4d9518bda 100644 --- a/i18n/chs/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "建议仅在工作区文件夹上可用。", + "ManageExtensionAction.uninstallingTooltip": "正在卸载", "OpenExtensionsFile.failed": "无法在 \".vscode\" 文件夹({0})内创建 \"extensions.json\" 文件。", "Uninstalling": "正在卸载", "builtin": "内置", "clearExtensionsInput": "清除扩展输入", "configureWorkspaceRecommendedExtensions": "配置建议的扩展(工作区)", "disableAction": "禁用", + "disableAll": "禁用所有已安装的扩展", + "disableAllWorkspace": "禁用此工作区的所有已安装的扩展", "disableAlwaysAction.label": "禁用", "disableForWorkspaceAction": "工作区", "disableForWorkspaceAction.label": "禁用(工作区)", "disableGloballyAction": "始终", "enableAction": "启用", + "enableAll": "禁用所有已安装的扩展", + "enableAllWorkspace": "启用此工作区的所有已安装的扩展", "enableAlwaysAction.label": "启用", "enableForWorkspaceAction": "工作区", "enableForWorkspaceAction.label": "启用(工作区)", @@ -23,7 +28,14 @@ "installAction": "安装", "installExtensions": "安装扩展", "installing": "正在安装", + "postDisableMessage": "重载此窗口以停用扩展“{0}”?", + "postDisableTooltip": "重载以停用", + "postEnableMessage": "重载此窗口以激活扩展“{0}”?", + "postEnableTooltip": "重载以激活", + "postUninstallMessage": "重载此窗口以停用未安装的扩展“{0}”?", "postUninstallTooltip": "重新加载以停用", + "postUpdateMessage": "重载此窗口以激活更新的扩展“{0}”?", + "postUpdateTooltip": "重载以更新", "reloadAction": "重新加载", "showDisabledExtensions": "显示已禁用的扩展", "showInstalledExtensions": "显示已安装扩展", diff --git a/i18n/chs/src/vs/workbench/parts/feedback/browser/feedback.i18n.json b/i18n/chs/src/vs/workbench/parts/feedback/browser/feedback.i18n.json index 1d98f0d2b1c..efc77e3f042 100644 --- a/i18n/chs/src/vs/workbench/parts/feedback/browser/feedback.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/feedback/browser/feedback.i18n.json @@ -14,7 +14,7 @@ "label.sendASmile": "通过 Tweet 向我们发送反馈。", "other ways to contact us": "联系我们的其他方式", "patchedVersion1": "安装已损坏。", - "patchedVersion2": "如果 提交了 bug,请指定此项。", + "patchedVersion2": "如果提交了 bug,请指定此项。", "request a missing feature": "请求缺失功能", "sendFeedback": "Tweet 反馈", "sentiment": "您的体验如何?", diff --git a/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 719e66d10a4..42fe30f12cc 100644 --- a/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -10,6 +10,7 @@ "autoSaveDelay": "控制延迟(以秒为单位),在该延迟后将自动保存更新后的文件。仅在 \"files.autoSave\" 设置为“{0}”时适用。", "binaryFileEditor": "二进制文件编辑器", "dynamicHeight": "控制打开的编辑器部分的高度是否应动态适应元素数量。", + "editorConfigurationTitle": "编辑器", "enableDragAndDrop": "控制资源管理器是否应该允许通过拖放移动文件和文件夹。", "encoding": "读取和编写文件时将使用的默认字符集编码。", "eol": "默认行尾字符。", diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 30c9e13a74e..d126321d5f6 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -23,7 +23,6 @@ "confirmUndoMessage": "是否确定要清理所有更改?", "dirtyTreeCheckout": "无法签出。请首先提交你的工作或进行分段。", "dirtyTreePull": "无法请求。请首先提交你的工作或进行分段。", - "do you want to continue": "是否确定要继续?", "init": "初始化", "irreversible": "此操作不可逆!", "never again": "好,永不再显示", @@ -37,7 +36,7 @@ "refresh": "刷新", "stageAllChanges": "全部暂存", "stageChanges": "暂存", - "sync is unpredictable": "此操作会在“{0}”来回推送和拉取提交。", + "sync is unpredictable": "此操作从“{0}”推送和拉取提交。", "undoAllChanges": "全部清理", "undoChanges": "清理", "undoLastCommit": "撤消上次提交", diff --git a/i18n/chs/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/chs/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..0e15e07a452 100644 --- a/i18n/chs/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "目标存储库已存在,请选择要克隆到的另一个目录。", + "cloning": "正在克隆存储库“{0}”...", + "directory": "目标克隆目录", + "repo": "请提供一个 git 存储库 URL。", + "url": "存储库 URL" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/html/browser/webview.i18n.json b/i18n/chs/src/vs/workbench/parts/html/browser/webview.i18n.json index faf0e45a371..ad5eb63d630 100644 --- a/i18n/chs/src/vs/workbench/parts/html/browser/webview.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/html/browser/webview.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "devtools.webview": "开发人员:Webview 工具" + "devtools.webview": "开发人员: Webview 工具" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json index f8cfe4053dc..2219834cd18 100644 --- a/i18n/chs/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json @@ -74,7 +74,7 @@ "TaskSystem.invalidTaskJson": "错误: tasks.json 文件的内容具有语法错误。请先更正错误然后再执行任务。\n", "TaskSystem.noBuildType": "未配置任何有效的任务运行程序。支持的任务运行程序是“服务”和“程序”。", "TaskSystem.noConfiguration": "未配置任何任务运行程序。", - "TaskSystem.noProcess": "启动的任务不再存在。如果任务衍生的后台进程退出 VS Code,则可能会导致出现孤立的进程。若要避免此情况,请使用等待标记启动最后一个后台进程。", + "TaskSystem.noProcess": "启动的任务不再存在。如果任务已衍生出后台进程,则退出 VS Code 可能会导致出现孤立的进程。若要避免此情况,请使用等待标记启动最后一个后台进程。", "TaskSystem.runningTask": "存在运行中的任务。要终止它吗?", "TaskSystem.terminateTask": "终止任务(&&T)", "TaskSystem.unknownError": "运行任务时发生了错误。请参见任务日志了解详细信息。", diff --git a/i18n/chs/src/vs/workbench/parts/themes/electron-browser/themes.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/themes/electron-browser/themes.contribution.i18n.json index 9daae845947..608617dc271 100644 --- a/i18n/chs/src/vs/workbench/parts/themes/electron-browser/themes.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/themes/electron-browser/themes.contribution.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "findMore": "在应用商店中查找更多信息...", + "findMore": "在应用商店中查找更多...", "noIconThemeDesc": "禁用文件图标", "noIconThemeLabel": "无", "preferences": "首选项", diff --git a/i18n/chs/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/chs/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..4f0967c14d5 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.findInFiles": "在文件中查找", + "watermark.openFile": "打开文件", + "watermark.openFileFolder": "打开文件或文件夹", + "watermark.openFolder": "打开文件夹", + "watermark.openRecent": "打开最近的文件", + "watermark.quickOpen": "转到文件", + "watermark.showCommands": "显示所有命令", + "watermark.startDebugging": "开始调试", + "watermark.toggleTerminal": "切换终端", + "watermark.unboundCommand": "未绑定" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/chs/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/chs/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json b/i18n/chs/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json index 2d23cdfa302..8aebb264e1b 100644 --- a/i18n/chs/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json @@ -15,7 +15,7 @@ "reqpath": "“contributes.{0}.path”中应为字符串。提供的值: {1}", "schema.file": "默认文件图标,针对不与任何扩展名、文件名或语言 ID 匹配的所有文件显示。", "schema.fileExtension": "关联的图标定义的 ID。", - "schema.fileExtensions": "将文件扩展名关联到图标。对象键是文件扩展名。扩展名是文件名的最后一个点(不包括句点)的最后一部分。扩展名不区分大小写,以便进行比较。", + "schema.fileExtensions": "将文件扩展名关联到图标。对象键是文件扩展名。扩展名是文件名的最后一个部分,位于最后一个点之后(不包括该点)。比较扩展名时不区分大小写。", "schema.fileName": "关联的图标定义的 ID。", "schema.fileNames": "将文件名关联到图标。对象键是完整的文件名,但不包括任何路径段。文件名可以包括句点和可能的文件扩展名。不允许任何模式或通配符。文件名匹配不区分大小写。", "schema.folder": "折叠文件夹的文件夹图标,如果未设置 folderExpanded,也指展开文件夹的文件夹图标。", diff --git a/i18n/cht/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/cht/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 59c8a90c716..3cf697a6c79 100644 --- a/i18n/cht/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "只有在工作區資料夾中才能使用建議。", + "ManageExtensionAction.uninstallingTooltip": "正在解除安裝", "OpenExtensionsFile.failed": "無法在 '.vscode' 資料夾 ({0}) 中建立 'extensions.json' 檔案。", "Uninstalling": "正在解除安裝", "builtin": "內建", "clearExtensionsInput": "清除擴充功能輸入", "configureWorkspaceRecommendedExtensions": "設定建議的延伸模組 (工作區)", "disableAction": "停用", + "disableAll": "停用所有已安裝的延伸模組", + "disableAllWorkspace": "停用此工作區的所有已安裝延伸模組", "disableAlwaysAction.label": "停用", "disableForWorkspaceAction": "工作區", "disableForWorkspaceAction.label": "停用 (工作區)", "disableGloballyAction": "永遠", "enableAction": "啟用", + "enableAll": "啟用所有已安裝的延伸模組", + "enableAllWorkspace": "啟用此工作區的所有已安裝延伸模組", "enableAlwaysAction.label": "啟用", "enableForWorkspaceAction": "工作區", "enableForWorkspaceAction.label": "啟用 (工作區)", @@ -23,7 +28,14 @@ "installAction": "安裝", "installExtensions": "安裝擴充功能", "installing": "正在安裝", + "postDisableMessage": "要重新載入此視窗以停用延伸模組 '{0}' 嗎?", + "postDisableTooltip": "重新載入以停用", + "postEnableMessage": "要重新載入此視窗以啟動延伸模組 '{0}' 嗎?", + "postEnableTooltip": "重新載入以啟動", + "postUninstallMessage": "要重新載入此視窗以停用已解除安裝的延伸模組 '{0}' 嗎?", "postUninstallTooltip": "重新載入以停用", + "postUpdateMessage": "要重新載入此視窗以啟動已更新的延伸模組 '{0}' 嗎?", + "postUpdateTooltip": "重新載入以更新", "reloadAction": "重新載入", "showDisabledExtensions": "顯示停用的延伸模組", "showInstalledExtensions": "顯示安裝的擴充功能", @@ -34,5 +46,5 @@ "toggleExtensionsViewlet": "顯示擴充功能", "uninstallAction": "解除安裝", "updateAction": "更新", - "updateAll": "更新所有擴充功能" + "updateAll": "更新所有延伸模組" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/cht/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..0092fec5b53 100644 --- a/i18n/cht/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "目的地存放庫已存在,請選擇另一個目錄作為複製目標。", + "cloning": "正在複製存放庫 '{0}'...", + "directory": "目的地複製目錄", + "repo": "請提供 GIT 存放庫 URL。", + "url": "存放庫 URL" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/cht/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..45d414d6918 --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "開啟檔案", + "watermark.openFileFolder": "開啟檔案或資料夾", + "watermark.quickOpen": "前往檔案", + "watermark.showCommands": "顯示所有命令", + "watermark.toggleTerminal": "切換終端機", + "watermark.unboundCommand": "未繫結" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/cht/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/cht/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/deu/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 02bf6767cb0..dea71c58ef9 100644 --- a/i18n/deu/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "Empfehlungen sind nur für einen Arbeitsbereichsordner verfügbar.", + "ManageExtensionAction.uninstallingTooltip": "Wird deinstalliert", "OpenExtensionsFile.failed": "Die Datei \"extensions.json\" kann nicht im Ordner \".vscode\" erstellt werden ({0}).", "Uninstalling": "Wird deinstalliert", "builtin": "Integriert", "clearExtensionsInput": "Extensioneingabe löschen", "configureWorkspaceRecommendedExtensions": "Empfohlene Erweiterungen konfigurieren (Arbeitsbereich)", "disableAction": "Deaktivieren", + "disableAll": "Alle installierten Erweiterungen löschen", + "disableAllWorkspace": "Alle installierten Erweiterungen für diesen Arbeitsbereich deaktivieren", "disableAlwaysAction.label": "Deaktivieren", "disableForWorkspaceAction": "Arbeitsbereich", "disableForWorkspaceAction.label": "Deaktivieren (Arbeitsbereich)", "disableGloballyAction": "Immer", "enableAction": "Aktivieren", + "enableAll": "Alle installierten Erweiterungen aktivieren", + "enableAllWorkspace": "Alle installierten Erweiterungen für diesen Arbeitsbereich aktivieren", "enableAlwaysAction.label": "Aktivieren", "enableForWorkspaceAction": "Arbeitsbereich", "enableForWorkspaceAction.label": "Aktivieren (Arbeitsbereich)", @@ -23,7 +28,14 @@ "installAction": "Installieren", "installExtensions": "Extensions installieren", "installing": "Wird installiert.", + "postDisableMessage": "Dieses Fenster erneut laden, um die Erweiterung \"{0}\" zu deaktivieren?", + "postDisableTooltip": "Zum Deaktivieren erneut laden", + "postEnableMessage": "Dieses Fenster erneut laden, um die Erweiterung \"{0}\" zu aktivieren?", + "postEnableTooltip": "Zum Aktivieren erneut laden", + "postUninstallMessage": "Dieses Fenster erneut laden, um die deinstallierte Erweiterung \"{0}\" zu deaktivieren?", "postUninstallTooltip": "Zum Deaktivieren erneut laden", + "postUpdateMessage": "Dieses Fenster erneut laden, um die aktualisierte Erweiterung \"{0}\" zu aktivieren?", + "postUpdateTooltip": "Zum Aktualisieren erneut laden", "reloadAction": "Erneut laden", "showDisabledExtensions": "Deaktivierte Erweiterungen anzeigen", "showInstalledExtensions": "Installierte Extensions anzeigen", diff --git a/i18n/deu/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/deu/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..63d7bcb67a5 100644 --- a/i18n/deu/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "Das Zielverzeichnis ist bereits vorhanden, wählen Sie ein anderes Verzeichnis für den Klonvorgang aus.", + "cloning": "Das Repository \"{0}\" wird geklont...", + "directory": "Zielklonverzeichnis", + "repo": "Geben Sie eine URL für das Git-Repository an.", + "url": "Repository-URL" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/deu/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..99e08d6f3a9 --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "Datei öffnen", + "watermark.openFileFolder": "Datei oder Ordner öffnen", + "watermark.quickOpen": "Zu Datei wechseln", + "watermark.showCommands": "Alle Befehle anzeigen", + "watermark.toggleTerminal": "Terminal umschalten", + "watermark.unboundCommand": "Ungebunden" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/deu/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/deu/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json index 57ec19330e5..bddc1fee42e 100644 --- a/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -21,7 +21,7 @@ "glyphMargin": "Controla si el editor debe representar el margen de glifo vertical. El margen de glifo se usa, principalmente, para depuración.", "hideCursorInOverviewRuler": "Controla si el cursor debe ocultarse en la regla de visión general.", "ignoreTrimWhitespace": "Controla si el editor de diferencias muestra los cambios de espacio inicial o espacio final como diferencias.", - "insertSpaces": "Insertar espacios al presionar TAB. Este valor se invalida en función del contenido del archivo cuando `editor.detectIndentation` está activado.", + "insertSpaces": "Insertar espacios al presionar TAB. Este valor se invalida en función del contenido del archivo cuando \"editor.detectIndentation\" está activado.", "insertSpaces.errorMessage": "Se esperaba \"boolean\". Tenga en cuenta que el ajuste \"editor.detectIndentation\" ha reemplazado al valor \"auto\".", "lineHeight": "Controla la altura de línea. Utilice 0 para calcular el valor de lineHeight a partir de fontSize.", "lineNumbers": "Controla la presentación de los números de línea. Los valores posibles son \"on\", \"off\" y \"relative\". \"relative\" muestra el número de líneas desde la posición actual del cursor.", diff --git a/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 94b4b5fbd0a..7007c06a048 100644 --- a/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,7 +10,6 @@ "app.launch.json.title": "Iniciar", "app.launch.json.version": "Versión de este formato de archivo.", "debugNoType": "El valor \"type\" del adaptador de depuración no se puede omitir y debe ser de tipo \"string\".", - "duplicateDebuggerType": "El tipo de depuración '{0}' ya está registrado y tiene el atributo '{1}', se ignora el atributo '{1}'.", "selectDebug": "Seleccionar entorno", "vscode.extension.contributes.breakpoints": "Aporta puntos de interrupción.", "vscode.extension.contributes.breakpoints.language": "Permite puntos de interrupción para este lenguaje.", @@ -22,14 +21,14 @@ "vscode.extension.contributes.debuggers.initialConfigurations": "Configuraciones para generar el archivo \"launch.json\" inicial.", "vscode.extension.contributes.debuggers.label": "Nombre para mostrar del adaptador de depuración.", "vscode.extension.contributes.debuggers.linux": "Configuración específica de Linux.", - "vscode.extension.contributes.debuggers.linux.runtime": "Runtime que se usa para Linux.", + "vscode.extension.contributes.debuggers.linux.runtime": "Entorno de ejecución que se usa para Linux.", "vscode.extension.contributes.debuggers.osx": "Configuración específica de OS X.", - "vscode.extension.contributes.debuggers.osx.runtime": "Runtime que se usa para OSX.", + "vscode.extension.contributes.debuggers.osx.runtime": "Entorno de ejecución que se usa para OSX.", "vscode.extension.contributes.debuggers.program": "Ruta de acceso al programa de adaptadores de depuración, que puede ser absoluta o relativa respecto a la carpeta de extensión.", - "vscode.extension.contributes.debuggers.runtime": "Runtime opcional en caso de que el atributo del programa no sea un ejecutable pero requiera un runtime.", - "vscode.extension.contributes.debuggers.runtimeArgs": "Argumentos de runtime opcionales.", + "vscode.extension.contributes.debuggers.runtime": "Entorno de ejecución opcional en caso de que el atributo del programa no sea un ejecutable pero requiera un entorno de ejecución.", + "vscode.extension.contributes.debuggers.runtimeArgs": "Argumentos de entorno de ejecución opcionales.", "vscode.extension.contributes.debuggers.type": "Identificador único de este adaptador de depuración.", "vscode.extension.contributes.debuggers.variables": "Asignación de variables interactivas (por ejemplo, ${action.pickProcess}) en `launch.json` a un comando.", "vscode.extension.contributes.debuggers.windows": "Configuración específica de Windows.", - "vscode.extension.contributes.debuggers.windows.runtime": "Runtime que se usa para Windows." + "vscode.extension.contributes.debuggers.windows.runtime": "Entorno de ejecución que se usa para Windows." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/esn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 26399849b40..982710ea116 100644 --- a/i18n/esn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "Las recomendaciones solo están disponibles en una carpeta de área de trabajo.", + "ManageExtensionAction.uninstallingTooltip": "Desinstalando", "OpenExtensionsFile.failed": "No se puede crear el archivo \"extensions.json\" dentro de la carpeta \".vscode\" ({0}).", "Uninstalling": "Desinstalando", "builtin": "Integrada", "clearExtensionsInput": "Borrar entrada de extensiones", "configureWorkspaceRecommendedExtensions": "Configurar extensiones recomendadas (área de trabajo)", "disableAction": "Deshabilitar", + "disableAll": "Deshabilitar todas las extensiones instaladas", + "disableAllWorkspace": "Deshabilitar todas las extensiones instaladas para esta área de trabajo", "disableAlwaysAction.label": "Deshabilitar", "disableForWorkspaceAction": "Área de trabajo", "disableForWorkspaceAction.label": "Deshabilitar (área de trabajo)", "disableGloballyAction": "Siempre", "enableAction": "Habilitar", + "enableAll": "Habilitar todas las extensiones instaladas", + "enableAllWorkspace": "Habilitar todas las extensiones instaladas para esta área de trabajo", "enableAlwaysAction.label": "Habilitar", "enableForWorkspaceAction": "Área de trabajo", "enableForWorkspaceAction.label": "Habilitar (área de trabajo)", @@ -23,7 +28,14 @@ "installAction": "Instalar", "installExtensions": "Instalar extensiones", "installing": "Instalando", + "postDisableMessage": "¿Quiere recargar esta ventana para desactivar la extensión '{0}'?", + "postDisableTooltip": "Recargar para desactivar", + "postEnableMessage": "¿Quiere recargar esta ventana para activar la extensión '{0}'?", + "postEnableTooltip": "Recargar para activar", + "postUninstallMessage": "¿Quiere recargar esta ventana para desactivar la extensión desinstalada '{0}'?", "postUninstallTooltip": "Recargar para desactivar", + "postUpdateMessage": "¿Quiere recargar esta ventana para activar la extensión actualizada '{0}'?", + "postUpdateTooltip": "Recargar para actualizar", "reloadAction": "Recargar", "showDisabledExtensions": "Mostrar extensiones deshabilitadas", "showInstalledExtensions": "Mostrar extensiones instaladas", diff --git a/i18n/esn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/esn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..477128db84d 100644 --- a/i18n/esn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "El repositorio de destino ya existe. Elija otro directorio para la clonación.", + "cloning": "Clonando el repositorio '{0}'...", + "directory": "Directorio de destino de la clonación", + "repo": "Proporcione la dirección URL de un repositorio GIT.", + "url": "URL de repositorio" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.i18n.json b/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.i18n.json index f22ca7838fe..8c35b554e81 100644 --- a/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.i18n.json @@ -6,5 +6,5 @@ { "terminal.integrated.copySelection.noSelection": "No se puede copiar la selección del terminal cuando el terminal no tiene el foco", "terminal.integrated.exitedWithCode": "El proceso del terminal finalizó con el código de salida: {0}", - "terminal.integrated.launchFailed": "No se pudo iniciar el comando de proceso terminal \"{0}{1}\" (código de salida: 2})" + "terminal.integrated.launchFailed": "No se pudo iniciar el comando de proceso terminal \"{0}{1}\" (código de salida: {2})" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/esn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..1a815995394 --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "Abrir archivo", + "watermark.openFileFolder": "Abrir archivo o carpeta", + "watermark.quickOpen": "Ir al archivo", + "watermark.showCommands": "Mostrar todos los comandos", + "watermark.toggleTerminal": "Alternar terminal", + "watermark.unboundCommand": "sin enlazar" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/esn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/esn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/fra/src/vs/code/electron-main/menus.i18n.json b/i18n/fra/src/vs/code/electron-main/menus.i18n.json index d7dcd9cc719..0b5c0cbe506 100644 --- a/i18n/fra/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/fra/src/vs/code/electron-main/menus.i18n.json @@ -97,6 +97,7 @@ "miToggleDebugConsole": "Console de dé&&bogage", "miToggleDevTools": "Activer/désactiver les ou&&tils de développement", "miToggleEditorLayout": "Activer/désactiver la &&disposition du groupe d'éditeurs", + "miToggleFocusMode": "Basculer le mode Focus", "miToggleFullScreen": "Plei&&n écran", "miToggleIntegratedTerminal": "&&Terminal intégré", "miToggleMenuBar": "Activer/désactiver la &&barre de menus", diff --git a/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json index faeae842df7..95cc1821748 100644 --- a/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -33,7 +33,7 @@ "quickSuggestionsDelay": "Contrôle le délai en ms au bout duquel les suggestions rapides s'affichent", "renderControlCharacters": "Contrôle si l'éditeur doit afficher les caractères de contrôle", "renderIndentGuides": "Contrôle si l'éditeur doit afficher les repères de mise en retrait", - "renderLineHighlight": "Contrôle si l'éditeur doit afficher la surbrillance de la ligne active", + "renderLineHighlight": "Contrôle la façon dont l'éditeur doit afficher la surbrillance de la ligne active. Les différentes possibilités sont 'none', 'gutter', 'line' et 'all'.", "renderWhitespace": "Contrôle la façon dont l'éditeur affiche les espaces blancs. Il existe trois options possibles : 'none', 'boundary' et 'all'. L'option 'boundary' n'affiche pas les espaces uniques qui séparent les mots.", "roundedSelection": "Contrôle si les sélections ont des angles arrondis", "rulers": "Colonnes où afficher les règles verticales", diff --git a/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index f47e4814f7d..f51add069c2 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -33,10 +33,12 @@ "navigateEditorHistoryByInput": "Ouvrir l'éditeur précédent dans l'historique", "navigateNext": "Suivant", "navigatePrevious": "Précédent", + "nextEditorInGroup": "Ouvrir l'éditeur suivant du groupe", "openNextEditor": "Ouvrir l'éditeur suivant", - "openNextEditorInGroup": "Ouvrir l'éditeur suivant du groupe", + "openNextRecentlyUsedEditorInGroup": "Ouvrir l'éditeur suivant du groupe", "openPreviousEditor": "Ouvrir l'éditeur précédent", "openPreviousEditorInGroup": "Ouvrir l'éditeur précédent du groupe", + "openPreviousRecentlyUsedEditorInGroup": "Ouvrir l'éditeur précédent du groupe", "openToSide": "Ouvrir sur le côté", "reopenClosedEditor": "Rouvrir l'éditeur fermé", "showAllEditors": "Afficher tous les éditeurs", diff --git a/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json index a238791d193..209d6bb99a9 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json @@ -13,6 +13,7 @@ "diffLeftRightLabel": "{0} - {1}", "files": "fichiers", "folders": "dossiers", + "keybindingsReference": "Référence des raccourcis clavier", "newWindow": "Nouvelle fenêtre", "noFolderOpened": "Il n'existe actuellement aucun dossier ouvert à fermer dans cette instance.", "openRecent": "Ouvrir les éléments récents", diff --git a/i18n/fra/src/vs/workbench/electron-browser/crashReporter.i18n.json b/i18n/fra/src/vs/workbench/electron-browser/crashReporter.i18n.json index 51b4e11a971..674273e80f7 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/crashReporter.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/crashReporter.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "telemetry.enableCrashReporting": "Activez l'envoi de rapports d'incidents à Microsoft.\n\t// Cette option nécessite un redémarrage pour être prise en compte." + "telemetry.enableCrashReporting": "Activez l'envoi de rapports d'incidents à Microsoft.\nCette option nécessite un redémarrage pour être prise en compte.", + "telemetryConfigurationTitle": "Télémétrie" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json index 642d4fc73fb..9fdcb3e709b 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -10,6 +10,7 @@ "enablePreview": "Contrôle si les éditeurs ouverts s'affichent en mode aperçu. Les éditeurs en mode aperçu sont réutilisés jusqu'à ce qu'ils soient conservés (par exemple, après un double-clic ou une modification).", "enablePreviewFromQuickOpen": "Contrôle si les éditeurs de Quick Open s'affichent en mode aperçu. Les éditeurs en mode aperçu sont réutilisés jusqu'à ce qu'ils soient conservés (par exemple, après un double-clic ou une modification).", "file": "Fichier", + "fullScreenFocusMode": "Contrôle si le mode Focus doit automatiquement passer le banc d'essai en mode plein écran.", "help": "Aide", "openDefaultSettings": "Contrôle si l'ouverture des paramètres entraîne également l'ouverture d'un éditeur qui affiche tous les paramètres par défaut.", "openFilesInNewWindow": "Après activation, les fichiers s'ouvrent dans une nouvelle fenêtre au lieu de réutiliser une instance existante.", diff --git a/i18n/fra/src/vs/workbench/parts/debug/common/debugModel.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/common/debugModel.i18n.json index 4638cbf9a3d..3240efcf8d8 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/common/debugModel.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/common/debugModel.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "notAvailable": "non disponible", "snapshotObj": "Seules les valeurs primitives sont affichées pour cet objet.", "startDebugFirst": "Démarrez une session de débogage pour évaluation", "unknownSource": "Source inconnue", diff --git a/i18n/fra/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/fra/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 16dd6671984..eac35739308 100644 --- a/i18n/fra/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "Les recommandations ne sont disponibles que pour un dossier d'espace de travail.", + "ManageExtensionAction.uninstallingTooltip": "Désinstallation", "OpenExtensionsFile.failed": "Impossible de créer le fichier 'extensions.json' dans le dossier '.vscode' ({0}).", "Uninstalling": "Désinstallation en cours", "builtin": "Intégrée", "clearExtensionsInput": "Effacer l'entrée des extensions", "configureWorkspaceRecommendedExtensions": "Configurer les extensions recommandées (espace de travail)", "disableAction": "Désactiver", + "disableAll": "Désactiver toutes les extensions installées", + "disableAllWorkspace": "Désactiver toutes les extensions installées pour cet espace de travail", "disableAlwaysAction.label": "Désactiver", "disableForWorkspaceAction": "Espace de travail", "disableForWorkspaceAction.label": "Désactiver (espace de travail)", "disableGloballyAction": "Toujours", "enableAction": "Activer", + "enableAll": "Activer toutes les extensions installées", + "enableAllWorkspace": "Activer toutes les extensions installées pour cet espace de travail", "enableAlwaysAction.label": "Activer", "enableForWorkspaceAction": "Espace de travail", "enableForWorkspaceAction.label": "Activer (espace de travail)", @@ -23,7 +28,14 @@ "installAction": "Installer", "installExtensions": "Installer les extensions", "installing": "Installation", + "postDisableMessage": "Recharger cette fenêtre pour désactiver l'extension '{0}' ?", + "postDisableTooltip": "Recharger pour désactiver", + "postEnableMessage": "Recharger cette fenêtre pour activer l'extension '{0}' ?", + "postEnableTooltip": "Recharger pour activer", + "postUninstallMessage": "Recharger cette fenêtre pour désactiver l'extension désinstallée '{0}' ?", "postUninstallTooltip": "Recharger pour désactiver", + "postUpdateMessage": "Recharger cette fenêtre pour activer l'extension mise à jour '{0}' ?", + "postUpdateTooltip": "Recharger pour mettre à jour", "reloadAction": "Recharger", "showDisabledExtensions": "Afficher les extensions désactivées", "showInstalledExtensions": "Afficher les extensions installées", diff --git a/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index c31d2342803..4d489bfbf8d 100644 --- a/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -10,6 +10,7 @@ "autoSaveDelay": "Contrôle le délai en ms au bout duquel un fichier à l'intégrité compromise est enregistré automatiquement. S'applique uniquement quand \"files.autoSave\" a la valeur \"{0}\"", "binaryFileEditor": "Éditeur de fichier binaire", "dynamicHeight": "Contrôle si la hauteur de la section des éditeurs ouverts doit s'adapter dynamiquement ou non au nombre d'éléments.", + "editorConfigurationTitle": "Éditeur", "enableDragAndDrop": "Contrôle si l'explorateur doit autoriser le déplacement de fichiers et de dossiers par glisser-déplacer.", "encoding": "Encodage du jeu de caractères par défaut à utiliser durant la lecture et l'écriture des fichiers.", "eol": "Caractère de fin de ligne par défaut.", diff --git a/i18n/fra/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/fra/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..60c603e6b71 100644 --- a/i18n/fra/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "Le dépôt de destination existe déjà. Choisissez un autre répertoire dans lequel enregistrer le clone.", + "cloning": "Clonage du dépôt '{0}'...", + "directory": "Répertoire du clone de destination", + "repo": "Indiquez l'URL d'un dépôt GIT.", + "url": "URL du dépôt" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index a75f6f332e2..cbac107053f 100644 --- a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -11,6 +11,7 @@ "terminal.integrated.fontLigatures": "Contrôle si les ligatures de police sont activées sur le terminal.", "terminal.integrated.fontSize": "Contrôle la taille de police en pixels du terminal. La valeur par défaut est la valeur associée à editor.fontSize.", "terminal.integrated.lineHeight": "Contrôle la hauteur de ligne du terminal. La multiplication de ce nombre par la taille de police du terminal permet d'obtenir la hauteur de ligne réelle en pixels.", + "terminal.integrated.scrollback": "Contrôle la quantité maximale de lignes que le terminal conserve dans sa mémoire tampon.", "terminal.integrated.setLocaleVariables": "Contrôle si les variables locales sont définies au démarrage du terminal. La valeur par défaut est true sur OS X, false sur les autres plateformes.", "terminal.integrated.shell.linux": "Chemin de l'interpréteur de commandes utilisé par le terminal sur Linux.", "terminal.integrated.shell.osx": "Chemin de l'interpréteur de commandes utilisé par le terminal sur OS X.", diff --git a/i18n/fra/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/fra/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..07933b1a86a --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.findInFiles": "Chercher dans les fichiers", + "watermark.keybindingsReference": "Référence de clavier", + "watermark.newUntitledFile": "Nouveau fichier sans titre", + "watermark.openFile": "Ouvrir le fichier", + "watermark.openFileFolder": "Ouvrir un fichier ou un dossier", + "watermark.openFolder": "Ouvrir le dossier", + "watermark.openGlobalKeybindings": "Raccourcis clavier", + "watermark.openRecent": "Ouvrir les éléments récents", + "watermark.quickOpen": "Accéder au fichier", + "watermark.selectKeymap": "Modifier le mappage de clés", + "watermark.selectTheme": "Modifier le thème de couleur", + "watermark.showCommands": "Afficher toutes les commandes", + "watermark.startDebugging": "Démarrer le débogage", + "watermark.toggleTerminal": "Activer/désactiver le terminal", + "watermark.unboundCommand": "indépendant" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/fra/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..53fb4332f21 --- /dev/null +++ b/i18n/fra/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "files.backup.failSave": "Les fichiers n'ont pas pu être sauvegardés (Erreur : {0}), essayez d'enregistrer vos fichiers pour quitter." +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/ita/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index c3fb4c18871..6c187197f28 100644 --- a/i18n/ita/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "Gli elementi consigliati sono disponibili solo per una cartella dell'area di lavoro.", + "ManageExtensionAction.uninstallingTooltip": "Disinstallazione", "OpenExtensionsFile.failed": "Non è possibile creare il file 'extensions.json' all'interno della cartella '.vscode' ({0}).", "Uninstalling": "Disinstallazione", "builtin": "Predefinita", "clearExtensionsInput": "Cancella input estensioni", "configureWorkspaceRecommendedExtensions": "Configura estensioni consigliate (area di lavoro)", "disableAction": "Disabilita", + "disableAll": "Disabilita tutte le estensioni installate", + "disableAllWorkspace": "Disabilita tutte le estensioni installate per questa area di lavoro", "disableAlwaysAction.label": "Disabilita", "disableForWorkspaceAction": "Area di lavoro", "disableForWorkspaceAction.label": "Disabilita (area di lavoro)", "disableGloballyAction": "Sempre", "enableAction": "Abilita", + "enableAll": "Abilita tutte le estensioni installate", + "enableAllWorkspace": "Abilita tutte le estensioni installate per questa area di lavoro", "enableAlwaysAction.label": "Abilita", "enableForWorkspaceAction": "Area di lavoro", "enableForWorkspaceAction.label": "Abilita (area di lavoro)", @@ -23,7 +28,14 @@ "installAction": "Installa", "installExtensions": "Installa estensioni", "installing": "Installazione", + "postDisableMessage": "Ricaricare questa finestra per disattivare l'estensione '{0}'?", + "postDisableTooltip": "Ricaricare per disattivare", + "postEnableMessage": "Ricaricare questa finestra per attivare l'estensione '{0}'?", + "postEnableTooltip": "Ricaricare per attivare", + "postUninstallMessage": "Ricaricare questa finestra per disattivare l'estensione disinstallata '{0}'?", "postUninstallTooltip": "Ricaricare per disattivare", + "postUpdateMessage": "Ricaricare questa finestra per attivare l'estensione aggiornata '{0}'?", + "postUpdateTooltip": "Ricaricare per aggiornare", "reloadAction": "Ricarica", "showDisabledExtensions": "Mostra estensioni disabilitate", "showInstalledExtensions": "Mostra estensioni installate", diff --git a/i18n/ita/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/ita/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..31363111d65 100644 --- a/i18n/ita/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "Il repository di destinazione esiste già. Selezionare un'altra directory in cui eseguire la clonazione.", + "cloning": "Clonazione del repository '{0}'...", + "directory": "Directory di clonazione di destinazione", + "repo": "Specificare un URL per il repository GIT.", + "url": "URL del repository" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/ita/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..bee76453c28 --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "Apri file", + "watermark.openFileFolder": "Apri file o cartella", + "watermark.quickOpen": "Vai al file", + "watermark.showCommands": "Mostra tutti i comandi", + "watermark.toggleTerminal": "Attiva/Disattiva terminale", + "watermark.unboundCommand": "non associato" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/ita/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/ita/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 3e01d45afc4..031ae3e2a22 100644 --- a/i18n/jpn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "推奨事項はワークスペース フォルダーでのみ利用可能です。", + "ManageExtensionAction.uninstallingTooltip": "アンインストールしています", "OpenExtensionsFile.failed": "'.vscode' ファルダー ({0}) 内に 'extensions.json' ファイルを作成できません。", "Uninstalling": "アンインストールしています", "builtin": "ビルトイン", "clearExtensionsInput": "拡張機能の入力のクリア", "configureWorkspaceRecommendedExtensions": "お勧めの拡張機能の構成 (ワークスペース)", "disableAction": "無効にする", + "disableAll": "インストール済みのすべての拡張機能を無効にする", + "disableAllWorkspace": "このワークスペースのインストール済みの拡張機能をすべて無効にする", "disableAlwaysAction.label": "無効にする", "disableForWorkspaceAction": "ワークスペース", "disableForWorkspaceAction.label": "無効にする (ワークスペース)", "disableGloballyAction": "常に行う", "enableAction": "有効", + "enableAll": "インストール済みの拡張機能をすべて有効にする", + "enableAllWorkspace": "このワークスペースのインストール済みの拡張機能をすべて有効にする", "enableAlwaysAction.label": "有効にする", "enableForWorkspaceAction": "ワークスペース", "enableForWorkspaceAction.label": "有効にする (ワークスペース)", @@ -23,7 +28,14 @@ "installAction": "インストール", "installExtensions": "拡張機能のインストール", "installing": "インストールしています", + "postDisableMessage": "このウィンドウを再度読み込んで、拡張機能 '{0}' を非アクティブ化しますか?", + "postDisableTooltip": "読み込んで非アクティブ化する", + "postEnableMessage": "このウィンドウを再度読み込んで、拡張機能 '{0}' をアクティブ化しますか?", + "postEnableTooltip": "再度読み込んでアクティブにする", + "postUninstallMessage": "このウィンドウを再度読み込んで、アンインストール済みの拡張機能 '{0}' を非アクティブ化しますか?", "postUninstallTooltip": "読み込んで非アクティブ化する", + "postUpdateMessage": "このウィンドウを再度読み込んで、更新済みの拡張機能 '{0}' をアクティブ化しますか?", + "postUpdateTooltip": "再度読み込んで更新する", "reloadAction": "再度読み込む", "showDisabledExtensions": "無効な拡張機能の表示", "showInstalledExtensions": "インストール済みの拡張機能の表示", diff --git a/i18n/jpn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..12e03eedf68 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "宛先レポジトリは既に存在しています。複製するための別のディレクトリを選択してください。", + "cloning": "リポジトリ '{0}' を複製しています...", + "directory": "宛先の複製ディレクトリ", + "repo": "Git リポジトリの URL を入力してください。", + "url": "リポジトリ URL" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/jpn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..7c0675d5e1d --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "ファイルを開く", + "watermark.openFileFolder": "ファイルまたはフォルダーを開く", + "watermark.quickOpen": "ファイルに移動する", + "watermark.showCommands": "すべてのコマンドの表示", + "watermark.toggleTerminal": "端末の切り替え", + "watermark.unboundCommand": "バインドなし" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/jpn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/jpn/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/kor/extensions/typescript/out/features/bufferSyncSupport.i18n.json b/i18n/kor/extensions/typescript/out/features/bufferSyncSupport.i18n.json index 5f11993b3f1..5f909c6beb5 100644 --- a/i18n/kor/extensions/typescript/out/features/bufferSyncSupport.i18n.json +++ b/i18n/kor/extensions/typescript/out/features/bufferSyncSupport.i18n.json @@ -8,5 +8,5 @@ "doNotCheckAgain": "다시 확인 안 함", "moreInformation": "추가 정보", "updateTscCheck": "사용자 설정 'typescript.check.tscVersion'을 false로 업데이트했습니다.", - "versionMismatch": "버전이 일치하지 않습니다. 전역 tsc({0})가 VS 코드의 언어 서비스({1})와 다릅니다. 일관되지 않은 컴파일 오류가 발생할 수 있습니다." + "versionMismatch": "버전이 일치하지 않습니다. 전역 tsc({0})가 VS Code의 언어 서비스({1})와 다릅니다. 일관되지 않은 컴파일 오류가 발생할 수 있습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json index 0aafa8f647a..274df56c010 100644 --- a/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -34,7 +34,7 @@ "renderControlCharacters": "편집기에서 제어 문자를 렌더링할지를 제어합니다.", "renderIndentGuides": "편집기에서 들여쓰기 가이드를 렌더링할지를 제어합니다.", "renderLineHighlight": "편집기가 현재 줄 강조 표시를 렌더링하는지 여부를 제어합니다.", - "renderWhitespace": "편집기에서 공백 문자를 렌더링하는 방법을 제어합니다. 가능한 값은 '없음', '경계' 및 '모두'입니다. '경계' 옵션은 단어 사이의 한 칸 공백을 렌더링하지 않습니다.", + "renderWhitespace": "편집기에서 공백 문자를 렌더링하는 방법을 제어합니다. 가능한 값은 'none', 'boundary' 및 'all'입니다. 'boundary' 옵션은 단어 사이의 한 칸 공백을 렌더링하지 않습니다.", "roundedSelection": "선택 항목의 모서리를 둥글게 할지 여부를 제어합니다.", "rulers": "세로 눈금자를 표시할 열", "scrollBeyondLastLine": "편집기에서 마지막 줄 이후로 스크롤할지 여부를 제어합니다.", diff --git a/i18n/kor/src/vs/editor/node/languageConfigurationExtensionPoint.i18n.json b/i18n/kor/src/vs/editor/node/languageConfigurationExtensionPoint.i18n.json index d673dec4585..4cb15a80eea 100644 --- a/i18n/kor/src/vs/editor/node/languageConfigurationExtensionPoint.i18n.json +++ b/i18n/kor/src/vs/editor/node/languageConfigurationExtensionPoint.i18n.json @@ -12,7 +12,7 @@ "schema.blockComments": "블록 주석이 표시되는 방법을 정의합니다.", "schema.brackets": "들여쓰기를 늘리거나 줄이는 대괄호 기호를 정의합니다.", "schema.closeBracket": "닫는 대괄호 문자 또는 문자열 시퀀스입니다.", - "schema.comments": "주석 기호 정의", + "schema.comments": "주석 기호를 정의합니다.", "schema.lineComment": "줄 주석을 시작하는 문자 시퀀스입니다.", "schema.openBracket": "여는 대괄호 문자 또는 문자열 시퀀스입니다.", "schema.surroundingPairs": "선택한 문자열을 둘러싸는 데 사용할 수 있는 대괄호 쌍을 정의합니다." diff --git a/i18n/kor/src/vs/editor/node/textMate/TMSnippets.i18n.json b/i18n/kor/src/vs/editor/node/textMate/TMSnippets.i18n.json index cf55fb74eef..1d475dd5b62 100644 --- a/i18n/kor/src/vs/editor/node/textMate/TMSnippets.i18n.json +++ b/i18n/kor/src/vs/editor/node/textMate/TMSnippets.i18n.json @@ -9,5 +9,5 @@ "invalid.path.1": "확장 폴더({2})에 포함할 `contributes.{0}.path`({1})가 필요합니다. 확장이 이식 불가능해질 수 있습니다.", "vscode.extension.contributes.snippets": "코드 조각을 적용합니다.", "vscode.extension.contributes.snippets-language": "이 코드 조각이 적용되는 언어 식별자입니다.", - "vscode.extension.contributes.snippets-path": "코드 조각 파일의 경로입니다. 이 경로는 확장 폴더에 상대적이며 일반적으로 './snippets/'로 시작합니다." + "vscode.extension.contributes.snippets-path": "코드 조각 파일의 경로입니다. 이 경로는 확장 폴더의 상대 경로이며 일반적으로 './snippets/'로 시작합니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json index 3950e46910a..98bd826c2f9 100644 --- a/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -14,6 +14,6 @@ "vscode.extension.contributes.grammars.embeddedLanguages": "이 문법에 포함된 언어가 있는 경우 언어 ID에 대한 범위 이름의 맵입니다.", "vscode.extension.contributes.grammars.injectTo": "이 문법이 삽입되는 언어 범위 이름 목록입니다.", "vscode.extension.contributes.grammars.language": "이 구문이 적용되는 언어 식별자입니다.", - "vscode.extension.contributes.grammars.path": "tmLanguage 파일의 경로입니다. 이 경로는 확장 폴더에 상대적이며 일반적으로 './syntaxes/'로 시작합니다.", + "vscode.extension.contributes.grammars.path": "tmLanguage 파일의 경로입니다. 확장 폴더의 상대 경로이며 일반적으로 './syntaxes/'로 시작합니다.", "vscode.extension.contributes.grammars.scopeName": "tmLanguage 파일에 사용되는 Textmate 범위 이름입니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/platform/extensionManagement/node/extensionGalleryService.i18n.json b/i18n/kor/src/vs/platform/extensionManagement/node/extensionGalleryService.i18n.json index f57421a4818..79a565af98c 100644 --- a/i18n/kor/src/vs/platform/extensionManagement/node/extensionGalleryService.i18n.json +++ b/i18n/kor/src/vs/platform/extensionManagement/node/extensionGalleryService.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "noCompatible": "이 버전의 코드에서 {0}의 호환 버전을 찾을 수 없습니다.", + "noCompatible": "이 버전의 Code에서 {0}의 호환 버전을 찾을 수 없습니다.", "notFound": "확장을 찾을 수 없습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 71451b2ac72..8118f68097f 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -14,12 +14,12 @@ "closeOtherEditorsInGroup": "다른 편집기 닫기", "evenEditorGroups": "균등한 편집기 그룹 너비", "focusActiveEditorGroup": "활성 편집기 그룹에 포커스", - "focusFirstEditorGroup": "첫 번째 편집기 그룹으로 포커스 이동", + "focusFirstEditorGroup": "첫 번째 편집기 그룹에 포커스", "focusLastEditorInStack": "그룹의 마지막 편집기 열기", - "focusNextGroup": "다음 그룹으로 포커스 이동", - "focusPreviousGroup": "이전 그룹으로 포커스 이동", - "focusSecondEditorGroup": "두 번째 편집기 그룹으로 포커스 이동", - "focusThirdEditorGroup": "세 번째 편집기 그룹으로 포커스 이동", + "focusNextGroup": "다음 그룹에 포커스", + "focusPreviousGroup": "이전 그룹에 포커스", + "focusSecondEditorGroup": "두 번째 편집기 그룹에 포커스", + "focusThirdEditorGroup": "세 번째 편집기 그룹에 포커스", "keepEditor": "편집기 유지", "maximizeEditor": "편집기 그룹 최대화 및 사이드바 숨기기", "minimizeOtherEditorGroups": "다른 편집기 그룹 최소화", @@ -34,7 +34,6 @@ "navigateNext": "앞으로 이동", "navigatePrevious": "뒤로 이동", "openNextEditor": "다음 편집기 열기", - "openNextEditorInGroup": "그룹에서 최근에 사용한 다음 편집기 열기", "openPreviousEditor": "이전 편집기 열기", "openPreviousEditorInGroup": "그룹에서 최근에 사용한 이전 편집기 열기", "openToSide": "측면에서 열기", diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 9fb077c3b8c..93adb4c1011 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -7,6 +7,6 @@ "commandDeprecated": "**{0}** 명령이 제거되었습니다. 대신 **{1}** 명령을 사용할 수 있습니다.", "editorCommand.activeEditorMove.arg.description": "인수 속성:\n\t\t\t\t\t\t* 'to': 이동할 위치를 지정하는 문자열 값입니다.\n\t\t\t\t\t\t'by': 이동할 단위를 지정하는 문자열 값입니다. 탭 단위 또는 그룹 단위입니다.\n\t\t\t\t\t\t'value': 이동할 위치 수 또는 절대 위치를 지정하는 숫자 값입니다.\n\t\t\t\t\t", "editorCommand.activeEditorMove.arg.name": "활성 편집기 이동 인수", - "editorCommand.activeEditorMove.description": "활성 편집기를 탭 또는 그룹 단위로 이동합니다.", + "editorCommand.activeEditorMove.description": "활성 편집기를 탭 또는 그룹 단위로 이동", "openKeybindings": "바로 가기 키 구성" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/panel/panelPart.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/panel/panelPart.i18n.json index bce4b1f8ff9..bc736d28532 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/panel/panelPart.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/panel/panelPart.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "closePanel": "패널 닫기", - "focusPanel": "패널로 포커스 이동", + "focusPanel": "패널에 포커스", "toggleMaximizedPanel": "최대화된 패널 설정/해제", "togglePanel": "패널 설정/해제", "view": "보기" diff --git a/i18n/kor/src/vs/workbench/browser/parts/sidebar/sidebarPart.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/sidebar/sidebarPart.i18n.json index 549baedd816..5e2f77ce29d 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/sidebar/sidebarPart.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/sidebar/sidebarPart.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "focusSideBar": "사이드바로 포커스 이동", + "focusSideBar": "사이드바에 포커스", "viewCategory": "보기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/electron-browser/shell.i18n.json b/i18n/kor/src/vs/workbench/electron-browser/shell.i18n.json index 17d90a16f11..d09575b170f 100644 --- a/i18n/kor/src/vs/workbench/electron-browser/shell.i18n.json +++ b/i18n/kor/src/vs/workbench/electron-browser/shell.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "runningAsRoot": "코드를 '루트'로 실행하지 않는 것이 좋습니다.", + "runningAsRoot": "Code를 '루트'로 실행하지 않는 것이 좋습니다.", "sharedProcessCrashed": "공유 프로세스가 예기치 않게 종료되었습니다. 복구하려면 창을 다시 로드하세요." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/debug/browser/debugActions.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/browser/debugActions.i18n.json index b4e853b2669..691ce046ac5 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/browser/debugActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/browser/debugActions.i18n.json @@ -13,13 +13,13 @@ "continueDebug": "계속", "deactivateBreakpoints": "중단점 비활성화", "debugConsoleAction": "디버그 콘솔", - "debugFocusConsole": "포커스 디버그 콘솔", + "debugFocusConsole": "디버그 콘솔에 포커스", "disableAllBreakpoints": "모든 중단점 해제", "disconnectDebug": "연결 끊기", "editConditionalBreakpoint": "중단점 편집...", "editWatchExpression": "식 편집", "enableAllBreakpoints": "모든 중단점 설정", - "focusProcess": "포커스 프로세스", + "focusProcess": "프로세스에 포커스", "launchJsonNeedsConfigurtion": "'launch.json' 구성 또는 수정", "openLaunchJson": "{0} 열기", "pauseDebug": "일시 중지", diff --git a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json index c4165e7cf36..d74b9425f5c 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "actions.repl.acceptInput": "REPL 입력 수락", + "actions.repl.acceptInput": "REPL 입력 적용", "actions.repl.historyNext": "기록 다음", "actions.repl.historyPrevious": "기록 이전", "replAriaLabel": "read–eval–print loop 패널" diff --git a/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index 2153c7fe72c..a84a41a5e71 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -9,7 +9,7 @@ "debugOSXConfiguration": "OS X 특정 시작 구성 특성입니다.", "debugPrelaunchTask": "디버그 세션이 시작되기 이전에 실행할 작업입니다.", "debugRequest": "구성 형식을 요청합니다. \"시작\" 또는 \"연결\"일 수 있습니다.", - "debugServer": "디버그 확장 배포 전용입니다. 포트가 지정된 경우 VS 코드에서는 서버 모드로 실행하는 디버그 어댑터에 연결을 시도합니다.", + "debugServer": "디버그 확장 배포 전용입니다. 포트가 지정된 경우 VS Code에서는 서버 모드로 실행하는 디버그 어댑터에 연결을 시도합니다.", "debugType": "구성의 형식입니다.", "debugWindowsConfiguration": "Windows 특정 시작 구성 특성입니다.", "internalConsoleOptions": "내부 디버그 콘솔의 동작을 제어합니다.", diff --git a/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index f9803d85d56..ac020422159 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,7 +10,6 @@ "app.launch.json.title": "시작", "app.launch.json.version": "이 파일 형식의 버전입니다.", "debugNoType": "디버그 어댑터 '형식'은 생략할 수 없으며 '문자열' 형식이어야 합니다.", - "duplicateDebuggerType": "디버그 형식 '{0}'은(는) 이미 등록되어 있고 '{1}' 특성을 포함합니다. '{1}' 특성을 무시합니다.", "selectDebug": "환경 선택", "vscode.extension.contributes.breakpoints": "중단점을 적용합니다.", "vscode.extension.contributes.breakpoints.language": "이 언어에 대해 중단점을 허용합니다.", @@ -25,7 +24,7 @@ "vscode.extension.contributes.debuggers.linux.runtime": "Linux에 사용되는 런타임입니다.", "vscode.extension.contributes.debuggers.osx": "OS X 특정 설정입니다.", "vscode.extension.contributes.debuggers.osx.runtime": "OSX에 사용되는 런타임입니다.", - "vscode.extension.contributes.debuggers.program": "디버그 어댑터 프로그램의 경로입니다. 절대 경로이거나 확장 폴더에 대한 상대 경로입니다.", + "vscode.extension.contributes.debuggers.program": "디버그 어댑터 프로그램의 경로입니다. 절대 경로이거나 확장 폴더의 상대 경로입니다.", "vscode.extension.contributes.debuggers.runtime": "프로그램 특성이 실행 파일이 아니지만 런타임이 필요한 경우의 선택적 런타임입니다.", "vscode.extension.contributes.debuggers.runtimeArgs": "선택적 런타임 인수입니다.", "vscode.extension.contributes.debuggers.type": "이 디버그 어댑터에 대한 고유한 식별자입니다.", diff --git a/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionEditor.i18n.json b/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionEditor.i18n.json index 98e7611e1b7..7eeb9402fb2 100644 --- a/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionEditor.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionEditor.i18n.json @@ -26,7 +26,7 @@ "license": "라이선스", "menuContexts": "메뉴 컨텍스트", "name": "확장 이름", - "noChangelog": "변경 로그를 사용할 수 없습니다.", + "noChangelog": "CHANGELOG를 사용할 수 없습니다.", "noContributions": "참여 없음", "noDependencies": "종속성 없음", "noReadme": "사용 가능한 추가 정보가 없습니다.", diff --git a/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index ea18d84bd5d..5d8f04ac47e 100644 --- a/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "권장 사항은 작업 영역 폴더에서만 사용할 수 있습니다.", - "OpenExtensionsFile.failed": "'.vscode' 폴더 내에 'extensions.json' 파일을 만들 수 없습니다({0}).", + "ManageExtensionAction.uninstallingTooltip": "제거하는 중", + "OpenExtensionsFile.failed": "'.vscode' 폴더({0}) 내에 'extensions.json' 파일을 만들 수 없습니다.", "Uninstalling": "제거하는 중", "builtin": "기본 제공", "clearExtensionsInput": "확장 입력 지우기", "configureWorkspaceRecommendedExtensions": "권장 확장 구성(작업 영역)", "disableAction": "사용 안 함", + "disableAll": "설치된 모든 확장 사용 안 함", + "disableAllWorkspace": "이 작업 영역에 대해 설치된 모든 확장 사용 안 함", "disableAlwaysAction.label": "사용 안 함", "disableForWorkspaceAction": "작업 영역", "disableForWorkspaceAction.label": "사용 안 함(작업 영역)", "disableGloballyAction": "항상", "enableAction": "사용", + "enableAll": "설치된 모든 확장 사용", + "enableAllWorkspace": "이 작업 영역에 대해 설치된 모든 확장 사용", "enableAlwaysAction.label": "사용", "enableForWorkspaceAction": "작업 영역", "enableForWorkspaceAction.label": "사용(작업 영역)", @@ -23,7 +28,14 @@ "installAction": "설치", "installExtensions": "확장 설치", "installing": "설치 중", + "postDisableMessage": "이 창을 다시 로드하여 '{0}' 확장을 비활성화하시겠습니까?", + "postDisableTooltip": "비활성화하려면 다시 로드", + "postEnableMessage": "이 창을 다시 로드하여 '{0}' 확장을 활성화하시겠습니까?", + "postEnableTooltip": "활성화하려면 다시 로드", + "postUninstallMessage": "이 창을 다시 로드하여 제거된 확장 '{0}'을(를) 비활성화하시겠습니까?", "postUninstallTooltip": "비활성화하려면 다시 로드", + "postUpdateMessage": "이 창을 다시 로드하여 업데이트된 확장 '{0}'을(를) 활성화하시겠습니까?", + "postUpdateTooltip": "업데이트하려면 다시 로드", "reloadAction": "다시 로드", "showDisabledExtensions": "사용할 수 없는 확장 표시", "showInstalledExtensions": "설치된 확장 표시", diff --git a/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json index e6ec699abf0..d6c0a091a5c 100644 --- a/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -31,8 +31,8 @@ "emptyFileNameError": "파일 또는 폴더 이름을 입력해야 합니다.", "fileNameExistsError": "파일 또는 폴더 **{0}**이(가) 이 위치에 이미 있습니다. 다른 이름을 선택하세요.", "filePathTooLongError": "**{0}**(이)라는 이름을 사용하면 경로가 너무 길어집니다. 짧은 이름을 선택하세요.", - "focusFilesExplorer": "파일 탐색기에 포커스 설정", - "focusOpenEditors": "열려 있는 편집기 뷰에 포커스 설정", + "focusFilesExplorer": "파일 탐색기에 포커스", + "focusOpenEditors": "열려 있는 편집기 뷰에 포커스", "globalCompareFile": "활성 파일을 다음과 비교...", "importFiles": "파일 가져오기", "invalidFileNameError": "**{0}**(이)라는 이름은 파일 또는 폴더 이름으로 올바르지 않습니다. 다른 이름을 선택하세요.", diff --git a/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 3ea98fcd19e..8c1f06e6297 100644 --- a/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -19,7 +19,7 @@ "files.exclude.boolean": "파일 경로를 일치시킬 GLOB 패턴입니다. 패턴을 사용하거나 사용하지 않도록 설정하려면 true 또는 false로 설정하세요.", "files.exclude.when": "일치하는 파일의 형제에 대한 추가 검사입니다. $(basename)을 일치하는 파일 이름에 대한 변수로 사용하세요.", "filesConfigurationTitle": "파일", - "formatOnSave": "파일 저장 시 서식을 지정합니다. 포맷터를 사용할 수 있어야 하며, 파일이 자동으로 저장되어야 하고, 편집기가 종료되지 않아야 합니다.", + "formatOnSave": "파일 저장 시 서식을 지정합니다. 포맷터를 사용할 수 있어야 하며, 파일이 자동으로 저장되지 않아야 하고, 편집기가 종료되지 않아야 합니다.", "insertFinalNewline": "사용하도록 설정되면 저장할 때 파일 끝에 마지막 줄바꿈을 삽입합니다.", "openEditorsVisible": "열려 있는 편집기 창에 표시되는 편집기 수입니다. 창을 숨기려면 0으로 설정합니다.", "showExplorerViewlet": "탐색기 표시", diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index ea1a1d7df6a..793029be440 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -12,7 +12,7 @@ "gitCommands": "Git 명령", "gitConfigurationTitle": "Git", "gitEnabled": "git를 사용하도록 설정할까요?", - "gitLargeRepos": "항상 대규모 리포지토리가 코드로 관리되도록 허용합니다.", + "gitLargeRepos": "항상 대규모 리포지토리가 Code로 관리되도록 허용합니다.", "gitLongCommit": "긴 커밋 메시지에 대해 경고할지 여부입니다.", "gitPath": "Git 실행 파일의 경로", "gitPendingChangesBadge": "{0}이(가) 변경 내용을 보류 중입니다.", diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/views/huge/hugeView.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/views/huge/hugeView.i18n.json index 308746a103b..6dc9cb25b7d 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/views/huge/hugeView.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/views/huge/hugeView.i18n.json @@ -5,6 +5,6 @@ // Do not edit this file. It is machine generated. { "allo": "대규모 리포지토리 허용", - "huge": "리포지토리에 활성 변경 내용이 많은 것 같습니다.\n코드가 매우 느려질 수 있습니다.", + "huge": "리포지토리에 활성 변경 내용이 많은 것 같습니다.\nCode가 매우 느려질 수 있습니다.", "setting": "다음 설정을 사용하여 이 경고를 영구적으로 사용하지 않을 수 있습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/kor/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..cdbc76b862d 100644 --- a/i18n/kor/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "대상 리포지토리가 이미 있습니다. 복제할 다른 디렉터리를 선택하세요.", + "cloning": "'{0}' 리포지토리를 복제하는 중...", + "directory": "대상 복제 디렉터리", + "repo": "Git 리포지토리 URL을 입력하세요.", + "url": "리포지토리 URL" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json index fab90b25aea..5229ebfb252 100644 --- a/i18n/kor/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/tasks/electron-browser/task.contribution.i18n.json @@ -53,12 +53,12 @@ "JsonSchema.taskSelector": "인수가 작업임을 나타내는 접두사입니다.", "JsonSchema.tasks": "작업 구성입니다. 일반적으로 외부 Task Runner에 이미 정의되어 있는 작업을 보강합니다.", "JsonSchema.tasks.args": "이 작업이 호출될 때 명령에 전달되는 추가 인수입니다.", - "JsonSchema.tasks.build": "이 작업을 코드의 기본 빌드 명령에 매핑합니다.", + "JsonSchema.tasks.build": "이 작업을 Code의 기본 빌드 명령에 매핑합니다.", "JsonSchema.tasks.matchers": "사용할 문제 선택기입니다. 문자열, 문제 선택기 정의 또는 문자열 및 문제 선택기 배열일 수 있습니다.", "JsonSchema.tasks.showOutput": "실행 중인 작업에 대한 출력을 표시할지 여부를 제어합니다. 생략하면 전역적으로 정의된 값이 사용됩니다.", "JsonSchema.tasks.suppressTaskName": "작업 이름을 명령에 인수로 추가할지 여부를 제어합니다. 생략하면 전역적으로 정의된 값이 사용됩니다.", "JsonSchema.tasks.taskName": "작업 이름", - "JsonSchema.tasks.test": "이 작업을 코드의 기본 테스트 명령에 매핑합니다.", + "JsonSchema.tasks.test": "이 작업을 Code의 기본 테스트 명령에 매핑합니다.", "JsonSchema.tasks.watching": "실행된 작업을 활성 상태로 유지할지 파일 시스템을 조사할지 여부를 나타냅니다.", "JsonSchema.version": "구성의 버전 번호입니다.", "JsonSchema.watching": "실행된 작업을 활성 상태로 유지할지 파일 시스템을 조사할지 여부를 나타냅니다.", @@ -74,13 +74,13 @@ "TaskSystem.invalidTaskJson": "오류: tasks.json 파일의 내용에 구문 오류가 있습니다. 작업을 실행하기 전에 오류를 정정하세요.\n", "TaskSystem.noBuildType": "유효한 Task Runner가 구성되어 있지 않습니다. 지원되는 Task Runner는 '서비스' 및 '프로그램'입니다.", "TaskSystem.noConfiguration": "구성된 Task Runner가 없습니다.", - "TaskSystem.noProcess": "시작된 작업이 더 이상 존재하지 않습니다. 작업에서 생성된, VS 코드를 끝내는 백그라운드 프로세스가 분리된 프로세스가 될 수 있습니다. 이를 방지하려면 wait 플래그를 사용하여 마지막 백그라운드 프로세스를 시작하세요.", + "TaskSystem.noProcess": "시작된 작업이 더 이상 존재하지 않습니다. 작업에서 생성된, VS Code를 끝내는 백그라운드 프로세스가 분리된 프로세스가 될 수 있습니다. 이를 방지하려면 wait 플래그를 사용하여 마지막 백그라운드 프로세스를 시작하세요.", "TaskSystem.runningTask": "실행 중인 작업이 있습니다. 이 작업을 종료할까요?", "TaskSystem.terminateTask": "작업 종료(&&T)", "TaskSystem.unknownError": "작업을 실행하는 동안 오류가 발생했습니다. 자세한 내용은 작업 로그를 참조하세요.", "TerminateAction.failed": "실행 중인 작업을 종료하지 못했습니다.", "TerminateAction.label": "실행 중인 작업 종료", - "TerminateAction.noProcess": "시작된 프로세스가 더 이상 존재하지 않습니다. 작업에서 생성된, VS 코드를 끝내는 백그라운드 작업이 분리된 프로세스가 될 수 있습니다.", + "TerminateAction.noProcess": "시작된 프로세스가 더 이상 존재하지 않습니다. 작업에서 생성된, VS Code를 끝내는 백그라운드 작업이 분리된 프로세스가 될 수 있습니다.", "TestAction.label": "테스트 작업 실행", "manyMarkers": "99+", "problems": "문제", diff --git a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index 47d3b7db30a..c5752f212ca 100644 --- a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "terminal": "터미널", - "terminal.integrated.commandsToSkipShell": "키 바인딩이 셸에 전송되지 않고 항상 코드에서 처리되는 명령 ID 집합입니다. 따라서 셸에서 정상적으로 사용되어 터미널에 포커스가 없을 때와 동일하게 작동하는 키 바인딩을 사용할 수 있습니다(예: 를 사용하여 Quick Open 시작).", + "terminal.integrated.commandsToSkipShell": "키 바인딩이 셸에 전송되지 않고 항상 Code에서 처리되는 명령 ID 집합입니다. 따라서 셸에서 정상적으로 사용되어 터미널에 포커스가 없을 때와 동일하게 작동하는 키 바인딩을 사용할 수 있습니다(예: 를 사용하여 Quick Open 시작).", "terminal.integrated.cursorBlinking": "터미널 커서 깜박임 여부를 제어합니다.", "terminal.integrated.fontFamily": "터미널의 글꼴 패밀리를 제어하며, 기본값은 editor.fontFamily의 값입니다.", "terminal.integrated.fontLigatures": "터미널에서 글꼴 합자가 사용되는지를 제어합니다.", diff --git a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index 4090e5f95c3..7b2757f8f77 100644 --- a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -6,9 +6,9 @@ { "workbench.action.terminal.clear": "지우기", "workbench.action.terminal.copySelection": "선택 영역 복사", - "workbench.action.terminal.focus": "터미널로 포커스 이동", - "workbench.action.terminal.focusNext": "다음 터미널로 포커스 이동", - "workbench.action.terminal.focusPrevious": "이전 터미널로 포커스 이동", + "workbench.action.terminal.focus": "터미널에 포커스", + "workbench.action.terminal.focusNext": "다음 터미널에 포커스", + "workbench.action.terminal.focusPrevious": "이전 터미널에 포커스", "workbench.action.terminal.kill": "활성 터미널 인스턴스 종료", "workbench.action.terminal.kill.short": "터미널 종료", "workbench.action.terminal.new": "새 통합 터미널 만들기", diff --git a/i18n/kor/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/kor/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..3e8983a9f11 --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "파일 열기", + "watermark.openFileFolder": "파일 또는 폴더 열기", + "watermark.quickOpen": "파일로 이동", + "watermark.showCommands": "모든 명령 표시", + "watermark.toggleTerminal": "터미널 설정/해제", + "watermark.unboundCommand": "바인딩 안 됨" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/kor/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/kor/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json b/i18n/kor/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json index 73cca9e15fe..8f0ab73fd29 100644 --- a/i18n/kor/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json +++ b/i18n/kor/src/vs/workbench/services/themes/electron-browser/themeService.i18n.json @@ -25,7 +25,7 @@ "schema.folderNames": "폴더 이름을 아이콘과 연결합니다. 개체 키는 경로 세그먼트를 제외한 폴더 이름입니다. 패턴이나 와일드카드는 허용되지 않습니다. 폴더 이름 일치는 대/소문자를 구분하지 않습니다.", "schema.folderNamesExpanded": "폴더 이름을 확장된 폴더의 아이콘과 연결합니다. 개체 키는 경로 세그먼트를 제외한 폴더 이름입니다. 패턴이나 와일드카드는 허용되지 않습니다. 폴더 이름 일치는 대/소문자를 구분하지 않습니다.", "schema.font-format": "글꼴의 형식입니다.", - "schema.font-path": "현재 아이콘 테마 파일을 기준으로 한 글꼴 경로입니다.", + "schema.font-path": "현재 아이콘 테마 파일의 상대 글꼴 경로입니다.", "schema.font-size": "글꼴의 기본 크기입니다.", "schema.font-sstyle": "글꼴의 스타일입니다.", "schema.font-weight": "글꼴의 두께입니다.", @@ -37,7 +37,7 @@ "schema.highContrast": "고대비 색 테마에서 파일 아이콘에 대한 선택적 연결입니다.", "schema.iconDefinition": "아이콘 정의입니다. 개체 키는 정의의 ID입니다.", "schema.iconDefinitions": "파일을 아이콘과 연결할 때 사용할 수 있는 모든 아이콘의 설명입니다.", - "schema.iconPath": "SVG 또는 PNG를 사용하는 경우: 이미지의 경로입니다. 경로는 아이콘 집합 파일을 기준으로 합니다.", + "schema.iconPath": "SVG 또는 PNG를 사용하는 경우: 이미지의 경로입니다. 아이콘 집합 파일의 상대 경로입니다.", "schema.id": "글꼴의 ID입니다.", "schema.languageId": "연결에 대한 아이콘 정의의 ID입니다.", "schema.languageIds": "언어를 아이콘과 연결합니다. 개체 키는 언어 기여 지점에 정의된 언어 ID입니다.", @@ -46,9 +46,9 @@ "vscode.extension.contributes.iconThemes": "파일 아이콘 테마를 제공합니다.", "vscode.extension.contributes.iconThemes.id": "사용자 설정에 사용된 아이콘 테마의 ID입니다.", "vscode.extension.contributes.iconThemes.label": "UI에 표시된 아이콘 테마의 레이블입니다.", - "vscode.extension.contributes.iconThemes.path": "아이콘 테마 정의 파일의 경로입니다. 경로는 확장 폴더를 기준으로 하며 일반적으로 './icons/awesome-icon-theme.json'입니다.", + "vscode.extension.contributes.iconThemes.path": "아이콘 테마 정의 파일의 경로입니다. 확장 폴더의 상대 경로이며 일반적으로 './icons/awesome-icon-theme.json'입니다.", "vscode.extension.contributes.themes": "textmate 색 테마를 적용합니다.", "vscode.extension.contributes.themes.label": "UI에 표시되는 색 테마의 레이블입니다.", - "vscode.extension.contributes.themes.path": "tmTheme 파일의 경로입니다. 이 경로는 확장 폴더에 상대적이며 일반적으로 './themes/themeFile.tmTheme'입니다.", + "vscode.extension.contributes.themes.path": "tmTheme 파일의 경로입니다. 확장 폴더의 상대 경로이며 일반적으로 './themes/themeFile.tmTheme'입니다.", "vscode.extension.contributes.themes.uiTheme": "편집기 주변의 색을 정의하는 기본 테마입니다. 'vs'는 밝은색 테마이고, 'vs-dark'는 어두운색 테마입니다. 'hc-black'은 어두운 고대비 테마입니다." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json b/i18n/rus/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json index 6aa6a41de3f..1bf0a9ee7c1 100644 --- a/i18n/rus/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/extensions/browser/extensionsActions.i18n.json @@ -5,17 +5,22 @@ // Do not edit this file. It is machine generated. { "ConfigureWorkspaceRecommendations.noWorkspace": "Рекомендации доступны только для папки рабочей области.", + "ManageExtensionAction.uninstallingTooltip": "Идет удаление", "OpenExtensionsFile.failed": "Не удается создать файл \"extensions.json\" в папке \".vscode\" ({0}).", "Uninstalling": "Идет удаление", "builtin": "Встроенное", "clearExtensionsInput": "Очистить входные данные расширений", "configureWorkspaceRecommendedExtensions": "Настроить рекомендуемые расширения (рабочая область)", "disableAction": "Отключить", + "disableAll": "Отключить все установленные расширения", + "disableAllWorkspace": "Отключить все установленные расширения для этой рабочей области", "disableAlwaysAction.label": "Отключить", "disableForWorkspaceAction": "Рабочая область", "disableForWorkspaceAction.label": "Отключить (рабочая область)", "disableGloballyAction": "Всегда", "enableAction": "Включить", + "enableAll": "Включить все установленные расширения", + "enableAllWorkspace": "Включить все установленные расширения для этой рабочей области", "enableAlwaysAction.label": "Включить", "enableForWorkspaceAction": "Рабочая область", "enableForWorkspaceAction.label": "Включить (рабочая область)", @@ -23,7 +28,14 @@ "installAction": "Установить", "installExtensions": "Установить расширения", "installing": "Идет установка", + "postDisableMessage": "Обновить это окно, чтобы отключить расширение \"{0}\"?", + "postDisableTooltip": "Обновление для отключения", + "postEnableMessage": "Обновить это окно, чтобы активировать расширение \"{0}\"?", + "postEnableTooltip": "Обновление для активации", + "postUninstallMessage": "Обновить это окно, чтобы отключить удаленное расширение \"{0}\"?", "postUninstallTooltip": "Перезагрузка для деактивации", + "postUpdateMessage": "Обновить это окно, чтобы активировать обновленное расширение \"{0}\"?", + "postUpdateTooltip": "Обновление окна для обновления", "reloadAction": "Перезагрузить", "showDisabledExtensions": "Показать отключенные расширения", "showInstalledExtensions": "Показать установленные расширения", diff --git a/i18n/rus/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json b/i18n/rus/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json index 8b6ad71cd4e..cd723848e61 100644 --- a/i18n/rus/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/git/electron-browser/gitActions.i18n.json @@ -3,4 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{} \ No newline at end of file +{ + "already exists": "Целевой репозиторий уже существует, выберите другой каталог-назначение для клонирования.", + "cloning": "Клонирование репозитория \"{0}\"...", + "directory": "Каталог-назначение для клонирования", + "repo": "Укажите URL-адрес репозитория Git.", + "url": "URL-адрес репозитория" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json b/i18n/rus/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json new file mode 100644 index 00000000000..1b994d08fff --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/watermark/electron-browser/watermark.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "watermark.openFile": "Открыть файл", + "watermark.openFileFolder": "Открыть файл или папку", + "watermark.quickOpen": "Перейти к файлу", + "watermark.showCommands": "Показать все команды", + "watermark.toggleTerminal": "Терминал", + "watermark.unboundCommand": "свободный" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/services/textfile/browser/textFileService.i18n.json b/i18n/rus/src/vs/workbench/services/textfile/browser/textFileService.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/rus/src/vs/workbench/services/textfile/browser/textFileService.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file From 154fef0e0da97a1f3f2428550deb16f15d4727ce Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 25 Nov 2016 15:54:44 +0100 Subject: [PATCH 16/30] launch.json / tasks.json allow to reference any command fixes #12735 --- .../node/configurationResolverService.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts index c5fccbc37aa..ba6c8a916f9 100644 --- a/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import nls = require('vs/nls'); import * as paths from 'vs/base/common/paths'; import * as types from 'vs/base/common/types'; import uri from 'vs/base/common/uri'; @@ -226,14 +225,15 @@ export class ConfigurationResolverService implements IConfigurationResolverServi let commandId = null; commandId = interactiveVariablesMap ? interactiveVariablesMap[interactiveVariable] : null; if (!commandId) { - return TPromise.wrapError(nls.localize('interactiveVariableNotFound', "Interactive variable {0} is not contributed but is specified in a configuration.", interactiveVariable)); - } else { - return this.commandService.executeCommand(commandId, configuration).then(result => { - interactiveVariablesToSubstitutes[interactiveVariable].forEach(substitute => - substitute.object[substitute.key] = substitute.object[substitute.key].replace(`\${command.${interactiveVariable}}`, result) - ); - }); + // Just launch any command if the interactive variable is not contributed by the adapter #12735 + commandId = interactiveVariable; } + + return this.commandService.executeCommand(commandId, configuration).then(result => { + interactiveVariablesToSubstitutes[interactiveVariable].forEach(substitute => + substitute.object[substitute.key] = substitute.object[substitute.key].replace(`\${command.${interactiveVariable}}`, result) + ); + }); }; }); From 63dbeee8717a38c07463798ab8f72185e93da868 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 25 Nov 2016 16:29:46 +0100 Subject: [PATCH 17/30] remove newline --- src/vs/workbench/parts/debug/electron-browser/debugService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 0d0e8934e08..5abcbe2821b 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -1060,7 +1060,6 @@ export class DebugService implements debug.IDebugService { this.sendBreakpoints(event.resource, true).done(null, errors.onUnexpectedError); } }); - } private store(): void { From 93c1334282d62a98d2e94b3bd21d4fa55444ef13 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 25 Nov 2016 16:37:45 +0100 Subject: [PATCH 18/30] [json] adopt SnippetString (#15573) and update to TS 2.0 --- extensions/json/client/src/jsonMain.ts | 4 +- extensions/json/client/src/typings/ref.d.ts | 7 +- extensions/json/client/tsconfig.json | 11 +- extensions/json/npm-shrinkwrap.json | 16 +-- extensions/json/package.json | 11 +- extensions/json/server/npm-shrinkwrap.json | 27 ++--- extensions/json/server/package.json | 9 +- extensions/json/server/src/jsonServerMain.ts | 4 +- .../fileAssociationContribution.ts | 9 +- .../globPatternContribution.ts | 18 ++- .../projectJSONContribution.ts | 17 +-- .../json/server/src/typings/promise.d.ts | 112 ------------------ extensions/json/server/src/typings/ref.d.ts | 8 -- extensions/json/server/tsconfig.json | 6 +- 14 files changed, 66 insertions(+), 193 deletions(-) delete mode 100644 extensions/json/server/src/typings/promise.d.ts delete mode 100644 extensions/json/server/src/typings/ref.d.ts diff --git a/extensions/json/client/src/jsonMain.ts b/extensions/json/client/src/jsonMain.ts index f9757ad16ac..7dc61a32e1c 100644 --- a/extensions/json/client/src/jsonMain.ts +++ b/extensions/json/client/src/jsonMain.ts @@ -14,7 +14,7 @@ import * as nls from 'vscode-nls'; let localize = nls.loadMessageBundle(); namespace VSCodeContentRequest { - export const type: RequestType = { get method() { return 'vscode/content'; } }; + export const type: RequestType = { get method() { return 'vscode/content'; }, _: null }; } export interface ISchemaAssociations { @@ -22,7 +22,7 @@ export interface ISchemaAssociations { } namespace SchemaAssociationNotification { - export const type: NotificationType = { get method() { return 'json/schemaAssociations'; } }; + export const type: NotificationType = { get method() { return 'json/schemaAssociations'; }, _: null }; } interface IPackageInfo { diff --git a/extensions/json/client/src/typings/ref.d.ts b/extensions/json/client/src/typings/ref.d.ts index 25ca0850b75..7c0805ba6c3 100644 --- a/extensions/json/client/src/typings/ref.d.ts +++ b/extensions/json/client/src/typings/ref.d.ts @@ -3,9 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/// -/// -/// -/// -/// -/// \ No newline at end of file +/// \ No newline at end of file diff --git a/extensions/json/client/tsconfig.json b/extensions/json/client/tsconfig.json index 8cb16334377..31c07df105b 100644 --- a/extensions/json/client/tsconfig.json +++ b/extensions/json/client/tsconfig.json @@ -1,11 +1,10 @@ { "compilerOptions": { - "noLib": true, "target": "es5", "module": "commonjs", - "outDir": "./out" - }, - "exclude": [ - "node_modules" - ] + "outDir": "./out", + "lib": [ + "es5", "es2015.promise" + ] + } } \ No newline at end of file diff --git a/extensions/json/npm-shrinkwrap.json b/extensions/json/npm-shrinkwrap.json index c6f216d2d28..763f414436d 100644 --- a/extensions/json/npm-shrinkwrap.json +++ b/extensions/json/npm-shrinkwrap.json @@ -13,19 +13,19 @@ "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.5.tgz" }, "vscode-jsonrpc": { - "version": "2.3.2-next.5", - "from": "vscode-jsonrpc@>=2.3.2-next.2 <3.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.3.2-next.5.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-jsonrpc@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.0.1-alpha.2.tgz" }, "vscode-languageclient": { - "version": "2.4.2-next.22", + "version": "3.0.1-alpha.3", "from": "vscode-languageclient@next", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-2.4.2-next.22.tgz" + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.0.1-alpha.3.tgz" }, "vscode-languageserver-types": { - "version": "1.0.3", - "from": "vscode-languageserver-types@>=1.0.3 <2.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.3.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-languageserver-types@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.1-alpha.2.tgz" }, "vscode-nls": { "version": "1.0.7", diff --git a/extensions/json/package.json b/extensions/json/package.json index d2641cdafba..9bb6c933e2c 100644 --- a/extensions/json/package.json +++ b/extensions/json/package.json @@ -66,9 +66,9 @@ "type": "object", "default": { "fileMatch": [ - "{{/myfile}}" + "/myfile" ], - "url": "{{schemaURL}}" + "url": "schemaURL" }, "properties": { "url": { @@ -103,7 +103,10 @@ }, "dependencies": { "vscode-extension-telemetry": "^0.0.5", - "vscode-languageclient": "^2.4.2-next.22", + "vscode-languageclient": "^3.0.1-alpha.3", "vscode-nls": "^1.0.7" + }, + "devDependencies": { + "@types/node": "^6.0.51" } -} \ No newline at end of file +} diff --git a/extensions/json/server/npm-shrinkwrap.json b/extensions/json/server/npm-shrinkwrap.json index 84caeb7f0ed..bf468c136a4 100644 --- a/extensions/json/server/npm-shrinkwrap.json +++ b/extensions/json/server/npm-shrinkwrap.json @@ -43,31 +43,24 @@ "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.1.0.tgz" }, "vscode-json-languageservice": { - "version": "2.0.0-next.2", + "version": "2.0.0-next.4", "from": "vscode-json-languageservice@next", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.0-next.2.tgz", - "dependencies": { - "vscode-languageserver-types": { - "version": "1.0.4", - "from": "vscode-languageserver-types@>=1.0.4 <2.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.4.tgz" - } - } + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.0-next.4.tgz" }, "vscode-jsonrpc": { - "version": "2.3.2-next.5", - "from": "vscode-jsonrpc@>=2.3.2-next.2 <3.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.3.2-next.5.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-jsonrpc@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.0.1-alpha.2.tgz" }, "vscode-languageserver": { - "version": "2.4.0-next.12", + "version": "3.0.1-alpha.3", "from": "vscode-languageserver@next", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-2.4.0-next.12.tgz" + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.0.1-alpha.3.tgz" }, "vscode-languageserver-types": { - "version": "1.0.3", - "from": "vscode-languageserver-types@>=1.0.3 <2.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.3.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-languageserver-types@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.1-alpha.2.tgz" }, "vscode-nls": { "version": "1.0.7", diff --git a/extensions/json/server/package.json b/extensions/json/server/package.json index acbadb593f1..da194402f9d 100644 --- a/extensions/json/server/package.json +++ b/extensions/json/server/package.json @@ -9,9 +9,12 @@ }, "dependencies": { "request-light": "^0.1.0", - "vscode-json-languageservice": "^2.0.0-next.2", - "vscode-languageserver": "^2.4.0-next.12", - "vscode-nls": "^1.0.4" + "vscode-json-languageservice": "^2.0.0-next.4", + "vscode-languageserver": "^3.0.1-alpha.3", + "vscode-nls": "^1.0.7" + }, + "devDependencies": { + "@types/node": "^6.0.51" }, "scripts": { "compile": "gulp compile-extension:json-server", diff --git a/extensions/json/server/src/jsonServerMain.ts b/extensions/json/server/src/jsonServerMain.ts index d72825e0db0..a419abbf6e7 100644 --- a/extensions/json/server/src/jsonServerMain.ts +++ b/extensions/json/server/src/jsonServerMain.ts @@ -29,11 +29,11 @@ interface ISchemaAssociations { } namespace SchemaAssociationNotification { - export const type: NotificationType = { get method() { return 'json/schemaAssociations'; } }; + export const type: NotificationType = { get method() { return 'json/schemaAssociations'; }, _: null }; } namespace VSCodeContentRequest { - export const type: RequestType = { get method() { return 'vscode/content'; } }; + export const type: RequestType = { get method() { return 'vscode/content'; }, _: null }; } // Create a connection for the server diff --git a/extensions/json/server/src/jsoncontributions/fileAssociationContribution.ts b/extensions/json/server/src/jsoncontributions/fileAssociationContribution.ts index 3d5a6e669fb..a6a589b5fa8 100644 --- a/extensions/json/server/src/jsoncontributions/fileAssociationContribution.ts +++ b/extensions/json/server/src/jsoncontributions/fileAssociationContribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { MarkedString, CompletionItemKind, CompletionItem } from 'vscode-languageserver'; +import { MarkedString, CompletionItemKind, CompletionItem, SnippetString } from 'vscode-languageserver'; import Strings = require('../utils/strings'); import { JSONWorkerContribution, JSONPath, CompletionsCollector } from 'vscode-json-languageservice'; @@ -12,8 +12,8 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); let globProperties: CompletionItem[] = [ - { kind: CompletionItemKind.Value, label: localize('assocLabelFile', "Files with Extension"), insertText: '"*.{{extension}}": "{{language}}"', documentation: localize('assocDescriptionFile', "Map all files matching the glob pattern in their filename to the language with the given identifier.") }, - { kind: CompletionItemKind.Value, label: localize('assocLabelPath', "Files with Path"), insertText: '"/{{path to file}}/*.{{extension}}": "{{language}}"', documentation: localize('assocDescriptionPath', "Map all files matching the absolute path glob pattern in their path to the language with the given identifier.") } + { kind: CompletionItemKind.Value, label: localize('assocLabelFile', "Files with Extension"), insertText: SnippetString.create('"*.${1:extension}": "${2:language}"'), documentation: localize('assocDescriptionFile', "Map all files matching the glob pattern in their filename to the language with the given identifier.") }, + { kind: CompletionItemKind.Value, label: localize('assocLabelPath', "Files with Path"), insertText: SnippetString.create('"/${1:path to file}/*.${2:extension}": "${3:language}"'), documentation: localize('assocDescriptionPath', "Map all files matching the absolute path glob pattern in their path to the language with the given identifier.") } ]; export class FileAssociationContribution implements JSONWorkerContribution { @@ -37,7 +37,6 @@ export class FileAssociationContribution implements JSONWorkerContribution { public collectPropertyCompletions(resource: string, location: JSONPath, currentWord: string, addValue: boolean, isLast: boolean, result: CompletionsCollector): Thenable { if (this.isSettingsFile(resource) && location.length === 1 && location[0] === 'files.associations') { globProperties.forEach(e => { - e.filterText = e.insertText; result.add(e); }); } @@ -51,7 +50,7 @@ export class FileAssociationContribution implements JSONWorkerContribution { result.add({ kind: CompletionItemKind.Value, label: l, - insertText: JSON.stringify('{{' + l + '}}'), + insertText: SnippetString.create(JSON.stringify('${1:' + l + '}')), filterText: JSON.stringify(l) }); }); diff --git a/extensions/json/server/src/jsoncontributions/globPatternContribution.ts b/extensions/json/server/src/jsoncontributions/globPatternContribution.ts index bb3eb6bd802..1d79d6ae1a4 100644 --- a/extensions/json/server/src/jsoncontributions/globPatternContribution.ts +++ b/extensions/json/server/src/jsoncontributions/globPatternContribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { MarkedString, CompletionItemKind, CompletionItem } from 'vscode-languageserver'; +import { MarkedString, CompletionItemKind, CompletionItem, SnippetString } from 'vscode-languageserver'; import Strings = require('../utils/strings'); import { JSONWorkerContribution, JSONPath, CompletionsCollector } from 'vscode-json-languageservice'; @@ -12,18 +12,18 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); let globProperties: CompletionItem[] = [ - { kind: CompletionItemKind.Value, label: localize('fileLabel', "Files by Extension"), insertText: '"**/*.{{extension}}": true', documentation: localize('fileDescription', "Match all files of a specific file extension.") }, + { kind: CompletionItemKind.Value, label: localize('fileLabel', "Files by Extension"), insertText: SnippetString.create('"**/*.${1:extension}": true'), documentation: localize('fileDescription', "Match all files of a specific file extension.") }, { kind: CompletionItemKind.Value, label: localize('filesLabel', "Files with Multiple Extensions"), insertText: '"**/*.{ext1,ext2,ext3}": true', documentation: localize('filesDescription', "Match all files with any of the file extensions.") }, - { kind: CompletionItemKind.Value, label: localize('derivedLabel', "Files with Siblings by Name"), insertText: '"**/*.{{source-extension}}": { "when": "$(basename).{{target-extension}}" }', documentation: localize('derivedDescription', "Match files that have siblings with the same name but a different extension.") }, - { kind: CompletionItemKind.Value, label: localize('topFolderLabel', "Folder by Name (Top Level)"), insertText: '"{{name}}": true', documentation: localize('topFolderDescription', "Match a top level folder with a specific name.") }, + { kind: CompletionItemKind.Value, label: localize('derivedLabel', "Files with Siblings by Name"), insertText: SnippetString.create('"**/*.${1:source-extension}": { "when": "$(basename).{{target-extension}}" }'), documentation: localize('derivedDescription', "Match files that have siblings with the same name but a different extension.") }, + { kind: CompletionItemKind.Value, label: localize('topFolderLabel', "Folder by Name (Top Level)"), insertText: SnippetString.create('"${1:name}": true'), documentation: localize('topFolderDescription', "Match a top level folder with a specific name.") }, { kind: CompletionItemKind.Value, label: localize('topFoldersLabel', "Folders with Multiple Names (Top Level)"), insertText: '"{folder1,folder2,folder3}": true', documentation: localize('topFoldersDescription', "Match multiple top level folders.") }, - { kind: CompletionItemKind.Value, label: localize('folderLabel', "Folder by Name (Any Location)"), insertText: '"**/{{name}}": true', documentation: localize('folderDescription', "Match a folder with a specific name in any location.") }, + { kind: CompletionItemKind.Value, label: localize('folderLabel', "Folder by Name (Any Location)"), insertText: SnippetString.create('"**/${1:name}": true'), documentation: localize('folderDescription', "Match a folder with a specific name in any location.") }, ]; let globValues: CompletionItem[] = [ - { kind: CompletionItemKind.Value, label: localize('trueLabel', "true"), insertText: 'true', documentation: localize('trueDescription', "Enable the pattern.") }, - { kind: CompletionItemKind.Value, label: localize('falseLabel', "false"), insertText: 'false', documentation: localize('falseDescription', "Disable the pattern.") }, - { kind: CompletionItemKind.Value, label: localize('derivedLabel', "Files with Siblings by Name"), insertText: '{ "when": "$(basename).{{extension}}" }', documentation: localize('siblingsDescription', "Match files that have siblings with the same name but a different extension.") } + { kind: CompletionItemKind.Value, label: localize('trueLabel', "true"), filterText: 'true', insertText: 'true', documentation: localize('trueDescription', "Enable the pattern.") }, + { kind: CompletionItemKind.Value, label: localize('falseLabel', "false"), filterText: 'false', insertText: 'false', documentation: localize('falseDescription', "Disable the pattern.") }, + { kind: CompletionItemKind.Value, label: localize('derivedLabel', "Files with Siblings by Name"), insertText: SnippetString.create('{ "when": "$(basename).${1:extension}" }'), documentation: localize('siblingsDescription', "Match files that have siblings with the same name but a different extension.") } ]; export class GlobPatternContribution implements JSONWorkerContribution { @@ -42,7 +42,6 @@ export class GlobPatternContribution implements JSONWorkerContribution { public collectPropertyCompletions(resource: string, location: JSONPath, currentWord: string, addValue: boolean, isLast: boolean, result: CompletionsCollector): Thenable { if (this.isSettingsFile(resource) && location.length === 1 && ((location[0] === 'files.exclude') || (location[0] === 'search.exclude'))) { globProperties.forEach(e => { - e.filterText = e.insertText; result.add(e); }); } @@ -53,7 +52,6 @@ export class GlobPatternContribution implements JSONWorkerContribution { public collectValueCompletions(resource: string, location: JSONPath, currentKey: string, result: CompletionsCollector): Thenable { if (this.isSettingsFile(resource) && location.length === 1 && ((location[0] === 'files.exclude') || (location[0] === 'search.exclude'))) { globValues.forEach(e => { - e.filterText = e.insertText; result.add(e); }); } diff --git a/extensions/json/server/src/jsoncontributions/projectJSONContribution.ts b/extensions/json/server/src/jsoncontributions/projectJSONContribution.ts index 059c0c06579..c3b9141b4a0 100644 --- a/extensions/json/server/src/jsoncontributions/projectJSONContribution.ts +++ b/extensions/json/server/src/jsoncontributions/projectJSONContribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { MarkedString, CompletionItemKind, CompletionItem } from 'vscode-languageserver'; +import { MarkedString, CompletionItemKind, CompletionItem, SnippetString } from 'vscode-languageserver'; import Strings = require('../utils/strings'); import { XHRResponse, getErrorStatusDescription, xhr } from 'request-light'; import { JSONWorkerContribution, JSONPath, CompletionsCollector } from 'vscode-json-languageservice'; @@ -47,9 +47,10 @@ export class ProjectJSONContribution implements JSONWorkerContribution { this.cacheSize--; return false; } + let insertTextValue = (item.insertText).value; item.detail = entry.version; item.documentation = entry.description; - item.insertText = item.insertText.replace(/\{\{\}\}/, '{{' + entry.version + '}}'); + item.insertText = insertTextValue.replace(/\$1/, '${1:' + entry.version + '}'); return true; } return false; @@ -102,15 +103,15 @@ export class ProjectJSONContribution implements JSONWorkerContribution { public collectDefaultCompletions(resource: string, result: CompletionsCollector): Thenable { if (this.isProjectJSONFile(resource)) { - let defaultValue = { - 'version': '{{1.0.0-*}}', + let insertText = SnippetString.create(JSON.stringify({ + 'version': '${1:1.0.0-*}', 'dependencies': {}, 'frameworks': { 'net461': {}, 'netcoreapp1.0': {} } - }; - result.add({ kind: CompletionItemKind.Class, label: localize('json.project.default', 'Default project.json'), insertText: JSON.stringify(defaultValue, null, '\t'), documentation: '' }); + }, null, '\t')); + result.add({ kind: CompletionItemKind.Class, label: localize('json.project.default', 'Default project.json'), insertText, documentation: '' }); } return null; } @@ -149,12 +150,12 @@ export class ProjectJSONContribution implements JSONWorkerContribution { let name = results[i]; let insertText = JSON.stringify(name); if (addValue) { - insertText += ': "{{}}"'; + insertText += ': "$1"'; if (!isLast) { insertText += ','; } } - let item: CompletionItem = { kind: CompletionItemKind.Property, label: name, insertText: insertText, filterText: JSON.stringify(name) }; + let item: CompletionItem = { kind: CompletionItemKind.Property, label: name, insertText: SnippetString.create(insertText), filterText: JSON.stringify(name) }; if (!this.completeWithCache(name, item)) { item.data = RESOLVE_ID + name; } diff --git a/extensions/json/server/src/typings/promise.d.ts b/extensions/json/server/src/typings/promise.d.ts deleted file mode 100644 index 804a76812e9..00000000000 --- a/extensions/json/server/src/typings/promise.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - -/** - * The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's - * lib.core.es6.d.ts file. See above Copyright notice. - */ - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise libary is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommand the use of native promises which are available in VS Code. - */ -interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; -} - -/** - * Represents the completion of an asynchronous operation - */ -interface Promise extends Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Promise; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Promise; - - /** - * Attaches a callback for only the rejection of the Promise. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch(onrejected?: (reason: any) => T | Thenable): Promise; -} - -interface PromiseConstructor { - /** - * Creates a new Promise. - * @param executor A callback used to initialize the promise. This callback is passed two arguments: - * a resolve callback used resolve the promise with a value or the result of another promise, - * and a reject callback used to reject the promise with a provided reason or error. - */ - new (executor: (resolve: (value?: T | Thenable) => void, reject: (reason?: any) => void) => void): Promise; - - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - all(values: Array>): Promise; - - /** - * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved - * or rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - race(values: Array>): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new resolved promise for the provided value. - * @param value A promise. - * @returns A promise whose internal state matches the provided promise. - */ - resolve(value: T | Thenable): Promise; - - /** - * Creates a new resolved promise . - * @returns A resolved promise. - */ - resolve(): Promise; -} - -declare var Promise: PromiseConstructor; diff --git a/extensions/json/server/src/typings/ref.d.ts b/extensions/json/server/src/typings/ref.d.ts deleted file mode 100644 index c55bcba02fc..00000000000 --- a/extensions/json/server/src/typings/ref.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -/// -/// -/// -/// \ No newline at end of file diff --git a/extensions/json/server/tsconfig.json b/extensions/json/server/tsconfig.json index b37b37e55dc..c2a86a0af35 100644 --- a/extensions/json/server/tsconfig.json +++ b/extensions/json/server/tsconfig.json @@ -1,11 +1,13 @@ { "compilerOptions": { - "noLib": true, "target": "es5", "module": "commonjs", "sourceMap": true, "sourceRoot": "../src", - "outDir": "./out" + "outDir": "./out", + "lib": [ + "es5", "es2015.promise" + ] }, "exclude": [ "node_modules" From ea26b957f6c593410724cd341e1db2c7c37170b8 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 25 Nov 2016 17:04:18 +0100 Subject: [PATCH 19/30] Adopt new snippet syntax in JSON schema defaultSnippets (for #15573) --- extensions/javascript/src/features/bowerJSONContribution.ts | 2 +- .../server/src/jsoncontributions/globPatternContribution.ts | 2 +- src/vs/editor/common/services/modeServiceImpl.ts | 2 +- src/vs/editor/node/textMate/TMSnippets.ts | 2 +- src/vs/editor/node/textMate/TMSyntax.ts | 4 ++-- src/vs/platform/extensions/common/extensionsRegistry.ts | 2 +- .../jsonschemas/common/jsonValidationExtensionPoint.ts | 4 ++-- .../snippets/electron-browser/snippets.contribution.ts | 2 +- .../parts/tasks/electron-browser/task.contribution.ts | 2 +- .../test/node/configurationResolverService.test.ts | 6 +++--- .../keybinding/electron-browser/keybindingService.ts | 2 +- .../services/themes/electron-browser/themeService.ts | 4 ++-- 12 files changed, 17 insertions(+), 17 deletions(-) diff --git a/extensions/javascript/src/features/bowerJSONContribution.ts b/extensions/javascript/src/features/bowerJSONContribution.ts index d40b4477f97..c8ecb91aeb3 100644 --- a/extensions/javascript/src/features/bowerJSONContribution.ts +++ b/extensions/javascript/src/features/bowerJSONContribution.ts @@ -117,7 +117,7 @@ export class BowerJSONContribution implements IJSONContribution { if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']))) { // not implemented. Could be do done calling the bower command. Waiting for web API: https://github.com/bower/registry/issues/26 let proposal = new CompletionItem(localize('json.bower.latest.version', 'latest')); - proposal.insertText = '"{{latest}}"'; + proposal.insertText = new SnippetString('"${1:latest}"'); proposal.filterText = '""'; proposal.kind = CompletionItemKind.Value; proposal.documentation = 'The latest version of the package'; diff --git a/extensions/json/server/src/jsoncontributions/globPatternContribution.ts b/extensions/json/server/src/jsoncontributions/globPatternContribution.ts index 1d79d6ae1a4..91815efcc93 100644 --- a/extensions/json/server/src/jsoncontributions/globPatternContribution.ts +++ b/extensions/json/server/src/jsoncontributions/globPatternContribution.ts @@ -14,7 +14,7 @@ const localize = nls.loadMessageBundle(); let globProperties: CompletionItem[] = [ { kind: CompletionItemKind.Value, label: localize('fileLabel', "Files by Extension"), insertText: SnippetString.create('"**/*.${1:extension}": true'), documentation: localize('fileDescription', "Match all files of a specific file extension.") }, { kind: CompletionItemKind.Value, label: localize('filesLabel', "Files with Multiple Extensions"), insertText: '"**/*.{ext1,ext2,ext3}": true', documentation: localize('filesDescription', "Match all files with any of the file extensions.") }, - { kind: CompletionItemKind.Value, label: localize('derivedLabel', "Files with Siblings by Name"), insertText: SnippetString.create('"**/*.${1:source-extension}": { "when": "$(basename).{{target-extension}}" }'), documentation: localize('derivedDescription', "Match files that have siblings with the same name but a different extension.") }, + { kind: CompletionItemKind.Value, label: localize('derivedLabel', "Files with Siblings by Name"), insertText: SnippetString.create('"**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" }'), documentation: localize('derivedDescription', "Match files that have siblings with the same name but a different extension.") }, { kind: CompletionItemKind.Value, label: localize('topFolderLabel', "Folder by Name (Top Level)"), insertText: SnippetString.create('"${1:name}": true'), documentation: localize('topFolderDescription', "Match a top level folder with a specific name.") }, { kind: CompletionItemKind.Value, label: localize('topFoldersLabel', "Folders with Multiple Names (Top Level)"), insertText: '"{folder1,folder2,folder3}": true', documentation: localize('topFoldersDescription', "Match multiple top level folders.") }, { kind: CompletionItemKind.Value, label: localize('folderLabel', "Folder by Name (Any Location)"), insertText: SnippetString.create('"**/${1:name}": true'), documentation: localize('folderDescription', "Match a folder with a specific name in any location.") }, diff --git a/src/vs/editor/common/services/modeServiceImpl.ts b/src/vs/editor/common/services/modeServiceImpl.ts index ffb1424db08..7b723710f9c 100644 --- a/src/vs/editor/common/services/modeServiceImpl.ts +++ b/src/vs/editor/common/services/modeServiceImpl.ts @@ -29,7 +29,7 @@ export const languagesExtPoint: IExtensionPoint = Ext type: 'array', items: { type: 'object', - defaultSnippets: [{ body: { id: '{{languageId}}', aliases: ['{{label}}'], extensions: ['{{extension}}'], configuration: './language-configuration.json' } }], + defaultSnippets: [{ body: { id: '${1:languageId}', aliases: ['${2:label}'], extensions: ['${3:extension}'], configuration: './language-configuration.json' } }], properties: { id: { description: nls.localize('vscode.extension.contributes.languages.id', 'ID of the language.'), diff --git a/src/vs/editor/node/textMate/TMSnippets.ts b/src/vs/editor/node/textMate/TMSnippets.ts index 40273eca78d..359af387762 100644 --- a/src/vs/editor/node/textMate/TMSnippets.ts +++ b/src/vs/editor/node/textMate/TMSnippets.ts @@ -26,7 +26,7 @@ let snippetsExtensionPoint = ExtensionsRegistry.registerExtensionPoint = ExtensionsRegistry.registerExtensionPoint('grammars', [languagesExtPoint], { description: nls.localize('vscode.extension.contributes.grammars', 'Contributes textmate tokenizers.'), type: 'array', - defaultSnippets: [{ body: [{ language: '{{id}}', scopeName: 'source.{{id}}', path: './syntaxes/{{id}}.tmLanguage.' }] }], + defaultSnippets: [{ body: [{ language: '${1:id}', scopeName: 'source.${2:id}', path: './syntaxes/${3:id}.tmLanguage.' }] }], items: { type: 'object', - defaultSnippets: [{ body: { language: '{{id}}', scopeName: 'source.{{id}}', path: './syntaxes/{{id}}.tmLanguage.' } }], + defaultSnippets: [{ body: { language: '${1:id}', scopeName: 'source.${2:id}', path: './syntaxes/${3:id}.tmLanguage.' } }], properties: { language: { description: nls.localize('vscode.extension.contributes.grammars.language', 'Language identifier for which this syntax is contributed to.'), diff --git a/src/vs/platform/extensions/common/extensionsRegistry.ts b/src/vs/platform/extensions/common/extensionsRegistry.ts index 9ac75057f5a..9c03f542d3d 100644 --- a/src/vs/platform/extensions/common/extensionsRegistry.ts +++ b/src/vs/platform/extensions/common/extensionsRegistry.ts @@ -175,7 +175,7 @@ const schema: IJSONSchema = { type: 'array', items: { type: 'string', - defaultSnippets: [{ label: 'onLanguage', body: 'onLanguage:{{languageId}}' }, { label: 'onCommand', body: 'onCommand:{{commandId}}' }, { label: 'onDebug', body: 'onDebug:{{type}}' }, { label: 'workspaceContains', body: 'workspaceContains:{{fileName}}' }], + defaultSnippets: [{ label: 'onLanguage', body: 'onLanguage:${1:languageId}' }, { label: 'onCommand', body: 'onCommand:${2:commandId}' }, { label: 'onDebug', body: 'onDebug:${3:type}' }, { label: 'workspaceContains', body: 'workspaceContains:${4:fileName}' }], } }, badges: { diff --git a/src/vs/platform/jsonschemas/common/jsonValidationExtensionPoint.ts b/src/vs/platform/jsonschemas/common/jsonValidationExtensionPoint.ts index 70864e06df8..53e5c714ec3 100644 --- a/src/vs/platform/jsonschemas/common/jsonValidationExtensionPoint.ts +++ b/src/vs/platform/jsonschemas/common/jsonValidationExtensionPoint.ts @@ -18,10 +18,10 @@ interface IJSONValidationExtensionPoint { let configurationExtPoint = ExtensionsRegistry.registerExtensionPoint('jsonValidation', [], { description: nls.localize('contributes.jsonValidation', 'Contributes json schema configuration.'), type: 'array', - defaultSnippets: [{ body: [{ fileMatch: '{{file.json}}', url: '{{url}}' }] }], + defaultSnippets: [{ body: [{ fileMatch: '${1:file.json}', url: '${2:url}' }] }], items: { type: 'object', - defaultSnippets: [{ body: { fileMatch: '{{file.json}}', url: '{{url}}' } }], + defaultSnippets: [{ body: { fileMatch: '${1:file.json}', url: '${2:url}' } }], properties: { fileMatch: { type: 'string', diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts b/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts index f379808316e..695e9b98f9a 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts @@ -124,7 +124,7 @@ let schema: IJSONSchema = { 'id': schemaId, 'defaultSnippets': [{ 'label': nls.localize('snippetSchema.json.default', "Empty snippet"), - 'body': { '{{snippetName}}': { 'prefix': '{{prefix}}', 'body': '{{snippet}}', 'description': '{{description}}' } } + 'body': { '${1:snippetName}': { 'prefix': '${2:prefix}', 'body': '${3:snippet}', 'description': '${4:description}' } } }], 'type': 'object', 'description': nls.localize('snippetSchema.json', 'User snippet configuration'), diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 9144ac3d9ca..40900fc4c27 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -1361,7 +1361,7 @@ let schema: IJSONSchema = { 'label': 'Empty task', 'body': { - 'taskName': '{{taskName}}' + 'taskName': '${1:taskName}' } } ] diff --git a/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts index bbcf1bb2e5d..efde22699b2 100644 --- a/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts @@ -200,10 +200,10 @@ suite('Configuration Resolver Service', () => { schemas: [ { fileMatch: [ - '{{/myfile}}', - '{{/myOtherfile}}' + '/myfile', + '/myOtherfile' ], - url: '{{schemaURL}}' + url: 'schemaURL' } ] } diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index c64fd9f4d05..8457ab25e91 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -277,7 +277,7 @@ let schema: IJSONSchema = { 'items': { 'required': ['key'], 'type': 'object', - 'defaultSnippets': [{ 'body': { 'key': '{{_}}', 'command': '{{_}}', 'when': '{{_}}' } }], + 'defaultSnippets': [{ 'body': { 'key': '$1', 'command': '$2', 'when': '$3' } }], 'properties': { 'key': { 'type': 'string', diff --git a/src/vs/workbench/services/themes/electron-browser/themeService.ts b/src/vs/workbench/services/themes/electron-browser/themeService.ts index 10966a451ec..fc42eb47f2d 100644 --- a/src/vs/workbench/services/themes/electron-browser/themeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/themeService.ts @@ -58,7 +58,7 @@ let themesExtPoint = ExtensionsRegistry.registerExtensionPoint Date: Fri, 25 Nov 2016 17:21:43 +0100 Subject: [PATCH 20/30] more tests, escape \ when building, #16056 --- .../contrib/snippet/test/common/snippetParser.test.ts | 1 + src/vs/workbench/api/node/extHostTypes.ts | 8 ++++++-- src/vs/workbench/test/node/api/extHostTypes.test.ts | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts b/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts index bc4d54f2474..33c90427276 100644 --- a/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts +++ b/src/vs/editor/contrib/snippet/test/common/snippetParser.test.ts @@ -116,6 +116,7 @@ suite('SnippetParser', () => { assertEscape('\\abc', '\\abc'); assertEscape('foo${f:\\}}bar', 'foo}bar'); assertEscape('\\{', '{'); + assertEscape('I need \\\\\\$', 'I need \\$'); assertEscape('\\', '\\'); assertEscape('\\{{', '{{'); assertEscape('{{', '{{'); diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index d7a2ce867a0..8a6ca5041e3 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -524,6 +524,10 @@ export class WorkspaceEdit { export class SnippetString { + private static _escape(value: string): string { + return value.replace(/\$|}|\\/g, '\\$&'); + } + private _tabstop: number = 1; value: string; @@ -533,7 +537,7 @@ export class SnippetString { } appendText(string: string): SnippetString { - this.value += string.replace(/\$/g, '\\$'); + this.value += SnippetString._escape(string); return this; } @@ -552,7 +556,7 @@ export class SnippetString { this._tabstop = nested._tabstop; value = nested.value; } else { - value = value.replace(/\$|}/g, '\\$&'); + value = SnippetString._escape(value); } this.value += '${'; diff --git a/src/vs/workbench/test/node/api/extHostTypes.test.ts b/src/vs/workbench/test/node/api/extHostTypes.test.ts index b2253497d7d..87c9dc78186 100644 --- a/src/vs/workbench/test/node/api/extHostTypes.test.ts +++ b/src/vs/workbench/test/node/api/extHostTypes.test.ts @@ -424,6 +424,9 @@ suite('ExtHostTypes', function () { string = new types.SnippetString(); assert.equal(string.appendText('I need $ and $').value, 'I need \\$ and \\$'); + string = new types.SnippetString(); + assert.equal(string.appendText('I need \\$').value, 'I need \\\\\\$'); + string = new types.SnippetString(); string.appendPlaceholder('fo$o}'); assert.equal(string.value, '${1:fo\\$o\\}}'); From 6101251cf10285cd0ee022d0c8a160e268e4150c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 25 Nov 2016 17:23:06 +0100 Subject: [PATCH 21/30] more precise docs, #16056 --- src/vs/editor/contrib/snippet/common/snippet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/snippet/common/snippet.md b/src/vs/editor/contrib/snippet/common/snippet.md index c0cd8e0c43b..e7006f8f04b 100644 --- a/src/vs/editor/contrib/snippet/common/snippet.md +++ b/src/vs/editor/contrib/snippet/common/snippet.md @@ -27,7 +27,7 @@ With `$name` or `${name:default}` you can insert the value of a variable. When a Grammar -- -Below is the EBNF for snippets. The `$`-character can be escaped using backslash, like `\$`. +Below is the EBNF for snippets. With `\` (backslash) you can escape `$`, `}` and `\`. ``` any ::= tabstop | placeholder | variable | text From dcbfc1a9b70b6dc8a166c4911c895c1f5dd37ec4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 17:25:05 +0100 Subject: [PATCH 22/30] get rid of IViewletService#onReady() --- .../workbench/browser/parts/activitybar/activitybarPart.ts | 4 +++- src/vs/workbench/electron-browser/integration.ts | 6 ++++-- src/vs/workbench/services/viewlet/browser/viewlet.ts | 5 ----- src/vs/workbench/services/viewlet/browser/viewletService.ts | 6 +----- src/vs/workbench/test/browser/services.test.ts | 4 ---- 5 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 95c8070cd64..ad8e8f2b76a 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -21,6 +21,7 @@ import { IActivityService, IBadge } from 'vs/workbench/services/activity/common/ import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IExtensionService } from 'vs/platform/extensions/common/extensions'; export class ActivitybarPart extends Part implements IActivityService { public _serviceBrand: any; @@ -32,6 +33,7 @@ export class ActivitybarPart extends Part implements IActivityService { constructor( id: string, @IViewletService private viewletService: IViewletService, + @IExtensionService private extensionService: IExtensionService, @IKeybindingService private keybindingService: IKeybindingService, @IInstantiationService private instantiationService: IInstantiationService, @IPartService private partService: IPartService @@ -42,7 +44,7 @@ export class ActivitybarPart extends Part implements IActivityService { this.compositeIdToActions = {}; // Update viewlet switcher when external viewlets become ready - this.viewletService.onReady().then(() => this.updateViewletSwitcher()); + this.extensionService.onReady().then(() => this.updateViewletSwitcher()); this.registerListeners(); } diff --git a/src/vs/workbench/electron-browser/integration.ts b/src/vs/workbench/electron-browser/integration.ts index 2adb99774fa..862198cae98 100644 --- a/src/vs/workbench/electron-browser/integration.ts +++ b/src/vs/workbench/electron-browser/integration.ts @@ -42,6 +42,7 @@ import { ReloadWindowAction, ToggleDevToolsAction, ShowStartupPerformance, OpenR import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { ipcRenderer as ipc, webFrame, remote } from 'electron'; @@ -77,6 +78,7 @@ export class ElectronIntegration { @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IEnvironmentService private environmentService: IEnvironmentService, + @IExtensionService private extensionService: IExtensionService, @IThemeService private themeService: IThemeService, @IViewletService private viewletService: IViewletService ) { @@ -110,8 +112,8 @@ export class ElectronIntegration { }, () => errors.onUnexpectedError); }); - // Send over all extension viewlets when ready - this.viewletService.onReady().then(() => { + // Send over all extension viewlets when extensions are ready + this.extensionService.onReady().then(() => { ipc.send('vscode:extensionViewlets', JSON.stringify(this.viewletService.getViewlets().filter(v => v.fromExtension).map(v => { return { id: v.id, label: v.name }; }))); }); diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index b6ee280e5af..38fa31e77b1 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -23,11 +23,6 @@ export interface IViewletService { */ openViewlet(id: string, focus?: boolean): TPromise; - /** - * Allows to wait until all viewlets are ready, including contributed ones. - */ - onReady(): TPromise; - /** * Returns the current active viewlet or null if none. */ diff --git a/src/vs/workbench/services/viewlet/browser/viewletService.ts b/src/vs/workbench/services/viewlet/browser/viewletService.ts index d0be7110208..45e46aa42f5 100644 --- a/src/vs/workbench/services/viewlet/browser/viewletService.ts +++ b/src/vs/workbench/services/viewlet/browser/viewletService.ts @@ -37,10 +37,6 @@ export class ViewletService implements IViewletService { this.loadExtensionViewlets(); } - public onReady(): TPromise { - return this.extensionViewletsLoaded; - } - private loadExtensionViewlets(): void { this.extensionViewlets = []; @@ -70,7 +66,7 @@ export class ViewletService implements IViewletService { } // Extension viewlets need to be loaded first which can take time - return this.onReady().then(() => { + return this.extensionViewletsLoaded.then(() => { if (this.viewletRegistry.getViewlet(id)) { return this.sidebarPart.openViewlet(id, focus); } diff --git a/src/vs/workbench/test/browser/services.test.ts b/src/vs/workbench/test/browser/services.test.ts index fdd5ecdd494..59c76ffb782 100644 --- a/src/vs/workbench/test/browser/services.test.ts +++ b/src/vs/workbench/test/browser/services.test.ts @@ -104,10 +104,6 @@ class TestViewletService implements IViewletService { onDidViewletOpen = this.onDidViewletOpenEmitter.event; onDidViewletClose = this.onDidViewletCloseEmitter.event; - public onReady(): TPromise { - return TPromise.as(null); - } - public openViewlet(id: string, focus?: boolean): TPromise { return TPromise.as(null); } From e0a8269fcd571badf792e5d2b7bd9722dc00bd84 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 25 Nov 2016 17:33:57 +0100 Subject: [PATCH 23/30] Open file/folder dialog needs to know its target window (fixes #5796) --- src/vs/code/electron-main/windows.ts | 15 ++++++++------- .../windows/electron-main/windowsService.ts | 4 +++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 4a836792785..bb7793ba3b5 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -75,6 +75,7 @@ interface INativeOpenDialogOptions { pickFiles?: boolean; path?: string; forceNewWindow?: boolean; + window?: VSCodeWindow; } const ReopenFoldersSetting = { @@ -100,8 +101,8 @@ export interface IWindowsMainService { open(openConfig: IOpenConfiguration): VSCodeWindow[]; openPluginDevelopmentHostWindow(openConfig: IOpenConfiguration): void; openFileFolderPicker(forceNewWindow?: boolean): void; - openFilePicker(forceNewWindow?: boolean, path?: string): void; - openFolderPicker(forceNewWindow?: boolean): void; + openFilePicker(forceNewWindow?: boolean, path?: string, window?: VSCodeWindow): void; + openFolderPicker(forceNewWindow?: boolean, window?: VSCodeWindow): void; openAccessibilityOptions(): void; focusLastActive(cli: ParsedArgs): VSCodeWindow; getLastActiveWindow(): VSCodeWindow; @@ -862,12 +863,12 @@ export class WindowsManager implements IWindowsMainService { this.doPickAndOpen({ pickFolders: true, pickFiles: true, forceNewWindow }); } - public openFilePicker(forceNewWindow?: boolean, path?: string): void { - this.doPickAndOpen({ pickFiles: true, forceNewWindow, path }); + public openFilePicker(forceNewWindow?: boolean, path?: string, window?: VSCodeWindow): void { + this.doPickAndOpen({ pickFiles: true, forceNewWindow, path, window }); } - public openFolderPicker(forceNewWindow?: boolean): void { - this.doPickAndOpen({ pickFolders: true, forceNewWindow }); + public openFolderPicker(forceNewWindow?: boolean, window?: VSCodeWindow): void { + this.doPickAndOpen({ pickFolders: true, forceNewWindow, window }); } public openAccessibilityOptions(): void { @@ -896,7 +897,7 @@ export class WindowsManager implements IWindowsMainService { private getFileOrFolderPaths(options: INativeOpenDialogOptions, clb: (paths: string[]) => void): void { const workingDir = options.path || this.storageService.getItem(WindowsManager.workingDirPickerStorageKey); - const focussedWindow = this.getFocusedWindow(); + const focussedWindow = options.window || this.getFocusedWindow(); let pickerProperties: ('openFile' | 'openDirectory' | 'multiSelections' | 'createDirectory')[]; if (options.pickFiles && options.pickFolders) { diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 031fb1c254e..12159a4db22 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -49,7 +49,9 @@ export class WindowsService implements IWindowsService, IDisposable { } openFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise { - this.windowsMainService.openFolderPicker(forceNewWindow); + const vscodeWindow = this.windowsMainService.getWindowById(windowId); + this.windowsMainService.openFolderPicker(forceNewWindow, vscodeWindow); + return TPromise.as(null); } From 42a2fb715dae15d06fabb7a7eaf10543e11bb133 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 26 Nov 2016 06:29:38 -0800 Subject: [PATCH 24/30] Indicate multiple licenses in rpm package Fixes #15993 --- resources/linux/rpm/code.spec.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/linux/rpm/code.spec.template b/resources/linux/rpm/code.spec.template index e0a9b681d15..8e5c3c95b65 100644 --- a/resources/linux/rpm/code.spec.template +++ b/resources/linux/rpm/code.spec.template @@ -5,7 +5,7 @@ Summary: Code editing. Redefined. Group: Development/Tools Vendor: Microsoft Corporation Packager: Visual Studio Code Team -License: MIT +License: Multiple, see https://code.visualstudio.com/license URL: https://code.visualstudio.com/ Icon: @@NAME@@.xpm Requires: glibc >= 2.15 From 2c8ab1a5ffc49ac26b2080bfbbbf9317fb8071bb Mon Sep 17 00:00:00 2001 From: roblou Date: Sun, 27 Nov 2016 19:21:22 -0800 Subject: [PATCH 25/30] node-debug2@1.8.2 --- build/gulpfile.vscode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index bcb65664b2c..94f73f29b9d 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -40,7 +40,7 @@ const nodeModules = ['electron', 'original-fs'] const builtInExtensions = [ { name: 'ms-vscode.node-debug', version: '1.8.5' }, - { name: 'ms-vscode.node-debug2', version: '1.8.1' } + { name: 'ms-vscode.node-debug2', version: '1.8.2' } ]; const vscodeEntryPoints = _.flatten([ From aac98278822a18a0bd09415957446ea4e970c5e0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 28 Nov 2016 09:59:18 +0100 Subject: [PATCH 26/30] ConfigurationService#lookup is responsible for 25% of startup time (fixes #15884) --- src/vs/platform/configuration/common/model.ts | 5 ++ .../node/configurationService.ts | 11 +++-- src/vs/workbench/api/node/extHost.protocol.ts | 6 +-- .../api/node/extHostConfiguration.ts | 10 ++-- .../api/node/mainThreadConfiguration.ts | 5 +- .../electron-browser/extensionHost.ts | 4 +- .../configuration/common/configuration.ts | 28 ++++------- .../node/configurationService.ts | 20 +++++++- .../test/node/configurationService.test.ts | 48 +++++++++++++++++++ .../node/api/extHostConfiguration.test.ts | 4 +- 10 files changed, 101 insertions(+), 40 deletions(-) diff --git a/src/vs/platform/configuration/common/model.ts b/src/vs/platform/configuration/common/model.ts index 319d6f65bc8..a981336a59d 100644 --- a/src/vs/platform/configuration/common/model.ts +++ b/src/vs/platform/configuration/common/model.ts @@ -10,18 +10,22 @@ import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/co export function getDefaultValues(): any { const valueTreeRoot: any = Object.create(null); const properties = Registry.as(Extensions.Configuration).getConfigurationProperties(); + for (let key in properties) { let value = properties[key].default; addToValueTree(valueTreeRoot, key, value); } + return valueTreeRoot; } export function toValuesTree(properties: { [qualifiedKey: string]: any }): any { const root = Object.create(null); + for (let key in properties) { addToValueTree(root, key, properties[key]); } + return root; } @@ -51,5 +55,6 @@ function addToValueTree(settingsTreeRoot: any, key: string, value: any): void { export function getConfigurationKeys(): string[] { const properties = Registry.as(Extensions.Configuration).getConfigurationProperties(); + return Object.keys(properties); } \ No newline at end of file diff --git a/src/vs/platform/configuration/node/configurationService.ts b/src/vs/platform/configuration/node/configurationService.ts index 6ab74957ded..a6d45964518 100644 --- a/src/vs/platform/configuration/node/configurationService.ts +++ b/src/vs/platform/configuration/node/configurationService.ts @@ -50,7 +50,9 @@ export class ConfigurationService implements IConfigurationService, IDisposab private onConfigurationChange(source: ConfigurationSource): void { this.cache = void 0; // reset our caches + const cache = this.getCache(); + this._onDidUpdateConfiguration.fire({ config: this.getConfiguration(), source, @@ -74,6 +76,7 @@ export class ConfigurationService implements IConfigurationService, IDisposab public getConfiguration(section?: string): C { const cache = this.getCache(); + return section ? cache.consolidated[section] : cache.consolidated; } @@ -82,11 +85,13 @@ export class ConfigurationService implements IConfigurationService, IDisposab } public lookup(key: string): IConfigurationValue { + const cache = this.getCache(); + // make sure to clone the configuration so that the receiver does not tamper with the values return { - default: objects.clone(getConfigurationValue(getDefaultValues(), key)), - user: objects.clone(getConfigurationValue(toValuesTree(this.rawConfig.getConfig()), key)), - value: objects.clone(getConfigurationValue(this.getConfiguration(), key)) + default: objects.clone(getConfigurationValue(cache.defaults, key)), + user: objects.clone(getConfigurationValue(cache.user, key)), + value: objects.clone(getConfigurationValue(cache.consolidated, key)) }; } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index f3f2d98ab63..43d81718bf8 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -29,7 +29,7 @@ import * as modes from 'vs/editor/common/modes'; import { IResourceEdit } from 'vs/editor/common/services/bulkEdit'; import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing'; -import { IWorkspaceConfiguration } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkspaceConfigurationValues } from 'vs/workbench/services/configuration/common/configuration'; import { IPickOpenEntry, IPickOptions } from 'vs/workbench/services/quickopen/common/quickOpenService'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; @@ -54,7 +54,7 @@ export interface IInitData { workspace: IWorkspace; }; extensions: IExtensionDescription[]; - configuration: IWorkspaceConfiguration; + configuration: IWorkspaceConfigurationValues; telemetryInfo: ITelemetryInfo; } @@ -236,7 +236,7 @@ export abstract class ExtHostCommandsShape { } export abstract class ExtHostConfigurationShape { - $acceptConfigurationChanged(entries: IWorkspaceConfiguration) { throw ni(); } + $acceptConfigurationChanged(values: IWorkspaceConfigurationValues) { throw ni(); } } export abstract class ExtHostDiagnosticsShape { diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 8f7a6be3450..32d39cf84c5 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -9,7 +9,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import { WorkspaceConfiguration } from 'vscode'; import { ExtHostConfigurationShape, MainThreadConfigurationShape } from './extHost.protocol'; import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing'; -import { IWorkspaceConfiguration } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkspaceConfigurationValues } from 'vs/workbench/services/configuration/common/configuration'; import { toValuesTree } from 'vs/platform/configuration/common/model'; function lookUp(tree: any, key: string) { @@ -24,11 +24,11 @@ function lookUp(tree: any, key: string) { } interface UsefulConfiguration { - data: IWorkspaceConfiguration; + data: IWorkspaceConfigurationValues; valueTree: any; } -function createUsefulConfiguration(data: IWorkspaceConfiguration): { data: IWorkspaceConfiguration, valueTree: any } { +function createUsefulConfiguration(data: IWorkspaceConfigurationValues): { data: IWorkspaceConfigurationValues, valueTree: any } { const valueMap: { [key: string]: any } = Object.create(null); for (let key in data) { if (Object.prototype.hasOwnProperty.call(data, key)) { @@ -48,7 +48,7 @@ export class ExtHostConfiguration extends ExtHostConfigurationShape { private _proxy: MainThreadConfigurationShape; private _configuration: UsefulConfiguration; - constructor(proxy: MainThreadConfigurationShape, data: IWorkspaceConfiguration) { + constructor(proxy: MainThreadConfigurationShape, data: IWorkspaceConfigurationValues) { super(); this._proxy = proxy; this._configuration = createUsefulConfiguration(data); @@ -58,7 +58,7 @@ export class ExtHostConfiguration extends ExtHostConfigurationShape { return this._onDidChangeConfiguration && this._onDidChangeConfiguration.event; } - public $acceptConfigurationChanged(data: IWorkspaceConfiguration) { + public $acceptConfigurationChanged(data: IWorkspaceConfigurationValues) { this._configuration = createUsefulConfiguration(data); this._onDidChangeConfiguration.fire(undefined); } diff --git a/src/vs/workbench/api/node/mainThreadConfiguration.ts b/src/vs/workbench/api/node/mainThreadConfiguration.ts index 486d4023598..c77a7b026f4 100644 --- a/src/vs/workbench/api/node/mainThreadConfiguration.ts +++ b/src/vs/workbench/api/node/mainThreadConfiguration.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; -import { IWorkspaceConfigurationService, getEntries } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing'; import { MainThreadConfigurationShape, ExtHostContext } from './extHost.protocol'; @@ -26,8 +26,7 @@ export class MainThreadConfiguration extends MainThreadConfigurationShape { const proxy = threadService.get(ExtHostContext.ExtHostConfiguration); this._toDispose = configurationService.onDidUpdateConfiguration(() => { - const entries = getEntries(configurationService); - proxy.$acceptConfigurationChanged(entries); + proxy.$acceptConfigurationChanged(configurationService.values()); }); } diff --git a/src/vs/workbench/electron-browser/extensionHost.ts b/src/vs/workbench/electron-browser/extensionHost.ts index 73eb60ec53a..45cb2377562 100644 --- a/src/vs/workbench/electron-browser/extensionHost.ts +++ b/src/vs/workbench/electron-browser/extensionHost.ts @@ -30,7 +30,7 @@ import { WatchDog } from 'vs/base/common/watchDog'; import { createQueuedSender, IQueuedSender } from 'vs/base/node/processes'; import { IInitData } from 'vs/workbench/api/node/extHost.protocol'; import { MainProcessExtensionService } from 'vs/workbench/api/node/mainThreadExtensionService'; -import { IWorkspaceConfigurationService, getEntries } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; export const EXTENSION_LOG_BROADCAST_CHANNEL = 'vscode:extensionLog'; export const EXTENSION_ATTACH_BROADCAST_CHANNEL = 'vscode:extensionAttach'; @@ -260,7 +260,7 @@ export class ExtensionHostProcessWorker { workspace: this.contextService.getWorkspace() }, extensions: extensionDescriptions, - configuration: getEntries(this.configurationService), + configuration: this.configurationService.values(), telemetryInfo }; this.extensionHostProcessQueuedSender.send(stringify(initData)); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 22d6bce007a..5a5f277bb74 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -12,6 +12,8 @@ export const WORKSPACE_CONFIG_DEFAULT_PATH = `${WORKSPACE_CONFIG_FOLDER_DEFAULT_ export const IWorkspaceConfigurationService = createDecorator('configurationService'); +export type IWorkspaceConfigurationValues = { [key: string]: IWorkspaceConfigurationValue } + export interface IWorkspaceConfigurationService extends IConfigurationService { /** @@ -28,6 +30,11 @@ export interface IWorkspaceConfigurationService extends IConfigurationService { * Override for the IConfigurationService#keys() method that adds information about workspace settings. */ keys(): IWorkspaceConfigurationKeys; + + /** + * Returns the defined values of configurations in the different scopes. + */ + values(): IWorkspaceConfigurationValues; } export interface IWorkspaceConfigurationValue extends IConfigurationValue { @@ -41,23 +48,4 @@ export interface IWorkspaceConfigurationKeys extends IConfigurationKeys { export const WORKSPACE_STANDALONE_CONFIGURATIONS = { 'tasks': `${WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME}/tasks.json`, 'launch': `${WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME}/launch.json` -}; - -export type IWorkspaceConfiguration = { [key: string]: IWorkspaceConfigurationValue } - -export function getEntries(configurationService: IWorkspaceConfigurationService): IWorkspaceConfiguration { - - const result: IWorkspaceConfiguration = Object.create(null); - const keyset = configurationService.keys(); - const keys = [...keyset.workspace, ...keyset.user, ...keyset.default].sort(); - let lastKey: string; - for (const key of keys) { - if (key !== lastKey) { - lastKey = key; - const config = configurationService.lookup(key); - result[key] = config; - } - } - - return result; -} +}; \ No newline at end of file diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index e5ffa8328ad..8bbe0bb8c48 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -21,7 +21,7 @@ import errors = require('vs/base/common/errors'); import { IConfigFile, consolidate, newConfigFile } from 'vs/workbench/services/configuration/common/model'; import { IConfigurationServiceEvent, ConfigurationSource, getConfigurationValue } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService as BaseConfigurationService } from 'vs/platform/configuration/node/configurationService'; -import { IWorkspaceConfigurationService, IWorkspaceConfigurationValue, CONFIG_DEFAULT_NAME, WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME, WORKSPACE_STANDALONE_CONFIGURATIONS, WORKSPACE_CONFIG_DEFAULT_PATH } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkspaceConfigurationValues, IWorkspaceConfigurationService, IWorkspaceConfigurationValue, CONFIG_DEFAULT_NAME, WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME, WORKSPACE_STANDALONE_CONFIGURATIONS, WORKSPACE_CONFIG_DEFAULT_PATH } from 'vs/workbench/services/configuration/common/configuration'; import { EventType as FileEventType, FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; import Event, { Emitter } from 'vs/base/common/event'; @@ -136,7 +136,7 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer default: configurationValue.default, user: configurationValue.user, workspace: getConfigurationValue(this.cachedWorkspaceConfig, key), - value: getConfigurationValue(this.getConfiguration(), key) + value: getConfigurationValue(this.cachedConfig, key) }; } @@ -150,6 +150,22 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer }; } + public values(): IWorkspaceConfigurationValues { + const result: IWorkspaceConfigurationValues = Object.create(null); + const keyset = this.keys(); + const keys = [...keyset.workspace, ...keyset.user, ...keyset.default].sort(); + + let lastKey: string; + for (const key of keys) { + if (key !== lastKey) { + lastKey = key; + result[key] = this.lookup(key); + } + } + + return result; + } + public reloadConfiguration(section?: string): TPromise { // Reset caches to ensure we are hitting the disk diff --git a/src/vs/workbench/services/configuration/test/node/configurationService.test.ts b/src/vs/workbench/services/configuration/test/node/configurationService.test.ts index d3ea1f4423e..dfa694fe0f3 100644 --- a/src/vs/workbench/services/configuration/test/node/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/node/configurationService.test.ts @@ -361,4 +361,52 @@ suite('WorkspaceConfigurationService - Node', () => { }); }); }); + + test('values', (done: () => void) => { + const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); + configurationRegistry.registerConfiguration({ + 'id': '_test', + 'type': 'object', + 'properties': { + 'workspaceLookup.service.testSetting': { + 'type': 'string', + 'default': 'isSet' + } + } + }); + + createWorkspace((workspaceDir, globalSettingsFile, cleanUp) => { + return createService(workspaceDir, globalSettingsFile).then(service => { + let values = service.values(); + let value = values['workspaceLookup.service.testSetting']; + + assert.ok(value); + assert.equal(value.default, 'isSet'); + + fs.writeFileSync(globalSettingsFile, '{ "workspaceLookup.service.testSetting": true }'); + + return service.reloadConfiguration().then(() => { + values = service.values(); + value = values['workspaceLookup.service.testSetting']; + + assert.ok(value); + assert.equal(value.user, true); + + const settingsFile = path.join(workspaceDir, '.vscode', 'settings.json'); + fs.writeFileSync(settingsFile, '{ "workspaceLookup.service.testSetting": 55 }'); + + return service.reloadConfiguration().then(() => { + values = service.values(); + value = values['workspaceLookup.service.testSetting']; + + assert.ok(value); + assert.equal(value.user, true); + assert.equal(value.workspace, 55); + + done(); + }); + }); + }); + }); + }); }); \ No newline at end of file diff --git a/src/vs/workbench/test/node/api/extHostConfiguration.test.ts b/src/vs/workbench/test/node/api/extHostConfiguration.test.ts index 825611201c3..6eaf22734ae 100644 --- a/src/vs/workbench/test/node/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/node/api/extHostConfiguration.test.ts @@ -10,7 +10,7 @@ import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration import { MainThreadConfigurationShape } from 'vs/workbench/api/node/extHost.protocol'; import { TPromise } from 'vs/base/common/winjs.base'; import { ConfigurationTarget, ConfigurationEditingErrorCode, IConfigurationEditingError } from 'vs/workbench/services/configuration/common/configurationEditing'; -import { IWorkspaceConfiguration, IWorkspaceConfigurationValue } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkspaceConfigurationValues, IWorkspaceConfigurationValue } from 'vs/workbench/services/configuration/common/configuration'; suite('ExtHostConfiguration', function () { @@ -22,7 +22,7 @@ suite('ExtHostConfiguration', function () { } }; - function createExtHostConfiguration(data: IWorkspaceConfiguration = Object.create(null), shape?: MainThreadConfigurationShape) { + function createExtHostConfiguration(data: IWorkspaceConfigurationValues = Object.create(null), shape?: MainThreadConfigurationShape) { if (!shape) { shape = new class extends MainThreadConfigurationShape { }; } From 527d9662eaeac4b36a531276653f8db85ec9e6b1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 28 Nov 2016 10:01:20 +0100 Subject: [PATCH 27/30] perf - add memory info and loadvavg --- src/vs/workbench/electron-browser/actions.ts | 3 ++- src/vs/workbench/electron-browser/common.ts | 11 +++++++++++ src/vs/workbench/electron-browser/shell.ts | 13 +++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 3c243d2c02c..a23624c2134 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -342,7 +342,8 @@ export class ShowStartupPerformance extends Action { const fingerprint: IStartupFingerprint = timers.fingerprint; console.log(`OS: ${fingerprint.platform} (${fingerprint.release})`); console.log(`CPUs: ${fingerprint.cpus.model} (${fingerprint.cpus.count} x ${fingerprint.cpus.speed})`); - console.log(`Memory: ${(fingerprint.totalmem / (1024 * 1024 * 1024)).toFixed(2)}GB (${(fingerprint.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`); + console.log(`Memory (System): ${(fingerprint.totalmem / (1024 * 1024 * 1024)).toFixed(2)}GB (${(fingerprint.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`); + console.log(`Memory (Process): ${(fingerprint.meminfo.workingSetSize / 1024).toFixed(2)}MB working set (${(fingerprint.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(fingerprint.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(fingerprint.meminfo.sharedBytes / 1024).toFixed(2)}MB shared)`); console.log(`Initial Startup: ${fingerprint.initialStartup}`); console.log(`Screen Reader Active: ${fingerprint.hasAccessibilitySupport}`); console.log(`Empty Workspace: ${fingerprint.emptyWorkbench}`); diff --git a/src/vs/workbench/electron-browser/common.ts b/src/vs/workbench/electron-browser/common.ts index f9deeb5b3af..9f0daa8d39b 100644 --- a/src/vs/workbench/electron-browser/common.ts +++ b/src/vs/workbench/electron-browser/common.ts @@ -21,7 +21,15 @@ export interface IWindowConfiguration { window: IWindowSettings; } +export interface IMemoryInfo { + workingSetSize: number; + peakWorkingSetSize: number; + privateBytes: number; + sharedBytes: number; +} + export interface IStartupFingerprint { + version: number; ellapsed: number; timers: { ellapsedWindowLoad?: number; @@ -32,13 +40,16 @@ export interface IStartupFingerprint { ellapsedViewletRestore: number; ellapsedEditorRestore: number; ellapsedWorkbench: number; + ellapsedTimersToTimersComputed: number; }; platform: string; release: string; totalmem: number; freemem: number; + meminfo: IMemoryInfo; cpus: { count: number; speed: number; model: string; }; initialStartup: boolean; hasAccessibilitySupport: boolean; emptyWorkbench: boolean; + loadavg: number[]; } \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 26adb26638f..a927b9dc424 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -20,7 +20,7 @@ import product from 'vs/platform/product'; import pkg from 'vs/platform/package'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import timer = require('vs/base/common/timer'); -import { IStartupFingerprint } from 'vs/workbench/electron-browser/common'; +import { IStartupFingerprint, IMemoryInfo } from 'vs/workbench/electron-browser/common'; import { Workbench } from 'vs/workbench/electron-browser/workbench'; import { StorageService, inMemoryLocalStorageInstance } from 'vs/workbench/services/storage/common/storageService'; import { ITelemetryService, NullTelemetryService, configurationTelemetry, loadExperiments } from 'vs/platform/telemetry/common/telemetry'; @@ -212,6 +212,7 @@ export class WorkbenchShell { const workbenchStarted = Date.now(); timers.workbenchStarted = new Date(workbenchStarted); this.extensionService.onReady().done(() => { + const now = Date.now(); const initialStartup = !!timers.isInitialStartup; const start = initialStartup ? timers.perfStartTime : timers.perfWindowLoadTime; let totalmem: number; @@ -219,12 +220,16 @@ export class WorkbenchShell { let cpus: { count: number; speed: number; model: string; }; let platform: string; let release: string; + let loadavg: number[]; + let meminfo: IMemoryInfo; try { totalmem = os.totalmem(); freemem = os.freemem(); platform = os.platform(); release = os.release(); + loadavg = os.loadavg(); + meminfo = process.getProcessMemoryInfo(); const rawCpus = os.cpus(); if (rawCpus && rawCpus.length > 0) { @@ -235,6 +240,7 @@ export class WorkbenchShell { } const startupTimeEvent: IStartupFingerprint = { + version: 1, ellapsed: Math.round(workbenchStarted - start), timers: { ellapsedExtensions: Math.round(timers.perfAfterExtensionLoad - timers.perfBeforeExtensionLoad), @@ -243,13 +249,16 @@ export class WorkbenchShell { ellapsedViewletRestore: Math.round(restoreViewletDuration), ellapsedEditorRestore: Math.round(restoreEditorsDuration), ellapsedWorkbench: Math.round(workbenchStarted - timers.perfBeforeWorkbenchOpen), - ellapsedWindowLoadToRequire: Math.round(timers.perfBeforeLoadWorkbenchMain - timers.perfWindowLoadTime) + ellapsedWindowLoadToRequire: Math.round(timers.perfBeforeLoadWorkbenchMain - timers.perfWindowLoadTime), + ellapsedTimersToTimersComputed: Date.now() - now }, platform, release, totalmem, freemem, + meminfo, cpus, + loadavg, initialStartup, hasAccessibilitySupport: !!timers.hasAccessibilitySupport, emptyWorkbench: !this.contextService.getWorkspace() From eb271c85d56ae7cd6e03b1203c812650e476e465 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 28 Nov 2016 10:03:40 +0100 Subject: [PATCH 28/30] Investigate regression to `code ` in hot exit (fixes #15274) --- src/vs/code/electron-main/windows.ts | 41 ++++++++++++---------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 5d3b9b894ce..cf37cc95c01 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -330,9 +330,10 @@ export class WindowsManager implements IWindowsMainService { iPathsToOpen = this.cliToPaths(openConfig.cli, ignoreFileNotFound); } + let foldersToOpen = arrays.distinct(iPathsToOpen.filter(iPath => iPath.workspacePath && !iPath.filePath).map(iPath => iPath.workspacePath), folder => platform.isLinux ? folder : folder.toLowerCase()); // prevent duplicates + let foldersToRestore = (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath) ? this.backupService.getWorkspaceBackupPaths() : []; let filesToOpen: IPath[] = []; let filesToDiff: IPath[] = []; - let foldersToOpen = iPathsToOpen.filter(iPath => iPath.workspacePath && !iPath.filePath); let emptyToOpen = iPathsToOpen.filter(iPath => !iPath.workspacePath && !iPath.filePath); let filesToCreate = iPathsToOpen.filter(iPath => !!iPath.filePath && iPath.createFilePath); @@ -345,27 +346,15 @@ export class WindowsManager implements IWindowsMainService { emptyToOpen = [Object.create(null)]; // improper use of diffMode, open empty } - foldersToOpen = []; // diff is always in empty workspace - filesToCreate = []; // diff ignores other files that do not exist + foldersToOpen = []; // diff is always in empty workspace + foldersToRestore = []; // diff is always in empty workspace + filesToCreate = []; // diff ignores other files that do not exist } else { filesToOpen = candidates; } let openInNewWindow = openConfig.preferNewWindow || openConfig.forceNewWindow; - // Restore any existing backup workspaces on the first initial startup, provided an - // extension development path is not being launch. - if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath) { - const workspacesWithBackups = this.backupService.getWorkspaceBackupPaths(); - workspacesWithBackups.forEach(workspacePath => { - const configuration = this.toConfiguration(openConfig, workspacePath); - const browserWindow = this.openInBrowserWindow(configuration, true /* new window */); - usedWindows.push(browserWindow); - - openInNewWindow = true; // any other folders to open must open in new window then - }); - } - // Handle files to open/diff or to create when we dont open a folder if (!foldersToOpen.length && (filesToOpen.length > 0 || filesToCreate.length > 0 || filesToDiff.length > 0)) { @@ -400,15 +389,21 @@ export class WindowsManager implements IWindowsMainService { const browserWindow = this.openInBrowserWindow(configuration, true /* new window */); usedWindows.push(browserWindow); - openConfig.forceNewWindow = true; // any other folders to open must open in new window then + openInNewWindow = true; // any other folders to open must open in new window then } + + // Reset these because we handled them + filesToOpen = []; + filesToCreate = []; + filesToDiff = []; } - // Handle folders to open - if (foldersToOpen.length > 0) { + // Handle folders to open (instructed and to restore) + let allFoldersToOpen = arrays.distinct([...foldersToOpen, ...foldersToRestore], folder => platform.isLinux ? folder : folder.toLowerCase()); // prevent duplicates + if (allFoldersToOpen.length > 0) { // Check for existing instances - const windowsOnWorkspacePath = arrays.coalesce(foldersToOpen.map(iPath => this.findWindow(iPath.workspacePath))); + const windowsOnWorkspacePath = arrays.coalesce(allFoldersToOpen.map(folderToOpen => this.findWindow(folderToOpen))); if (windowsOnWorkspacePath.length > 0) { const browserWindow = windowsOnWorkspacePath[0]; browserWindow.focus(); // just focus one of them @@ -427,12 +422,12 @@ export class WindowsManager implements IWindowsMainService { } // Open remaining ones - foldersToOpen.forEach(folderToOpen => { - if (windowsOnWorkspacePath.some(win => this.isPathEqual(win.openedWorkspacePath, folderToOpen.workspacePath))) { + allFoldersToOpen.forEach(folderToOpen => { + if (windowsOnWorkspacePath.some(win => this.isPathEqual(win.openedWorkspacePath, folderToOpen))) { return; // ignore folders that are already open } - const configuration = this.toConfiguration(openConfig, folderToOpen.workspacePath, filesToOpen, filesToCreate, filesToDiff); + const configuration = this.toConfiguration(openConfig, folderToOpen, filesToOpen, filesToCreate, filesToDiff); const browserWindow = this.openInBrowserWindow(configuration, openInNewWindow, openInNewWindow ? void 0 : openConfig.windowToUse); usedWindows.push(browserWindow); From 8f92dcd2bc33b276ffab3a96a0bc886c5ca3a597 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 28 Nov 2016 10:17:41 +0100 Subject: [PATCH 29/30] Manage extension from status bar and viewlets (for #15155) --- .../base/browser/ui/actionbar/actionbar.css | 1 - src/vs/platform/statusbar/common/statusbar.ts | 5 + src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- src/vs/workbench/api/node/extHostStatusBar.ts | 13 +- .../workbench/api/node/mainThreadStatusBar.ts | 4 +- .../api/node/mainThreadTreeExplorers.ts | 4 +- .../parts/activitybar/activityAction.ts | 127 +++++++++++++++--- .../parts/activitybar/activitybarPart.ts | 94 ++++--------- .../browser/parts/statusbar/statusbarPart.ts | 34 +++++ src/vs/workbench/browser/viewlet.ts | 8 +- .../workbench/electron-browser/integration.ts | 2 +- .../explorers/{ => browser}/media/Refresh.svg | 0 .../{ => browser}/media/Refresh_inverse.svg | 0 .../media/treeExplorer.contribution.css | 0 .../browser/treeExplorer.contribution.ts | 12 +- ...lorerService.ts => treeExplorerService.ts} | 4 +- .../browser/views/treeExplorerView.ts | 12 +- .../browser/views/treeExplorerViewer.ts | 10 +- ...lorerService.ts => treeExplorerService.ts} | 4 +- .../extensions.contribution.ts | 14 +- .../viewlet/browser/viewletService.ts | 4 +- 22 files changed, 229 insertions(+), 127 deletions(-) rename src/vs/workbench/parts/explorers/{ => browser}/media/Refresh.svg (100%) rename src/vs/workbench/parts/explorers/{ => browser}/media/Refresh_inverse.svg (100%) rename src/vs/workbench/parts/explorers/{ => browser}/media/treeExplorer.contribution.css (100%) rename src/vs/workbench/parts/explorers/browser/{customTreeExplorerService.ts => treeExplorerService.ts} (93%) rename src/vs/workbench/parts/explorers/common/{customTreeExplorerService.ts => treeExplorerService.ts} (87%) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.css b/src/vs/base/browser/ui/actionbar/actionbar.css index 6a0a66de8f3..81c86cb8eff 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.css +++ b/src/vs/base/browser/ui/actionbar/actionbar.css @@ -71,7 +71,6 @@ } .monaco-action-bar.vertical .action-item { - padding-bottom: 0.1em; display: block; } diff --git a/src/vs/platform/statusbar/common/statusbar.ts b/src/vs/platform/statusbar/common/statusbar.ts index b5f9a3c0e5d..6e45f806115 100644 --- a/src/vs/platform/statusbar/common/statusbar.ts +++ b/src/vs/platform/statusbar/common/statusbar.ts @@ -40,6 +40,11 @@ export interface IStatusbarEntry { * An optional id of a command that is known to the workbench to execute on click */ command?: string; + + /** + * An optional extension ID if this entry is provided from an extension. + */ + extensionId?: string; } export interface IStatusbarService { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index be5a2dfb6b0..bc4b9611d82 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -269,7 +269,7 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ return extHostQuickOpen.showInput(options, token); }, createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem { - return extHostStatusBar.createStatusBarEntry(position, priority); + return extHostStatusBar.createStatusBarEntry(extension.id, position, priority); }, setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): vscode.Disposable { return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable); diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 43d81718bf8..6637c5b3e35 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -201,7 +201,7 @@ export abstract class MainThreadQuickOpenShape { } export abstract class MainThreadStatusBarShape { - $setEntry(id: number, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { throw ni(); } + $setEntry(id: number, extensionId: string, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { throw ni(); } $dispose(id: number) { throw ni(); } } diff --git a/src/vs/workbench/api/node/extHostStatusBar.ts b/src/vs/workbench/api/node/extHostStatusBar.ts index aa695ebe033..97c917caf51 100644 --- a/src/vs/workbench/api/node/extHostStatusBar.ts +++ b/src/vs/workbench/api/node/extHostStatusBar.ts @@ -27,11 +27,14 @@ export class ExtHostStatusBarEntry implements StatusBarItem { private _timeoutHandle: number; private _proxy: MainThreadStatusBarShape; - constructor(proxy: MainThreadStatusBarShape, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) { + private _extensionId: string; + + constructor(proxy: MainThreadStatusBarShape, extensionId: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) { this._id = ExtHostStatusBarEntry.ID_GEN++; this._proxy = proxy; this._alignment = alignment; this._priority = priority; + this._extensionId = extensionId; } public get id(): number { @@ -105,7 +108,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem { this._timeoutHandle = undefined; // Set to status bar - this._proxy.$setEntry(this.id, this.text, this.tooltip, this.command, this.color, + this._proxy.$setEntry(this.id, this._extensionId, this.text, this.tooltip, this.command, this.color, this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT, this._priority); }, 0); @@ -123,7 +126,7 @@ class StatusBarMessage { private _messages: { message: string }[] = []; constructor(statusBar: ExtHostStatusBar) { - this._item = statusBar.createStatusBarEntry(ExtHostStatusBarAlignment.Left, Number.MIN_VALUE); + this._item = statusBar.createStatusBarEntry(void 0, ExtHostStatusBarAlignment.Left, Number.MIN_VALUE); } dispose() { @@ -165,8 +168,8 @@ export class ExtHostStatusBar { this._statusMessage = new StatusBarMessage(this); } - createStatusBarEntry(alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem { - return new ExtHostStatusBarEntry(this._proxy, alignment, priority); + createStatusBarEntry(extensionId: string, alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem { + return new ExtHostStatusBarEntry(this._proxy, extensionId, alignment, priority); } setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): Disposable { diff --git a/src/vs/workbench/api/node/mainThreadStatusBar.ts b/src/vs/workbench/api/node/mainThreadStatusBar.ts index dd5b87b78ab..ed435c97485 100644 --- a/src/vs/workbench/api/node/mainThreadStatusBar.ts +++ b/src/vs/workbench/api/node/mainThreadStatusBar.ts @@ -18,13 +18,13 @@ export class MainThreadStatusBar extends MainThreadStatusBarShape { this.mapIdToDisposable = Object.create(null); } - $setEntry(id: number, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { + $setEntry(id: number, extensionId: string, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { // Dispose any old this.$dispose(id); // Add new - let disposeable = this.statusbarService.addEntry({ text, tooltip, command, color }, alignment, priority); + let disposeable = this.statusbarService.addEntry({ text, tooltip, command, color, extensionId }, alignment, priority); this.mapIdToDisposable[id] = disposeable; } diff --git a/src/vs/workbench/api/node/mainThreadTreeExplorers.ts b/src/vs/workbench/api/node/mainThreadTreeExplorers.ts index 1116abd95c4..c0f8ded4be4 100644 --- a/src/vs/workbench/api/node/mainThreadTreeExplorers.ts +++ b/src/vs/workbench/api/node/mainThreadTreeExplorers.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; import { ExtHostContext, MainThreadTreeExplorersShape, ExtHostTreeExplorersShape } from './extHost.protocol'; -import { ICustomTreeExplorerService } from 'vs/workbench/parts/explorers/common/customTreeExplorerService'; +import { ITreeExplorerService } from 'vs/workbench/parts/explorers/common/treeExplorerService'; import { InternalTreeExplorerNodeContent } from 'vs/workbench/parts/explorers/common/treeExplorerViewModel'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -17,7 +17,7 @@ export class MainThreadTreeExplorers extends MainThreadTreeExplorersShape { constructor( @IThreadService private threadService: IThreadService, - @ICustomTreeExplorerService private treeExplorerService: ICustomTreeExplorerService, + @ITreeExplorerService private treeExplorerService: ITreeExplorerService, @IMessageService private messageService: IMessageService, @ICommandService private commandService: ICommandService ) { diff --git a/src/vs/workbench/browser/parts/activitybar/activityAction.ts b/src/vs/workbench/browser/parts/activitybar/activityAction.ts index 7d2094c0866..f828641da67 100644 --- a/src/vs/workbench/browser/parts/activitybar/activityAction.ts +++ b/src/vs/workbench/browser/parts/activitybar/activityAction.ts @@ -7,15 +7,25 @@ import 'vs/css!./media/activityaction'; import nls = require('vs/nls'); +import DOM = require('vs/base/browser/dom'); +import errors = require('vs/base/common/errors'); +import { TPromise } from 'vs/base/common/winjs.base'; import { Builder, $ } from 'vs/base/browser/builder'; import { DelayedDragHandler } from 'vs/base/browser/dnd'; import { Action } from 'vs/base/common/actions'; import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge } from 'vs/workbench/services/activity/common/activityService'; import Event, { Emitter } from 'vs/base/common/event'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; export class ActivityAction extends Action { - private badge: IBadge; private _onDidChangeBadge = new Emitter(); @@ -51,6 +61,49 @@ export class ActivityAction extends Action { } } +export class ViewletActivityAction extends ActivityAction { + + private static preventDoubleClickDelay = 300; + + private lastRun: number = 0; + + constructor( + id: string, + private viewlet: ViewletDescriptor, + @IViewletService private viewletService: IViewletService, + @IPartService private partService: IPartService + ) { + super(id, viewlet.name, viewlet.cssClass); + } + + public run(event): TPromise { + if (event instanceof MouseEvent && event.button === 2) { + return TPromise.as(false); // do not run on right click + } + + // prevent accident trigger on a doubleclick (to help nervous people) + const now = Date.now(); + if (now - this.lastRun < ViewletActivityAction.preventDoubleClickDelay) { + return TPromise.as(true); + } + this.lastRun = now; + + const sideBarVisible = this.partService.isVisible(Parts.SIDEBAR_PART); + const activeViewlet = this.viewletService.getActiveViewlet(); + + // Hide sidebar if selected viewlet already visible + if (sideBarVisible && activeViewlet && activeViewlet.getId() === this.viewlet.id) { + this.partService.setSideBarHidden(true); + } else { + this.viewletService.openViewlet(this.viewlet.id, true).done(null, errors.onUnexpectedError); + this.activate(); + } + + return TPromise.as(true); + } +} + +let manageExtensionAction: ManageExtensionAction; export class ActivityActionItem extends BaseActionItem { private $e: Builder; @@ -59,14 +112,34 @@ export class ActivityActionItem extends BaseActionItem { private cssClass: string; private $badge: Builder; private $badgeContent: Builder; + private toDispose: IDisposable[]; - constructor(action: ActivityAction, activityName: string = action.label, keybinding: string = null) { + constructor( + action: ActivityAction, + private viewlet: ViewletDescriptor, + @IContextMenuService private contextMenuService: IContextMenuService, + @IKeybindingService private keybindingService: IKeybindingService, + @IInstantiationService instantiationService: IInstantiationService + ) { super(null, action); this.cssClass = action.class; - this.name = activityName; - this._keybinding = keybinding; - action.onDidChangeBadge(this._handleBadgeChangeEvenet, this, this._callOnDispose); + this.name = viewlet.name; + this._keybinding = this.getKeybindingLabel(viewlet.id); + action.onDidChangeBadge(this.handleBadgeChangeEvenet, this, this._callOnDispose); + + if (!manageExtensionAction) { + manageExtensionAction = instantiationService.createInstance(ManageExtensionAction); + } + } + + private getKeybindingLabel(id: string): string { + const keys = this.keybindingService.lookupKeybindings(id).map(k => this.keybindingService.getLabelFor(k)); + if (keys && keys.length) { + return keys[0]; + } + + return null; } public render(container: HTMLElement): void { @@ -77,6 +150,18 @@ export class ActivityActionItem extends BaseActionItem { role: 'button' }).appendTo(this.builder); + if (this.viewlet.extensionId) { + $(container).on('contextmenu', e => { + DOM.EventHelper.stop(e, true); + + this.contextMenuService.showContextMenu({ + getAnchor: () => container, + getActionsContext: () => this.viewlet.extensionId, + getActions: () => TPromise.as([manageExtensionAction]) + }); + }, this.toDispose); + } + if (this.cssClass) { this.$e.addClass(this.cssClass); } @@ -113,7 +198,6 @@ export class ActivityActionItem extends BaseActionItem { } let title: string; - if (keybinding) { title = nls.localize('titleKeybinding', "{0} ({1})", this.name, keybinding); } else { @@ -132,17 +216,15 @@ export class ActivityActionItem extends BaseActionItem { // Number if (badge instanceof NumberBadge) { - let n = (badge).number; - - if (n) { - this.$badgeContent.text(n > 99 ? '99+' : n.toString()); + if (badge.number) { + this.$badgeContent.text(badge.number > 99 ? '99+' : badge.number.toString()); this.$badge.show(); } } // Text else if (badge instanceof TextBadge) { - this.$badgeContent.text((badge).text); + this.$badgeContent.text(badge.text); this.$badge.show(); } @@ -156,7 +238,7 @@ export class ActivityActionItem extends BaseActionItem { this.$badge.show(); } - this.$e.attr('aria-label', this.name + ' - ' + badge.getDescription()); + this.$e.attr('aria-label', `${this.name} - ${badge.getDescription()}`); } } @@ -177,10 +259,10 @@ export class ActivityActionItem extends BaseActionItem { } } - private _handleBadgeChangeEvenet(): void { - let action = this.getAction(); + private handleBadgeChangeEvenet(): void { + const action = this.getAction(); if (action instanceof ActivityAction) { - this.updateBadge((action).getBadge()); + this.updateBadge(action.getBadge()); } } @@ -195,7 +277,22 @@ export class ActivityActionItem extends BaseActionItem { public dispose(): void { super.dispose(); + dispose(this.toDispose); + this.$badge.destroy(); this.$e.destroy(); } +} + +class ManageExtensionAction extends Action { + + constructor( + @ICommandService private commandService: ICommandService + ) { + super('statusbar.manage.extension', nls.localize('manageExtension', "Manage Extension")); + } + + public run(extensionId: string): TPromise { + return this.commandService.executeCommand('_extensions.manage', extensionId); + } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index ad8e8f2b76a..2495758d828 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -7,18 +7,16 @@ import 'vs/css!./media/activitybarpart'; import nls = require('vs/nls'); -import { TPromise } from 'vs/base/common/winjs.base'; import { Builder, $ } from 'vs/base/browser/builder'; import { Action } from 'vs/base/common/actions'; -import errors = require('vs/base/common/errors'); import { ActionsOrientation, ActionBar, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { IComposite } from 'vs/workbench/common/composite'; import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; import { Part } from 'vs/workbench/browser/part'; -import { ActivityAction, ActivityActionItem } from 'vs/workbench/browser/parts/activitybar/activityAction'; +import { ViewletActivityAction, ActivityAction, ActivityActionItem } from 'vs/workbench/browser/parts/activitybar/activityAction'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IActivityService, IBadge } from 'vs/workbench/services/activity/common/activityService'; -import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; +import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; @@ -28,7 +26,7 @@ export class ActivitybarPart extends Part implements IActivityService { private viewletSwitcherBar: ActionBar; private activityActionItems: { [actionId: string]: IActionItem; }; - private compositeIdToActions: { [compositeId: string]: ActivityAction; }; + private viewletIdToActions: { [viewletId: string]: ActivityAction; }; constructor( id: string, @@ -41,7 +39,7 @@ export class ActivitybarPart extends Part implements IActivityService { super(id); this.activityActionItems = {}; - this.compositeIdToActions = {}; + this.viewletIdToActions = {}; // Update viewlet switcher when external viewlets become ready this.extensionService.onReady().then(() => this.updateViewletSwitcher()); @@ -59,19 +57,19 @@ export class ActivitybarPart extends Part implements IActivityService { } private onActiveCompositeChanged(composite: IComposite): void { - if (this.compositeIdToActions[composite.getId()]) { - this.compositeIdToActions[composite.getId()].activate(); + if (this.viewletIdToActions[composite.getId()]) { + this.viewletIdToActions[composite.getId()].activate(); } } private onCompositeClosed(composite: IComposite): void { - if (this.compositeIdToActions[composite.getId()]) { - this.compositeIdToActions[composite.getId()].deactivate(); + if (this.viewletIdToActions[composite.getId()]) { + this.viewletIdToActions[composite.getId()].deactivate(); } } - public showActivity(compositeId: string, badge: IBadge, clazz?: string): void { - const action = this.compositeIdToActions[compositeId]; + public showActivity(viewletId: string, badge: IBadge, clazz?: string): void { + const action = this.viewletIdToActions[viewletId]; if (action) { action.setBadge(badge); if (clazz) { @@ -80,8 +78,8 @@ export class ActivitybarPart extends Part implements IActivityService { } } - public clearActivity(compositeId: string): void { - this.showActivity(compositeId, null); + public clearActivity(viewletId: string): void { + this.showActivity(viewletId, null); } public createContentArea(parent: Builder): Builder { @@ -109,7 +107,7 @@ export class ActivitybarPart extends Part implements IActivityService { // Pull out viewlets no longer needed const newViewletIds = viewlets.map(v => v.id); - const existingViewletIds = Object.keys(this.compositeIdToActions); + const existingViewletIds = Object.keys(this.viewletIdToActions); existingViewletIds.forEach(viewletId => { if (newViewletIds.indexOf(viewletId) === -1) { this.pullViewlet(viewletId); @@ -118,7 +116,7 @@ export class ActivitybarPart extends Part implements IActivityService { // Built actions for viewlets to show const actionsToPush = viewlets - .filter(viewlet => !this.compositeIdToActions[viewlet.id]) + .filter(viewlet => !this.viewletIdToActions[viewlet.id]) .map(viewlet => this.toAction(viewlet)); // Add to viewlet switcher @@ -127,7 +125,7 @@ export class ActivitybarPart extends Part implements IActivityService { // Make sure to activate the active one const activeViewlet = this.viewletService.getActiveViewlet(); if (activeViewlet) { - const activeViewletEntry = this.compositeIdToActions[activeViewlet.getId()]; + const activeViewletEntry = this.viewletIdToActions[activeViewlet.getId()]; if (activeViewletEntry) { activeViewletEntry.activate(); } @@ -135,11 +133,11 @@ export class ActivitybarPart extends Part implements IActivityService { } private pullViewlet(viewletId: string): void { - const index = Object.keys(this.compositeIdToActions).indexOf(viewletId); + const index = Object.keys(this.viewletIdToActions).indexOf(viewletId); - const action = this.compositeIdToActions[viewletId]; + const action = this.viewletIdToActions[viewletId]; action.dispose(); - delete this.compositeIdToActions[viewletId]; + delete this.viewletIdToActions[viewletId]; const actionItem = this.activityActionItems[action.id]; actionItem.dispose(); @@ -148,24 +146,15 @@ export class ActivitybarPart extends Part implements IActivityService { this.viewletSwitcherBar.pull(index); } - private toAction(composite: ViewletDescriptor): ActivityAction { - const action = this.instantiationService.createInstance(ViewletActivityAction, `${composite.id}.activity-bar-action`, composite); + private toAction(viewlet: ViewletDescriptor): ActivityAction { + const action = this.instantiationService.createInstance(ViewletActivityAction, `${viewlet.id}.activity-bar-action`, viewlet); - this.activityActionItems[action.id] = new ActivityActionItem(action, composite.name, this.getKeybindingLabel(composite.id)); - this.compositeIdToActions[composite.id] = action; + this.activityActionItems[action.id] = this.instantiationService.createInstance(ActivityActionItem, action, viewlet); + this.viewletIdToActions[viewlet.id] = action; return action; }; - private getKeybindingLabel(id: string): string { - const keys = this.keybindingService.lookupKeybindings(id).map(k => this.keybindingService.getLabelFor(k)); - if (keys && keys.length) { - return keys[0]; - } - - return null; - } - public dispose(): void { if (this.viewletSwitcherBar) { this.viewletSwitcherBar.dispose(); @@ -174,41 +163,4 @@ export class ActivitybarPart extends Part implements IActivityService { super.dispose(); } -} - -class ViewletActivityAction extends ActivityAction { - private static preventDoubleClickDelay = 300; - private lastRun: number = 0; - - constructor( - id: string, - private viewlet: ViewletDescriptor, - @IViewletService private viewletService: IViewletService, - @IPartService private partService: IPartService - ) { - super(id, viewlet.name, viewlet.cssClass); - } - - public run(): TPromise { - - // prevent accident trigger on a doubleclick (to help nervous people) - const now = Date.now(); - if (now - this.lastRun < ViewletActivityAction.preventDoubleClickDelay) { - return TPromise.as(true); - } - this.lastRun = now; - - const sideBarVisible = this.partService.isVisible(Parts.SIDEBAR_PART); - const activeViewlet = this.viewletService.getActiveViewlet(); - - // Hide sidebar if selected viewlet already visible - if (sideBarVisible && activeViewlet && activeViewlet.getId() === this.viewlet.id) { - this.partService.setSideBarHidden(true); - } else { - this.viewletService.openViewlet(this.viewlet.id, true).done(null, errors.onUnexpectedError); - this.activate(); - } - - return TPromise.as(true); - } -} +} \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index 8523116bda5..3be9c056516 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -24,6 +24,8 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { IStatusbarService, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar'; import { getCodeEditor } from 'vs/editor/common/services/codeEditorService'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { Action } from 'vs/base/common/actions'; export class StatusbarPart extends Part implements IStatusbarService { @@ -184,6 +186,7 @@ export class StatusbarPart extends Part implements IStatusbarService { } } +let manageExtensionAction: ManageExtensionAction; class StatusBarEntryItem implements IStatusbarItem { private entry: IStatusbarEntry; @@ -193,9 +196,14 @@ class StatusBarEntryItem implements IStatusbarItem { @IInstantiationService private instantiationService: IInstantiationService, @IMessageService private messageService: IMessageService, @ITelemetryService private telemetryService: ITelemetryService, + @IContextMenuService private contextMenuService: IContextMenuService, @IWorkbenchEditorService private editorService: IWorkbenchEditorService ) { this.entry = entry; + + if (!manageExtensionAction) { + manageExtensionAction = this.instantiationService.createInstance(ManageExtensionAction); + } } public render(el: HTMLElement): IDisposable { @@ -225,6 +233,19 @@ class StatusBarEntryItem implements IStatusbarItem { $(textContainer).color(this.entry.color); } + // Context Menu + if (this.entry.extensionId) { + $(textContainer).on('contextmenu', e => { + dom.EventHelper.stop(e, true); + + this.contextMenuService.showContextMenu({ + getAnchor: () => el, + getActionsContext: () => this.entry.extensionId, + getActions: () => TPromise.as([manageExtensionAction]) + }); + }, toDispose); + } + el.appendChild(textContainer); return { @@ -264,3 +285,16 @@ class StatusBarEntryItem implements IStatusbarItem { this.commandService.executeCommand(id).done(undefined, err => this.messageService.show(Severity.Error, toErrorMessage(err))); } } + +class ManageExtensionAction extends Action { + + constructor( + @ICommandService private commandService: ICommandService + ) { + super('statusbar.manage.extension', nls.localize('manageExtension', "Manage Extension")); + } + + public run(extensionId: string): TPromise { + return this.commandService.executeCommand('_extensions.manage', extensionId); + } +} \ No newline at end of file diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index 26c750ed022..f39bf7369bc 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -160,17 +160,17 @@ export class ViewletDescriptor extends CompositeDescriptor { name: string, cssClass?: string, order?: number, - private _fromExtension = false + private _extensionId?: string ) { super(moduleId, ctorName, id, name, cssClass, order); - if (_fromExtension) { + if (_extensionId) { this.appendStaticArguments([id]); // Pass viewletId to external viewlet, which doesn't know its id until runtime. } } - public get fromExtension(): boolean { - return this._fromExtension; + public get extensionId(): string { + return this._extensionId; } } diff --git a/src/vs/workbench/electron-browser/integration.ts b/src/vs/workbench/electron-browser/integration.ts index 862198cae98..7818d5d6fae 100644 --- a/src/vs/workbench/electron-browser/integration.ts +++ b/src/vs/workbench/electron-browser/integration.ts @@ -114,7 +114,7 @@ export class ElectronIntegration { // Send over all extension viewlets when extensions are ready this.extensionService.onReady().then(() => { - ipc.send('vscode:extensionViewlets', JSON.stringify(this.viewletService.getViewlets().filter(v => v.fromExtension).map(v => { return { id: v.id, label: v.name }; }))); + ipc.send('vscode:extensionViewlets', JSON.stringify(this.viewletService.getViewlets().filter(v => !!v.extensionId).map(v => { return { id: v.id, label: v.name }; }))); }); ipc.on('vscode:reportError', (event, error) => { diff --git a/src/vs/workbench/parts/explorers/media/Refresh.svg b/src/vs/workbench/parts/explorers/browser/media/Refresh.svg similarity index 100% rename from src/vs/workbench/parts/explorers/media/Refresh.svg rename to src/vs/workbench/parts/explorers/browser/media/Refresh.svg diff --git a/src/vs/workbench/parts/explorers/media/Refresh_inverse.svg b/src/vs/workbench/parts/explorers/browser/media/Refresh_inverse.svg similarity index 100% rename from src/vs/workbench/parts/explorers/media/Refresh_inverse.svg rename to src/vs/workbench/parts/explorers/browser/media/Refresh_inverse.svg diff --git a/src/vs/workbench/parts/explorers/media/treeExplorer.contribution.css b/src/vs/workbench/parts/explorers/browser/media/treeExplorer.contribution.css similarity index 100% rename from src/vs/workbench/parts/explorers/media/treeExplorer.contribution.css rename to src/vs/workbench/parts/explorers/browser/media/treeExplorer.contribution.css diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts index 474caf43f57..a5f958a63b6 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorer.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import 'vs/css!../media/treeExplorer.contribution'; +import 'vs/css!./media/treeExplorer.contribution'; import { localize } from 'vs/nls'; import { join } from 'vs/base/common/paths'; @@ -12,8 +12,8 @@ import { createCSSRule } from 'vs/base/browser/dom'; import { Registry } from 'vs/platform/platform'; import { ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { ICustomTreeExplorerService } from 'vs/workbench/parts/explorers/common/customTreeExplorerService'; -import { CustomTreeExplorerService } from 'vs/workbench/parts/explorers/browser/customTreeExplorerService'; +import { ITreeExplorerService } from 'vs/workbench/parts/explorers/common/treeExplorerService'; +import { TreeExplorerService } from 'vs/workbench/parts/explorers/browser/treeExplorerService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ToggleViewletAction } from 'vs/workbench/browser/viewlet'; import { ITreeExplorer } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -24,7 +24,7 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; -registerSingleton(ICustomTreeExplorerService, CustomTreeExplorerService); +registerSingleton(ITreeExplorerService, TreeExplorerService); const explorerSchema: IJSONSchema = { description: localize('vscode.extension.contributes.explorer', 'Contributes custom tree explorer viewlet to the sidebar'), @@ -103,8 +103,8 @@ export class ExtensionExplorersContribtion implements IWorkbenchContribution { viewletId, treeLabel, viewletCSSClass, - -1, // External viewlets are ordered by enabling sequence, so order here doesn't matter. - true // from extension + -1, + extension.description.id )); } }); diff --git a/src/vs/workbench/parts/explorers/browser/customTreeExplorerService.ts b/src/vs/workbench/parts/explorers/browser/treeExplorerService.ts similarity index 93% rename from src/vs/workbench/parts/explorers/browser/customTreeExplorerService.ts rename to src/vs/workbench/parts/explorers/browser/treeExplorerService.ts index 9983ec6ccc8..28db0e0c146 100644 --- a/src/vs/workbench/parts/explorers/browser/customTreeExplorerService.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorerService.ts @@ -10,9 +10,9 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { InternalTreeExplorerNode, InternalTreeExplorerNodeProvider } from 'vs/workbench/parts/explorers/common/treeExplorerViewModel'; -import { ICustomTreeExplorerService } from 'vs/workbench/parts/explorers/common/customTreeExplorerService'; +import { ITreeExplorerService } from 'vs/workbench/parts/explorers/common/treeExplorerService'; -export class CustomTreeExplorerService implements ICustomTreeExplorerService { +export class TreeExplorerService implements ITreeExplorerService { public _serviceBrand: any; private _onTreeExplorerNodeProviderRegistered = new Emitter(); diff --git a/src/vs/workbench/parts/explorers/browser/views/treeExplorerView.ts b/src/vs/workbench/parts/explorers/browser/views/treeExplorerView.ts index 5024a6f1baa..e8326f1461b 100644 --- a/src/vs/workbench/parts/explorers/browser/views/treeExplorerView.ts +++ b/src/vs/workbench/parts/explorers/browser/views/treeExplorerView.ts @@ -15,7 +15,7 @@ import { IMessageService } from 'vs/platform/message/common/message'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ICustomTreeExplorerService } from 'vs/workbench/parts/explorers/common/customTreeExplorerService'; +import { ITreeExplorerService } from 'vs/workbench/parts/explorers/common/treeExplorerService'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { TreeExplorerViewletState, TreeDataSource, TreeRenderer, TreeController } from 'vs/workbench/parts/explorers/browser/views/treeExplorerViewer'; @@ -35,7 +35,7 @@ export class TreeExplorerView extends CollapsibleViewletView { @IContextMenuService contextMenuService: IContextMenuService, @IWorkspaceContextService private contextService: IWorkspaceContextService, @IInstantiationService private instantiationService: IInstantiationService, - @ICustomTreeExplorerService private treeExplorerViewletService: ICustomTreeExplorerService, + @ITreeExplorerService private treeExplorerService: ITreeExplorerService, @IProgressService private progressService: IProgressService ) { super(actionRunner, false, nls.localize('treeExplorerViewlet.tree', "Tree Explorer Section"), messageService, keybindingService, contextMenuService, headerSize); @@ -86,8 +86,8 @@ export class TreeExplorerView extends CollapsibleViewletView { } public updateInput(): TPromise { - if (this.treeExplorerViewletService.hasProvider(this.treeNodeProviderId)) { - return this.treeExplorerViewletService.provideRootNode(this.treeNodeProviderId).then(tree => { + if (this.treeExplorerService.hasProvider(this.treeNodeProviderId)) { + return this.treeExplorerService.provideRootNode(this.treeNodeProviderId).then(tree => { this.tree.setInput(tree); }); } @@ -96,9 +96,9 @@ export class TreeExplorerView extends CollapsibleViewletView { // is registered. // This renders the viewlet first and wait for a corresponding provider is registered. else { - this.treeExplorerViewletService.onTreeExplorerNodeProviderRegistered(providerId => { + this.treeExplorerService.onTreeExplorerNodeProviderRegistered(providerId => { if (this.treeNodeProviderId === providerId) { - return this.treeExplorerViewletService.provideRootNode(this.treeNodeProviderId).then(tree => { + return this.treeExplorerService.provideRootNode(this.treeNodeProviderId).then(tree => { this.tree.setInput(tree); }); } diff --git a/src/vs/workbench/parts/explorers/browser/views/treeExplorerViewer.ts b/src/vs/workbench/parts/explorers/browser/views/treeExplorerViewer.ts index 27fc03aa8a1..6ed86f1c419 100644 --- a/src/vs/workbench/parts/explorers/browser/views/treeExplorerViewer.ts +++ b/src/vs/workbench/parts/explorers/browser/views/treeExplorerViewer.ts @@ -16,14 +16,14 @@ import { ContributableActionProvider } from 'vs/workbench/browser/actionBarRegis import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { ICustomTreeExplorerService } from 'vs/workbench/parts/explorers/common/customTreeExplorerService'; +import { ITreeExplorerService } from 'vs/workbench/parts/explorers/common/treeExplorerService'; import { IProgressService } from 'vs/platform/progress/common/progress'; export class TreeDataSource implements IDataSource { constructor( private treeNodeProviderId: string, - @ICustomTreeExplorerService private treeExplorerViewletService: ICustomTreeExplorerService, + @ITreeExplorerService private treeExplorerService: ITreeExplorerService, @IProgressService private progressService: IProgressService ) { @@ -38,7 +38,7 @@ export class TreeDataSource implements IDataSource { } public getChildren(tree: ITree, node: InternalTreeExplorerNode): TPromise { - const promise = this.treeExplorerViewletService.resolveChildren(this.treeNodeProviderId, node); + const promise = this.treeExplorerService.resolveChildren(this.treeNodeProviderId, node); this.progressService.showWhile(promise, 800); @@ -89,7 +89,7 @@ export class TreeController extends DefaultController { constructor( private treeNodeProviderId: string, - @ICustomTreeExplorerService private treeExplorerViewletService: ICustomTreeExplorerService + @ITreeExplorerService private treeExplorerService: ITreeExplorerService ) { super({ clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change to not break DND */ }); } @@ -98,7 +98,7 @@ export class TreeController extends DefaultController { super.onLeftClick(tree, node, event, origin); if (node.clickCommand) { - this.treeExplorerViewletService.executeCommand(this.treeNodeProviderId, node); + this.treeExplorerService.executeCommand(this.treeNodeProviderId, node); } return true; diff --git a/src/vs/workbench/parts/explorers/common/customTreeExplorerService.ts b/src/vs/workbench/parts/explorers/common/treeExplorerService.ts similarity index 87% rename from src/vs/workbench/parts/explorers/common/customTreeExplorerService.ts rename to src/vs/workbench/parts/explorers/common/treeExplorerService.ts index 00a402e68c9..1ce4896a478 100644 --- a/src/vs/workbench/parts/explorers/common/customTreeExplorerService.ts +++ b/src/vs/workbench/parts/explorers/common/treeExplorerService.ts @@ -9,9 +9,9 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { InternalTreeExplorerNode, InternalTreeExplorerNodeProvider } from 'vs/workbench/parts/explorers/common/treeExplorerViewModel'; -export const ICustomTreeExplorerService = createDecorator('customTreeExplorerService'); +export const ITreeExplorerService = createDecorator('treeExplorerService'); -export interface ICustomTreeExplorerService { +export interface ITreeExplorerService { _serviceBrand: any; onTreeExplorerNodeProviderRegistered: Event; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 30c5172ee4c..08c8cf09980 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -5,6 +5,7 @@ import 'vs/css!./media/extensions'; import { localize } from 'vs/nls'; +import * as errors from 'vs/base/common/errors'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { Registry } from 'vs/platform/platform'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; @@ -34,6 +35,8 @@ import { IQuickOpenRegistry, Extensions, QuickOpenHandlerDescriptor } from 'vs/w import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import jsonContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry'); import { ExtensionsConfigurationSchema, ExtensionsConfigurationSchemaId } from 'vs/workbench/parts/extensions/common/extensionsFileTemplate'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; // Singletons registerSingleton(IExtensionGalleryService, ExtensionGalleryService); @@ -161,4 +164,13 @@ Registry.as(ConfigurationExtensions.Configuration) }); const jsonRegistry = Registry.as(jsonContributionRegistry.Extensions.JSONContribution); -jsonRegistry.registerSchema(ExtensionsConfigurationSchemaId, ExtensionsConfigurationSchema); \ No newline at end of file +jsonRegistry.registerSchema(ExtensionsConfigurationSchemaId, ExtensionsConfigurationSchema); + +// Register Commands +CommandsRegistry.registerCommand('_extensions.manage', (accessor: ServicesAccessor, extensionId: string) => { + const extensionService = accessor.get(IExtensionsWorkbenchService); + const extension = extensionService.local.filter(e => e.identifier === extensionId); + if (extension.length === 1) { + extensionService.open(extension[0]).done(null, errors.onUnexpectedError); + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/viewlet/browser/viewletService.ts b/src/vs/workbench/services/viewlet/browser/viewletService.ts index 45e46aa42f5..fc4f3188875 100644 --- a/src/vs/workbench/services/viewlet/browser/viewletService.ts +++ b/src/vs/workbench/services/viewlet/browser/viewletService.ts @@ -47,7 +47,7 @@ export class ViewletService implements IViewletService { this.extensionService.onReady().then(() => { const viewlets = this.viewletRegistry.getViewlets(); viewlets.forEach(v => { - if (v.fromExtension) { + if (!!v.extensionId) { this.extensionViewlets.push(v); } }); @@ -88,7 +88,7 @@ export class ViewletService implements IViewletService { private getBuiltInViewlets(): ViewletDescriptor[] { return this.viewletRegistry.getViewlets() - .filter(viewlet => !viewlet.fromExtension) + .filter(viewlet => !viewlet.extensionId) .sort((v1, v2) => v1.order - v2.order); } } \ No newline at end of file From d31e0ebef53f846bd52e854f473be4d70a277f04 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 28 Nov 2016 10:29:08 +0100 Subject: [PATCH 30/30] fixes #16138 --- src/vs/workbench/parts/git/common/gitContentProvider.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/git/common/gitContentProvider.ts b/src/vs/workbench/parts/git/common/gitContentProvider.ts index 22ef8c2db4c..c526d6ec578 100644 --- a/src/vs/workbench/parts/git/common/gitContentProvider.ts +++ b/src/vs/workbench/parts/git/common/gitContentProvider.ts @@ -70,6 +70,7 @@ export class GitContentProvider implements IWorkbenchContribution, ITextModelCon ]; model.onWillDispose(() => dispose(disposables)); + triggerModelUpdate(); return TPromise.as(model); }