diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index c65f680b60d..35a04e7687e 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -39,7 +39,7 @@ const nodeModules = ['electron', 'original-fs'] // Build const builtInExtensions = [ - { name: 'ms-vscode.node-debug', version: '1.8.3' }, + { name: 'ms-vscode.node-debug', version: '1.8.4' }, { name: 'ms-vscode.node-debug2', version: '1.8.1' } ]; diff --git a/extensions/html/OSSREADME.json b/extensions/html/OSSREADME.json index c2825ad5e53..9949448fbcb 100644 --- a/extensions/html/OSSREADME.json +++ b/extensions/html/OSSREADME.json @@ -1,7 +1,7 @@ // ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS: [{ "name": "js-beautify", - "version": "1.6.2", + "version": "1.6.4", "license": "MIT", "repositoryURL": "https://github.com/beautify-web/js-beautify" },{ diff --git a/extensions/html/client/src/htmlMain.ts b/extensions/html/client/src/htmlMain.ts index 834f4075400..79de03d9f87 100644 --- a/extensions/html/client/src/htmlMain.ts +++ b/extensions/html/client/src/htmlMain.ts @@ -7,7 +7,7 @@ import * as path from 'path'; import { languages, workspace, ExtensionContext, IndentAction } from 'vscode'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Range, RequestType, Protocol2Code } from 'vscode-languageclient'; +import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Range, RequestType } from 'vscode-languageclient'; import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared'; import { activateColorDecorations } from './colorDecorators'; @@ -15,7 +15,7 @@ import * as nls from 'vscode-nls'; let localize = nls.loadMessageBundle(); namespace ColorSymbolRequest { - export const type: RequestType = { get method() { return 'css/colorSymbols'; } }; + export const type: RequestType = { get method() { return 'css/colorSymbols'; }, _: null }; } export function activate(context: ExtensionContext) { @@ -56,7 +56,7 @@ export function activate(context: ExtensionContext) { context.subscriptions.push(disposable); let colorRequestor = (uri: string) => { - return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(Protocol2Code.asRange)); + return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(client.protocol2CodeConverter.asRange)); }; disposable = activateColorDecorations(colorRequestor, { html: true, handlebars: true, razor: true }); context.subscriptions.push(disposable); diff --git a/extensions/html/client/src/typings/ref.d.ts b/extensions/html/client/src/typings/ref.d.ts index 25ca0850b75..7c0805ba6c3 100644 --- a/extensions/html/client/src/typings/ref.d.ts +++ b/extensions/html/client/src/typings/ref.d.ts @@ -3,9 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/// -/// -/// -/// -/// -/// \ No newline at end of file +/// \ No newline at end of file diff --git a/extensions/html/client/tsconfig.json b/extensions/html/client/tsconfig.json index 8cb16334377..31c07df105b 100644 --- a/extensions/html/client/tsconfig.json +++ b/extensions/html/client/tsconfig.json @@ -1,11 +1,10 @@ { "compilerOptions": { - "noLib": true, "target": "es5", "module": "commonjs", - "outDir": "./out" - }, - "exclude": [ - "node_modules" - ] + "outDir": "./out", + "lib": [ + "es5", "es2015.promise" + ] + } } \ No newline at end of file diff --git a/extensions/html/npm-shrinkwrap.json b/extensions/html/npm-shrinkwrap.json index 0288034b88f..b368f41dbf9 100644 --- a/extensions/html/npm-shrinkwrap.json +++ b/extensions/html/npm-shrinkwrap.json @@ -3,19 +3,19 @@ "version": "0.1.0", "dependencies": { "vscode-jsonrpc": { - "version": "2.4.0", - "from": "vscode-jsonrpc@>=2.4.0 <3.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.4.0.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-jsonrpc@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.0.1-alpha.2.tgz" }, "vscode-languageclient": { - "version": "2.6.4-next.1", + "version": "3.0.1-alpha.2", "from": "vscode-languageclient@next", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-2.6.4-next.1.tgz" + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.0.1-alpha.2.tgz" }, "vscode-languageserver-types": { - "version": "1.0.5-next.1", + "version": "3.0.1-alpha.2", "from": "vscode-languageserver-types@next", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.5-next.1.tgz" + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.1-alpha.2.tgz" }, "vscode-nls": { "version": "1.0.7", diff --git a/extensions/html/package.json b/extensions/html/package.json index d2463f92da6..91f765da500 100644 --- a/extensions/html/package.json +++ b/extensions/html/package.json @@ -143,8 +143,12 @@ } }, "dependencies": { - "vscode-languageclient": "^2.6.4-next.1", - "vscode-languageserver-types": "^1.0.5-next.1", + "vscode-languageclient": "^3.0.1-alpha.2", + "vscode-languageserver-types": "^3.0.1-alpha.2", "vscode-nls": "^1.0.7" + }, + "devDependencies": { + "@types/node": "^6.0.51", + "@types/mocha": "^2.2.33" } } diff --git a/extensions/html/server/npm-shrinkwrap.json b/extensions/html/server/npm-shrinkwrap.json index 97e582e4cdb..27420e241aa 100644 --- a/extensions/html/server/npm-shrinkwrap.json +++ b/extensions/html/server/npm-shrinkwrap.json @@ -3,29 +3,29 @@ "version": "1.0.0", "dependencies": { "vscode-css-languageservice": { - "version": "2.0.0-next.3", + "version": "2.0.0-next.5", "from": "vscode-css-languageservice@next", - "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.0.0-next.3.tgz" + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.0.0-next.5.tgz" }, "vscode-html-languageservice": { - "version": "1.0.1-next.4", + "version": "2.0.0-next.1", "from": "vscode-html-languageservice@next", - "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-1.0.1-next.4.tgz" + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-2.0.0-next.1.tgz" }, "vscode-jsonrpc": { - "version": "2.4.0", - "from": "vscode-jsonrpc@>=2.4.0 <3.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.4.0.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-jsonrpc@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.0.1-alpha.2.tgz" }, "vscode-languageserver": { - "version": "2.6.2-next.1", + "version": "3.0.1-alpha.2", "from": "vscode-languageserver@next", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-2.6.2-next.1.tgz" + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.0.1-alpha.2.tgz" }, "vscode-languageserver-types": { - "version": "1.0.5-next.1", - "from": "vscode-languageserver-types@>=1.0.5-next.1 <2.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.5-next.1.tgz" + "version": "3.0.1-alpha.2", + "from": "vscode-languageserver-types@>=3.0.1-alpha.2 <4.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.1-alpha.2.tgz" }, "vscode-nls": { "version": "1.0.7", diff --git a/extensions/html/server/package.json b/extensions/html/server/package.json index 0b3e859b07f..7805ca18099 100644 --- a/extensions/html/server/package.json +++ b/extensions/html/server/package.json @@ -8,15 +8,19 @@ "node": "*" }, "dependencies": { - "vscode-css-languageservice": "^2.0.0-next.3", - "vscode-html-languageservice": "^1.0.1-next.4", - "vscode-languageserver": "^2.6.2-next.1", - "vscode-nls": "^1.0.4", + "vscode-css-languageservice": "^2.0.0-next.5", + "vscode-html-languageservice": "^2.0.0-next.1", + "vscode-languageserver": "^3.0.1-alpha.2", + "vscode-nls": "^1.0.7", "vscode-uri": "^1.0.0" }, + "devDependencies": { + "@types/node": "^6.0.51", + "@types/mocha": "^2.2.33" + }, "scripts": { - "compile": "gulp compile-extension:json-server", - "watch": "gulp watch-extension:json-server", + "compile": "gulp compile-extension:html-server", + "watch": "gulp watch-extension:html-server", "install-service-next": "npm install vscode-css-languageservice@next -f -S && npm install vscode-html-languageservice@next -f -S", "install-service-local": "npm install ../../../../vscode-css-languageservice -f -S && npm install ../../../../vscode-html-languageservice -f -S", "install-server-next": "npm install vscode-languageserver@next -f -S", diff --git a/extensions/html/server/src/htmlServerMain.ts b/extensions/html/server/src/htmlServerMain.ts index d806a73267a..77f5ec493cd 100644 --- a/extensions/html/server/src/htmlServerMain.ts +++ b/extensions/html/server/src/htmlServerMain.ts @@ -17,7 +17,7 @@ import * as nls from 'vscode-nls'; nls.config(process.env['VSCODE_NLS_CONFIG']); namespace ColorSymbolRequest { - export const type: RequestType = { get method() { return 'css/colorSymbols'; } }; + export const type: RequestType = { get method() { return 'css/colorSymbols'; }, _: null }; } // Create a connection for the server diff --git a/extensions/html/server/src/test/ref.d.ts b/extensions/html/server/src/test/ref.d.ts new file mode 100644 index 00000000000..619436f24cc --- /dev/null +++ b/extensions/html/server/src/test/ref.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/extensions/html/server/src/typings/promise.d.ts b/extensions/html/server/src/typings/promise.d.ts deleted file mode 100644 index 804a76812e9..00000000000 --- a/extensions/html/server/src/typings/promise.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - -/** - * The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's - * lib.core.es6.d.ts file. See above Copyright notice. - */ - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise libary is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommand the use of native promises which are available in VS Code. - */ -interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; -} - -/** - * Represents the completion of an asynchronous operation - */ -interface Promise extends Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Promise; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Promise; - - /** - * Attaches a callback for only the rejection of the Promise. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch(onrejected?: (reason: any) => T | Thenable): Promise; -} - -interface PromiseConstructor { - /** - * Creates a new Promise. - * @param executor A callback used to initialize the promise. This callback is passed two arguments: - * a resolve callback used resolve the promise with a value or the result of another promise, - * and a reject callback used to reject the promise with a provided reason or error. - */ - new (executor: (resolve: (value?: T | Thenable) => void, reject: (reason?: any) => void) => void): Promise; - - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - all(values: Array>): Promise; - - /** - * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved - * or rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - race(values: Array>): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new resolved promise for the provided value. - * @param value A promise. - * @returns A promise whose internal state matches the provided promise. - */ - resolve(value: T | Thenable): Promise; - - /** - * Creates a new resolved promise . - * @returns A resolved promise. - */ - resolve(): Promise; -} - -declare var Promise: PromiseConstructor; diff --git a/extensions/html/server/src/typings/ref.d.ts b/extensions/html/server/src/typings/ref.d.ts deleted file mode 100644 index c55bcba02fc..00000000000 --- a/extensions/html/server/src/typings/ref.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -/// -/// -/// -/// \ No newline at end of file diff --git a/extensions/html/server/tsconfig.json b/extensions/html/server/tsconfig.json index 8cb16334377..31c07df105b 100644 --- a/extensions/html/server/tsconfig.json +++ b/extensions/html/server/tsconfig.json @@ -1,11 +1,10 @@ { "compilerOptions": { - "noLib": true, "target": "es5", "module": "commonjs", - "outDir": "./out" - }, - "exclude": [ - "node_modules" - ] + "outDir": "./out", + "lib": [ + "es5", "es2015.promise" + ] + } } \ No newline at end of file diff --git a/src/vs/workbench/api/node/mainThreadDocuments.ts b/src/vs/workbench/api/node/mainThreadDocuments.ts index fd123e00b57..ad138c4fb5a 100644 --- a/src/vs/workbench/api/node/mainThreadDocuments.ts +++ b/src/vs/workbench/api/node/mainThreadDocuments.ts @@ -189,7 +189,9 @@ export class MainThreadDocuments extends MainThreadDocumentsShape { private _handleAsResourceInput(uri: URI): TPromise { return this._textModelResolverService.createModelReference(uri).then(ref => { const result = !!ref.object; - ref.dispose(); + + // TODO@Joao TODO@Joh when should this model reference be disposed? + // ref.dispose(); return result; }); diff --git a/src/vs/workbench/parts/preferences/browser/media/preferences.css b/src/vs/workbench/parts/preferences/browser/media/preferences.css index 8ca08bb0e30..50ebe870c5b 100644 --- a/src/vs/workbench/parts/preferences/browser/media/preferences.css +++ b/src/vs/workbench/parts/preferences/browser/media/preferences.css @@ -3,9 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-editor .view-line:hover :not(.inline-folded).selectSettingValue { +.monaco-editor .view-line:hover :not(.inline-folded).settingValue { text-decoration: underline; - cursor: pointer; } .monaco-editor .copy-preferences-light-bulb { diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 28b14d06f94..a5ecac35a49 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -8,7 +8,6 @@ import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; import { hasClass, getDomNodePagePosition } from 'vs/base/browser/dom'; -import { parse } from 'vs/base/common/json'; import { Disposable } from 'vs/base/common/lifecycle'; import { IAction } from 'vs/base/common/actions'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; @@ -16,7 +15,6 @@ import Event, { Emitter } from 'vs/base/common/event'; import { LinkedMap as Map } from 'vs/base/common/map'; import { Registry } from 'vs/platform/platform'; import { EditorOptions, EditorInput, } from 'vs/workbench/common/editor'; -import { Range } from 'vs/editor/common/core/range'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { StringEditor } from 'vs/workbench/browser/parts/editor/stringEditor'; @@ -24,7 +22,7 @@ import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorIn import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IFoldingController, ID as FoldingContributionId } from 'vs/editor/contrib/folding/common/folding'; import { IPreferencesService, ISettingsGroup, ISetting, ISettingsEditorModel, IKeybindingsEditorModel, IPreferencesEditorModel } from 'vs/workbench/parts/preferences/common/preferences'; -import { DefaultSettings } from 'vs/workbench/parts/preferences/common/preferencesModels'; +import { SettingsEditorModel, DefaultSettingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels'; import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions'; import { ICodeEditor, IEditorMouseEvent } from 'vs/editor/browser/editorBrowser'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; @@ -176,9 +174,12 @@ export class PreferencesEditorContribution extends Disposable implements editorC } private createPreferencesRenderer(editorModel: IPreferencesEditorModel): IPreferencesRenderer { - if (editorModel instanceof DefaultSettings) { + if (editorModel instanceof DefaultSettingsEditorModel) { return this.instantiationService.createInstance(DefaultSettingsRenderer, this.editor, editorModel); } + if (editorModel instanceof SettingsEditorModel) { + // return this.instantiationService.createInstance(SettingsRenderer, this.editor, editorModel); + } return null; } @@ -195,22 +196,37 @@ export class PreferencesEditorContribution extends Disposable implements editorC } } -export class DefaultSettingsRenderer extends Disposable implements IPreferencesRenderer { +export class SettingsRenderer extends Disposable implements IPreferencesRenderer { - private settingsActionsRenderer: SettingsActionsRenderer; - private copyPreferenceLightBulbRenderer: CopySettingsLightBulbRenderer; + private selectSettingValueRenderer: SettingsDecorationsRenderer; - constructor(protected editor: ICodeEditor, protected settingsEditorModel: DefaultSettings, + constructor(protected editor: ICodeEditor, protected settingsEditorModel: SettingsEditorModel, @IPreferencesService protected preferencesService: IPreferencesService, @IInstantiationService protected instantiationService: IInstantiationService ) { super(); - this.settingsActionsRenderer = this._register(instantiationService.createInstance(SettingsActionsRenderer, editor)); - this.copyPreferenceLightBulbRenderer = this._register(instantiationService.createInstance(CopySettingsLightBulbRenderer, editor, this.settingsEditorModel.settingsGroups)); + this.selectSettingValueRenderer = this._register(instantiationService.createInstance(SettingsDecorationsRenderer, editor, false)); } public render() { - this.settingsActionsRenderer.render(this.settingsEditorModel.settingsGroups); + this.selectSettingValueRenderer.render(this.settingsEditorModel.settingsGroups); + } +} + +export class DefaultSettingsRenderer extends Disposable implements IPreferencesRenderer { + + private selectSettingValueRenderer: SettingsDecorationsRenderer; + + constructor(protected editor: ICodeEditor, protected settingsEditorModel: DefaultSettingsEditorModel, + @IPreferencesService protected preferencesService: IPreferencesService, + @IInstantiationService protected instantiationService: IInstantiationService + ) { + super(); + this.selectSettingValueRenderer = this._register(instantiationService.createInstance(SettingsDecorationsRenderer, editor, true)); + } + + public render() { + this.selectSettingValueRenderer.render(this.settingsEditorModel.settingsGroups); } } @@ -236,45 +252,18 @@ export class CopySettingsLightBulbRenderer extends Disposable { } private copy(setting: ISetting, copyPreferenceWidget: CopyPreferenceWidget) { - let jsonSchema: IJSONSchema = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties()[setting.key]; let elementPosition = getDomNodePagePosition(copyPreferenceWidget.getDomNode()); const anchor = { x: elementPosition.left + elementPosition.width, y: elementPosition.top + elementPosition.height + 10 }; - const actions = this.getActions(setting, jsonSchema); - if (actions) { - this.contextMenuService.showContextMenu({ - getAnchor: () => anchor, - getActions: () => TPromise.wrap(actions) - }); - return; - } - this.preferencesService.copyConfiguration(setting); - } - - private getActions(setting: ISetting, jsonSchema: IJSONSchema): IAction[] { - if (jsonSchema.type === 'boolean') { - return [{ - id: 'truthyValue', - label: 'true', - enabled: true, - run: () => this.preferencesService.copyConfiguration({ key: setting.key, value: true }) - }, { - id: 'falsyValue', - label: 'false', - enabled: true, - run: () => this.preferencesService.copyConfiguration({ key: setting.key, value: false }) - }]; - } - if (jsonSchema.enum) { - return jsonSchema.enum.map(value => { - return { - id: value, - label: value, - enabled: true, - run: () => this.preferencesService.copyConfiguration({ key: setting.key, value }) - }; - }); - } - return null; + const actions = [{ + id: 'helpMessage', + label: this.getHelpMessage(setting), + enabled: true, + run: () => this.preferencesService.copyConfiguration(setting) + }]; + this.contextMenuService.showContextMenu({ + getAnchor: () => anchor, + getActions: () => TPromise.wrap(actions) + }); } private onPositionChanged(positionChangeEvent: editorCommon.ICursorPositionChangedEvent) { @@ -302,17 +291,21 @@ export class CopySettingsLightBulbRenderer extends Disposable { private showCopyPreferencesWidget(copyPreferencesWidget: CopyPreferenceWidget, setting: ISetting) { copyPreferencesWidget.show(setting.valueRange.startLineNumber, setting); + copyPreferencesWidget.getDomNode().title = this.getHelpMessage(setting); + } + + private getHelpMessage(setting: ISetting): string { let jsonSchema: IJSONSchema = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties()[setting.key]; if (jsonSchema.type === 'boolean' || jsonSchema.enum) { - copyPreferencesWidget.getDomNode().title = nls.localize('selectAndCopyTitle', "Select a value and copy in Settings"); + return platform.isMacintosh ? nls.localize('selectAndCopyHelpMessageMac', "Cmd + click on the value to choose a value and copy to settings") : nls.localize('selectAndCopyHelpMessage', "Ctrl + click on the value to choose a value and copy to settings"); } else { - copyPreferencesWidget.getDomNode().title = nls.localize('copyTitle', "Copy in Settings"); + return platform.isMacintosh ? nls.localize('copyHelpMessageMac', "Cmd + click on the value to copy to settings") : nls.localize('copyHelpMessage', "Ctrl + click on the value to copy to settings"); } } private getSetting(lineNumber: number): ISetting { for (const group of this.settingsGroups) { - if (Range.containsPosition(group.range, { lineNumber, column: 1 })) { + if (lineNumber >= group.range.startLineNumber && lineNumber <= group.range.endLineNumber) { for (const section of group.sections) { for (const setting of section.settings) { if (lineNumber === setting.valueRange.startLineNumber) { @@ -326,35 +319,46 @@ export class CopySettingsLightBulbRenderer extends Disposable { } } -export class SettingsActionsRenderer extends Disposable { +export class SettingsDecorationsRenderer extends Disposable { private decorationIds: string[] = []; - private static HOVER_MESSAGE = platform.isMacintosh ? nls.localize('selectAndCopyHoverMac', "Cmd + click to select and copy in Settings") : nls.localize('selectAndCopyHover', "Ctrl + click to select and copy in Settings"); + private chooseHoverMessage: string; + private copyHoverMessage: string; - constructor(private editor: ICodeEditor, + private settingsGroups: ISettingsGroup[]; + private model: editorCommon.IModel; + + constructor(private editor: ICodeEditor, private isDefaultSettings: boolean, @IPreferencesService private settingsService: IPreferencesService, @IContextMenuService private contextMenuService: IContextMenuService ) { super(); + if (this.isDefaultSettings) { + this.copyHoverMessage = platform.isMacintosh ? nls.localize('copyDefaultSettingMac', "Cmd + click to copy to settings") : nls.localize('copyDefaultSetting', "Ctrl + click to copy to settings"); + this.chooseHoverMessage = platform.isMacintosh ? nls.localize('selectAndCopyDefaultSettingsHoverMac', "Cmd + click to choose value and copy to settings") : nls.localize('selectAndCopyDefaultSettingsHover', "Ctrl + click to choose a value and copy to settings"); + } else { + this.chooseHoverMessage = platform.isMacintosh ? nls.localize('selectAndCopyHoverMac', "Cmd + click to choose value") : nls.localize('selectAndCopyHover', "Ctrl + click to choose value"); + } this._register(editor.onMouseUp(e => this.onEditorMouseUp(e))); } - public render(settingGroups: ISettingsGroup[]): void { - const model = this.editor.getModel(); - model.changeDecorations(changeAccessor => { + public render(settingsGroups: ISettingsGroup[]): void { + this.model = this.editor.getModel(); + this.settingsGroups = settingsGroups; + this.model.changeDecorations(changeAccessor => { this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, []); }); - model.changeDecorations(changeAccessor => { - this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, this.createDecorations(settingGroups, model)); + this.model.changeDecorations(changeAccessor => { + this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, this.createDecorations(this.model)); }); } - private createDecorations(settingsGroups: ISettingsGroup[], model: editorCommon.IModel): editorCommon.IModelDeltaDecoration[] { + private createDecorations(model: editorCommon.IModel): editorCommon.IModelDeltaDecoration[] { let result: editorCommon.IModelDeltaDecoration[] = []; - for (const settingsGroup of settingsGroups) { + for (const settingsGroup of this.settingsGroups) { for (const settingsSection of settingsGroup.sections) { for (const setting of settingsSection.settings) { - const decoration = this.createSelectSettingDecoration(setting, model); + const decoration = this.createSettingDecoration(setting, model); if (decoration) { result.push(decoration); } @@ -364,17 +368,20 @@ export class SettingsActionsRenderer extends Disposable { return result; } - private createSelectSettingDecoration(setting: ISetting, model: editorCommon.IModel): editorCommon.IModelDeltaDecoration { + private createSettingDecoration(setting: ISetting, model: editorCommon.IModel): editorCommon.IModelDeltaDecoration { const jsonSchema: IJSONSchema = this.getConfigurationsMap()[setting.key]; - if (jsonSchema.enum || jsonSchema.type === 'boolean') { - return { - range: setting.valueRange, - options: { - inlineClassName: 'selectSettingValue', - stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, - hoverMessage: SettingsActionsRenderer.HOVER_MESSAGE - } - }; + if (jsonSchema) { + const canChooseValue = jsonSchema.enum || jsonSchema.type === 'boolean'; + if (this.isDefaultSettings || canChooseValue) { + return { + range: setting.valueRange, + options: { + inlineClassName: 'settingValue', + stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, + hoverMessage: canChooseValue ? this.chooseHoverMessage : this.copyHoverMessage + } + }; + } } return null; } @@ -390,7 +397,7 @@ export class SettingsActionsRenderer extends Disposable { switch (e.target.type) { case editorCommon.MouseTargetType.CONTENT_TEXT: - if ((e.event.ctrlKey || e.event.metaKey) && hasClass(e.target.element, 'selectSettingValue')) { + if ((e.event.ctrlKey || e.event.metaKey) && hasClass(e.target.element, 'settingValue')) { this.onClick(e); } return; @@ -404,36 +411,50 @@ export class SettingsActionsRenderer extends Disposable { } private onClick(e: IEditorMouseEvent) { - const model = this.editor.getModel(); - const setting = parse('{' + model.getLineContent(e.target.range.startLineNumber) + '}'); - const key = Object.keys(setting)[0]; - let value = setting[key]; - let jsonSchema: IJSONSchema = this.getConfigurationsMap()[key]; - const actions = this.getActions(key, jsonSchema); - if (actions) { - let elementPosition = getDomNodePagePosition(e.target.element); - const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 }; - this.contextMenuService.showContextMenu({ - getAnchor: () => anchor, - getActions: () => TPromise.wrap(actions) - }); - return; + const setting = this.getSetting(e.target.range.startLineNumber); + if (setting) { + let jsonSchema: IJSONSchema = this.getConfigurationsMap()[setting.key]; + const actions = this.getActions(setting, jsonSchema); + if (actions) { + let elementPosition = getDomNodePagePosition(e.target.element); + const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 }; + this.contextMenuService.showContextMenu({ + getAnchor: () => anchor, + getActions: () => TPromise.wrap(actions) + }); + return; + } + this.settingsService.copyConfiguration(setting); } - this.settingsService.copyConfiguration({ key, value }); } - private getActions(key: string, jsonSchema: IJSONSchema): IAction[] { + private getSetting(lineNumber: number): ISetting { + for (const group of this.settingsGroups) { + if (lineNumber >= group.range.startLineNumber && lineNumber <= group.range.endLineNumber) { + for (const section of group.sections) { + for (const setting of section.settings) { + if (lineNumber >= setting.valueRange.startLineNumber && lineNumber <= setting.valueRange.endLineNumber) { + return setting; + } + } + } + } + } + return null; + } + + private getActions(setting: ISetting, jsonSchema: IJSONSchema): IAction[] { if (jsonSchema.type === 'boolean') { return [{ id: 'truthyValue', label: 'true', enabled: true, - run: () => this.settingsService.copyConfiguration({ key, value: true }) + run: () => this.settingsService.copyConfiguration({ key: setting.key, value: true }) }, { id: 'falsyValue', label: 'false', enabled: true, - run: () => this.settingsService.copyConfiguration({ key, value: false }) + run: () => this.settingsService.copyConfiguration({ key: setting.key, value: false }) }]; } if (jsonSchema.enum) { @@ -442,10 +463,15 @@ export class SettingsActionsRenderer extends Disposable { id: value, label: value, enabled: true, - run: () => this.settingsService.copyConfiguration({ key, value }) + run: () => this.settingsService.copyConfiguration({ key: setting.key, value }) }; }); } return null; } + + public dispose() { + this.model.deltaDecorations(this.decorationIds, []); + super.dispose(); + } } \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/preferencesService.ts b/src/vs/workbench/parts/preferences/browser/preferencesService.ts index 50e6fa47989..7153a12aa21 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/preferences'; +import * as network from 'vs/base/common/network'; import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; @@ -25,9 +26,10 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { IConfigurationEditingService, ConfigurationTarget, IConfigurationValue } from 'vs/workbench/services/configuration/common/configurationEditing'; import { IPreferencesService, IPreferencesEditorModel, ISettingsEditorModel, IKeybindingsEditorModel } from 'vs/workbench/parts/preferences/common/preferences'; -import { DefaultSettings, DefaultKeybindings } from 'vs/workbench/parts/preferences/common/preferencesModels'; +import { SettingsEditorModel, DefaultSettingsEditorModel, DefaultKeybindingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { DefaultSettingsInput, DefaultKeybindingsInput, DefaultPreferencesInput } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; +import { ITextModelResolverService } from 'vs/editor/common/services/resolverService'; const SETTINGS_INFO_IGNORE_KEY = 'settings.workspace.info.ignore'; @@ -42,12 +44,17 @@ interface IWorkbenchSettingsConfiguration { export class PreferencesService extends Disposable implements IPreferencesService { + private static DEFAULT_SETTINGS_URI: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/settings.json' }); + private static DEFAULT_KEY_BINDINGS_URI: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' }); + _serviceBrand: any; private configurationTarget: ConfigurationTarget = null; - private _defaultSettings: ISettingsEditorModel; - private _defaultKeybindings: IKeybindingsEditorModel; + private _userSettingsEditorModel: SettingsEditorModel; + private _workspaceSettingsEditorModel: SettingsEditorModel; + private _defaultSettingsEditorModel: DefaultSettingsEditorModel; + private _defaultKeybindingsEditorModel: IKeybindingsEditorModel; constructor( @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @@ -61,6 +68,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic @IStorageService private storageService: IStorageService, @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, + @ITextModelResolverService private textModelResolverService: ITextModelResolverService, @IConfigurationEditingService private configurationEditingService: IConfigurationEditingService ) { super(); @@ -78,30 +86,54 @@ export class PreferencesService extends Disposable implements IPreferencesServic })); } - public get defaultSettings(): ISettingsEditorModel { - if (!this._defaultSettings) { - this._defaultSettings = this.instantiationService.createInstance(DefaultSettings); + public resolvePreferencesEditorModel(uri: URI): TPromise { + if (PreferencesService.DEFAULT_SETTINGS_URI.fsPath === uri.fsPath) { + return this.getDefaultSettingsEditorModel(); } - return this._defaultSettings; - } - public get defaultKeybindings(): IKeybindingsEditorModel { - if (!this._defaultKeybindings) { - this._defaultKeybindings = this.instantiationService.createInstance(DefaultKeybindings); + if (PreferencesService.DEFAULT_KEY_BINDINGS_URI.fsPath === uri.fsPath) { + return this.getDefaultKeybindingsEditorModel(); } - return this._defaultKeybindings; - } - resolvePreferencesEditorModel(uri: URI): TPromise { - if (this.defaultSettings.uri.fsPath === uri.fsPath) { - return TPromise.wrap(this._defaultSettings); + if (this.getEditableSettingsURI(ConfigurationTarget.USER).fsPath === uri.fsPath) { + return this.getUserSettingsEditorModel(); } - if (this.defaultKeybindings.uri.fsPath === uri.fsPath) { - return TPromise.wrap(this._defaultKeybindings); + + if (this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE).fsPath === uri.fsPath) { + return this.getWorkspaceSettingsEditorModel(); } + return TPromise.wrap(null); } + public getDefaultSettingsEditorModel(): TPromise { + if (!this._defaultSettingsEditorModel) { + this._defaultSettingsEditorModel = this.instantiationService.createInstance(DefaultSettingsEditorModel, PreferencesService.DEFAULT_SETTINGS_URI); + } + return TPromise.wrap(this._defaultSettingsEditorModel); + } + + public getDefaultKeybindingsEditorModel(): TPromise { + if (!this._defaultKeybindingsEditorModel) { + this._defaultKeybindingsEditorModel = this.instantiationService.createInstance(DefaultKeybindingsEditorModel, PreferencesService.DEFAULT_KEY_BINDINGS_URI); + } + return TPromise.wrap(this._defaultKeybindingsEditorModel); + } + + public getUserSettingsEditorModel(): TPromise { + if (this._userSettingsEditorModel) { + return TPromise.wrap(this._userSettingsEditorModel); + } + return this.resolveSettingsEditorModel(ConfigurationTarget.USER).then(() => this._userSettingsEditorModel); + } + + public getWorkspaceSettingsEditorModel(): TPromise { + if (this._workspaceSettingsEditorModel) { + return TPromise.wrap(this._workspaceSettingsEditorModel); + } + return this.resolveSettingsEditorModel(ConfigurationTarget.WORKSPACE).then(() => this._workspaceSettingsEditorModel); + } + openGlobalSettings(): TPromise { if (this.configurationService.hasWorkspaceConfiguration() && !this.storageService.getBoolean(SETTINGS_INFO_IGNORE_KEY, StorageScope.WORKSPACE)) { this.promptToOpenWorkspaceSettings(); @@ -120,7 +152,9 @@ export class PreferencesService extends Disposable implements IPreferencesServic openGlobalKeybindingSettings(): TPromise { const emptyContents = '// ' + nls.localize('emptyKeybindingsHeader', "Place your key bindings in this file to overwrite the defaults") + '\n[\n]'; - return this.openTwoEditors(DefaultKeybindingsInput.getInstance(this.instantiationService, this.defaultKeybindings), URI.file(this.environmentService.appKeybindingsPath), emptyContents).then(() => null); + return this.getDefaultKeybindingsEditorModel() + .then(defaultKeybindingsEditorModel => this.openTwoEditors(DefaultKeybindingsInput.getInstance(this.instantiationService, defaultKeybindingsEditorModel), URI.file(this.environmentService.appKeybindingsPath), emptyContents)) + .then(() => null); } openEditableSettings(configurationTarget: ConfigurationTarget, showVisibleEditor: boolean = false): TPromise { @@ -157,6 +191,33 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } + private resolveSettingsEditorModel(configurationTarget: ConfigurationTarget): TPromise { + return this.textModelResolverService.createModelReference(this.getEditableSettingsURI(configurationTarget)) + .then(reference => this.onModelResolved(reference.object.textEditorModel, configurationTarget)); + } + + private onModelResolved(model: editorCommon.IModel, configurationTarget: ConfigurationTarget) { + const settingsEditorModel = this.instantiationService.createInstance(SettingsEditorModel, model, configurationTarget); + if (configurationTarget === ConfigurationTarget.USER) { + this._userSettingsEditorModel = settingsEditorModel; + } + if (configurationTarget === ConfigurationTarget.WORKSPACE) { + this._workspaceSettingsEditorModel = settingsEditorModel; + } + model.onWillDispose(() => this.onModelDisposed(configurationTarget)); + } + + private onModelDisposed(configurationTarget: ConfigurationTarget) { + if (configurationTarget === ConfigurationTarget.USER) { + this._userSettingsEditorModel.dispose(); + this._userSettingsEditorModel = null; + } + if (configurationTarget === ConfigurationTarget.WORKSPACE) { + this._workspaceSettingsEditorModel.dispose(); + this._workspaceSettingsEditorModel = null; + } + } + private isEditorFor(editor: IEditor, configurationTarget: ConfigurationTarget): boolean { const fileEditorInput = asFileEditorInput(editor.input); return !!fileEditorInput && fileEditorInput.getResource().fsPath === this.getEditableSettingsURI(configurationTarget).fsPath; @@ -208,7 +269,9 @@ export class PreferencesService extends Disposable implements IPreferencesServic if (openDefaultSettings) { const emptySettingsContents = this.getEmptyEditableSettingsContent(configurationTarget); const settingsResource = this.getEditableSettingsURI(configurationTarget); - return this.openTwoEditors(DefaultSettingsInput.getInstance(this.instantiationService, this.defaultSettings), settingsResource, emptySettingsContents).then(() => null); + return this.getDefaultSettingsEditorModel() + .then(defaultSettingsEditorModel => this.openTwoEditors(DefaultSettingsInput.getInstance(this.instantiationService, defaultSettingsEditorModel), settingsResource, emptySettingsContents)) + .then(() => null); } return this.openEditableSettings(configurationTarget).then(() => null); } diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts index ba13058b1de..8833c128c50 100644 --- a/src/vs/workbench/parts/preferences/common/preferences.ts +++ b/src/vs/workbench/parts/preferences/common/preferences.ts @@ -47,8 +47,10 @@ export const IPreferencesService = createDecorator('prefere export interface IPreferencesService { _serviceBrand: any; - defaultSettings: ISettingsEditorModel; - defaultKeybindings: IKeybindingsEditorModel; + getDefaultSettingsEditorModel(): TPromise; + getUserSettingsEditorModel(): TPromise; + getWorkspaceSettingsEditorModel(): TPromise; + getDefaultKeybindingsEditorModel(): TPromise; resolvePreferencesEditorModel(uri: URI): TPromise; diff --git a/src/vs/workbench/parts/preferences/common/preferencesModels.ts b/src/vs/workbench/parts/preferences/common/preferencesModels.ts index db1f8a1c252..9967dec1c9b 100644 --- a/src/vs/workbench/parts/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/parts/preferences/common/preferencesModels.ts @@ -4,25 +4,184 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import * as network from 'vs/base/common/network'; import * as strings from 'vs/base/common/strings'; +import { assign } from 'vs/base/common/objects'; import URI from 'vs/base/common/uri'; +import { Disposable } from 'vs/base/common/lifecycle'; import { Registry } from 'vs/platform/platform'; +import { visit, JSONVisitor } from 'vs/base/common/json'; +import { IModel } from 'vs/editor/common/editorCommon'; import { IConfigurationNode, IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; import { ISettingsEditorModel, IKeybindingsEditorModel, ISettingsGroup, ISetting } from 'vs/workbench/parts/preferences/common/preferences'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing'; -export class DefaultSettings implements ISettingsEditorModel { +export class SettingsEditorModel extends Disposable implements ISettingsEditorModel { + + private _settingsGroups: ISettingsGroup[]; + + constructor(private model: IModel, private _configurationTarget: ConfigurationTarget) { + super(); + this._register(this.model.onDidChangeContent(() => { + this._settingsGroups = null; + })); + } + + public get uri(): URI { + return this.model.uri; + } + + public get configurationTarget(): ConfigurationTarget { + return this._configurationTarget; + } + + public get settingsGroups(): ISettingsGroup[] { + if (!this._settingsGroups) { + this.parse(); + } + return this._settingsGroups; + } + + public get content(): string { + return this.model.getValue(); + } + + private parse() { + const model = this.model; + const settings: ISetting[] = []; + let parsingSettings = false; + let parsingSettingValue = false; + + let currentProperty: string = null; + let currentParent: any = []; + let previousParents: any[] = []; + + function onValue(value: any, offset: number, length: number) { + if (Array.isArray(currentParent)) { + (currentParent).push(value); + } else if (currentProperty) { + currentParent[currentProperty] = value; + } + if (previousParents.length === 1) { + let valueStartPosition = model.getPositionAt(offset); + let valueEndPosition = model.getPositionAt(offset + length); + settings[settings.length - 1].value = value; + settings[settings.length - 1].valueRange = { + startLineNumber: valueStartPosition.lineNumber, + startColumn: valueStartPosition.column, + endLineNumber: valueEndPosition.lineNumber, + endColumn: valueEndPosition.column + }; + settings[settings.length - 1].range = assign(settings[settings.length - 1].range, { + endLineNumber: valueEndPosition.lineNumber, + endColumn: valueEndPosition.column + }); + } + } + let visitor: JSONVisitor = { + onObjectBegin: (offset: number, length: number) => { + if (!parsingSettings) { + parsingSettings = true; + } else { + parsingSettingValue = true; + } + let object = {}; + onValue(object, offset, length); + currentParent = object; + currentProperty = null; + previousParents.push(currentParent); + }, + onObjectProperty: (name: string, offset: number, length: number) => { + currentProperty = name; + if (parsingSettings && !parsingSettingValue) { + let settingStartPosition = model.getPositionAt(offset); + settings.push({ + key: name, + description: '', + range: { + startLineNumber: settingStartPosition.lineNumber, + startColumn: settingStartPosition.column, + endLineNumber: 0, + endColumn: 0 + }, + value: null, + valueRange: null + }); + } + }, + onObjectEnd: (offset: number, length: number) => { + currentParent = previousParents.pop(); + if (previousParents.length === 1) { + let valueEndPosition = model.getPositionAt(offset + length); + settings[settings.length - 1].valueRange = assign(settings[settings.length - 1].valueRange, { + endLineNumber: valueEndPosition.lineNumber, + endColumn: valueEndPosition.column + }); + settings[settings.length - 1].range = assign(settings[settings.length - 1].range, { + endLineNumber: valueEndPosition.lineNumber, + endColumn: valueEndPosition.column + }); + } + if (parsingSettingValue) { + parsingSettingValue = false; + } else if (parsingSettings) { + parsingSettings = false; + } + }, + onArrayBegin: (offset: number, length: number) => { + let array = []; + onValue(array, offset, length); + previousParents.push(currentParent); + currentParent = array; + currentProperty = null; + }, + onArrayEnd: (offset: number, length: number) => { + if (parsingSettings && !parsingSettingValue && settings.length > 0) { + let valueEndPosition = model.getPositionAt(offset + length); + settings[settings.length - 1].valueRange = assign(settings[settings.length - 1].valueRange, { + endLineNumber: valueEndPosition.lineNumber, + endColumn: valueEndPosition.column + }); + settings[settings.length - 1].range = assign(settings[settings.length - 1].range, { + endLineNumber: valueEndPosition.lineNumber, + endColumn: valueEndPosition.column + }); + } + currentParent = previousParents.pop(); + }, + onLiteralValue: onValue, + onError: (error) => { + } + }; + visit(model.getValue(), visitor); + this._settingsGroups = settings.length > 0 ? [{ + sections: [ + { + settings + } + ], + title: null, + titleRange: null, + range: { + startLineNumber: settings[0].range.startLineNumber, + startColumn: settings[0].range.startColumn, + endLineNumber: settings[settings.length - 1].range.endLineNumber, + endColumn: settings[settings.length - 1].range.endColumn, + } + }] : []; + } +} + +export class DefaultSettingsEditorModel implements ISettingsEditorModel { - private _uri: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/settings.json' }); private indent: string; private _settingsGroups: ISettingsGroup[]; private _content: string; private _contentByLines: string[]; - constructor( @IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService) { + constructor(private _uri: URI, @IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService) { const editorConfig = this.configurationService.getConfiguration(); this.indent = editorConfig.editor.insertSpaces ? strings.repeat(' ', editorConfig.editor.tabSize) : '\t'; } @@ -161,12 +320,11 @@ export class DefaultSettings implements ISettingsEditorModel { } } -export class DefaultKeybindings implements IKeybindingsEditorModel { +export class DefaultKeybindingsEditorModel implements IKeybindingsEditorModel { - private _uri: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' }); private _content: string; - constructor( @IKeybindingService private keybindingService: IKeybindingService) { + constructor(private _uri: URI, @IKeybindingService private keybindingService: IKeybindingService) { } public get uri(): URI {