提交 2d0003bb 编写于 作者: D Daniel Imms

Merge remote-tracking branch 'origin/master' into...

Merge remote-tracking branch 'origin/master' into tyriar/hot_exit/14068_load_backups_on_main_process
......@@ -40,7 +40,7 @@ const nodeModules = ['electron', 'original-fs']
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.7.8' },
{ name: 'ms-vscode.node-debug2', version: '1.7.2' }
{ name: 'ms-vscode.node-debug2', version: '1.8.0' }
];
const vscodeEntryPoints = _.flatten([
......
......@@ -42,6 +42,7 @@ export interface IJSONSchema {
defaultSnippets?: { label?: string; description?: string; body: any; }[]; // VSCode extension
errorMessage?: string; // VSCode extension
deprecatedMessage?: string; // VSCode extension
}
export interface IJSONSchemaMap {
......
/*---------------------------------------------------------------------------------------------
* 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 Event, { Emitter } from 'vs/base/common/event';
export class WatchDog {
private _timeout: number;
private _threshold: number;
private _onAlert = new Emitter<this>();
private _handle: number;
private _missed: number;
private _lastSignal: number;
constructor(timeout: number, threshold: number) {
this._timeout = timeout;
this._threshold = threshold;
}
dispose(): void {
this.stop();
}
get onAlert(): Event<this> {
return this._onAlert.event;
}
start(): void {
this.reset();
this._handle = setInterval(this._check.bind(this), this._timeout * 1.5);
}
stop(): void {
clearInterval(this._handle);
}
reset(): void {
this._lastSignal = Date.now();
this._missed = 0;
}
private _check(): void {
if ((Date.now() - this._lastSignal) > this._timeout) {
this._missed += 1;
if (this._missed > this._threshold) {
this._onAlert.fire(this);
this._missed = 0;
}
}
}
}
......@@ -25,7 +25,11 @@ export class Protocol implements IMessagePassingProtocol {
}
send(message: any): void {
this.sender.send('ipc:message', message);
try {
this.sender.send('ipc:message', message);
} catch (e) {
// systems are going down
}
}
dispose(): void {
......
/*---------------------------------------------------------------------------------------------
* 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 * as assert from 'assert';
import { WatchDog } from 'vs/base/common/watchDog';
suite('WatchDog', function () {
test('start/stop', function (done) {
const dog = new WatchDog(10, 1);
dog.onAlert(e => {
dog.stop();
assert.ok(e === dog);
done();
});
dog.start();
});
});
......@@ -5,7 +5,7 @@
'use strict';
import { IWindowsService } from 'vs/code/electron-main/windows';
import { IWindowsMainService } from 'vs/code/electron-main/windows';
import { VSCodeWindow } from 'vs/code/electron-main/window';
import { TPromise } from 'vs/base/common/winjs.base';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
......@@ -63,7 +63,7 @@ export class LaunchService implements ILaunchService {
constructor(
@ILogService private logService: ILogService,
@IWindowsService private windowsService: IWindowsService,
@IWindowsMainService private windowsService: IWindowsMainService,
@IURLService private urlService: IURLService
) { }
......
......@@ -12,7 +12,10 @@ import * as platform from 'vs/base/common/platform';
import { parseMainProcessArgv, ParsedArgs } from 'vs/platform/environment/node/argv';
import { mkdirp } from 'vs/base/node/pfs';
import { validatePaths } from 'vs/code/electron-main/paths';
import { IWindowsService, WindowsManager } from 'vs/code/electron-main/windows';
import { IWindowsMainService, WindowsManager } from 'vs/code/electron-main/windows';
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 { WindowEventChannel } from 'vs/code/common/windowsIpc';
import { ILifecycleService, LifecycleService } from 'vs/code/electron-main/lifecycle';
import { VSCodeMenu } from 'vs/code/electron-main/menus';
......@@ -73,11 +76,11 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
const instantiationService = accessor.get(IInstantiationService);
const logService = accessor.get(ILogService);
const environmentService = accessor.get(IEnvironmentService);
const windowsService = accessor.get(IWindowsService);
const windowsMainService = accessor.get(IWindowsMainService);
const lifecycleService = accessor.get(ILifecycleService);
const updateService = accessor.get(IUpdateService);
const configurationService = accessor.get(IConfigurationService) as ConfigurationService<any>;
const windowEventChannel = new WindowEventChannel(windowsService);
const windowEventChannel = new WindowEventChannel(windowsMainService);
// We handle uncaught exceptions here to prevent electron from opening a dialog to the user
process.on('uncaughtException', (err: any) => {
......@@ -90,7 +93,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
};
// handle on client side
windowsService.sendToFocused('vscode:reportError', JSON.stringify(friendlyError));
windowsMainService.sendToFocused('vscode:reportError', JSON.stringify(friendlyError));
}
console.error('[uncaught exception in main]: ' + err);
......@@ -131,6 +134,10 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
const urlChannel = instantiationService.createInstance(URLChannel, urlService);
electronIpcServer.registerChannel('url', urlChannel);
const windowsService = accessor.get(IWindowsService);
const windowsChannel = new WindowsChannel(windowsService);
electronIpcServer.registerChannel('windows', windowsChannel);
// Spawn shared process
const initData = { args: environmentService.args };
const options = {
......@@ -191,7 +198,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
lifecycleService.ready();
// Propagate to clients
windowsService.ready(userEnv);
windowsMainService.ready(userEnv);
// Install Menu
const menu = instantiationService.createInstance(VSCodeMenu);
......@@ -218,12 +225,12 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
});
// Recent Folders
const folders = windowsService.getRecentPathsList().folders;
const folders = windowsMainService.getRecentPathsList().folders;
if (folders.length > 0) {
jumpList.push({
type: 'custom',
name: 'Recent Folders',
items: windowsService.getRecentPathsList().folders.slice(0, 7 /* limit number of entries here */).map(folder => {
items: windowsMainService.getRecentPathsList().folders.slice(0, 7 /* limit number of entries here */).map(folder => {
return <Electron.JumpListItem>{
type: 'task',
title: getPathLabel(folder),
......@@ -254,11 +261,11 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
// Open our first window
if (environmentService.args['new-window'] && environmentService.args._.length === 0) {
windowsService.open({ cli: environmentService.args, forceNewWindow: true, forceEmpty: true, restoreBackups: true }); // new window if "-n" was used without paths
windowsMainService.open({ cli: environmentService.args, forceNewWindow: true, forceEmpty: true, restoreBackups: true }); // new window if "-n" was used without paths
} else if (global.macOpenFiles && global.macOpenFiles.length && (!environmentService.args._ || !environmentService.args._.length)) {
windowsService.open({ cli: environmentService.args, pathsToOpen: global.macOpenFiles, restoreBackups: true }); // mac: open-file event received on startup
windowsMainService.open({ cli: environmentService.args, pathsToOpen: global.macOpenFiles, restoreBackups: true }); // mac: open-file event received on startup
} else {
windowsService.open({ cli: environmentService.args, forceNewWindow: environmentService.args['new-window'], diffMode: environmentService.args.diff, restoreBackups: true }); // default: read paths from cli
windowsMainService.open({ cli: environmentService.args, forceNewWindow: environmentService.args['new-window'], diffMode: environmentService.args.diff, restoreBackups: true }); // default: read paths from cli
}
}
......@@ -424,7 +431,7 @@ function getShellEnvironment(): TPromise<platform.IProcessEnvironment> {
}
function createPaths(environmentService: IEnvironmentService): TPromise<any> {
const paths = [environmentService.appSettingsHome, environmentService.userHome, environmentService.extensionsPath];
const paths = [environmentService.appSettingsHome, environmentService.userProductHome, environmentService.extensionsPath];
return TPromise.join(paths.map(p => mkdirp(p))) as TPromise<any>;
}
......@@ -446,7 +453,8 @@ function start(): void {
services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, args, process.execPath));
services.set(ILogService, new SyncDescriptor(MainLogService));
services.set(IWindowsService, new SyncDescriptor(WindowsManager));
services.set(IWindowsMainService, new SyncDescriptor(WindowsManager));
services.set(IWindowsService, new SyncDescriptor(WindowsService));
services.set(ILifecycleService, new SyncDescriptor(LifecycleService));
services.set(IStorageService, new SyncDescriptor(StorageService));
services.set(IConfigurationService, new SyncDescriptor(ConfigurationService));
......
......@@ -10,7 +10,7 @@ import * as platform from 'vs/base/common/platform';
import * as arrays from 'vs/base/common/arrays';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ipcMain as ipc, app, shell, dialog, Menu, MenuItem } from 'electron';
import { IWindowsService } from 'vs/code/electron-main/windows';
import { IWindowsMainService } from 'vs/code/electron-main/windows';
import { IPath, VSCodeWindow } from 'vs/code/electron-main/window';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IStorageService } from 'vs/code/electron-main/storage';
......@@ -57,7 +57,7 @@ export class VSCodeMenu {
@IStorageService private storageService: IStorageService,
@IUpdateService private updateService: IUpdateService,
@IConfigurationService private configurationService: IConfigurationService,
@IWindowsService private windowsService: IWindowsService,
@IWindowsMainService private windowsService: IWindowsMainService,
@IEnvironmentService private environmentService: IEnvironmentService
) {
this.actionIdKeybindingRequests = [];
......
......@@ -89,9 +89,9 @@ const ReopenFoldersSetting = {
NONE: 'none'
};
export const IWindowsService = createDecorator<IWindowsService>('windowsService');
export const IWindowsMainService = createDecorator<IWindowsMainService>('windowsMainService');
export interface IWindowsService {
export interface IWindowsMainService {
_serviceBrand: any;
// TODO make proper events
......@@ -108,7 +108,7 @@ export interface IWindowsService {
open(openConfig: IOpenConfiguration): VSCodeWindow[];
openPluginDevelopmentHostWindow(openConfig: IOpenConfiguration): void;
openFileFolderPicker(forceNewWindow?: boolean): void;
openFilePicker(forceNewWindow?: boolean): void;
openFilePicker(forceNewWindow?: boolean, path?: string): void;
openFolderPicker(forceNewWindow?: boolean): void;
openAccessibilityOptions(): void;
focusLastActive(cli: ParsedArgs): VSCodeWindow;
......@@ -126,7 +126,7 @@ export interface IWindowsService {
clearRecentPathsList(): void;
}
export class WindowsManager implements IWindowsService, IWindowEventService {
export class WindowsManager implements IWindowsMainService, IWindowEventService {
_serviceBrand: any;
......@@ -243,24 +243,6 @@ export class WindowsManager implements IWindowsService, IWindowEventService {
}
});
ipc.on('vscode:openFilePicker', (event, forceNewWindow?: boolean, path?: string) => {
this.logService.log('IPC#vscode-openFilePicker');
this.openFilePicker(forceNewWindow, path);
});
ipc.on('vscode:openFolderPicker', (event, forceNewWindow?: boolean) => {
this.logService.log('IPC#vscode-openFolderPicker');
this.openFolderPicker(forceNewWindow);
});
ipc.on('vscode:openFileFolderPicker', (event, forceNewWindow?: boolean) => {
this.logService.log('IPC#vscode-openFileFolderPicker');
this.openFileFolderPicker(forceNewWindow);
});
ipc.on('vscode:closeFolder', (event, windowId: number) => {
this.logService.log('IPC#vscode-closeFolder');
......@@ -276,15 +258,6 @@ export class WindowsManager implements IWindowsService, IWindowEventService {
this.openNewWindow();
});
ipc.on('vscode:reloadWindow', (event, windowId: number) => {
this.logService.log('IPC#vscode:reloadWindow');
const vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
this.reload(vscodeWindow);
}
});
ipc.on('vscode:toggleFullScreen', (event, windowId: number) => {
this.logService.log('IPC#vscode:toggleFullScreen');
......
......@@ -160,7 +160,7 @@ export function main(argv: ParsedArgs): TPromise<void> {
return instantiationService.invokeFunction(accessor => {
const envService = accessor.get(IEnvironmentService);
return TPromise.join([envService.appSettingsHome, envService.userHome, envService.extensionsPath].map(p => mkdirp(p))).then(() => {
return TPromise.join([envService.appSettingsHome, envService.userProductHome, envService.extensionsPath].map(p => mkdirp(p))).then(() => {
const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt } = envService;
const services = new ServiceCollection();
......
......@@ -1052,7 +1052,7 @@ export class Cursor extends EventEmitter {
if (sorted) {
cursors = cursors.sort((a, b) => {
return Range.compareRangesUsingStarts(a.getSelection(), b.getSelection());
return Range.compareRangesUsingStarts(a.modelState.selection, b.modelState.selection);
});
}
......@@ -1112,7 +1112,7 @@ export class Cursor extends EventEmitter {
private _getColumnSelectToLineNumber(): number {
if (!this._columnSelectToLineNumber) {
let primaryCursor = this.cursors.getAll()[0];
let primaryPos = primaryCursor.getViewPosition();
let primaryPos = primaryCursor.viewState.position;
return primaryPos.lineNumber;
}
return this._columnSelectToLineNumber;
......@@ -1122,7 +1122,7 @@ export class Cursor extends EventEmitter {
private _getColumnSelectToVisualColumn(): number {
if (!this._columnSelectToVisualColumn) {
let primaryCursor = this.cursors.getAll()[0];
let primaryPos = primaryCursor.getViewPosition();
let primaryPos = primaryCursor.viewState.position;
return primaryCursor.getViewVisibleColumnFromColumn(primaryPos.lineNumber, primaryPos.column);
}
return this._columnSelectToVisualColumn;
......
......@@ -82,78 +82,71 @@ export class CursorCollection {
public getPosition(index: number): Position {
if (index === 0) {
return this.primaryCursor.getPosition();
return this.primaryCursor.modelState.position;
} else {
return this.secondaryCursors[index - 1].getPosition();
return this.secondaryCursors[index - 1].modelState.position;
}
}
public getViewPosition(index: number): Position {
if (index === 0) {
return this.primaryCursor.getViewPosition();
return this.primaryCursor.viewState.position;
} else {
return this.secondaryCursors[index - 1].getViewPosition();
return this.secondaryCursors[index - 1].viewState.position;
}
}
public getPositions(): Position[] {
var result: Position[] = [];
result.push(this.primaryCursor.getPosition());
result.push(this.primaryCursor.modelState.position);
for (var i = 0, len = this.secondaryCursors.length; i < len; i++) {
result.push(this.secondaryCursors[i].getPosition());
result.push(this.secondaryCursors[i].modelState.position);
}
return result;
}
public getViewPositions(): Position[] {
var result: Position[] = [];
result.push(this.primaryCursor.getViewPosition());
result.push(this.primaryCursor.viewState.position);
for (var i = 0, len = this.secondaryCursors.length; i < len; i++) {
result.push(this.secondaryCursors[i].getViewPosition());
result.push(this.secondaryCursors[i].viewState.position);
}
return result;
}
public getSelection(index: number): Selection {
if (index === 0) {
return this.primaryCursor.getSelection();
return this.primaryCursor.modelState.selection;
} else {
return this.secondaryCursors[index - 1].getSelection();
return this.secondaryCursors[index - 1].modelState.selection;
}
}
public getSelections(): Selection[] {
var result: Selection[] = [];
result.push(this.primaryCursor.getSelection());
result.push(this.primaryCursor.modelState.selection);
for (var i = 0, len = this.secondaryCursors.length; i < len; i++) {
result.push(this.secondaryCursors[i].getSelection());
result.push(this.secondaryCursors[i].modelState.selection);
}
return result;
}
public getViewSelections(): Selection[] {
var result: Selection[] = [];
result.push(this.primaryCursor.getViewSelection());
result.push(this.primaryCursor.viewState.selection);
for (var i = 0, len = this.secondaryCursors.length; i < len; i++) {
result.push(this.secondaryCursors[i].getViewSelection());
result.push(this.secondaryCursors[i].viewState.selection);
}
return result;
}
public setSelections(selections: ISelection[], viewSelections?: ISelection[]): void {
this.primaryCursor.setSelection(selections[0]);
this._setSecondarySelections(selections.slice(1));
if (viewSelections) {
this.primaryCursor.setViewSelection(viewSelections[0]);
for (let i = 0; i < this.secondaryCursors.length; i++) {
this.secondaryCursors[i].setViewSelection(viewSelections[i + 1]);
}
}
this.primaryCursor.setSelection(selections[0], viewSelections ? viewSelections[0] : null);
this._setSecondarySelections(selections.slice(1), viewSelections ? viewSelections.slice(1) : null);
}
public killSecondaryCursors(): boolean {
return (this._setSecondarySelections([]) > 0);
return (this._setSecondarySelections([], []) > 0);
}
public normalize(): void {
......@@ -200,7 +193,7 @@ export class CursorCollection {
* - a negative number indicates the number of secondary cursors removed
* - 0 indicates that no changes have been done to the secondary cursors list
*/
private _setSecondarySelections(secondarySelections: ISelection[]): number {
private _setSecondarySelections(secondarySelections: ISelection[], viewSelections: ISelection[]): number {
var secondaryCursorsLength = this.secondaryCursors.length;
var secondarySelectionsLength = secondarySelections.length;
var returnValue = secondarySelectionsLength - secondaryCursorsLength;
......@@ -219,7 +212,7 @@ export class CursorCollection {
for (var i = 0; i < secondarySelectionsLength; i++) {
if (secondarySelections[i]) {
this.secondaryCursors[i].setSelection(secondarySelections[i]);
this.secondaryCursors[i].setSelection(secondarySelections[i], viewSelections ? viewSelections[i] : null);
}
}
......@@ -247,8 +240,8 @@ export class CursorCollection {
for (var i = 0; i < cursors.length; i++) {
sortedCursors.push({
index: i,
selection: cursors[i].getSelection(),
viewSelection: cursors[i].getViewSelection()
selection: cursors[i].modelState.selection,
viewSelection: cursors[i].viewState.selection
});
}
......
......@@ -4,101 +4,109 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IPosition } from 'vs/editor/common/editorCommon';
import { Selection } from 'vs/editor/common/core/selection';
import { CharCode } from 'vs/base/common/charCode';
import * as strings from 'vs/base/common/strings';
export interface IMoveResult {
lineNumber: number;
column: number;
leftoverVisibleColumns: number;
}
export class CursorMoveConfiguration {
_cursorMoveConfigurationBrand: void;
export interface IViewColumnSelectResult {
viewSelections: Selection[];
reversed: boolean;
}
export interface IColumnSelectResult extends IViewColumnSelectResult {
selections: Selection[];
toLineNumber: number;
toVisualColumn: number;
public readonly tabSize: number;
public readonly pageSize: number;
constructor(
tabSize: number,
pageSize: number
) {
this.tabSize = tabSize;
this.pageSize = pageSize;
}
}
export interface ICursorMoveHelperModel {
getLineCount(): number;
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
getLineContent(lineNumber: number): string;
getLineMinColumn(lineNumber: number): number;
getLineMaxColumn(lineNumber: number): number;
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
getLineLastNonWhitespaceColumn(lineNumber: number): number;
getLineContent(lineNumber: number): string;
}
/**
* Internal indentation options (computed) for the editor.
*/
export interface IInternalIndentationOptions {
/**
* Tab size in spaces. This is used for rendering and for editing.
*/
tabSize: number;
/**
* Insert spaces instead of tabs when indenting or when auto-indenting.
*/
insertSpaces: boolean;
}
export class CursorMoveResult {
_cursorMoveResultBrand: void;
export interface IConfiguration {
getIndentationOptions(): IInternalIndentationOptions;
}
public readonly lineNumber: number;
public readonly column: number;
public readonly leftoverVisibleColumns: number;
function isHighSurrogate(model: ICursorMoveHelperModel, lineNumber: number, column: number) {
return strings.isHighSurrogate(model.getLineContent(lineNumber).charCodeAt(column - 1));
constructor(lineNumber: number, column: number, leftoverVisibleColumns: number) {
this.lineNumber = lineNumber;
this.column = column;
this.leftoverVisibleColumns = leftoverVisibleColumns;
}
}
function isLowSurrogate(model: ICursorMoveHelperModel, lineNumber: number, column: number) {
return strings.isLowSurrogate(model.getLineContent(lineNumber).charCodeAt(column - 1));
}
/**
* Common operations that work and make sense both on the model and on the view model.
*/
export class CursorMove {
export class CursorMoveHelper {
private static _isLowSurrogate(model: ICursorMoveHelperModel, lineNumber: number, charOffset: number): boolean {
let lineContent = model.getLineContent(lineNumber);
if (charOffset < 0 || charOffset >= lineContent.length) {
return false;
}
return strings.isLowSurrogate(lineContent.charCodeAt(charOffset));
}
private configuration: IConfiguration;
private static _isHighSurrogate(model: ICursorMoveHelperModel, lineNumber: number, charOffset: number): boolean {
let lineContent = model.getLineContent(lineNumber);
if (charOffset < 0 || charOffset >= lineContent.length) {
return false;
}
return strings.isHighSurrogate(lineContent.charCodeAt(charOffset));
}
constructor(configuration: IConfiguration) {
this.configuration = configuration;
private static _isInsideSurrogatePair(model: ICursorMoveHelperModel, lineNumber: number, column: number): boolean {
return this._isHighSurrogate(model, lineNumber, column - 2);
}
public getLeftOfPosition(model: ICursorMoveHelperModel, lineNumber: number, column: number): IPosition {
public static left(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number): CursorMoveResult {
if (column > model.getLineMinColumn(lineNumber)) {
column = column - (isLowSurrogate(model, lineNumber, column - 1) ? 2 : 1);
if (this._isLowSurrogate(model, lineNumber, column - 2)) {
// character before column is a low surrogate
column = column - 2;
} else {
column = column - 1;
}
} else if (lineNumber > 1) {
lineNumber = lineNumber - 1;
column = model.getLineMaxColumn(lineNumber);
}
return {
lineNumber: lineNumber,
column: column
};
return new CursorMoveResult(lineNumber, column, 0);
}
public getRightOfPosition(model: ICursorMoveHelperModel, lineNumber: number, column: number): IPosition {
public static right(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number): CursorMoveResult {
if (column < model.getLineMaxColumn(lineNumber)) {
column = column + (isHighSurrogate(model, lineNumber, column) ? 2 : 1);
if (this._isHighSurrogate(model, lineNumber, column - 1)) {
// character after column is a high surrogate
column = column + 2;
} else {
column = column + 1;
}
} else if (lineNumber < model.getLineCount()) {
lineNumber = lineNumber + 1;
column = model.getLineMinColumn(lineNumber);
}
return {
lineNumber: lineNumber,
column: column
};
return new CursorMoveResult(lineNumber, column, 0);
}
public getPositionUp(model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): IMoveResult {
var currentVisibleColumn = this.visibleColumnFromColumn(model, lineNumber, column) + leftoverVisibleColumns;
public static up(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): CursorMoveResult {
const currentVisibleColumn = this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
lineNumber = lineNumber - count;
if (lineNumber < 1) {
......@@ -107,22 +115,24 @@ export class CursorMoveHelper {
column = model.getLineMinColumn(lineNumber);
} else {
column = Math.min(model.getLineMaxColumn(lineNumber), column);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
} else {
column = this.columnFromVisibleColumn(model, lineNumber, currentVisibleColumn);
column = this.columnFromVisibleColumn(config, model, lineNumber, currentVisibleColumn);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model, lineNumber, column);
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
return {
lineNumber: lineNumber,
column: column,
leftoverVisibleColumns: leftoverVisibleColumns
};
return new CursorMoveResult(lineNumber, column, leftoverVisibleColumns);
}
public getPositionDown(model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): IMoveResult {
var currentVisibleColumn = this.visibleColumnFromColumn(model, lineNumber, column) + leftoverVisibleColumns;
public static down(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): CursorMoveResult {
const currentVisibleColumn = this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
lineNumber = lineNumber + count;
var lineCount = model.getLineCount();
......@@ -132,17 +142,117 @@ export class CursorMoveHelper {
column = model.getLineMaxColumn(lineNumber);
} else {
column = Math.min(model.getLineMaxColumn(lineNumber), column);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
} else {
column = this.columnFromVisibleColumn(model, lineNumber, currentVisibleColumn);
column = this.columnFromVisibleColumn(config, model, lineNumber, currentVisibleColumn);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model, lineNumber, column);
return {
lineNumber: lineNumber,
column: column,
leftoverVisibleColumns: leftoverVisibleColumns
};
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
return new CursorMoveResult(lineNumber, column, leftoverVisibleColumns);
}
public static visibleColumnFromColumn(lineContent: string, column: number, tabSize: number): number {
let endOffset = lineContent.length;
if (endOffset > column - 1) {
endOffset = column - 1;
}
let result = 0;
for (let i = 0; i < endOffset; i++) {
let charCode = lineContent.charCodeAt(i);
if (charCode === CharCode.Tab) {
result = this.nextTabStop(result, tabSize);
} else {
result = result + 1;
}
}
return result;
}
private static _columnFromVisibleColumn(lineContent: string, visibleColumn: number, tabSize: number): number {
if (visibleColumn <= 0) {
return 1;
}
const lineLength = lineContent.length;
let beforeVisibleColumn = 0;
for (let i = 0; i < lineLength; i++) {
let charCode = lineContent.charCodeAt(i);
let afterVisibleColumn: number;
if (charCode === CharCode.Tab) {
afterVisibleColumn = this.nextTabStop(beforeVisibleColumn, tabSize);
} else {
afterVisibleColumn = beforeVisibleColumn + 1;
}
if (afterVisibleColumn >= visibleColumn) {
let prevDelta = visibleColumn - beforeVisibleColumn;
let afterDelta = afterVisibleColumn - visibleColumn;
if (afterDelta < prevDelta) {
return i + 2;
} else {
return i + 1;
}
}
beforeVisibleColumn = afterVisibleColumn;
}
// walked the entire string
return lineLength + 1;
}
public static columnFromVisibleColumn(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, visibleColumn: number): number {
let result = this._columnFromVisibleColumn(model.getLineContent(lineNumber), visibleColumn, config.tabSize);
let minColumn = model.getLineMinColumn(lineNumber);
if (result < minColumn) {
return minColumn;
}
let maxColumn = model.getLineMaxColumn(lineNumber);
if (result > maxColumn) {
return maxColumn;
}
return result;
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public static nextTabStop(visibleColumn: number, tabSize: number): number {
return visibleColumn + tabSize - visibleColumn % tabSize;
}
}
export interface IViewColumnSelectResult {
viewSelections: Selection[];
reversed: boolean;
}
export interface IColumnSelectResult extends IViewColumnSelectResult {
selections: Selection[];
toLineNumber: number;
toVisualColumn: number;
}
export class CursorMoveHelper {
private readonly _config: CursorMoveConfiguration;
constructor(config: CursorMoveConfiguration) {
this._config = config;
}
public columnSelect(model: ICursorMoveHelperModel, fromLineNumber: number, fromVisibleColumn: number, toLineNumber: number, toVisibleColumn: number): IViewColumnSelectResult {
......@@ -219,7 +329,7 @@ export class CursorMoveHelper {
}
public visibleColumnFromColumn(model: ICursorMoveHelperModel, lineNumber: number, column: number): number {
return CursorMoveHelper.visibleColumnFromColumn(model, lineNumber, column, this.configuration.getIndentationOptions().tabSize);
return CursorMoveHelper.visibleColumnFromColumn(model, lineNumber, column, this._config.tabSize);
}
public static visibleColumnFromColumn(model: ICursorMoveHelperModel, lineNumber: number, column: number, tabSize: number): number {
......@@ -227,47 +337,18 @@ export class CursorMoveHelper {
}
public static visibleColumnFromColumn2(line: string, column: number, tabSize: number): number {
var result = 0;
for (var i = 0; i < column - 1; i++) {
result = (line.charAt(i) === '\t') ? CursorMoveHelper.nextTabColumn(result, tabSize) : result + 1;
}
return result;
return CursorMove.visibleColumnFromColumn(line, column, tabSize);
}
public columnFromVisibleColumn(model: ICursorMoveHelperModel, lineNumber: number, visibleColumn: number): number {
var line = model.getLineContent(lineNumber);
var lastVisibleColumn = -1;
var thisVisibleColumn = 0;
for (var i = 0; i < line.length && thisVisibleColumn <= visibleColumn; i++) {
lastVisibleColumn = thisVisibleColumn;
thisVisibleColumn = (line.charAt(i) === '\t') ? CursorMoveHelper.nextTabColumn(thisVisibleColumn, this.configuration.getIndentationOptions().tabSize) : thisVisibleColumn + 1;
}
// Choose the closest
thisVisibleColumn = Math.abs(visibleColumn - thisVisibleColumn);
lastVisibleColumn = Math.abs(visibleColumn - lastVisibleColumn);
var result: number;
if (thisVisibleColumn < lastVisibleColumn) {
result = i + 1;
} else {
result = i;
}
var minColumn = model.getLineMinColumn(lineNumber);
if (result < minColumn) {
result = minColumn;
}
return result;
return CursorMove.columnFromVisibleColumn(this._config, model, lineNumber, visibleColumn);
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public static nextTabColumn(column: number, tabSize: number): number {
return column + tabSize - column % tabSize;
return CursorMove.nextTabStop(column, tabSize);
}
/**
......
/*---------------------------------------------------------------------------------------------
* 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 * as assert from 'assert';
import * as strings from 'vs/base/common/strings';
import { CursorMoveHelper, ICursorMoveHelperModel, CursorMoveConfiguration } from 'vs/editor/common/controller/cursorMoveHelper';
suite('CursorMove', () => {
test('nextTabStop', () => {
assert.equal(CursorMoveHelper.nextTabColumn(0, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(1, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(2, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(3, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(4, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(5, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(6, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(7, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(8, 4), 12);
assert.equal(CursorMoveHelper.nextTabColumn(0, 2), 2);
assert.equal(CursorMoveHelper.nextTabColumn(1, 2), 2);
assert.equal(CursorMoveHelper.nextTabColumn(2, 2), 4);
assert.equal(CursorMoveHelper.nextTabColumn(3, 2), 4);
assert.equal(CursorMoveHelper.nextTabColumn(4, 2), 6);
assert.equal(CursorMoveHelper.nextTabColumn(5, 2), 6);
assert.equal(CursorMoveHelper.nextTabColumn(6, 2), 8);
assert.equal(CursorMoveHelper.nextTabColumn(7, 2), 8);
assert.equal(CursorMoveHelper.nextTabColumn(8, 2), 10);
assert.equal(CursorMoveHelper.nextTabColumn(0, 1), 1);
assert.equal(CursorMoveHelper.nextTabColumn(1, 1), 2);
assert.equal(CursorMoveHelper.nextTabColumn(2, 1), 3);
assert.equal(CursorMoveHelper.nextTabColumn(3, 1), 4);
assert.equal(CursorMoveHelper.nextTabColumn(4, 1), 5);
assert.equal(CursorMoveHelper.nextTabColumn(5, 1), 6);
assert.equal(CursorMoveHelper.nextTabColumn(6, 1), 7);
assert.equal(CursorMoveHelper.nextTabColumn(7, 1), 8);
assert.equal(CursorMoveHelper.nextTabColumn(8, 1), 9);
});
class OneLineModel implements ICursorMoveHelperModel {
private _line: string;
constructor(line: string) {
this._line = line;
}
getLineCount(): number {
return 1;
}
getLineContent(lineNumber: number): string {
return this._line;
}
getLineMinColumn(lineNumber: number): number {
return 1;
}
getLineMaxColumn(lineNumber: number): number {
return this._line.length + 1;
}
getLineFirstNonWhitespaceColumn(lineNumber: number): number {
let result = strings.firstNonWhitespaceIndex(this._line);
if (result === -1) {
return 0;
}
return result + 1;
}
getLineLastNonWhitespaceColumn(lineNumber: number): number {
let result = strings.lastNonWhitespaceIndex(this._line);
if (result === -1) {
return 0;
}
return result + 2;
}
}
test('visibleColumnFromColumn', () => {
function testVisibleColumnFromColumn(text:string, tabSize:number, column:number, expected:number): void {
let helper = new CursorMoveHelper(new CursorMoveConfiguration(tabSize, 13));
let model = new OneLineModel(text);
assert.equal(helper.visibleColumnFromColumn(model, 1, column), expected);
}
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 1, 0);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 2, 4);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 3, 8);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 4, 9);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 5, 10);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 6, 11);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 7, 12);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 8, 13);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 9, 14);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 10, 15);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 11, 16);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 12, 17);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 13, 18);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 1, 0);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 2, 4);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 3, 5);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 4, 8);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 5, 9);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 6, 10);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 7, 11);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 8, 12);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 9, 13);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 10, 14);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 11, 15);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 12, 16);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 13, 17);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 14, 18);
testVisibleColumnFromColumn('\t \tx\t', 4, -1, 0);
testVisibleColumnFromColumn('\t \tx\t', 4, 0, 0);
testVisibleColumnFromColumn('\t \tx\t', 4, 1, 0);
testVisibleColumnFromColumn('\t \tx\t', 4, 2, 4);
testVisibleColumnFromColumn('\t \tx\t', 4, 3, 5);
testVisibleColumnFromColumn('\t \tx\t', 4, 4, 6);
testVisibleColumnFromColumn('\t \tx\t', 4, 5, 8);
testVisibleColumnFromColumn('\t \tx\t', 4, 6, 9);
testVisibleColumnFromColumn('\t \tx\t', 4, 7, 12);
testVisibleColumnFromColumn('\t \tx\t', 4, 8, 12);
testVisibleColumnFromColumn('\t \tx\t', 4, 9, 12);
testVisibleColumnFromColumn('baz', 4, 1, 0);
testVisibleColumnFromColumn('baz', 4, 2, 1);
testVisibleColumnFromColumn('baz', 4, 3, 2);
testVisibleColumnFromColumn('baz', 4, 4, 3);
testVisibleColumnFromColumn('📚az', 4, 1, 0);
testVisibleColumnFromColumn('📚az', 4, 2, 1);
testVisibleColumnFromColumn('📚az', 4, 3, 2);
testVisibleColumnFromColumn('📚az', 4, 4, 3);
testVisibleColumnFromColumn('📚az', 4, 5, 4);
});
test('columnFromVisibleColumn', () => {
function testColumnFromVisibleColumn(text:string, tabSize:number, visibleColumn:number, expected:number): void {
let helper = new CursorMoveHelper(new CursorMoveConfiguration(tabSize, 13));
let model = new OneLineModel(text);
assert.equal(helper.columnFromVisibleColumn(model, 1, visibleColumn), expected);
}
// testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 0, 1);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 1, 1);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 2, 1);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 3, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 4, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 5, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 6, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 7, 3);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 8, 3);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 9, 4);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 10, 5);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 11, 6);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 12, 7);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 13, 8);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 14, 9);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 15, 10);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 16, 11);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 17, 12);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 18, 13);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 0, 1);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 1, 1);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 2, 1);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 3, 2);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 4, 2);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 5, 3);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 6, 3);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 7, 4);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 8, 4);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 9, 5);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 10, 6);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 11, 7);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 12, 8);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 13, 9);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 14, 10);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 15, 11);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 16, 12);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 17, 13);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 18, 14);
testColumnFromVisibleColumn('\t \tx\t', 4, -2, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, -1, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 0, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 1, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 2, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 3, 2);
testColumnFromVisibleColumn('\t \tx\t', 4, 4, 2);
testColumnFromVisibleColumn('\t \tx\t', 4, 5, 3);
testColumnFromVisibleColumn('\t \tx\t', 4, 6, 4);
testColumnFromVisibleColumn('\t \tx\t', 4, 7, 4);
testColumnFromVisibleColumn('\t \tx\t', 4, 8, 5);
testColumnFromVisibleColumn('\t \tx\t', 4, 9, 6);
testColumnFromVisibleColumn('\t \tx\t', 4, 10, 6);
testColumnFromVisibleColumn('\t \tx\t', 4, 11, 7);
testColumnFromVisibleColumn('\t \tx\t', 4, 12, 7);
testColumnFromVisibleColumn('\t \tx\t', 4, 13, 7);
testColumnFromVisibleColumn('\t \tx\t', 4, 14, 7);
testColumnFromVisibleColumn('baz', 4, 0, 1);
testColumnFromVisibleColumn('baz', 4, 1, 2);
testColumnFromVisibleColumn('baz', 4, 2, 3);
testColumnFromVisibleColumn('baz', 4, 3, 4);
testColumnFromVisibleColumn('📚az', 4, 0, 1);
testColumnFromVisibleColumn('📚az', 4, 1, 2);
testColumnFromVisibleColumn('📚az', 4, 2, 3);
testColumnFromVisibleColumn('📚az', 4, 3, 4);
testColumnFromVisibleColumn('📚az', 4, 4, 5);
});
});
\ No newline at end of file
......@@ -17,6 +17,7 @@ export interface IEnvironmentService {
appRoot: string;
userHome: string;
userProductHome: string;
userDataPath: string;
appSettingsHome: string;
......
......@@ -63,7 +63,10 @@ export class EnvironmentService implements IEnvironmentService {
get execPath(): string { return this._execPath; }
@memoize
get userHome(): string { return path.join(os.homedir(), product.dataFolderName); }
get userHome(): string { return os.homedir(); }
@memoize
get userProductHome(): string { return path.join(this.userHome, product.dataFolderName); }
@memoize
get userDataPath(): string { return parseUserDataDir(this._args, process); }
......@@ -84,7 +87,7 @@ export class EnvironmentService implements IEnvironmentService {
get backupWorkspacesPath(): string { return path.join(this.backupHome, 'workspaces.json'); }
@memoize
get extensionsPath(): string { return path.normalize(this._args['extensions-dir'] || path.join(this.userHome, 'extensions')); }
get extensionsPath(): string { return path.normalize(this._args['extensions-dir'] || path.join(this.userProductHome, 'extensions')); }
@memoize
get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath ? path.normalize(this._args.extensionDevelopmentPath) : this._args.extensionDevelopmentPath; }
......
......@@ -6,23 +6,26 @@
import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { distinct } from 'vs/base/common/arrays';
import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IExtensionManagementService, DidUninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { IExtensionRuntimeService } from 'vs/platform/extensions/common/extensions';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IMessageService } from 'vs/platform/message/common/message';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
const DISABLED_EXTENSIONS_STORAGE_PATH = 'extensions/disabled';
export class ExtensionRuntimeService implements IExtensionRuntimeService {
export class ExtensionEnablementService implements IExtensionEnablementService {
_serviceBrand: any;
private workspace: IWorkspace;
private disposables: IDisposable[] = [];
private _onEnablementChanged = new Emitter<string>();
public onEnablementChanged: Event<string> = this._onEnablementChanged.event;
constructor(
@IStorageService private storageService: IStorageService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
......@@ -99,7 +102,7 @@ export class ExtensionRuntimeService implements IExtensionRuntimeService {
private disableExtension(identifier: string, scope: StorageScope): TPromise<boolean> {
let disabledExtensions = this._getDisabledExtensions(scope);
disabledExtensions.push(identifier);
this._setDisabledExtensions(disabledExtensions, scope);
this._setDisabledExtensions(disabledExtensions, scope, identifier);
return TPromise.wrap(true);
}
......@@ -108,7 +111,7 @@ export class ExtensionRuntimeService implements IExtensionRuntimeService {
const index = disabledExtensions.indexOf(identifier);
if (index !== -1) {
disabledExtensions.splice(index, 1);
this._setDisabledExtensions(disabledExtensions, scope);
this._setDisabledExtensions(disabledExtensions, scope, identifier);
}
return TPromise.wrap(true);
}
......@@ -118,12 +121,13 @@ export class ExtensionRuntimeService implements IExtensionRuntimeService {
return value ? distinct(value.split(',')) : [];
}
private _setDisabledExtensions(disabledExtensions: string[], scope: StorageScope): void {
private _setDisabledExtensions(disabledExtensions: string[], scope: StorageScope, extension: string): void {
if (disabledExtensions.length) {
this.storageService.store(DISABLED_EXTENSIONS_STORAGE_PATH, disabledExtensions.join(','), scope);
} else {
this.storageService.remove(DISABLED_EXTENSIONS_STORAGE_PATH, scope);
}
this._onEnablementChanged.fire(extension);
}
private onDidUninstallExtension({id, error}: DidUninstallExtensionEvent): void {
......
......@@ -233,6 +233,46 @@ export interface IExtensionManagementService {
getInstalled(type?: LocalExtensionType): TPromise<ILocalExtension[]>;
}
export const IExtensionEnablementService = createDecorator<IExtensionEnablementService>('extensionEnablementService');
// TODO: @sandy: Merge this into IExtensionManagementService when we have a storage service available in Shared process
export interface IExtensionEnablementService {
_serviceBrand: any;
/**
* Event to listen on for extension enablement changes
*/
onEnablementChanged: Event<string>;
/**
* Returns all globally disabled extension identifiers.
* Returns an empty array if none exist.
*/
getGloballyDisabledExtensions(): string[];
/**
* Returns all workspace disabled extension identifiers.
* Returns an empty array if none exist or workspace does not exist.
*/
getWorkspaceDisabledExtensions(): string[];
/**
* Returns `true` if given extension can be enabled by calling `setEnablement`, otherwise false`.
*/
canEnable(identifier: string): boolean;
/**
* Enable or disable the given extension.
* if `workspace` is `true` then enablement is done for workspace, otherwise globally.
*
* Returns a promise that resolves to boolean value.
* if resolves to `true` then requires restart for the change to take effect.
*
* Throws error if enablement is requested for workspace and there is no workspace
*/
setEnablement(identifier: string, enable: boolean, workspace?: boolean): TPromise<boolean>;
}
export const IExtensionTipsService = createDecorator<IExtensionTipsService>('extensionTipsService');
export interface IExtensionTipsService {
......
......@@ -77,38 +77,4 @@ export interface IExtensionService {
* Get information about extensions status.
*/
getExtensionsStatus(): { [id: string]: IExtensionsStatus };
}
export const IExtensionRuntimeService = createDecorator<IExtensionRuntimeService>('extensionRuntimeService');
export interface IExtensionRuntimeService {
_serviceBrand: any;
/**
* Returns all globally disabled extension identifiers.
* Returns an empty array if none exist.
*/
getGloballyDisabledExtensions(): string[];
/**
* Returns all workspace disabled extension identifiers.
* Returns an empty array if none exist or workspace does not exist.
*/
getWorkspaceDisabledExtensions(): string[];
/**
* Returns `true` if given extension can be enabled by calling `setEnablement`, otherwise false`.
*/
canEnable(identifier: string): boolean;
/**
* Enable or disable the given extension.
* if `workspace` is `true` then enablement is done for workspace, otherwise globally.
*
* Returns a promise that resolves to boolean value.
* if resolves to `true` then requires restart for the change to take effect.
*
* Throws error if enablement is requested for workspace and there is no workspace
*/
setEnablement(identifier: string, enable: boolean, workspace?: boolean): TPromise<boolean>;
}
}
\ No newline at end of file
......@@ -182,7 +182,7 @@ export abstract class KeybindingService implements IKeybindingService {
e.preventDefault();
}
let commandId = resolveResult.commandId.replace(/^\^/, '');
this._commandService.executeCommand(commandId, {}).done(undefined, err => {
this._commandService.executeCommand(commandId, resolveResult.commandArgs || {}).done(undefined, err => {
this._messageService.show(Severity.Warning, err);
});
}
......
......@@ -13,6 +13,7 @@ import Event from 'vs/base/common/event';
export interface IUserFriendlyKeybinding {
key: string;
command: string;
args?: any;
when?: string;
}
......@@ -36,6 +37,7 @@ export interface IKeybindings {
export interface IKeybindingItem {
keybinding: number;
command: string;
commandArgs?: any;
when: ContextKeyExpr;
weight1: number;
weight2: number;
......
......@@ -13,6 +13,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
export interface IResolveResult {
enterChord: number;
commandId: string;
commandArgs: any;
}
export interface IBoundCommands {
......@@ -31,11 +32,13 @@ interface ICommandEntry {
when: ContextKeyExpr;
keybinding: number;
commandId: string;
commandArgs: any;
}
export class NormalizedKeybindingItem {
keybinding: number;
command: string;
commandArgs: any;
when: ContextKeyExpr;
isDefault: boolean;
actualCommand: string;
......@@ -45,12 +48,13 @@ export class NormalizedKeybindingItem {
if (source.when) {
when = source.when.normalize();
}
return new NormalizedKeybindingItem(source.keybinding, source.command, when, isDefault);
return new NormalizedKeybindingItem(source.keybinding, source.command, source.commandArgs, when, isDefault);
}
constructor(keybinding: number, command: string, when: ContextKeyExpr, isDefault: boolean) {
constructor(keybinding: number, command: string, commandArgs: any, when: ContextKeyExpr, isDefault: boolean) {
this.keybinding = keybinding;
this.command = command;
this.commandArgs = commandArgs;
this.actualCommand = this.command ? this.command.replace(/^\^/, '') : this.command;
this.when = when;
this.isDefault = isDefault;
......@@ -97,7 +101,8 @@ export class KeybindingResolver {
let entry: ICommandEntry = {
when: k.when,
keybinding: k.keybinding,
commandId: k.command
commandId: k.command,
commandArgs: k.commandArgs
};
if (BinaryKeybindings.hasChord(k.keybinding)) {
......@@ -313,13 +318,15 @@ export class KeybindingResolver {
if (currentChord === 0 && BinaryKeybindings.hasChord(result.keybinding)) {
return {
enterChord: keypress,
commandId: null
commandId: null,
commandArgs: null
};
}
return {
enterChord: 0,
commandId: result.commandId
commandId: result.commandId,
commandArgs: result.commandArgs
};
}
......@@ -424,9 +431,15 @@ export class IOSupport {
command = input.command;
}
let commandArgs: any = null;
if (typeof input.args !== 'undefined') {
commandArgs = input.args;
}
return {
keybinding: key,
command: command,
commandArgs: commandArgs,
when: when,
weight1: 1000,
weight2: index
......
......@@ -113,6 +113,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
this._keybindings.push({
keybinding: keybinding,
command: commandId,
commandArgs: null,
when: when,
weight1: weight1,
weight2: weight2
......
......@@ -136,4 +136,12 @@ suite('Keybinding IO', () => {
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.keybinding, 0);
});
test('test commands args', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [], "args": { "text": "theText" } }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = IOSupport.readKeybindingItem(userKeybinding, 0);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.commandArgs.text, 'theText');
});
});
......@@ -31,6 +31,23 @@ suite('Keybinding Service', () => {
assert.equal(resolver.resolve({ bar: 'bz' }, 0, keybinding), null);
});
test('resolve key with arguments', function () {
let commandArgs = { text: 'no' };
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z;
let contextRules = ContextKeyExpr.equals('bar', 'baz');
let keybindingItem: IKeybindingItem = {
command: 'yes',
commandArgs: commandArgs,
when: contextRules,
keybinding: keybinding,
weight1: 0,
weight2: 0
};
let resolver = new KeybindingResolver([keybindingItem], []);
assert.equal(resolver.resolve({ bar: 'baz' }, 0, keybinding).commandArgs, commandArgs);
});
test('KbAndExpression.equals', function () {
let a = ContextKeyExpr.and(
ContextKeyExpr.has('a1'),
......@@ -74,8 +91,8 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), false),
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), false),
]);
});
......@@ -102,9 +119,9 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true),
new NormalizedKeybindingItem(KeyCode.KEY_C, 'yes3', ContextKeyExpr.equals('3', 'c'), false),
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true),
new NormalizedKeybindingItem(KeyCode.KEY_C, 'yes3', null, ContextKeyExpr.equals('3', 'c'), false),
]);
});
......@@ -131,8 +148,8 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -159,8 +176,8 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -187,7 +204,7 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -214,7 +231,7 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -241,7 +258,7 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -268,7 +285,7 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -295,7 +312,7 @@ suite('Keybinding Service', () => {
}];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepEqual(actual, [
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', ContextKeyExpr.equals('2', 'b'), true)
new NormalizedKeybindingItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
......@@ -471,8 +488,6 @@ suite('Keybinding Service', () => {
let resolver = new KeybindingResolver(items, [], false);
let testKey = (commandId: string, expectedKeys: number[]) => {
// Test lookup
let lookupResult = resolver.lookupKeybinding(commandId);
......
......@@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { IChannel, eventToCall, eventFromCall, Serializer, Deserializer } from 'vs/base/parts/ipc/common/ipc';
import { IURLService } from './url';
import Event, { filterEvent } from 'vs/base/common/event';
import { IWindowsService } from 'vs/code/electron-main/windows';
import { IWindowsMainService } from 'vs/code/electron-main/windows';
import URI from 'vs/base/common/uri';
const URISerializer: Serializer<URI, any> = uri => uri.toJSON();
......@@ -24,7 +24,7 @@ export class URLChannel implements IURLChannel {
constructor(
private service: IURLService,
@IWindowsService private windowsService: IWindowsService
@IWindowsMainService private windowsService: IWindowsMainService
) { }
call(command: string, arg?: any): TPromise<any> {
......
/*---------------------------------------------------------------------------------------------
* 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 { TPromise } from 'vs/base/common/winjs.base';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IWindowsService = createDecorator<IWindowsService>('windowsService');
export interface IWindowsService {
_serviceBrand: any;
openFileFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise<void>;
openFilePicker(windowId: number, forceNewWindow?: boolean, path?: string): TPromise<void>;
openFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise<void>;
reloadWindow(windowId: number): TPromise<void>;
}
export const IWindowService = createDecorator<IWindowService>('windowService');
export interface IWindowService {
_serviceBrand: any;
openFileFolderPicker(forceNewWindow?: boolean): TPromise<void>;
openFilePicker(forceNewWindow?: boolean, path?: string): TPromise<void>;
openFolderPicker(forceNewWindow?: boolean): TPromise<void>;
reloadWindow(): TPromise<void>;
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* 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 { TPromise } from 'vs/base/common/winjs.base';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWindowsService } from './windows';
export interface IWindowsChannel extends IChannel {
call(command: 'openFileFolderPicker', args: [number, boolean]): TPromise<void>;
call(command: 'openFilePicker', args: [number, boolean, string]): TPromise<void>;
call(command: 'openFolderPicker', args: [number, boolean]): TPromise<void>;
call(command: 'reloadWindow', arg: number): TPromise<void>;
call(command: string, arg?: any): TPromise<any>;
}
export class WindowsChannel implements IWindowsChannel {
constructor(private service: IWindowsService) { }
call(command: string, arg?: any): TPromise<any> {
switch (command) {
case 'openFileFolderPicker': return this.service.openFileFolderPicker(arg[0], arg[1]);
case 'openFilePicker': return this.service.openFilePicker(arg[0], arg[1], arg[2]);
case 'openFolderPicker': return this.service.openFolderPicker(arg[0], arg[1]);
case 'reloadWindow': return this.service.reloadWindow(arg);
}
}
}
export class WindowsChannelClient implements IWindowsService {
_serviceBrand: any;
constructor(private channel: IWindowsChannel) { }
openFileFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise<void> {
return this.channel.call('openFileFolderPicker', [windowId, forceNewWindow]);
}
openFilePicker(windowId: number, forceNewWindow?: boolean, path?: string): TPromise<void> {
return this.channel.call('openFilePicker', [windowId, forceNewWindow, path]);
}
openFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise<void> {
return this.channel.call('openFolderPicker', [windowId, forceNewWindow]);
}
reloadWindow(windowId: number): TPromise<void> {
return this.channel.call('reloadWindow', windowId);
}
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* 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 { TPromise } from 'vs/base/common/winjs.base';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
export class WindowService implements IWindowService {
_serviceBrand: any;
constructor(
private windowId: number,
@IWindowsService private windowsService: IWindowsService
) { }
openFileFolderPicker(forceNewWindow?: boolean): TPromise<void> {
return this.windowsService.openFileFolderPicker(this.windowId, forceNewWindow);
}
openFilePicker(forceNewWindow?: boolean, path?: string): TPromise<void> {
return this.windowsService.openFilePicker(this.windowId, forceNewWindow, path);
}
openFolderPicker(forceNewWindow?: boolean): TPromise<void> {
return this.windowsService.openFolderPicker(this.windowId, forceNewWindow);
}
reloadWindow(): TPromise<void> {
return this.windowsService.reloadWindow(this.windowId);
}
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* 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 { TPromise } from 'vs/base/common/winjs.base';
import { IWindowsService } from 'vs/platform/windows/common/windows';
// TODO@Joao: remove this dependency, move all implementation to this class
import { IWindowsMainService } from 'vs/code/electron-main/windows';
export class WindowsService implements IWindowsService {
_serviceBrand: any;
constructor(
@IWindowsMainService private windowsMainService: IWindowsMainService
) { }
openFileFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise<void> {
this.windowsMainService.openFileFolderPicker(forceNewWindow);
return TPromise.as(null);
}
openFilePicker(windowId: number, forceNewWindow?: boolean, path?: string): TPromise<void> {
this.windowsMainService.openFilePicker(forceNewWindow, path);
return TPromise.as(null);
}
openFolderPicker(windowId: number, forceNewWindow?: boolean): TPromise<void> {
this.windowsMainService.openFolderPicker(forceNewWindow);
return TPromise.as(null);
}
reloadWindow(windowId: number): TPromise<void> {
const vscodeWindow = this.windowsMainService.getWindowById(windowId);
if (vscodeWindow) {
this.windowsMainService.reload(vscodeWindow);
}
return TPromise.as(null);
}
}
\ No newline at end of file
......@@ -47,11 +47,11 @@ import * as languageConfiguration from 'vs/editor/common/modes/languageConfigura
export interface IExtensionApiFactory {
(extension: IExtensionDescription): typeof vscode;
(extension?: IExtensionDescription): typeof vscode;
}
function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
if (extension.enableProposedApi) {
if (extension && extension.enableProposedApi) {
return fn;
} else {
return <any>(() => {
......@@ -92,9 +92,9 @@ export function createApiFactory(initDataConfiguration: IInitConfiguration, init
// Register API-ish commands
ExtHostApiCommands.register(extHostCommands);
return function (extension: IExtensionDescription): typeof vscode {
return function (extension?: IExtensionDescription): typeof vscode {
if (extension.enableProposedApi) {
if (extension && extension.enableProposedApi) {
console.warn(`${extension.name} (${extension.id}) uses PROPOSED API which is subject to change and removal without notice`);
}
......@@ -435,7 +435,7 @@ export function defineAPI(factory: IExtensionApiFactory, extensionService: ExtHo
const trie = new TrieMap<IExtensionDescription>(TrieMap.PathSplitter);
const extensions = extensionService.getAllExtensionDescriptions();
for (const ext of extensions) {
if (ext.name) {
if (ext.main) {
const path = realpathSync(ext.extensionFolderPath);
trie.insert(path, ext);
}
......
......@@ -183,12 +183,12 @@ export class ExtHostApiCommands {
]
});
this._register('vscode.openFolder', (uri?: URI, newWindow?: boolean) => {
this._register('vscode.openFolder', (uri?: URI, forceNewWindow?: boolean) => {
if (!uri) {
return this._commands.executeCommand('_workbench.ipc', 'vscode:openFolderPicker', [newWindow]);
return this._commands.executeCommand('_files.openFolderPicker', forceNewWindow);
}
return this._commands.executeCommand('_workbench.ipc', 'vscode:windowOpen', [[uri.fsPath], newWindow]);
return this._commands.executeCommand('_workbench.ipc', 'vscode:windowOpen', [[uri.fsPath], forceNewWindow]);
}, {
description: 'Open a folder in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder unless the newWindow parameter is set to true.',
args: [
......
......@@ -11,7 +11,8 @@ import { localize } from 'vs/nls';
import * as path from 'path';
import URI from 'vs/base/common/uri';
import { AbstractExtensionService, ActivatedExtension } from 'vs/platform/extensions/common/abstractExtensionService';
import { IExtensionRuntimeService, IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
import { IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
import { IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry';
import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extensionPoints';
import { IMessageService } from 'vs/platform/message/common/message';
......@@ -61,7 +62,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
@IThreadService threadService: IThreadService,
@IMessageService messageService: IMessageService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IExtensionRuntimeService extensionsRuntimeService: IExtensionRuntimeService
@IExtensionEnablementService extensionEnablementService: IExtensionEnablementService
) {
super(false);
this._isDev = !environmentService.isBuilt || !!environmentService.extensionDevelopmentPath;
......@@ -71,7 +72,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService);
this._extensionsStatus = {};
const disabledExtensions = [...extensionsRuntimeService.getGloballyDisabledExtensions(), ...extensionsRuntimeService.getWorkspaceDisabledExtensions()];
const disabledExtensions = [...extensionEnablementService.getGloballyDisabledExtensions(), ...extensionEnablementService.getWorkspaceDisabledExtensions()];
this.scanExtensions().done(extensionDescriptions => {
this._onExtensionDescriptions(disabledExtensions.length ? extensionDescriptions.filter(e => disabledExtensions.indexOf(`${e.publisher}.${e.name}`) === -1) : extensionDescriptions);
});
......
......@@ -83,7 +83,11 @@ export class UntitledEditorInput extends AbstractUntitledEditorInput {
}
public isDirty(): boolean {
return this.cachedModel && this.cachedModel.isDirty();
if (this.cachedModel) {
return this.cachedModel.isDirty();
}
return this.hasAssociatedFilePath; // untitled files with associated path are always dirty
}
public confirmSave(): ConfirmResult {
......
......@@ -144,13 +144,6 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS
// Listen to content changes
this.textModelChangeListener = this.textEditorModel.onDidChangeContent(e => this.onModelContentChanged());
// Emit initial dirty event if we are
if (this.dirty) {
setTimeout(() => {
this._onDidChangeDirty.fire();
}, 0 /* prevent race condition between creating model and emitting dirty event */);
}
return model;
});
}
......
......@@ -9,7 +9,8 @@ import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import timer = require('vs/base/common/timer');
import { Action } from 'vs/base/common/actions';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { EditorInput } from 'vs/workbench/common/editor';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
......@@ -66,7 +67,7 @@ export class CloseWindowAction extends Action {
public static ID = 'workbench.action.closeWindow';
public static LABEL = nls.localize('closeWindow', "Close Window");
constructor(id: string, label: string, @IWindowService private windowService: IWindowService) {
constructor(id: string, label: string, @IWindowIPCService private windowService: IWindowIPCService) {
super(id, label);
}
......@@ -85,7 +86,7 @@ export class SwitchWindow extends Action {
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@IQuickOpenService private quickOpenService: IQuickOpenService
) {
super(id, label);
......@@ -121,7 +122,7 @@ export class CloseFolderAction extends Action {
label: string,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IMessageService private messageService: IMessageService,
@IWindowService private windowService: IWindowService
@IWindowIPCService private windowService: IWindowIPCService
) {
super(id, label);
}
......@@ -145,7 +146,7 @@ export class NewWindowAction extends Action {
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService
@IWindowIPCService private windowService: IWindowIPCService
) {
super(id, label);
}
......@@ -162,7 +163,7 @@ export class ToggleFullScreenAction extends Action {
public static ID = 'workbench.action.toggleFullScreen';
public static LABEL = nls.localize('toggleFullScreen', "Toggle Full Screen");
constructor(id: string, label: string, @IWindowService private windowService: IWindowService) {
constructor(id: string, label: string, @IWindowIPCService private windowService: IWindowIPCService) {
super(id, label);
}
......@@ -178,7 +179,7 @@ export class ToggleMenuBarAction extends Action {
public static ID = 'workbench.action.toggleMenuBar';
public static LABEL = nls.localize('toggleMenuBar', "Toggle Menu Bar");
constructor(id: string, label: string, @IWindowService private windowService: IWindowService) {
constructor(id: string, label: string, @IWindowIPCService private windowService: IWindowIPCService) {
super(id, label);
}
......@@ -194,7 +195,7 @@ export class ToggleDevToolsAction extends Action {
public static ID = 'workbench.action.toggleDevTools';
public static LABEL = nls.localize('toggleDevTools', "Toggle Developer Tools");
constructor(id: string, label: string, @IWindowService private windowService: IWindowService) {
constructor(id: string, label: string, @IWindowIPCService private windowService: IWindowIPCService) {
super(id, label);
}
......@@ -329,7 +330,7 @@ export class ShowStartupPerformance extends Action {
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@IEnvironmentService environmentService: IEnvironmentService
) {
super(id, label);
......@@ -420,8 +421,8 @@ export class ShowStartupPerformance extends Action {
export class ReloadWindowAction extends Action {
public static ID = 'workbench.action.reloadWindow';
public static LABEL = nls.localize('reloadWindow', "Reload Window");
static ID = 'workbench.action.reloadWindow';
static LABEL = nls.localize('reloadWindow', "Reload Window");
constructor(
id: string,
......@@ -432,11 +433,9 @@ export class ReloadWindowAction extends Action {
super(id, label);
}
public run(): TPromise<boolean> {
run(): TPromise<boolean> {
this.partService.setRestoreSidebar(); // we want the same sidebar after a reload restored
this.windowService.getWindow().reload();
return TPromise.as(true);
return this.windowService.reloadWindow().then(() => true);
}
}
......@@ -448,7 +447,7 @@ export class OpenRecentAction extends Action {
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@IQuickOpenService private quickOpenService: IQuickOpenService,
@IWorkspaceContextService private contextService: IWorkspaceContextService
) {
......
......@@ -81,8 +81,9 @@ function registerListeners(enableDeveloperTools) {
const key = extractKey(e);
if (key === TOGGLE_DEV_TOOLS_KB) {
ipc.send('vscode:toggleDevTools', windowId);
// remote.getCurrentWebContents().toggleDevTools();
} else if (key === RELOAD_KB) {
ipc.send('vscode:reloadWindow', windowId);
remote.getCurrentWindow().reload();
}
});
}
......
......@@ -17,7 +17,7 @@ import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { ILifecycleService, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { ChildProcess, fork } from 'child_process';
import { ipcRenderer as ipc } from 'electron';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
......@@ -25,6 +25,7 @@ import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import Event, { Emitter } from 'vs/base/common/event';
import { WatchDog } from 'vs/base/common/watchDog';
import { createQueuedSender, IQueuedSender } from 'vs/base/node/processes';
import { IInitData, IInitConfiguration } from 'vs/workbench/api/node/extHost.protocol';
import { MainProcessExtensionService } from 'vs/workbench/api/node/mainThreadExtensionService';
......@@ -55,6 +56,8 @@ export class ExtensionHostProcessWorker {
private isExtensionDevelopmentTestFromCli: boolean;
private isExtensionDevelopmentDebugging: boolean;
private extHostWatchDog = new WatchDog(250, 4);
private _onMessage = new Emitter<any>();
public get onMessage(): Event<any> {
return this._onMessage.event;
......@@ -65,7 +68,7 @@ export class ExtensionHostProcessWorker {
constructor(
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IMessageService private messageService: IMessageService,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@ILifecycleService lifecycleService: ILifecycleService,
@IInstantiationService private instantiationService: IInstantiationService,
@IEnvironmentService private environmentService: IEnvironmentService,
......@@ -110,6 +113,29 @@ export class ExtensionHostProcessWorker {
// Initialize extension host process with hand shakes
this.initializeExtensionHostProcess = this.doInitializeExtensionHostProcess(opts);
// Check how well the extension host is doing
if (this.environmentService.isBuilt) {
this.initializeExtensionHostProcess.done(() => {
this.extHostWatchDog.start();
this.extHostWatchDog.onAlert(() => {
this.extHostWatchDog.stop();
// log the identifiers of those extensions that
// have code and are loaded in the extension host
this.extensionService.getExtensions().then(extensions => {
const ids: string[] = [];
for (const ext of extensions) {
if (ext.main) {
ids.push(ext.id);
}
}
this.telemetryService.publicLog('extHostUnresponsive', ids);
});
});
});
}
}
public get messagingProtocol(): IMessagePassingProtocol {
......@@ -191,6 +217,12 @@ export class ExtensionHostProcessWorker {
return true;
}
// Heartbeat message
if (msg === '__$heartbeat') {
this.extHostWatchDog.reset();
return false;
}
// Support logging from extension host
if (msg && (<ILogEntry>msg).type === '__$console') {
this.logExtensionHostMessage(<ILogEntry>msg);
......@@ -339,4 +371,4 @@ export class ExtensionHostProcessWorker {
event.veto(TPromise.timeout(100 /* wait a bit for IPC to get delivered */).then(() => false));
}
}
}
\ No newline at end of file
}
......@@ -21,7 +21,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { AutoSaveConfiguration } from 'vs/platform/files/common/files';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
......@@ -58,7 +58,7 @@ export class ElectronIntegration {
constructor(
@IInstantiationService private instantiationService: IInstantiationService,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@IPartService private partService: IPartService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@ITelemetryService private telemetryService: ITelemetryService,
......
......@@ -15,7 +15,7 @@ import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
import platform = require('vs/base/common/platform');
import { IKeybindings } from 'vs/platform/keybinding/common/keybinding';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { CloseEditorAction, ReloadWindowAction, ShowStartupPerformance, ReportIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleDevToolsAction, ToggleFullScreenAction, ToggleMenuBarAction, OpenRecentAction, CloseFolderAction, CloseWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction } from 'vs/workbench/electron-browser/actions';
import { MessagesVisibleContext, NoEditorsVisibleContext } from 'vs/workbench/electron-browser/workbench';
......@@ -61,7 +61,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
when: NoEditorsVisibleContext,
primary: closeEditorOrWindowKeybindings.primary,
handler: accessor => {
const windowService = accessor.get(IWindowService);
const windowService = accessor.get(IWindowIPCService);
windowService.getWindow().close();
}
});
......@@ -151,6 +151,11 @@ configurationRegistry.registerConfiguration({
'type': 'number',
'default': 0,
'description': nls.localize('zoomLevel', "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.")
},
'window.showFullPath': {
'type': 'boolean',
'default': false,
'description': nls.localize('showFullPath', "If enabled, will show the full path of opened files in the window title.")
}
}
});
\ No newline at end of file
......@@ -30,7 +30,10 @@ import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties';
import { ElectronIntegration } from 'vs/workbench/electron-browser/integration';
import { WorkspaceStats } from 'vs/workbench/services/telemetry/common/workspaceStats';
import { IWindowService, WindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService, WindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows';
import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc';
import { WindowService } from 'vs/platform/windows/electron-browser/windowService';
import { MessageService } from 'vs/workbench/services/message/electron-browser/messageService';
import { IRequestService } from 'vs/platform/request/common/request';
import { RequestService } from 'vs/platform/request/node/requestService';
......@@ -50,6 +53,7 @@ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerServ
import { MainProcessExtensionService } from 'vs/workbench/api/node/mainThreadExtensionService';
import { IOptions } from 'vs/workbench/common/options';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
......@@ -64,7 +68,7 @@ import { IThreadService } from 'vs/workbench/services/thread/common/threadServic
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/platform/commands/common/commandService';
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { IExtensionService, IExtensionRuntimeService } from 'vs/platform/extensions/common/extensions';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { MainThreadModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
......@@ -75,13 +79,13 @@ import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser';
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
import { URLChannelClient } from 'vs/platform/url/common/urlIpc';
import { IURLService } from 'vs/platform/url/common/url';
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
import { WorkspaceConfigurationService } from 'vs/workbench/services/configuration/node/configurationService';
import { ExtensionHostProcessWorker } from 'vs/workbench/electron-browser/extensionHost';
import { ExtensionRuntimeService } from 'vs/workbench/services/extensions/common/extensionRuntimeService';
import { remote } from 'electron';
// self registering services
......@@ -107,7 +111,6 @@ export class WorkbenchShell {
private eventService: IEventService;
private environmentService: IEnvironmentService;
private contextViewService: ContextViewService;
private windowService: IWindowService;
private threadService: MainThreadService;
private configurationService: IConfigurationService;
private themeService: ThemeService;
......@@ -221,12 +224,21 @@ export class WorkbenchShell {
serviceCollection.set(IConfigurationService, this.configurationService);
serviceCollection.set(IEnvironmentService, this.environmentService);
const instantiationService = new InstantiationService(serviceCollection, true);
const instantiationServiceImpl = new InstantiationService(serviceCollection, true);
const instantiationService = instantiationServiceImpl as IInstantiationService;
this.windowService = instantiationService.createInstance(WindowService);
serviceCollection.set(IWindowService, this.windowService);
// TODO@joao remove this
const windowIPCService = instantiationService.createInstance<IWindowIPCService>(WindowIPCService);
serviceCollection.set(IWindowIPCService, windowIPCService);
const sharedProcess = connectNet(this.environmentService.sharedIPCHandle, `window:${this.windowService.getWindowId()}`);
const windowsChannel = mainProcessClient.getChannel('windows');
const windowsChannelClient = new WindowsChannelClient(windowsChannel);
serviceCollection.set(IWindowsService, windowsChannelClient);
const windowService = new WindowService(windowIPCService.getWindowId(), windowsChannelClient);
serviceCollection.set(IWindowService, windowService);
const sharedProcess = connectNet(this.environmentService.sharedIPCHandle, `window:${windowIPCService.getWindowId()}`);
sharedProcess.done(client => {
client.registerChannel('choice', new ChoiceChannel(this.messageService));
......@@ -292,9 +304,9 @@ export class WorkbenchShell {
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel);
serviceCollection.set(IExtensionManagementService, extensionManagementChannelClient);
const extensionsRuntimeService = instantiationService.createInstance(ExtensionRuntimeService);
serviceCollection.set(IExtensionRuntimeService, extensionsRuntimeService);
disposables.add(extensionsRuntimeService);
const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
disposables.add(extensionEnablementService);
const extensionHostProcessWorker = instantiationService.createInstance(ExtensionHostProcessWorker);
this.threadService = instantiationService.createInstance(MainThreadService, extensionHostProcessWorker.messagingProtocol);
......@@ -333,17 +345,17 @@ export class WorkbenchShell {
const searchService = instantiationService.createInstance(SearchService);
serviceCollection.set(ISearchService, searchService);
const codeEditorService = instantiationService.createInstance(CodeEditorServiceImpl);
const codeEditorService = instantiationServiceImpl.createInstance(CodeEditorServiceImpl);
serviceCollection.set(ICodeEditorService, codeEditorService);
const integrityService = instantiationService.createInstance(IntegrityServiceImpl);
serviceCollection.set(IIntegrityService, integrityService);
const urlChannel = mainProcessClient.getChannel('url');
const urlChannelClient = new URLChannelClient(urlChannel, this.windowService.getWindowId());
const urlChannelClient = new URLChannelClient(urlChannel, windowIPCService.getWindowId());
serviceCollection.set(IURLService, urlChannelClient);
return [instantiationService, serviceCollection];
return [instantiationServiceImpl, serviceCollection];
}
public open(): void {
......
......@@ -149,6 +149,7 @@ export class ElectronWindow {
}
public reload(): void {
this.partService.setRestoreSidebar(); // we want the same sidebar after a reload restored
ipc.send('vscode:reloadWindow', this.windowId);
}
......
......@@ -106,6 +106,12 @@ function connectToRenderer(): TPromise<IRendererConnection> {
stats.length = 0;
}, 1000);
// Send heartbeat
setInterval(function () {
queuedSender.send('__$heartbeat');
}, 250);
// Tell the outside that we are initialized
queuedSender.send('initialized');
......@@ -121,4 +127,4 @@ connectToRenderer().then(renderer => {
const extensionHostMain = new ExtensionHostMain(renderer.remoteCom, renderer.initData);
onTerminate = () => extensionHostMain.terminate();
return extensionHostMain.start();
}).done(null, err => console.error(err));
\ No newline at end of file
}).done(null, err => console.error(err));
......@@ -106,59 +106,50 @@ export abstract class ExpressionContainer implements debug.IExpressionContainer
private static BASE_CHUNK_SIZE = 100;
public valueChanged: boolean;
private children: TPromise<debug.IExpression[]>;
private _value: string;
constructor(
public stackFrame: debug.IStackFrame,
public reference: number,
private id: string,
private cacheChildren: boolean,
public namedVariables: number,
public indexedVariables: number,
private startOfVariables = 0
) {
// noop
}
) { }
public getChildren(): TPromise<debug.IExpression[]> {
if (!this.cacheChildren || !this.children) {
// only variables with reference > 0 have children.
if (this.reference <= 0) {
this.children = TPromise.as([]);
} else {
if (!this.getChildrenInChunks) {
return this.fetchVariables(undefined, undefined, undefined);
// only variables with reference > 0 have children.
if (this.reference <= 0) {
return TPromise.as([]);
}
if (!this.getChildrenInChunks) {
return this.fetchVariables(undefined, undefined, undefined);
}
// Check if object has named variables, fetch them independent from indexed variables #9670
return (!!this.namedVariables ? this.fetchVariables(undefined, undefined, 'named') : TPromise.as([])).then(childrenArray => {
// Use a dynamic chunk size based on the number of elements #9774
let chunkSize = ExpressionContainer.BASE_CHUNK_SIZE;
while (this.indexedVariables > chunkSize * ExpressionContainer.BASE_CHUNK_SIZE) {
chunkSize *= ExpressionContainer.BASE_CHUNK_SIZE;
}
if (this.indexedVariables > chunkSize) {
// There are a lot of children, create fake intermediate values that represent chunks #9537
const numberOfChunks = Math.ceil(this.indexedVariables / chunkSize);
for (let i = 0; i < numberOfChunks; i++) {
const start = this.startOfVariables + i * chunkSize;
const count = Math.min(chunkSize, this.indexedVariables - i * chunkSize);
childrenArray.push(new Variable(this.stackFrame, this, this.reference, `[${start}..${start + count - 1}]`, '', '', null, count, null, true, start));
}
// Check if object has named variables, fetch them independent from indexed variables #9670
this.children = (!!this.namedVariables ? this.fetchVariables(undefined, undefined, 'named')
: TPromise.as([])).then(childrenArray => {
// Use a dynamic chunk size based on the number of elements #9774
let chunkSize = ExpressionContainer.BASE_CHUNK_SIZE;
while (this.indexedVariables > chunkSize * ExpressionContainer.BASE_CHUNK_SIZE) {
chunkSize *= ExpressionContainer.BASE_CHUNK_SIZE;
}
if (this.indexedVariables > chunkSize) {
// There are a lot of children, create fake intermediate values that represent chunks #9537
const numberOfChunks = Math.ceil(this.indexedVariables / chunkSize);
for (let i = 0; i < numberOfChunks; i++) {
const start = this.startOfVariables + i * chunkSize;
const count = Math.min(chunkSize, this.indexedVariables - i * chunkSize);
childrenArray.push(new Variable(this.stackFrame, this, this.reference, `[${start}..${start + count - 1}]`, '', '', null, count, null, true, start));
}
return childrenArray;
}
return this.fetchVariables(this.startOfVariables, this.indexedVariables, 'indexed')
.then(variables => childrenArray.concat(variables));
});
return childrenArray;
}
}
return this.children;
return this.fetchVariables(this.startOfVariables, this.indexedVariables, 'indexed')
.then(variables => childrenArray.concat(variables));
});
}
public getId(): string {
......@@ -205,10 +196,14 @@ export class Expression extends ExpressionContainer implements debug.IExpression
public available: boolean;
public type: string;
constructor(public name: string, cacheChildren: boolean, id = generateUuid()) {
super(null, 0, id, cacheChildren, 0, 0);
this.value = Expression.DEFAULT_VALUE;
constructor(public name: string, id = generateUuid()) {
super(null, 0, id, 0, 0);
this.available = false;
// name is not set if the expression is just being added
// in that case do not set default value to prevent flashing #14499
if (name) {
this.value = Expression.DEFAULT_VALUE;
}
}
public evaluate(process: debug.IProcess, stackFrame: debug.IStackFrame, context: string): TPromise<void> {
......@@ -265,7 +260,7 @@ export class Variable extends ExpressionContainer implements debug.IExpression {
public available = true,
startOfVariables = 0
) {
super(stackFrame, reference, `variable:${parent.getId()}:${name}:${reference}`, true, namedVariables, indexedVariables, startOfVariables);
super(stackFrame, reference, `variable:${parent.getId()}:${name}:${reference}`, namedVariables, indexedVariables, startOfVariables);
this.value = massageValue(value);
}
......@@ -327,7 +322,7 @@ export class Scope extends ExpressionContainer implements debug.IScope {
namedVariables: number,
indexedVariables: number
) {
super(stackFrame, reference, `scope:${stackFrame.getId()}:${name}:${reference}`, true, namedVariables, indexedVariables);
super(stackFrame, reference, `scope:${stackFrame.getId()}:${name}:${reference}`, namedVariables, indexedVariables);
}
}
......@@ -817,7 +812,7 @@ export class Model implements debug.IModel {
}
public addReplExpression(process: debug.IProcess, stackFrame: debug.IStackFrame, name: string): TPromise<void> {
const expression = new Expression(name, true);
const expression = new Expression(name);
this.addReplElements([expression]);
return expression.evaluate(process, stackFrame, 'repl')
.then(() => this._onDidChangeREPLElements.fire());
......@@ -892,7 +887,7 @@ export class Model implements debug.IModel {
}
public addWatchExpression(process: debug.IProcess, stackFrame: debug.IStackFrame, name: string): TPromise<void> {
const we = new Expression(name, false);
const we = new Expression(name);
this.watchExpressions.push(we);
if (!name) {
this._onDidChangeWatchExpressions.fire(we);
......
......@@ -160,7 +160,7 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget {
const matchingExpression = lineContent.substring(expressionRange.startColumn - 1, expressionRange.endColumn);
let promise: TPromise<debug.IExpression>;
if (process.session.configuration.capabilities.supportsEvaluateForHovers) {
const result = new Expression(matchingExpression, true);
const result = new Expression(matchingExpression);
promise = result.evaluate(process, focusedStackFrame, 'hover').then(() => result);
} else {
promise = this.findExpressionInStackFrame(matchingExpression.split('.').map(word => word.trim()).filter(word => !!word));
......
......@@ -52,7 +52,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWindowService, IBroadcast } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService, IBroadcast } from 'vs/workbench/services/window/electron-browser/windowService';
import { ILogEntry, EXTENSION_LOG_BROADCAST_CHANNEL, EXTENSION_ATTACH_BROADCAST_CHANNEL, EXTENSION_TERMINATE_BROADCAST_CHANNEL } from 'vs/workbench/electron-browser/extensionHost';
import { ipcRenderer as ipc } from 'electron';
......@@ -87,7 +87,7 @@ export class DebugService implements debug.IDebugService {
@IFileService private fileService: IFileService,
@IMessageService private messageService: IMessageService,
@IPartService private partService: IPartService,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@ITelemetryService private telemetryService: ITelemetryService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IContextKeyService contextKeyService: IContextKeyService,
......@@ -402,7 +402,7 @@ export class DebugService implements debug.IDebugService {
let result: Expression[];
try {
result = JSON.parse(this.storageService.get(DEBUG_WATCH_EXPRESSIONS_KEY, StorageScope.WORKSPACE, '[]')).map((watchStoredData: { name: string, id: string }) => {
return new Expression(watchStoredData.name, false, watchStoredData.id);
return new Expression(watchStoredData.name, watchStoredData.id);
});
} catch (e) { }
......@@ -641,7 +641,8 @@ export class DebugService implements debug.IDebugService {
const process = this.model.addProcess(configuration.name, session);
if (!this.viewModel.focusedProcess) {
this.setFocusedStackFrameAndEvaluate(null, process);
this.viewModel.setFocusedStackFrame(null, process);
this._onDidChangeState.fire();
}
this.toDisposeOnSessionEnd[session.getId()] = [];
if (client) {
......
......@@ -56,7 +56,7 @@ export function renderExpressionValue(expressionOrValue: debug.IExpression | str
dom.addClass(container, 'string');
}
if (showChanged && (<any>expressionOrValue).valueChanged) {
if (showChanged && (<any>expressionOrValue).valueChanged && value !== Expression.DEFAULT_VALUE) {
// value changed color has priority over other colors.
container.className = 'value changed';
}
......@@ -502,7 +502,7 @@ export class CallStackRenderer implements IRenderer {
}
private renderProcess(process: debug.IProcess, data: IProcessTemplateData): void {
data.process.title = nls.localize('process', "Process");
data.process.title = nls.localize({ key: 'process', comment: ['Process is a noun'] }, "Process");
data.name.textContent = process.name;
}
......
......@@ -177,7 +177,7 @@ export class WatchExpressionsView extends CollapsibleViewletView {
this.tree.refresh().done(() => {
return this.toReveal instanceof Expression ? this.tree.reveal(this.toReveal) : TPromise.as(true);
}, errors.onUnexpectedError);
}, 250);
}, 50);
}
public renderHeader(container: HTMLElement): void {
......
......@@ -18,10 +18,12 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { KeyCode } from 'vs/base/common/keyCodes';
import tree = require('vs/base/parts/tree/browser/tree');
import treeimpl = require('vs/base/parts/tree/browser/treeImpl');
import { Context as SuggestContext } from 'vs/editor/contrib/suggest/common/suggest';
import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestController';
import { IEditorOptions, IReadOnlyModel, EditorContextKeys, ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { Position } from 'vs/editor/common/core/position';
import * as modes from 'vs/editor/common/modes';
import { editorAction, ServicesAccessor, EditorAction } from 'vs/editor/common/editorCommonExtensions';
import { editorAction, ServicesAccessor, EditorAction, EditorCommand, CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
......@@ -270,7 +272,8 @@ export class Repl extends Panel implements IPrivateReplService {
scrollBeyondLastLine: false,
theme: this.themeService.getColorTheme(),
renderLineHighlight: false,
fixedOverflowWidgets: true
fixedOverflowWidgets: true,
acceptSuggestionOnEnter: false
};
}
......@@ -349,6 +352,19 @@ class AcceptReplInputAction extends EditorAction {
}
public run(accessor: ServicesAccessor, editor: ICommonCodeEditor): void | TPromise<void> {
SuggestController.get(editor).acceptSelectedSuggestion();
accessor.get(IPrivateReplService).acceptReplInput();
}
}
const SuggestCommand = EditorCommand.bindToContribution<SuggestController>(SuggestController.get);
CommonEditorRegistry.registerEditorCommand(new SuggestCommand({
id: 'repl.action.acceptSuggestion',
precondition: ContextKeyExpr.and(debug.CONTEXT_IN_DEBUG_REPL, SuggestContext.Visible),
handler: x => x.acceptSelectedSuggestion(),
kbOpts: {
weight: 50,
kbExpr: EditorContextKeys.TextFocus,
primary: KeyCode.RightArrow
}
}));
......@@ -34,7 +34,7 @@ suite('Debug - View Model', () => {
test('selected expression', () => {
assert.equal(model.getSelectedExpression(), null);
const expression = new Expression('my expression', false);
const expression = new Expression('my expression');
model.setSelectedExpression(expression);
assert.equal(model.getSelectedExpression(), expression);
......
......@@ -11,7 +11,7 @@ import { TPromise, Promise } from 'vs/base/common/winjs.base';
import { IDataSource, ITree, IRenderer } from 'vs/base/parts/tree/browser/tree';
import { DefaultController } from 'vs/base/parts/tree/browser/treeDefaults';
import { Action } from 'vs/base/common/actions';
import { IExtensionDependencies, IExtensionsWorkbenchService } from '../common/extensions';
import { IExtensionDependencies, IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
......
......@@ -27,15 +27,15 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IExtensionGalleryService, IExtensionManifest, IKeyBinding } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension, IExtensionDependencies } from '../common/extensions';
import { Renderer, DataSource, Controller } from './dependenciesViewer';
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension, IExtensionDependencies } from 'vs/workbench/parts/extensions/common/extensions';
import { Renderer, DataSource, Controller } from 'vs/workbench/parts/extensions/browser/dependenciesViewer';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITemplateData } from './extensionsList';
import { RatingsWidget, InstallWidget } from './extensionsWidgets';
import { ITemplateData } from 'vs/workbench/parts/extensions/browser/extensionsList';
import { RatingsWidget, InstallWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets';
import { EditorOptions } from 'vs/workbench/common/editor';
import product from 'vs/platform/product';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, BuiltinStatusLabelAction } from './extensionsActions';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction, ReloadAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import WebView from 'vs/workbench/parts/html/browser/webview';
import { Keybinding } from 'vs/base/common/keybinding';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
......
......@@ -8,14 +8,14 @@ import { forEach } from 'vs/base/common/collections';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { match } from 'vs/base/common/glob';
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, LocalExtensionType, EXTENSION_IDENTIFIER_PATTERN } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionsConfiguration, ConfigurationKey } from '../common/extensions';
import { IExtensionsConfiguration, ConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModel } from 'vs/editor/common/editorCommon';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import product from 'vs/platform/product';
import { IChoiceService } from 'vs/platform/message/common/message';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ShowRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction } from './extensionsActions';
import { ShowRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import Severity from 'vs/base/common/severity';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Schemas } from 'vs/base/common/network';
......
......@@ -15,9 +15,9 @@ import { IDelegate } from 'vs/base/browser/ui/list/list';
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IExtension, IExtensionsWorkbenchService } from '../common/extensions';
import { InstallAction, UpdateAction, BuiltinStatusLabelAction, ReloadAction, ManageExtensionAction } from './extensionsActions';
import { Label, RatingsWidget, InstallWidget } from './extensionsWidgets';
import { IExtension, IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
import { InstallAction, UpdateAction, BuiltinStatusLabelAction, ManageExtensionAction, ReloadAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import { Label, RatingsWidget, InstallWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets';
import { EventType } from 'vs/base/common/events';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
......
......@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { IAutoFocus, Mode, IModel } from 'vs/base/parts/quickopen/common/quickOpen';
import { QuickOpenEntry, QuickOpenModel } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { QuickOpenHandler } from 'vs/workbench/browser/quickopen';
import { IExtensionsViewlet, VIEWLET_ID } from '../common/extensions';
import { IExtensionsViewlet, VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
class SimpleEntry extends QuickOpenEntry {
......
......@@ -12,7 +12,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IExtensionGalleryService, IExtensionTipsService, ExtensionsLabel, ExtensionsChannelId } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actionRegistry';
import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService';
import { ExtensionTipsService } from 'vs/workbench/parts/extensions/browser/extensionTipsService';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/parts/output/common/output';
import { EditorDescriptor } from 'vs/workbench/browser/parts/editor/baseEditor';
......@@ -22,17 +22,18 @@ import { VIEWLET_ID, IExtensionsWorkbenchService } from '../common/extensions';
import { ExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/node/extensionsWorkbenchService';
import {
OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction, ShowPopularExtensionsAction,
ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, UpdateAllAction, OpenExtensionsFolderAction, ConfigureWorkspaceRecommendedExtensionsAction, InstallVSIXAction,
ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, UpdateAllAction, ConfigureWorkspaceRecommendedExtensionsAction,
EnableAllAction, EnableAllWorkpsaceAction, DisableAllAction, DisableAllWorkpsaceAction
} from './extensionsActions';
} from 'vs/workbench/parts/extensions/browser/extensionsActions';
import { OpenExtensionsFolderAction, InstallVSIXAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
import { ExtensionEditor } from './extensionEditor';
import { StatusUpdater } from './extensionsViewlet';
import { ExtensionEditor } from 'vs/workbench/parts/extensions/browser/extensionEditor';
import { StatusUpdater } from 'vs/workbench/parts/extensions/electron-browser/extensionsViewlet';
import { IQuickOpenRegistry, Extensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen';
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/electron-browser/extensionsFileTemplate';
import { ExtensionsConfigurationSchema, ExtensionsConfigurationSchemaId } from 'vs/workbench/parts/extensions/common/extensionsFileTemplate';
// Singletons
registerSingleton(IExtensionGalleryService, ExtensionGalleryService);
......@@ -48,7 +49,7 @@ Registry.as<IOutputChannelRegistry>(OutputExtensions.OutputChannels)
// Quickopen
Registry.as<IQuickOpenRegistry>(Extensions.Quickopen).registerQuickOpenHandler(
new QuickOpenHandlerDescriptor(
'vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen',
'vs/workbench/parts/extensions/browser/extensionsQuickOpen',
'ExtensionsHandler',
'ext ',
localize('extensionsCommands', "Manage Extensions"),
......@@ -58,7 +59,7 @@ Registry.as<IQuickOpenRegistry>(Extensions.Quickopen).registerQuickOpenHandler(
Registry.as<IQuickOpenRegistry>(Extensions.Quickopen).registerQuickOpenHandler(
new QuickOpenHandlerDescriptor(
'vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen',
'vs/workbench/parts/extensions/browser/extensionsQuickOpen',
'GalleryExtensionsHandler',
'ext install ',
localize('galleryExtensionsCommands', "Install Gallery Extensions"),
......@@ -70,7 +71,7 @@ Registry.as<IQuickOpenRegistry>(Extensions.Quickopen).registerQuickOpenHandler(
const editorDescriptor = new EditorDescriptor(
ExtensionEditor.ID,
localize('extension', "Extension"),
'vs/workbench/parts/extensions/electron-browser/extensionEditor',
'vs/workbench/parts/extensions/browser/extensionEditor',
'ExtensionEditor'
);
......
......@@ -28,12 +28,13 @@ import { PagedModel, IPagedModel } from 'vs/base/common/paging';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { PagedList } from 'vs/base/browser/ui/list/listPaging';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Delegate, Renderer } from './extensionsList';
import { Delegate, Renderer } from 'vs/workbench/parts/extensions/browser/extensionsList';
import { IExtensionsWorkbenchService, IExtension, IExtensionsViewlet, VIEWLET_ID, ExtensionState } from '../common/extensions';
import {
ShowRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowInstalledExtensionsAction, ShowDisabledExtensionsAction,
ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, InstallVSIXAction
} from './extensionsActions';
ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction
} from 'vs/workbench/parts/extensions/browser/extensionsActions';
import { InstallVSIXAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, SortBy, SortOrder, IQueryOptions, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
import { Query } from '../common/extensionQuery';
......
......@@ -122,9 +122,8 @@
.explorer-viewlet:lang(ko) .explorer-open-editors .monaco-tree .monaco-tree-row .editor-group { font-weight: normal; }
/* Disable tree twistie */
.explorer-viewlet .explorer-open-editors > .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content:after,
.explorer-viewlet .explorer-open-editors > .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content:before {
border: none;
display: none;
}
/* High Contrast Theming */
......
......@@ -11,7 +11,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { VIEWLET_ID } from 'vs/workbench/parts/files/common/files';
import { TextFileModelChangeEvent, ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles';
import { platform, Platform } from 'vs/base/common/platform';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { Position } from 'vs/platform/editor/common/editor';
import { IEditorStacksModel } from 'vs/workbench/common/editor';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
......@@ -41,7 +41,7 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
@IEditorGroupService editorGroupService: IEditorGroupService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IActivityService private activityService: IActivityService,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService
) {
this.toUnbind = [];
......
......@@ -19,6 +19,9 @@ import { DirtyFilesTracker } from 'vs/workbench/parts/files/electron-browser/dir
import { OpenFolderAction, OpenFileAction, OpenFileFolderAction, ShowOpenedFileInNewWindow, GlobalRevealInOSAction, GlobalCopyPathAction, CopyPathAction, RevealInOSAction } from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IWindowService } from 'vs/platform/windows/common/windows';
class FileViewerActionContributor extends ActionBarContributor {
......@@ -76,4 +79,10 @@ actionsRegistry.registerActionBarContributor(Scope.VIEWER, FileViewerActionContr
// Register Dirty Files Tracker
(<IWorkbenchContributionsRegistry>Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution(
DirtyFilesTracker
);
\ No newline at end of file
);
// Register Commands
CommandsRegistry.registerCommand('_files.openFolderPicker', (accessor: ServicesAccessor, forceNewWindow: boolean) => {
const windowService = accessor.get(IWindowService);
windowService.openFolderPicker(forceNewWindow);
});
\ No newline at end of file
......@@ -29,7 +29,7 @@ import { IGitService, IFileStatus, Status, StatusType, ServiceState, IModel, IBr
import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService';
import paths = require('vs/base/common/paths');
import URI from 'vs/base/common/uri';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
function flatten(context?: any, preferFocus = false): IFileStatus[] {
......@@ -1152,7 +1152,7 @@ export class SyncAction extends GitAction {
@IGitService gitService: IGitService,
@IConfigurationService private configurationService: IConfigurationService,
@IConfigurationEditingService private configurationEditingService: IConfigurationEditingService,
@IWindowService private windowService: IWindowService
@IWindowIPCService private windowService: IWindowIPCService
) {
super(id, label, 'git-action sync', gitService);
}
......
......@@ -9,7 +9,7 @@ import Severity from 'vs/base/common/severity';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ILifecycleService, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { IMessageService } from 'vs/platform/message/common/message';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { ipcRenderer as ipc } from 'electron';
import Event, { Emitter } from 'vs/base/common/event';
......@@ -24,7 +24,7 @@ export class LifecycleService implements ILifecycleService {
constructor(
@IMessageService private messageService: IMessageService,
@IWindowService private windowService: IWindowService
@IWindowIPCService private windowService: IWindowIPCService
) {
this.registerListeners();
}
......
......@@ -22,7 +22,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelBuilder } from 'vs/editor/node/model/modelBuilder';
......@@ -46,7 +46,7 @@ export class TextFileService extends AbstractTextFileService {
@IModeService private modeService: IModeService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
@IEditorGroupService editorGroupService: IEditorGroupService,
@IWindowService private windowService: IWindowService,
@IWindowIPCService private windowService: IWindowIPCService,
@IModelService private modelService: IModelService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IBackupService backupService: IBackupService
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册