提交 fa056757 编写于 作者: J Johannes Rieken

merge with 'master'

......@@ -9,6 +9,9 @@ if not exist node_modules call .\scripts\npm.bat install
:: Get electron
node .\node_modules\gulp\bin\gulp.js electron
:: Build
if not exist out node .\node_modules\gulp\bin\gulp.js compile
:: Configuration
set NODE_ENV=development
set VSCODE_DEV=1
......
......@@ -16,6 +16,9 @@ function code() {
# Get electron
node node_modules/gulp/bin/gulp.js electron
# Build
test -d out || gulp compile
# Configuration
export NODE_ENV=development
export VSCODE_DEV=1
......
......@@ -55,7 +55,6 @@ var globals = <IGlobalScope><any> (typeof self === 'object' ? self : global);
var userAgent = globals.navigator ? globals.navigator.userAgent : '';
var isTest = !!globals.isTest;
var isPseudo = globals.document && globals.document.URL.match(/[^\?]*\?[^\#]*pseudo=true/);
// DOCUMENTED FOR FUTURE REFERENCE:
// When running IE11 in IE10 document mode, the code below will identify the browser as being IE10,
......
......@@ -1046,25 +1046,6 @@ export function removeScriptTags(html:string):string {
return div.innerHTML;
};
export function parseSearch():{[key:string]:string} {
var result:{[key:string]:string} = {};
var search = window.location.search;
if (search) {
var params = search.split(/[?&]/);
for (var i = 0; i < params.length; i++) {
var param = params[i];
if (param) {
var keyValue = param.split('=');
if (keyValue.length === 2) {
result[keyValue[0]] = decodeURIComponent(keyValue[1]);
}
}
}
}
return result;
}
export function append<T extends Node>(parent: HTMLElement, child: T): T {
parent.appendChild(child);
return child;
......
......@@ -6,16 +6,7 @@
import { globals } from 'vs/base/common/platform';
function getWorkersCount(): number {
var defaultValue = 2;
var url_matches = (globals.location ? globals.location.search : '').match(/monaco-workers=(\d+)/i);
if (url_matches) {
defaultValue = parseInt(url_matches[1], 10);
}
return environment('workersCount', defaultValue);
}
export const workersCount = getWorkersCount();
export const workersCount = environment('workersCount', 2);
export const enableTasks = environment('enableTasks');
export const enableSendASmile = environment('enableSendASmile');
export const enableJavaScriptRewriting = environment('enableJavaScriptRewriting');
......
......@@ -174,7 +174,7 @@ export default class URI {
var ret = URI._parse(path);
if (ret.scheme || ret.fragment || ret.query) {
throw new Error();
throw new Error(`Path ${ path } contains a scheme, fragment or a query. Can not convert it to a file uri.`);
}
ret = ret.with('file', undefined,
......
......@@ -22,7 +22,7 @@ var NLSLoaderPlugin;
var global = _nlsPluginGlobal;
var Resources = global.Plugin && global.Plugin.Resources ? global.Plugin.Resources : undefined;
var DEFAULT_TAG = 'i-default';
var IS_PSEUDO = (global && global.document && global.document.URL.match(/[^\?]*\?[^\#]*pseudo=true/));
var IS_PSEUDO = (global && global.document && global.document.location && global.document.location.hash.indexOf('pseudo=true') >= 0);
var slice = Array.prototype.slice;
function _format(message, args) {
var result;
......
......@@ -34,7 +34,6 @@ import {WorkbenchLayout, LayoutOptions} from 'vs/workbench/browser/layout';
import {IActionBarRegistry, Extensions as ActionBarExtensions} from 'vs/workbench/browser/actionBarRegistry';
import {IViewletRegistry, Extensions as ViewletExtensions} from 'vs/workbench/browser/viewlet';
import {QuickOpenController} from 'vs/workbench/browser/parts/quickopen/quickOpenController';
import {WorkspaceStats} from 'vs/platform/telemetry/common/workspaceStats';
import {getServices} from 'vs/platform/instantiation/common/extensions';
import {AbstractKeybindingService} from 'vs/platform/keybinding/browser/keybindingServiceImpl';
import {UntitledEditorService, IUntitledEditorService} from 'vs/workbench/services/untitled/browser/untitledEditorService';
......@@ -71,6 +70,7 @@ interface WorkbenchParams {
export interface IWorkbenchCallbacks {
onServicesCreated?: () => void;
onWorkbenchStarted?: () => void;
}
/**
......@@ -247,26 +247,9 @@ export class Workbench implements IPartService {
this.eventService.emit(EventType.WORKBENCH_CREATED);
this.creationPromiseComplete(true);
// Log to telemetry service
let windowSize = {
innerHeight: window.innerHeight,
innerWidth: window.innerWidth,
outerHeight: window.outerHeight,
outerWidth: window.outerWidth
};
this.telemetryService.publicLog('workspaceLoad',
{
userAgent: navigator.userAgent,
windowSize: windowSize,
autoSaveEnabled: this.contextService.isAutoSaveEnabled && this.contextService.isAutoSaveEnabled(),
emptyWorkbench: !this.contextService.getWorkspace(),
customKeybindingsCount: this.keybindingService.customKeybindingsCount(),
theme: this.currentTheme
});
let workspaceStats: WorkspaceStats = <WorkspaceStats>this.instantiationService.createInstance(WorkspaceStats);
workspaceStats.reportWorkspaceTags();
if (this.callbacks && this.callbacks.onWorkbenchStarted) {
this.callbacks.onWorkbenchStarted();
}
}, errors.onUnexpectedError);
} catch (error) {
......
......@@ -14,7 +14,7 @@ import 'vs/css!vs/workbench/browser/media/vs-theme';
import 'vs/css!vs/workbench/browser/media/vs-dark-theme';
import 'vs/css!vs/workbench/browser/media/hc-black-theme';
import {Promise,TPromise} from 'vs/base/common/winjs.base';
import {Promise, TPromise} from 'vs/base/common/winjs.base';
import {Dimension, Builder, $} from 'vs/base/browser/builder';
import objects = require('vs/base/common/objects');
import env = require('vs/base/common/flags');
......@@ -32,6 +32,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {ElectronTelemetryService} from 'vs/platform/telemetry/electron-browser/electronTelemetryService';
import {ElectronIntegration} from 'vs/workbench/electron-browser/integration';
import {Update} from 'vs/workbench/electron-browser/update';
import {WorkspaceStats} from 'vs/platform/telemetry/common/workspaceStats';
import {IWindowService, WindowService} from 'vs/workbench/services/window/electron-browser/windowService';
import {MessageService} from 'vs/workbench/services/message/electron-browser/messageService';
import {RequestService} from 'vs/workbench/services/request/node/requestService';
......@@ -146,7 +147,7 @@ export function getDelayedService<TService>(clientPromise: TPromise<Client>, ser
return servicePromise().then(service => service[key](...args));
}
});
}, <TService> {});
}, <TService>{});
}
/**
......@@ -154,12 +155,15 @@ export function getDelayedService<TService>(clientPromise: TPromise<Client>, ser
* With the Shell being the top level element in the page, it is also responsible for driving the layouting.
*/
export class WorkbenchShell {
private storageServiceInstance: IStorageService;
private messageServiceInstance: IMessageService;
private contextViewServiceInstance: ContextViewService;
private windowServiceInstance: IWindowService;
private threadServiceInstance: MainThreadService;
private storageService: IStorageService;
private messageService: IMessageService;
private contextViewService: ContextViewService;
private windowService: IWindowService;
private threadService: MainThreadService;
private themeService: IThemeService;
private contextService: WorkspaceContextService;
private telemetryService: ElectronTelemetryService;
private keybindingService: PluginWorkbenchKeybindingService;
private container: HTMLElement;
private toUnbind: { (): void; }[];
......@@ -208,6 +212,9 @@ export class WorkbenchShell {
this.workbench.startup({
onServicesCreated: () => {
this.initPluginSystem();
},
onWorkbenchStarted: () => {
this.onWorkbenchStarted();
}
});
......@@ -229,88 +236,112 @@ export class WorkbenchShell {
return workbenchContainer;
}
private onWorkbenchStarted(): void {
// Log to telemetry service
let windowSize = {
innerHeight: window.innerHeight,
innerWidth: window.innerWidth,
outerHeight: window.outerHeight,
outerWidth: window.outerWidth
};
this.telemetryService.publicLog('workspaceLoad',
{
userAgent: navigator.userAgent,
windowSize: windowSize,
autoSaveEnabled: this.contextService.isAutoSaveEnabled && this.contextService.isAutoSaveEnabled(),
emptyWorkbench: !this.contextService.getWorkspace(),
customKeybindingsCount: this.keybindingService.customKeybindingsCount(),
theme: this.currentTheme
});
let workspaceStats: WorkspaceStats = <WorkspaceStats>this.workbench.getInstantiationService().createInstance(WorkspaceStats);
workspaceStats.reportWorkspaceTags();
}
private initInstantiationService(): IInstantiationService {
let eventServiceInstance = new EventService();
let eventService = new EventService();
let contextServiceInstance = new WorkspaceContextService(eventServiceInstance, this.workspace, this.configuration, this.options);
contextServiceInstance.getConfiguration().additionalWorkerServices = [
this.contextService = new WorkspaceContextService(eventService, this.workspace, this.configuration, this.options);
this.contextService.getConfiguration().additionalWorkerServices = [
{ serviceId: 'requestService', moduleName: 'vs/workbench/services/request/common/requestService', ctorName: 'WorkerRequestService' }
];
this.windowServiceInstance = new WindowService();
this.storageServiceInstance = new Storage(contextServiceInstance);
this.windowService = new WindowService();
this.storageService = new Storage(this.contextService);
// no telemetry in a window for plugin development!
let enableTelemetry = this.configuration.env.isBuilt && !this.configuration.env.pluginDevelopmentPath ? !!this.configuration.env.enableTelemetry : false;
let telemetryServiceInstance = new ElectronTelemetryService(this.storageServiceInstance, { enableTelemetry: enableTelemetry, version: this.configuration.env.version, commitHash: this.configuration.env.commitHash });
this.telemetryService = new ElectronTelemetryService(this.storageService, { enableTelemetry: enableTelemetry, version: this.configuration.env.version, commitHash: this.configuration.env.commitHash });
let keybindingServiceInstance = new PluginWorkbenchKeybindingService(contextServiceInstance, eventServiceInstance, telemetryServiceInstance, <any>window);
this.keybindingService = new PluginWorkbenchKeybindingService(this.contextService, eventService, this.telemetryService, <any>window);
this.messageServiceInstance = new MessageService(contextServiceInstance, this.windowServiceInstance, telemetryServiceInstance, keybindingServiceInstance);
keybindingServiceInstance.setMessageService(this.messageServiceInstance);
this.messageService = new MessageService(this.contextService, this.windowService, this.telemetryService, this.keybindingService);
this.keybindingService.setMessageService(this.messageService);
let configServiceInstance = new ConfigurationService(
contextServiceInstance,
eventServiceInstance
let configService = new ConfigurationService(
this.contextService,
eventService
);
let fileServiceInstance = new FileService(
configServiceInstance,
eventServiceInstance,
contextServiceInstance
let fileService = new FileService(
configService,
eventService,
this.contextService
);
this.contextViewServiceInstance = new ContextViewService(this.container, telemetryServiceInstance, this.messageServiceInstance);
this.contextViewService = new ContextViewService(this.container, this.telemetryService, this.messageService);
let lifecycleServiceInstance = new LifecycleService(this.messageServiceInstance, this.windowServiceInstance);
lifecycleServiceInstance.onShutdown.add(() => fileServiceInstance.dispose());
let lifecycleService = new LifecycleService(this.messageService, this.windowService);
lifecycleService.onShutdown.add(() => fileService.dispose());
this.threadServiceInstance = new MainThreadService(contextServiceInstance, this.messageServiceInstance, this.windowServiceInstance);
lifecycleServiceInstance.onShutdown.add(() => this.threadServiceInstance.dispose());
this.threadService = new MainThreadService(this.contextService, this.messageService, this.windowService);
lifecycleService.onShutdown.add(() => this.threadService.dispose());
let requestServiceInstance = new RequestService(
contextServiceInstance,
configServiceInstance,
telemetryServiceInstance
let requestService = new RequestService(
this.contextService,
configService,
this.telemetryService
);
this.threadServiceInstance.registerInstance(requestServiceInstance);
lifecycleServiceInstance.onShutdown.add(() => requestServiceInstance.dispose());
this.threadService.registerInstance(requestService);
lifecycleService.onShutdown.add(() => requestService.dispose());
let markerServiceInstance = new MarkerService(this.threadServiceInstance);
let markerService = new MarkerService(this.threadService);
let pluginService = new MainProcessPluginService(contextServiceInstance, this.threadServiceInstance, this.messageServiceInstance, telemetryServiceInstance);
keybindingServiceInstance.setPluginService(pluginService);
let pluginService = new MainProcessPluginService(this.contextService, this.threadService, this.messageService, this.telemetryService);
this.keybindingService.setPluginService(pluginService);
let modelServiceInstance = new ModelServiceImpl(this.threadServiceInstance, markerServiceInstance);
let modeService = new MainThreadModeServiceImpl(this.threadServiceInstance, pluginService, modelServiceInstance);
let modelService = new ModelServiceImpl(this.threadService, markerService);
let modeService = new MainThreadModeServiceImpl(this.threadService, pluginService, modelService);
let untitledEditorService = new UntitledEditorService();
this.themeService = new ThemeService(pluginService);
let result = createInstantiationService();
result.addSingleton(ITelemetryService, telemetryServiceInstance);
result.addSingleton(IEventService, eventServiceInstance);
result.addSingleton(IRequestService, requestServiceInstance);
result.addSingleton(IWorkspaceContextService, contextServiceInstance);
result.addSingleton(IContextViewService, this.contextViewServiceInstance);
result.addSingleton(IContextMenuService, new ContextMenuService(this.messageServiceInstance, telemetryServiceInstance));
result.addSingleton(IMessageService, this.messageServiceInstance);
result.addSingleton(IStorageService, this.storageServiceInstance);
result.addSingleton(ILifecycleService, lifecycleServiceInstance);
result.addSingleton(IThreadService, this.threadServiceInstance);
result.addSingleton(ITelemetryService, this.telemetryService);
result.addSingleton(IEventService, eventService);
result.addSingleton(IRequestService, requestService);
result.addSingleton(IWorkspaceContextService, this.contextService);
result.addSingleton(IContextViewService, this.contextViewService);
result.addSingleton(IContextMenuService, new ContextMenuService(this.messageService, this.telemetryService));
result.addSingleton(IMessageService, this.messageService);
result.addSingleton(IStorageService, this.storageService);
result.addSingleton(ILifecycleService, lifecycleService);
result.addSingleton(IThreadService, this.threadService);
result.addSingleton(IPluginService, pluginService);
result.addSingleton(IModeService, modeService);
result.addSingleton(IFileService, fileServiceInstance);
result.addSingleton(IFileService, fileService);
result.addSingleton(IUntitledEditorService, untitledEditorService);
result.addSingleton(ISearchService, new SearchService(modelServiceInstance, untitledEditorService, contextServiceInstance, configServiceInstance));
result.addSingleton(IWindowService, this.windowServiceInstance);
result.addSingleton(IConfigurationService, configServiceInstance);
result.addSingleton(IKeybindingService, keybindingServiceInstance);
result.addSingleton(IMarkerService, markerServiceInstance);
result.addSingleton(IModelService, modelServiceInstance);
result.addSingleton(ISearchService, new SearchService(modelService, untitledEditorService, this.contextService, configService));
result.addSingleton(IWindowService, this.windowService);
result.addSingleton(IConfigurationService, configService);
result.addSingleton(IKeybindingService, this.keybindingService);
result.addSingleton(IMarkerService, markerService);
result.addSingleton(IModelService, modelService);
result.addSingleton(ICodeEditorService, new CodeEditorServiceImpl());
result.addSingleton(IThemeService, this.themeService);
result.addSingleton(IActionsService, new ActionsService(pluginService, keybindingServiceInstance));
result.addSingleton(IActionsService, new ActionsService(pluginService, this.keybindingService));
return result;
......@@ -318,24 +349,24 @@ export class WorkbenchShell {
// TODO@Alex, TODO@Joh move this out of here?
private initPluginSystem(): void {
this.threadServiceInstance.getRemotable(MainProcessVSCodeAPIHelper);
this.threadServiceInstance.getRemotable(MainThreadDocuments);
this.threadServiceInstance.getRemotable(RemoteTelemetryServiceHelper);
this.threadService.getRemotable(MainProcessVSCodeAPIHelper);
this.threadService.getRemotable(MainThreadDocuments);
this.threadService.getRemotable(RemoteTelemetryServiceHelper);
this.workbench.getInstantiationService().createInstance(MainProcessTextMateSyntax);
this.workbench.getInstantiationService().createInstance(MainProcessTextMateSnippet);
this.workbench.getInstantiationService().createInstance(LanguageConfigurationFileHandler);
this.threadServiceInstance.getRemotable(MainThreadConfiguration);
this.threadServiceInstance.getRemotable(MainThreadQuickOpen);
this.threadServiceInstance.getRemotable(MainThreadStatusBar);
this.threadService.getRemotable(MainThreadConfiguration);
this.threadService.getRemotable(MainThreadQuickOpen);
this.threadService.getRemotable(MainThreadStatusBar);
this.workbench.getInstantiationService().createInstance(MainThreadFileSystemEventService);
this.threadServiceInstance.getRemotable(MainThreadCommands);
this.threadServiceInstance.getRemotable(MainThreadOutputService);
this.threadServiceInstance.getRemotable(MainThreadDiagnostics);
this.threadServiceInstance.getRemotable(MainThreadMessageService);
this.threadServiceInstance.getRemotable(MainThreadLanguages);
this.threadServiceInstance.getRemotable(MainThreadWorkspace);
this.threadServiceInstance.getRemotable(MainThreadEditors);
this.threadServiceInstance.getRemotable(MainThreadStorage);
this.threadService.getRemotable(MainThreadCommands);
this.threadService.getRemotable(MainThreadOutputService);
this.threadService.getRemotable(MainThreadDiagnostics);
this.threadService.getRemotable(MainThreadMessageService);
this.threadService.getRemotable(MainThreadLanguages);
this.threadService.getRemotable(MainThreadWorkspace);
this.threadService.getRemotable(MainThreadEditors);
this.threadService.getRemotable(MainThreadStorage);
this.threadServiceInstance.getRemotable(MainThreadLanguageFeatures);
}
......@@ -365,15 +396,15 @@ export class WorkbenchShell {
this.registerListeners();
// Enable theme support
let themeId = this.storageServiceInstance.get(Preferences.THEME, StorageScope.GLOBAL, null);
let themeId = this.storageService.get(Preferences.THEME, StorageScope.GLOBAL, null);
if (!themeId) {
themeId = themes.toId(themes.BaseTheme.VS_DARK);
this.storageServiceInstance.store(Preferences.THEME, themeId, StorageScope.GLOBAL);
this.storageService.store(Preferences.THEME, themeId, StorageScope.GLOBAL);
}
this.setTheme(themeId, false);
this.toUnbind.push(this.storageServiceInstance.addListener(StorageEventType.STORAGE, (e: StorageEvent) => {
this.toUnbind.push(this.storageService.addListener(StorageEventType.STORAGE, (e: StorageEvent) => {
if (e.key === Preferences.THEME) {
this.setTheme(e.newValue);
}
......@@ -487,8 +518,8 @@ export class WorkbenchShell {
console.error(errorMsg);
// Show to user if friendly message provided
if (error.friendlyMessage && this.messageServiceInstance) {
this.messageServiceInstance.show(Severity.Error, error.friendlyMessage);
if (error.friendlyMessage && this.messageService) {
this.messageService.show(Severity.Error, error.friendlyMessage);
}
}
......@@ -498,7 +529,7 @@ export class WorkbenchShell {
let contentsSize = new Dimension(clArea.width, clArea.height);
this.contentsContainer.size(contentsSize.width, contentsSize.height);
this.contextViewServiceInstance.layout();
this.contextViewService.layout();
this.workbench.layout();
}
......@@ -518,8 +549,8 @@ export class WorkbenchShell {
}
}
this.contextViewServiceInstance.dispose();
this.storageServiceInstance.dispose();
this.contextViewService.dispose();
this.storageService.dispose();
// Listeners
while (this.toUnbind.length) {
......
......@@ -133,7 +133,7 @@ export class Lifecycle {
c(true); // veto
});
vscodeWindow.win.webContents.send('vscode:beforeUnload', { okChannel: oneTimeOkEvent, cancelChannel: oneTimeCancelEvent });
vscodeWindow.send('vscode:beforeUnload', { okChannel: oneTimeOkEvent, cancelChannel: oneTimeCancelEvent });
});
}
......
......@@ -37,7 +37,6 @@ export class VSCodeMenu {
private static lastKnownKeybindingsMapStorageKey = 'lastKnownKeybindings';
private static MAX_RECENT_ENTRIES = 10;
private static AUTO_SAVE_DELAY_DEFAULT = 1000; // in ms
private static AUTO_SAVE_DISABLED = -1;
......@@ -119,7 +118,7 @@ export class VSCodeMenu {
// Resolve keybindings when workbench window is up
if (this.actionIdKeybindingRequests.length) {
win.win.webContents.send('vscode:resolveKeybindings', JSON.stringify(this.actionIdKeybindingRequests));
win.send('vscode:resolveKeybindings', JSON.stringify(this.actionIdKeybindingRequests));
}
}
......@@ -423,7 +422,7 @@ export class VSCodeMenu {
// Folders
recentList.folders.forEach((folder, index) => {
if (index < VSCodeMenu.MAX_RECENT_ENTRIES) {
if (index < windows.WindowsManager.MAX_RECENT_ENTRIES) {
openRecentMenu.append(this.createOpenRecentMenuItem(folder));
}
});
......@@ -435,7 +434,7 @@ export class VSCodeMenu {
}
recentList.files.forEach((file, index) => {
if (index < VSCodeMenu.MAX_RECENT_ENTRIES) {
if (index < windows.WindowsManager.MAX_RECENT_ENTRIES) {
openRecentMenu.append(this.createOpenRecentMenuItem(file));
}
});
......
......@@ -294,9 +294,9 @@ export class VSCodeWindow {
// Support navigation via mouse buttons 4/5
if (cmd === 'browser-backward') {
this._win.webContents.send('vscode:runAction', 'workbench.action.navigateBack');
this.send('vscode:runAction', 'workbench.action.navigateBack');
} else if (cmd === 'browser-forward') {
this._win.webContents.send('vscode:runAction', 'workbench.action.navigateForward');
this.send('vscode:runAction', 'workbench.action.navigateForward');
}
});
......@@ -532,6 +532,16 @@ export class VSCodeWindow {
this.win.setMenuBarVisibility(isFullScreen);
}
public sendWhenReady(channel: string, ...args: any[]): void {
this.ready().then(() => {
this.send(channel, ...args);
});
}
public send(channel: string, ...args: any[]): void {
this._win.webContents.send(channel, ...args);
}
public dispose(): void {
if (this.showTimeoutHandle) {
clearTimeout(this.showTimeoutHandle);
......
......@@ -95,8 +95,9 @@ export class WindowsManager {
public static autoSaveDelayStorageKey = 'autoSaveDelay';
public static openedPathsListStorageKey = 'openedPathsList';
private static workingDirPickerStorageKey = 'pickerWorkingDir';
public static MAX_RECENT_ENTRIES = 10;
private static workingDirPickerStorageKey = 'pickerWorkingDir';
private static windowsStateStorageKey = 'windowsState';
private static themeStorageKey = 'theme'; // TODO@Ben this key is only used to find out if a window can be shown instantly because of light theme, remove once we have support for bg color
......@@ -390,13 +391,13 @@ export class WindowsManager {
if (!openFilesInNewWindow && lastActiveWindow) {
lastActiveWindow.restore();
lastActiveWindow.ready().then((readyWindow) => {
readyWindow.win.webContents.send('vscode:openFiles', {
readyWindow.send('vscode:openFiles', {
filesToOpen: filesToOpen,
filesToCreate: filesToCreate
});
if (extensionsToInstall.length) {
readyWindow.win.webContents.send('vscode:installExtensions', { extensionsToInstall });
readyWindow.send('vscode:installExtensions', { extensionsToInstall });
}
});
}
......@@ -418,13 +419,13 @@ export class WindowsManager {
if (windowsOnWorkspacePath.length > 0) {
windowsOnWorkspacePath[0].restore(); // just focus one of them
windowsOnWorkspacePath[0].ready().then((readyWindow) => {
readyWindow.win.webContents.send('vscode:openFiles', {
readyWindow.send('vscode:openFiles', {
filesToOpen: filesToOpen,
filesToCreate: filesToCreate
});
if (extensionsToInstall.length) {
readyWindow.win.webContents.send('vscode:installExtensions', { extensionsToInstall });
readyWindow.send('vscode:installExtensions', { extensionsToInstall });
}
});
......@@ -567,7 +568,8 @@ export class WindowsManager {
// Clear those dupes
recentPaths = arrays.distinct(recentPaths);
return recentPaths;
// Make sure it is bounded
return recentPaths.slice(0, WindowsManager.MAX_RECENT_ENTRIES);
}
private toIPath(anyPath: string, ignoreFileNotFound?: boolean, gotoLineMode?: boolean): window.IPath {
......@@ -889,9 +891,7 @@ export class WindowsManager {
const focusedWindow = this.getFocusedWindow() || this.getLastActiveWindow();
if (focusedWindow) {
focusedWindow.ready().then((readyWindow) => {
readyWindow.win.webContents.send(channel, ...args);
});
focusedWindow.sendWhenReady(channel, ...args);
}
}
......@@ -901,9 +901,7 @@ export class WindowsManager {
return; // do not send if we are instructed to ignore it
}
w.ready().then((readyWindow) => {
readyWindow.win.webContents.send(channel, payload);
});
w.sendWhenReady(channel, payload);
});
}
......
......@@ -8,12 +8,6 @@ import platform = require('vs/platform/platform');
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IDebugService } from 'vs/workbench/parts/debug/common/debug';
import service = require('vs/workbench/parts/debug/electron-browser/debugService');
import { ExtensionOutputHandler } from 'vs/workbench/parts/debug/electron-browser/extensionOutput';
// Register Service
registerSingleton(IDebugService, service.DebugService);
// Register Extension Output Handler
(<IWorkbenchContributionsRegistry>platform.Registry.as(Extensions.Workbench)).registerWorkbenchContribution(
ExtensionOutputHandler
);
\ No newline at end of file
registerSingleton(IDebugService, service.DebugService);
\ No newline at end of file
......@@ -13,6 +13,7 @@ import uri from 'vs/base/common/uri';
import arrays = require('vs/base/common/arrays');
import actions = require('vs/base/common/actions');
import json = require('vs/base/common/json');
import types = require('vs/base/common/types');
import errors = require('vs/base/common/errors');
import severity from 'vs/base/common/severity';
import { Promise, TPromise } from 'vs/base/common/winjs.base';
......@@ -49,7 +50,8 @@ import { IPluginService, IPluginDescription } from 'vs/platform/plugins/common/p
import { IOutputService } from 'vs/workbench/parts/output/common/output';
import { IKeybindingService, IKeybindingContextKey } from 'vs/platform/keybinding/common/keybindingService';
import { IQuickOpenService } from 'vs/workbench/services/quickopen/browser/quickOpenService';
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
import { IWindowService, IBroadcast } from 'vs/workbench/services/window/electron-browser/windowService';
import { ILogEntry, PLUGIN_LOG_BROADCAST_CHANNEL } from 'vs/workbench/services/thread/electron-browser/threadService';
var DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint';
var DEBUG_BREAKPOINTS_ACTIVATED_KEY = 'debug.breakpointactivated';
......@@ -184,6 +186,89 @@ export class DebugService extends ee.EventEmitter implements debug.IDebugService
lifecycleService.onShutdown.add(this.store, this);
lifecycleService.onShutdown.add(this.dispose, this);
this.windowService.onBroadcast.add(this.onBroadcast, this);
}
private onBroadcast(broadcast: IBroadcast): void {
let session = this.getActiveSession();
if (!session || session.getType() !== 'extensionHost') {
return; // we are only intersted if we have an active debug session for extensionHost
}
// A plugin logged output, show it inside the REPL
if (broadcast.channel === PLUGIN_LOG_BROADCAST_CHANNEL) {
let extensionOutput: ILogEntry = broadcast.payload;
let sev = extensionOutput.severity === 'warn' ? severity.Warning : extensionOutput.severity === 'error' ? severity.Error : severity.Info;
let args: any[] = [];
try {
let parsed = JSON.parse(extensionOutput.arguments);
args.push(...Object.getOwnPropertyNames(parsed).map(o => parsed[o]));
} catch (error) {
args.push(extensionOutput.arguments);
}
// Add output for each argument logged
let simpleVals: any[] = [];
for (let i = 0; i < args.length; i++) {
let a = args[i];
// Undefined gets printed as 'undefined'
if (typeof a === 'undefined') {
simpleVals.push('undefined');
}
// Null gets printed as 'null'
else if (a === null) {
simpleVals.push('null');
}
// Objects & Arrays are special because we want to inspect them in the REPL
else if (types.isObject(a) || Array.isArray(a)) {
// Flush any existing simple values logged
if (simpleVals.length) {
this.logToRepl(simpleVals.join(' '), sev);
simpleVals = [];
}
// Show object
this.logToRepl(a, sev);
}
// String: watch out for % replacement directive
// String substitution and formatting @ https://developer.chrome.com/devtools/docs/console
else if (typeof a === 'string') {
let buf = '';
for (let j = 0, len = a.length; j < len; j++) {
if (a[j] === '%' && (a[j + 1] === 's' || a[j + 1] === 'i' || a[j + 1] === 'd')) {
i++; // read over substitution
buf += !types.isUndefinedOrNull(args[i]) ? args[i] : ''; // replace
j++; // read over directive
} else {
buf += a[j];
}
}
simpleVals.push(buf);
}
// number or boolean is joined together
else {
simpleVals.push(a);
}
}
// Flush simple values
if (simpleVals.length) {
this.logToRepl(simpleVals.join(' '), sev);
}
// Show repl
this.revealRepl(true /* in background */).done(null, errors.onUnexpectedError);
}
}
private registerSessionListeners(): void {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IDebugService } from 'vs/workbench/parts/debug/common/debug';
import errors = require('vs/base/common/errors');
import types = require('vs/base/common/types');
import severity from 'vs/base/common/severity';
import { ILogEntry, PLUGIN_LOG_BROADCAST_CHANNEL } from 'vs/workbench/services/thread/electron-browser/threadService';
import { IWindowService, IBroadcast } from 'vs/workbench/services/window/electron-browser/windowService';
import ipc = require('ipc');
export class ExtensionOutputHandler implements IWorkbenchContribution {
static ID = 'debug.extensionOutputHandler';
constructor(
@IDebugService private debugService: IDebugService,
@IWindowService private windowService: IWindowService
) {
this.registerListeners();
}
private registerListeners(): void {
this.windowService.onBroadcast.add(this.onBroadcast, this);
}
private onBroadcast(broadcast: IBroadcast): void {
let session = this.debugService.getActiveSession();
if (!session || session.getType() !== 'extensionHost') {
return; // we are only intersted if we have an active debug session for extensionHost
}
// A plugin logged output, show it inside the REPL
if (broadcast.channel === PLUGIN_LOG_BROADCAST_CHANNEL) {
let extensionOutput: ILogEntry = broadcast.payload;
let sev = extensionOutput.severity === 'warn' ? severity.Warning : extensionOutput.severity === 'error' ? severity.Error : severity.Info;
let args: any[] = [];
try {
let parsed = JSON.parse(extensionOutput.arguments);
args.push(...Object.getOwnPropertyNames(parsed).map(o => parsed[o]));
} catch (error) {
args.push(extensionOutput.arguments);
}
// Add output for each argument logged
let simpleVals: any[] = [];
for (let i = 0; i < args.length; i++) {
let a = args[i];
// Undefined gets printed as 'undefined'
if (typeof a === 'undefined') {
simpleVals.push('undefined');
}
// Null gets printed as 'null'
else if (a === null) {
simpleVals.push('null');
}
// Objects & Arrays are special because we want to inspect them in the REPL
else if (types.isObject(a) || Array.isArray(a)) {
// Flush any existing simple values logged
if (simpleVals.length) {
this.debugService.logToRepl(simpleVals.join(' '), sev);
simpleVals = [];
}
// Show object
this.debugService.logToRepl(a, sev);
}
// String: watch out for % replacement directive
// String substitution and formatting @ https://developer.chrome.com/devtools/docs/console
else if (typeof a === 'string') {
let buf = '';
for (let j = 0, len = a.length; j < len; j++) {
if (a[j] === '%' && (a[j + 1] === 's' || a[j + 1] === 'i' || a[j + 1] === 'd')) {
i++; // read over substitution
buf += !types.isUndefinedOrNull(args[i]) ? args[i] : ''; // replace
j++; // read over directive
} else {
buf += a[j];
}
}
simpleVals.push(buf);
}
// number or boolean is joined together
else {
simpleVals.push(a);
}
}
// Flush simple values
if (simpleVals.length) {
this.debugService.logToRepl(simpleVals.join(' '), sev);
}
// Show repl
this.debugService.revealRepl(true /* in background */).done(null, errors.onUnexpectedError);
}
}
public getId(): string {
return ExtensionOutputHandler.ID;
}
}
\ 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.
*--------------------------------------------------------------------------------------------*/
import assert = require('assert');
import { ReplHistory } from 'vs/workbench/parts/debug/common/replHistory';
suite('Debug - Repl History', () => {
var history: ReplHistory;
setup(() => {
history = new ReplHistory(['one', 'two', 'three', 'four', 'five']);
});
teardown(() => {
history = null;
});
test('previous and next', () => {
assert.equal(history.previous(), 'five');
assert.equal(history.previous(), 'four');
assert.equal(history.previous(), 'three');
assert.equal(history.previous(), 'two');
assert.equal(history.previous(), 'one');
assert.equal(history.previous(), null);
assert.equal(history.next(), 'two');
assert.equal(history.next(), 'three');
assert.equal(history.next(), 'four');
assert.equal(history.next(), 'five');
});
test('evaluated and remember', () => {
history.evaluated('six');
assert.equal(history.previous(), 'six');
assert.equal(history.previous(), 'five');
assert.equal(history.next(), 'six');
history.remember('six++', true);
assert.equal(history.next(), 'six++');
assert.equal(history.previous(), 'six');
history.evaluated('seven');
assert.equal(history.previous(), 'seven');
assert.equal(history.previous(), 'six');
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册