very happy to delete settings.ts on main side

This commit is contained in:
Benjamin Pasero
2016-08-22 17:02:53 +02:00
parent 2e90ab0001
commit 43bb742920
10 changed files with 43 additions and 258 deletions
+5 -5
View File
@@ -16,7 +16,6 @@ import { IProcessEnvironment, IEnvService, EnvService } from 'vs/code/electron-m
import { IWindowsService, WindowsManager } from 'vs/code/electron-main/windows';
import { ILifecycleService, LifecycleService } from 'vs/code/electron-main/lifecycle';
import { VSCodeMenu } from 'vs/code/electron-main/menus';
import { ISettingsService, SettingsManager } from 'vs/code/electron-main/settings';
import { IUpdateService, UpdateManager } from 'vs/code/electron-main/update-manager';
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/common/ipc.electron';
import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net';
@@ -70,7 +69,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce
const windowsService = accessor.get(IWindowsService);
const lifecycleService = accessor.get(ILifecycleService);
const updateService = accessor.get(IUpdateService);
const settingsService = accessor.get(ISettingsService);
const configurationService = <ConfigurationService>accessor.get(IConfigurationService);
// We handle uncaught exceptions here to prevent electron from opening a dialog to the user
process.on('uncaughtException', (err: any) => {
@@ -146,6 +145,8 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce
if (windowsMutex) {
windowsMutex.release();
}
configurationService.dispose();
}
// Dispose on app quit
@@ -166,8 +167,8 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce
// Lifecycle
lifecycleService.ready();
// Load settings
settingsService.loadSync();
// Load settings (TODO@Ben remove)
global.globalSettingsValue = JSON.stringify(configurationService.getConfiguration());
// Propagate to clients
windowsService.ready(userEnv);
@@ -396,7 +397,6 @@ function start(): void {
services.set(IConfigurationService, new SyncDescriptor(ConfigurationService));
services.set(IRequestService, new SyncDescriptor(RequestService));
services.set(IUpdateService, new SyncDescriptor(UpdateManager));
services.set(ISettingsService, new SyncDescriptor(SettingsManager));
const instantiationService = new InstantiationService(services);
-218
View File
@@ -1,218 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { app } from 'electron';
import * as fs from 'fs';
import * as path from 'path';
import * as json from 'vs/base/common/json';
import * as objects from 'vs/base/common/objects';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IEnvService } from 'vs/code/electron-main/env';
import Event, {Emitter} from 'vs/base/common/event';
export const ISettingsService = createDecorator<ISettingsService>('settingsService');
export interface ISettings {
settings: any;
settingsParseErrors?: string[];
}
export interface ISettingsService {
_serviceBrand: any;
globalSettings: ISettings;
loadSync(): boolean;
getValue<T>(key: string, fallback?: T): T;
onChange: Event<ISettings>;
}
/**
* TODO@Joao TODO@Ben - this needs to die
*
* We need to have each participant (renderer, main, cli, shared) be able
* to listen on changes to each of these files, independently.
*/
export class SettingsManager implements ISettingsService {
_serviceBrand: any;
private static CHANGE_BUFFER_DELAY = 300;
globalSettings: ISettings;
private timeoutHandle: number;
private watcher: fs.FSWatcher;
private appSettingsPath: string;
private _onChange: Emitter<ISettings>;
constructor(@IEnvService envService: IEnvService) {
this.appSettingsPath = envService.appSettingsPath;
this._onChange = new Emitter<ISettings>();
this.registerWatchers();
app.on('will-quit', () => this.dispose());
}
loadSync(): boolean {
let settingsChanged = false;
const loadedSettings = this.doLoadSync();
if (!objects.equals(loadedSettings, this.globalSettings)) {
// Keep in class
this.globalSettings = loadedSettings;
settingsChanged = true; // changed value
}
// Store into global so that any renderer can access the value with remote.getGlobal()
if (settingsChanged) {
global.globalSettingsValue = JSON.stringify(this.globalSettings);
}
return settingsChanged;
}
get onChange(): Event<ISettings> {
return this._onChange.event;
}
getValue(key: string, fallback?: any): any {
return this.doGetValue(key, fallback);
}
private doGetValue(key: string, fallback?: any): any {
if (!key) {
return fallback;
}
let value = this.globalSettings.settings;
const parts = key.split('\.');
while (parts.length && value) {
const part = parts.shift();
value = value[part];
}
return typeof value !== 'undefined' ? value : fallback;
}
private registerWatchers(): void {
const self = this;
function attachSettingsChangeWatcher(watchPath: string): void {
self.watcher = fs.watch(watchPath);
self.watcher.on('change', () => self.onSettingsFileChange());
}
// Attach a watcher to the settings directory
attachSettingsChangeWatcher(path.dirname(this.appSettingsPath));
// Follow symlinks and attach watchers if they resolve
fs.lstat(this.appSettingsPath, (err, stats) => {
if (err) {
return;
}
if (stats.isSymbolicLink() && !stats.isDirectory()) {
fs.readlink(this.appSettingsPath, (err, realPath) => {
if (err) {
return;
}
attachSettingsChangeWatcher(realPath);
});
}
});
}
private onSettingsFileChange(): void {
// we can get multiple change events for one change, so we buffer through a timeout
if (this.timeoutHandle) {
global.clearTimeout(this.timeoutHandle);
this.timeoutHandle = null;
}
this.timeoutHandle = global.setTimeout(() => {
// Reload
const didChange = this.loadSync();
// Emit event
if (didChange) {
this._onChange.fire(this.globalSettings);
}
}, SettingsManager.CHANGE_BUFFER_DELAY);
}
private doLoadSync(): ISettings {
const settings = this.doLoadSettingsSync();
return {
settings: settings.contents,
settingsParseErrors: settings.parseErrors
};
}
private doLoadSettingsSync(): { contents: any; parseErrors?: string[]; } {
const root = Object.create(null);
let content = '{}';
try {
content = fs.readFileSync(this.appSettingsPath).toString();
} catch (error) {
// ignore
}
let contents = Object.create(null);
try {
contents = json.parse(content);
} catch (error) {
// parse problem
return {
contents: Object.create(null),
parseErrors: [this.appSettingsPath]
};
}
for (let key in contents) {
this.setNode(root, key, contents[key]);
}
return {
contents: root
};
}
private setNode(root: any, key: string, value: any): any {
const segments = key.split('.');
const last = segments.pop();
let curr = root;
segments.forEach((s) => {
let obj = curr[s];
switch (typeof obj) {
case 'undefined':
obj = curr[s] = {};
break;
case 'object':
break;
default:
console.log('Conflicting user settings: ' + key + ' at ' + s + ' with ' + JSON.stringify(obj));
}
curr = obj;
});
curr[last] = value;
}
dispose(): void {
if (this.watcher) {
this.watcher.close();
this.watcher = null;
}
}
}
+11 -3
View File
@@ -13,7 +13,7 @@ import { shell, screen, BrowserWindow } from 'electron';
import { TPromise, TValueCallback } from 'vs/base/common/winjs.base';
import { ICommandLineArguments, IEnvService, IProcessEnvironment } from 'vs/code/electron-main/env';
import { ILogService } from 'vs/code/electron-main/log';
import { ISettingsService } from 'vs/code/electron-main/settings';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { parseArgs } from 'vs/code/node/argv';
export interface IWindowState {
@@ -106,6 +106,13 @@ export interface IWindowConfiguration extends ICommandLineArguments {
extensionsToInstall: string[];
}
export interface IWindowSettings {
openFilesInNewWindow: boolean;
reopenFolders: 'all' | 'one' | 'none';
restoreFullscreen: boolean;
zoomLevel: number;
}
export class VSCodeWindow {
public static menuBarHiddenKey = 'menuBarHidden';
@@ -133,7 +140,7 @@ export class VSCodeWindow {
config: IWindowCreationOptions,
@ILogService private logService: ILogService,
@IEnvService private envService: IEnvService,
@ISettingsService private settingsService: ISettingsService,
@IConfigurationService private configurationService: IConfigurationService,
@IStorageService private storageService: IStorageService
) {
this.options = config;
@@ -395,7 +402,8 @@ export class VSCodeWindow {
let url = require.toUrl('vs/workbench/electron-browser/bootstrap/index.html');
// Set zoomlevel
const zoomLevel = this.settingsService.getValue('window.zoomLevel');
const windowConfig = this.configurationService.getConfiguration<IWindowSettings>('window');
const zoomLevel = windowConfig && windowConfig.zoomLevel;
if (typeof zoomLevel === 'number') {
windowConfiguration.zoomLevel = zoomLevel;
}
+19 -12
View File
@@ -14,11 +14,11 @@ import * as arrays from 'vs/base/common/arrays';
import { assign, mixin } from 'vs/base/common/objects';
import { EventEmitter } from 'events';
import { IStorageService } from 'vs/code/electron-main/storage';
import { IPath, VSCodeWindow, ReadyState, IWindowConfiguration, IWindowState as ISingleWindowState, defaultWindowState } from 'vs/code/electron-main/window';
import { IPath, VSCodeWindow, ReadyState, IWindowConfiguration, IWindowState as ISingleWindowState, defaultWindowState, IWindowSettings } from 'vs/code/electron-main/window';
import { ipcMain as ipc, app, screen, crashReporter, BrowserWindow, dialog } from 'electron';
import { ICommandLineArguments, IProcessEnvironment, IEnvService, IParsedPath, parseLineAndColumnAware } from 'vs/code/electron-main/env';
import { ILifecycleService } from 'vs/code/electron-main/lifecycle';
import { ISettingsService } from 'vs/code/electron-main/settings';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IUpdateService, IUpdate } from 'vs/code/electron-main/update-manager';
import { ILogService } from 'vs/code/electron-main/log';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -132,8 +132,8 @@ export class WindowsManager implements IWindowsService {
@IEnvService private envService: IEnvService,
@ILifecycleService private lifecycleService: ILifecycleService,
@IUpdateService private updateService: IUpdateService,
@ISettingsService private settingsService: ISettingsService
) { }
@IConfigurationService private configurationService: IConfigurationService
) { }
onOpen(clb: (path: IPath) => void): () => void {
this.eventEmitter.addListener(EventTypes.OPEN, clb);
@@ -193,8 +193,9 @@ export class WindowsManager implements IWindowsService {
}, 100);
});
this.settingsService.onChange((newSettings) => {
this.sendToAll('vscode:optionsChange', JSON.stringify({ globalSettings: newSettings }));
this.configurationService.onDidUpdateConfiguration(event => {
global.globalSettingsValue = JSON.stringify(event.config); // Load settings (TODO@Ben remove)
this.sendToAll('vscode:optionsChange', JSON.stringify(event.config));
}, this);
ipc.on('vscode:startCrashReporter', (event: any, config: any) => {
@@ -516,7 +517,7 @@ export class WindowsManager implements IWindowsService {
// Warn if the requested path to open does not exist
if (!iPath) {
let options:Electron.ShowMessageBoxOptions = {
let options: Electron.ShowMessageBoxOptions = {
title: this.envService.product.nameLong,
type: 'info',
buttons: [nls.localize('ok', "OK")],
@@ -589,7 +590,10 @@ export class WindowsManager implements IWindowsService {
} else {
openFilesInNewWindow = openConfig.preferNewWindow;
if (openFilesInNewWindow && !openConfig.cli.extensionDevelopmentPath) { // can be overriden via settings (not for PDE though!)
openFilesInNewWindow = this.settingsService.getValue('window.openFilesInNewWindow', openFilesInNewWindow);
const windowConfig = this.configurationService.getConfiguration<IWindowSettings>('window');
if (windowConfig && !windowConfig.openFilesInNewWindow) {
openFilesInNewWindow = false; // do not open in new window if user configured this explicitly
}
}
}
@@ -831,7 +835,8 @@ export class WindowsManager implements IWindowsService {
if (this.lifecycleService.wasUpdated) {
reopenFolders = ReopenFoldersSetting.ALL; // always reopen all folders when an update was applied
} else {
reopenFolders = this.settingsService.getValue('window.reopenFolders', ReopenFoldersSetting.ONE);
const windowConfig = this.configurationService.getConfiguration<IWindowSettings>('window');
reopenFolders = (windowConfig && windowConfig.reopenFolders) || ReopenFoldersSetting.ONE;
}
let lastActiveFolder = this.windowsState.lastActiveWindow && this.windowsState.lastActiveWindow.workspacePath;
@@ -877,10 +882,12 @@ export class WindowsManager implements IWindowsService {
// New window
if (!vscodeWindow) {
const windowConfig = this.configurationService.getConfiguration<IWindowSettings>('window');
vscodeWindow = this.instantiationService.createInstance(VSCodeWindow, {
state: this.getNewWindowState(configuration),
extensionDevelopmentPath: configuration.extensionDevelopmentPath,
allowFullscreen: this.lifecycleService.wasUpdated || this.settingsService.getValue('window.restoreFullscreen', false)
allowFullscreen: this.lifecycleService.wasUpdated || (windowConfig && windowConfig.restoreFullscreen)
});
WindowsManager.WINDOWS.push(vscodeWindow);
@@ -1000,7 +1007,7 @@ export class WindowsManager implements IWindowsService {
}
public openFileFolderPicker(forceNewWindow?: boolean): void {
this.doPickAndOpen({ pickFolders: true, pickFiles: true , forceNewWindow});
this.doPickAndOpen({ pickFolders: true, pickFiles: true, forceNewWindow });
}
public openFilePicker(forceNewWindow?: boolean, path?: string): void {
@@ -1020,7 +1027,7 @@ export class WindowsManager implements IWindowsService {
}
private getFileOrFolderPaths(options: INativeOpenDialogOptions, clb: (paths: string[]) => void): void {
let workingDir = options.path || this.storageService.getItem<string>(WindowsManager.workingDirPickerStorageKey);
let workingDir = options.path ||  this.storageService.getItem<string>(WindowsManager.workingDirPickerStorageKey);
let focussedWindow = this.getFocusedWindow();
let pickerProperties: ('openFile' | 'openDirectory' | 'multiSelections' | 'createDirectory')[];