提交 99864f9c 编写于 作者: S Sandeep Somavarapu

Default editor: Improve actions user affordance

- Use light bulb
上级 6126d34c
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><path fill="#1E1E1E" d="M13.5 4.2C13.1 2.1 10.8 0 9.3 0H6.7c-.4 0-.6.2-.6.2C4 .8 2.5 2.7 2.5 4.9c0 .5-.1 2.3 1.7 3.8.5.5 1.2 2 1.3 2.4v3.3L7.1 16h2l1.5-1.6V11c.1-.4.8-1.9 1.3-2.3 1.1-.9 1.5-1.9 1.6-2.7V4.2z"/><g><g fill="#C5C5C5"><path d="M6.5 12h3v1h-3zM7.5 15h1.1l.9-1h-3z"/></g><path fill="#DDB204" d="M12.6 5c0-2.3-1.8-4.1-4.1-4.1-.1 0-1.4.1-1.4.1-2.1.3-3.7 2-3.7 4 0 .1-.2 1.6 1.4 3 .7.7 1.5 2.4 1.6 2.9l.1.1h3l.1-.2c.1-.5.9-2.2 1.6-2.9 1.6-1.3 1.4-2.8 1.4-2.9zm-3 1l-.5 3h-.6V6c1.1 0 .9-1 .9-1H6.5v.1c0 .2.1.9 1 .9v3H7l-.2-.7L6.5 6c-.7 0-.9-.4-1-.7v-.4c0-.8.9-.9.9-.9h3.1s1 .1 1 1c0 0 .1 1-.9 1z"/></g><path fill="#252526" d="M10.5 5c0-.9-1-1-1-1H6.4s-.9.1-.9.9v.4c0 .3.3.7.9.7l.4 2.3.2.7h.5V6c-1 0-1-.7-1-.9V5h3s.1 1-.9 1v3h.6l.5-3c.9 0 .8-1 .8-1z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><path fill="#F6F6F6" d="M13.5 4.2C13.1 2.1 10.8 0 9.3 0H6.7c-.4 0-.6.2-.6.2C4 .8 2.5 2.7 2.5 4.9c0 .5-.1 2.3 1.7 3.8.5.5 1.2 2 1.3 2.4v3.3L7.1 16h2l1.5-1.6V11c.1-.4.8-1.9 1.3-2.3 1.1-.9 1.5-1.9 1.6-2.7V4.2z"/><g><g fill="#848484"><path d="M6.5 12h3v1h-3zM7.5 15h1.1l.9-1h-3z"/></g><path fill="#fc0" d="M12.6 5c0-2.3-1.8-4.1-4.1-4.1-.1 0-1.4.1-1.4.1-2.1.3-3.7 2-3.7 4 0 .1-.2 1.6 1.4 3 .7.7 1.5 2.4 1.6 2.9l.1.1h3l.1-.2c.1-.5.9-2.2 1.6-2.9 1.6-1.3 1.4-2.8 1.4-2.9zm-3 1l-.5 3h-.6V6c1.1 0 .9-1 .9-1H6.5v.1c0 .2.1.9 1 .9v3H7l-.2-.7L6.5 6c-.7 0-.9-.4-1-.7v-.4c0-.8.9-.9.9-.9h3.1s1 .1 1 1c0 0 .1 1-.9 1z"/></g><path fill="#F0EFF1" d="M10.5 5c0-.9-1-1-1-1H6.4s-.9.1-.9.9v.4c0 .3.3.7.9.7l.4 2.3.2.7h.5V6c-1 0-1-.7-1-.9V5h3s.1 1-.9 1v3h.6l.5-3c.9 0 .8-1 .8-1z"/></svg>
\ No newline at end of file
......@@ -3,16 +3,22 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-editor .view-line :not(.inline-folded).copySetting:after {
.monaco-editor .view-line:hover :not(.inline-folded).selectSettingValue {
text-decoration: underline;
cursor: pointer;
content:"⍈";
margin-left: 1em;
display:inline-block;
position: absolute;
height:16px;
width:16px;
}
.monaco-editor .view-line :not(.inline-folded).copySetting.select:after {
content:"...";
}
\ No newline at end of file
.monaco-editor .copy-preferences-light-bulb {
height: 16px;
width: 16px;
cursor: pointer;
}
.monaco-editor.vs .copy-preferences-light-bulb {
background: url('lightbulb.svg') center center no-repeat;
}
.monaco-editor.vs-dark .copy-preferences-light-bulb,
.monaco-editor.hc-black .copy-preferences-light-bulb {
background: url('lightbulb-dark.svg') center center no-repeat;
}
......@@ -5,6 +5,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
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';
......@@ -15,17 +16,20 @@ 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';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
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 } from 'vs/workbench/parts/preferences/common/preferences';
import { IPreferencesService, ISettingsGroup, ISetting, ISettingsEditorModel, IKeybindingsEditorModel, IPreferencesEditorModel } from 'vs/workbench/parts/preferences/common/preferences';
import { DefaultSettings } 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';
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
import { CopyPreferenceWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
export class DefaultPreferencesInput extends ResourceEditorInput {
......@@ -135,10 +139,15 @@ export class DefaultPreferencesEditor extends StringEditor {
}
}
export interface IPreferencesRenderer {
render();
dispose();
}
@editorContribution
export class DefaultSettingsContribution extends Disposable implements editorCommon.IEditorContribution {
export class PreferencesEditorContribution extends Disposable implements editorCommon.IEditorContribution {
private settingsActions: SettingsActionsDecorators = null;
private preferencesRenderer: IPreferencesRenderer;
constructor(private editor: ICodeEditor,
@IInstantiationService private instantiationService: IInstantiationService,
......@@ -148,48 +157,179 @@ export class DefaultSettingsContribution extends Disposable implements editorCom
this._register(editor.onDidChangeModel(() => this.onModelChanged()));
}
public getId(): string {
return 'editor.contrib.settings';
}
private onModelChanged(): void {
const model = this.editor.getModel();
this.disposePreferencesRenderer();
if (model) {
this.preferencesService.resolvePreferencesEditorModel(model.uri)
.then(editorModel => {
if (editorModel) {
this.preferencesRenderer = this.createPreferencesRenderer(editorModel);
this.preferencesRenderer.render();
}
});
}
}
if (!this.canHandle(model)) {
if (this.settingsActions) {
this.settingsActions.dispose();
this.settingsActions = null;
}
getId(): string {
return 'editor.contrib.preferences';
}
private createPreferencesRenderer(editorModel: IPreferencesEditorModel): IPreferencesRenderer {
if (editorModel instanceof DefaultSettings) {
return this.instantiationService.createInstance(DefaultSettingsRenderer, this.editor, editorModel);
}
return null;
}
private disposePreferencesRenderer() {
if (this.preferencesRenderer) {
this.preferencesRenderer.dispose();
this.preferencesRenderer = null;
}
}
public dispose() {
this.disposePreferencesRenderer();
super.dispose();
}
}
export class DefaultSettingsRenderer extends Disposable implements IPreferencesRenderer {
private settingsActionsRenderer: SettingsActionsRenderer;
private copyPreferenceLightBulbRenderer: CopySettingsLightBulbRenderer;
constructor(protected editor: ICodeEditor, protected settingsEditorModel: DefaultSettings,
@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));
}
public render() {
this.settingsActionsRenderer.render(this.settingsEditorModel.settingsGroups);
}
}
export class CopySettingsLightBulbRenderer extends Disposable {
private copyPreferenceWidgetForCusorPosition: CopyPreferenceWidget<ISetting>;
private copyPreferenceWidgetForMouseMove: CopyPreferenceWidget<ISetting>;
constructor(private editor: ICodeEditor, private settingsGroups: ISettingsGroup[],
@IPreferencesService private preferencesService: IPreferencesService,
@IInstantiationService private instantiationService: IInstantiationService,
@IContextMenuService private contextMenuService: IContextMenuService
) {
super();
this.copyPreferenceWidgetForCusorPosition = this._register(this.instantiationService.createInstance(CopyPreferenceWidget, editor));
this.copyPreferenceWidgetForMouseMove = this._register(this.instantiationService.createInstance(CopyPreferenceWidget, editor));
this._register(this.copyPreferenceWidgetForCusorPosition.onClick(setting => this.copy(setting, this.copyPreferenceWidgetForCusorPosition)));
this._register(this.copyPreferenceWidgetForMouseMove.onClick(setting => this.copy(setting, this.copyPreferenceWidgetForMouseMove)));
this._register(this.editor.onDidChangeCursorPosition((positionChangeEvent => this.onPositionChanged(positionChangeEvent))));
this._register(this.editor.onMouseMove((mouseMoveEvent => this.onMouseMoved(mouseMoveEvent))));
}
private copy(setting: ISetting, copyPreferenceWidget: CopyPreferenceWidget<ISetting>) {
let jsonSchema: IJSONSchema = Registry.as<IConfigurationRegistry>(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 [<IAction>{
id: 'truthyValue',
label: 'true',
enabled: true,
run: () => this.preferencesService.copyConfiguration({ key: setting.key, value: true })
}, <IAction>{
id: 'falsyValue',
label: 'false',
enabled: true,
run: () => this.preferencesService.copyConfiguration({ key: setting.key, value: false })
}];
}
if (jsonSchema.enum) {
return jsonSchema.enum.map(value => {
return <IAction>{
id: value,
label: value,
enabled: true,
run: () => this.preferencesService.copyConfiguration({ key: setting.key, value })
};
});
}
return null;
}
if (model.uri.fsPath === this.preferencesService.defaultSettings.uri.fsPath) {
this.styleDefaultSettings(model);
private onPositionChanged(positionChangeEvent: editorCommon.ICursorPositionChangedEvent) {
this.copyPreferenceWidgetForMouseMove.hide();
const setting = this.getSetting(positionChangeEvent.position.lineNumber);
if (setting) {
this.showCopyPreferencesWidget(this.copyPreferenceWidgetForCusorPosition, setting);
} else {
this.copyPreferenceWidgetForCusorPosition.hide();
}
}
private canHandle(model: editorCommon.IModel) {
if (model) {
if (model.uri.fsPath === this.preferencesService.defaultSettings.uri.fsPath) {
return true;
}
private onMouseMoved(mouseMoveEvent: IEditorMouseEvent) {
if (mouseMoveEvent.event.target === this.copyPreferenceWidgetForMouseMove.getDomNode() ||
mouseMoveEvent.event.target === this.copyPreferenceWidgetForCusorPosition.getDomNode()) {
return;
}
const setting = mouseMoveEvent.target.position ? this.getSetting(mouseMoveEvent.target.position.lineNumber) : null;
if (setting && mouseMoveEvent.target.position.lineNumber !== this.copyPreferenceWidgetForCusorPosition.getLine()) {
this.showCopyPreferencesWidget(this.copyPreferenceWidgetForMouseMove, setting);
} else {
this.copyPreferenceWidgetForMouseMove.hide();
}
return false;
}
private styleDefaultSettings(model: editorCommon.IModel) {
this.renderDecorations(model);
private showCopyPreferencesWidget(copyPreferencesWidget: CopyPreferenceWidget<ISetting>, setting: ISetting) {
copyPreferencesWidget.show(setting.valueRange.startLineNumber, setting);
let jsonSchema: IJSONSchema = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties()[setting.key];
if (jsonSchema.type === 'boolean' || jsonSchema.enum) {
copyPreferencesWidget.getDomNode().title = nls.localize('selectAndCopyTitle', "Select a value and copy in Settings");
} else {
copyPreferencesWidget.getDomNode().title = nls.localize('copyTitle', "Copy in Settings");
}
}
private renderDecorations(model: editorCommon.IModel) {
this.settingsActions = this.instantiationService.createInstance(SettingsActionsDecorators, this.editor);
this.settingsActions.render(this.preferencesService.defaultSettings.settingsGroups);
private getSetting(lineNumber: number): ISetting {
for (const group of this.settingsGroups) {
if (Range.containsPosition(group.range, { lineNumber, column: 1 })) {
for (const section of group.sections) {
for (const setting of section.settings) {
if (lineNumber === setting.valueRange.startLineNumber) {
return setting;
}
}
}
}
}
return null;
}
}
export class SettingsActionsDecorators extends Disposable {
export class SettingsActionsRenderer 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");
constructor(private editor: ICodeEditor,
@IPreferencesService private settingsService: IPreferencesService,
......@@ -214,27 +354,29 @@ export class SettingsActionsDecorators extends Disposable {
for (const settingsGroup of settingsGroups) {
for (const settingsSection of settingsGroup.sections) {
for (const setting of settingsSection.settings) {
result.push(this.createDecoration(setting, model));
const decoration = this.createSelectSettingDecoration(setting, model);
if (decoration) {
result.push(decoration);
}
}
}
}
return result;
}
private createDecoration(setting: ISetting, model: editorCommon.IModel): editorCommon.IModelDeltaDecoration {
private createSelectSettingDecoration(setting: ISetting, model: editorCommon.IModel): editorCommon.IModelDeltaDecoration {
const jsonSchema: IJSONSchema = this.getConfigurationsMap()[setting.key];
const maxColumn = model.getLineMaxColumn(setting.valueRange.startLineNumber);
const range = {
startLineNumber: setting.valueRange.startLineNumber,
startColumn: maxColumn,
endLineNumber: setting.valueRange.startLineNumber,
endColumn: maxColumn
};
return {
range, options: {
afterContentClassName: `copySetting${(jsonSchema.enum || jsonSchema.type === 'boolean') ? '.select' : ''}`,
}
};
if (jsonSchema.enum || jsonSchema.type === 'boolean') {
return {
range: setting.valueRange,
options: {
inlineClassName: 'selectSettingValue',
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
hoverMessage: SettingsActionsRenderer.HOVER_MESSAGE
}
};
}
return null;
}
private onEditorMouseUp(e: IEditorMouseEvent): void {
......@@ -247,8 +389,8 @@ export class SettingsActionsDecorators extends Disposable {
}
switch (e.target.type) {
case editorCommon.MouseTargetType.CONTENT_EMPTY:
if (hasClass(<HTMLElement>e.target.element, 'copySetting')) {
case editorCommon.MouseTargetType.CONTENT_TEXT:
if ((e.event.ctrlKey || e.event.metaKey) && hasClass(<HTMLElement>e.target.element, 'selectSettingValue')) {
this.onClick(e);
}
return;
......@@ -270,7 +412,7 @@ export class SettingsActionsDecorators extends Disposable {
const actions = this.getActions(key, jsonSchema);
if (actions) {
let elementPosition = getDomNodePagePosition(<HTMLElement>e.target.element);
const anchor = { x: elementPosition.left + elementPosition.width, y: elementPosition.top + elementPosition.height + 10 };
const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 };
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => TPromise.wrap(actions)
......
......@@ -93,10 +93,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}
resolvePreferencesEditorModel(uri: URI): TPromise<IPreferencesEditorModel> {
if (this._defaultSettings.uri.fsPath === uri.fsPath) {
if (this.defaultSettings.uri.fsPath === uri.fsPath) {
return TPromise.wrap(this._defaultSettings);
}
if (this._defaultKeybindings.uri.fsPath === uri.fsPath) {
if (this.defaultKeybindings.uri.fsPath === uri.fsPath) {
return TPromise.wrap(this._defaultKeybindings);
}
return TPromise.wrap(null);
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Widget } from 'vs/base/browser/ui/widget';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser';
import Event, { Emitter } from 'vs/base/common/event';
export class CopyPreferenceWidget<T> extends Widget implements IOverlayWidget {
private static counter: number = 1;
private _domNode: HTMLElement;
private _visible: boolean;
private _line: number;
private _id: string;
private _preference: T;
private _onClick: Emitter<T> = new Emitter<T>();
public get onClick(): Event<T> { return this._onClick.event; }
constructor(private editor: ICodeEditor) {
super();
this._id = 'preferences.copyPreferenceWidget' + CopyPreferenceWidget.counter++;
this.editor.addOverlayWidget(this);
this._register(this.editor.onDidScrollChange(() => {
if (this._visible) {
this._layout();
}
}));
}
public dispose(): void {
this.editor.removeOverlayWidget(this);
super.dispose();
}
getId(): string {
return this._id;
}
getDomNode(): HTMLElement {
if (!this._domNode) {
this._domNode = document.createElement('div');
this._domNode.style.width = '20px';
this._domNode.style.height = '20px';
this._domNode.className = 'copy-preferences-light-bulb hidden';
this.onclick(this._domNode, e => this._onClick.fire(this._preference));
}
return this._domNode;
}
getPosition(): IOverlayWidgetPosition {
return null;
}
getLine(): number {
return this._line;
}
show(line: number, preference: T): void {
this._preference = preference;
if (!this._visible || this._line !== line) {
this._line = line;
this._visible = true;
this._layout();
}
}
private _layout(): void {
const topForLineNumber = this.editor.getTopForLineNumber(this._line);
const editorScrollTop = this.editor.getScrollTop();
const maxColumn = this.editor.getModel().getLineMaxColumn(this._line);
const columnOffset = this.editor.getOffsetForColumn(this._line, maxColumn);
const contentLeft = this.editor.getLayoutInfo().contentLeft;
const editorScrollLeft = this.editor.getScrollLeft();
this._domNode.style.top = `${topForLineNumber - editorScrollTop - 2}px`;
this._domNode.style.left = `${contentLeft + columnOffset - editorScrollLeft}px`;
this._domNode.classList.remove('hidden');
}
hide(): void {
if (this._visible) {
this._visible = false;
this._domNode.classList.add('hidden');
}
}
}
......@@ -10,14 +10,15 @@ import URI from 'vs/base/common/uri';
import { IConfigurationValue } from 'vs/workbench/services/configuration/common/configurationEditing';
export interface ISettingsGroup {
titleRange: IRange;
range: IRange;
title: string;
titleRange: IRange;
sections: ISettingsSection[];
}
export interface ISettingsSection {
titleRange?: IRange;
title?: string;
descriptionRange?: IRange;
description?: string;
settings: ISetting[];
}
......
......@@ -20,6 +20,7 @@ export class DefaultSettings implements ISettingsEditorModel {
private _settingsGroups: ISettingsGroup[];
private _content: string;
private _contentByLines: string[];
constructor( @IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService) {
const editorConfig = this.configurationService.getConfiguration<any>();
......@@ -32,34 +33,39 @@ export class DefaultSettings implements ISettingsEditorModel {
public get content(): string {
if (!this._content) {
this._content = this.toContent(this.settingsGroups);
this.parse();
}
return this._content;
}
public get settingsGroups(): ISettingsGroup[] {
if (!this._settingsGroups) {
const configurations = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurations();
this._settingsGroups = configurations.sort(this.compareConfigurationNodes).reduce((result, config) => this.parseConfig(config, result), []);
this.parse();
}
return this._settingsGroups;
}
private parse() {
const configurations = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurations();
this._settingsGroups = configurations.sort(this.compareConfigurationNodes).reduce((result, config) => this.parseConfig(config, result), []);
this._content = this.toContent(this.settingsGroups);
}
private parseConfig(config: IConfigurationNode, result: ISettingsGroup[], settingsGroup?: ISettingsGroup): ISettingsGroup[] {
if (config.title) {
if (!settingsGroup) {
settingsGroup = result.filter(g => g.title === config.title)[0];
if (!settingsGroup) {
settingsGroup = { sections: [{ settings: [] }], title: config.title, titleRange: null };
settingsGroup = { sections: [{ settings: [] }], title: config.title, titleRange: null, range: null };
result.push(settingsGroup);
}
} else {
settingsGroup.sections[settingsGroup.sections.length - 1].title = config.title;
settingsGroup.sections[settingsGroup.sections.length - 1].description = config.title;
}
}
if (config.properties) {
if (!settingsGroup) {
settingsGroup = { sections: [{ settings: [] }], title: config.id, titleRange: null };
settingsGroup = { sections: [{ settings: [] }], title: config.id, titleRange: null, range: null };
result.push(settingsGroup);
}
const configurationSettings: ISetting[] = Object.keys(config.properties).map((key) => {
......@@ -93,51 +99,58 @@ export class DefaultSettings implements ISettingsEditorModel {
private toContent(settingsGroups: ISettingsGroup[]): string {
let lastSetting: ISetting = null;
const result: string[] = [];
this._contentByLines = [];
result.push('// ' + nls.localize('defaultSettingsHeader', "Overwrite settings by placing them into your settings file."));
result.push('// ' + nls.localize('defaultSettingsHeader2', "See http://go.microsoft.com/fwlink/?LinkId=808995 for the most commonly used settings."));
result.push('{');
this._contentByLines.push('// ' + nls.localize('defaultSettingsHeader', "Overwrite settings by placing them into your settings file."));
this._contentByLines.push('// ' + nls.localize('defaultSettingsHeader2', "See http://go.microsoft.com/fwlink/?LinkId=808995 for the most commonly used settings."));
this._contentByLines.push('{');
for (const group of settingsGroups) {
this.addTitleOrDescription(group.title, '', result);
let groupTitleStart = result.length + 1;
group.titleRange = { startLineNumber: groupTitleStart, startColumn: 1, endLineNumber: result.length, endColumn: result[result.length - 1].length };
let groupTitleStart = this._contentByLines.length + 1;
this.addTitleOrDescription(group.title, '', this._contentByLines);
group.titleRange = { startLineNumber: groupTitleStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
for (const section of group.sections) {
if (section.title) {
let sectionTitleStart = result.length + 1;
this.addTitleOrDescription(section.title, this.indent, result);
section.titleRange = { startLineNumber: sectionTitleStart, startColumn: 1, endLineNumber: result.length, endColumn: result[result.length - 1].length };
if (section.description) {
let sectionTitleStart = this._contentByLines.length + 1;
this.addTitleOrDescription(section.description, this.indent, this._contentByLines);
section.descriptionRange = { startLineNumber: sectionTitleStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
}
for (const setting of section.settings) {
const settingStart = result.length + 1;
this.addTitleOrDescription(setting.description, this.indent, result);
const valueStart = result.length + 1;
const settingStart = this._contentByLines.length + 1;
this.addTitleOrDescription(setting.description, this.indent, this._contentByLines);
const valueStart = this._contentByLines.length + 1;
let valueString = JSON.stringify(setting.value, null, this.indent);
const preValueContent = this.indent + JSON.stringify(setting.key) + ': ';
if (valueString && (typeof setting.value === 'object')) {
const mulitLineValue = valueString.split('\n');
result.push(this.indent + JSON.stringify(setting.key) + ': ' + mulitLineValue[0]);
this._contentByLines.push(preValueContent + mulitLineValue[0]);
for (let i = 1; i < mulitLineValue.length; i++) {
result.push(this.indent + mulitLineValue[i]);
this._contentByLines.push(this.indent + mulitLineValue[i]);
}
} else {
result.push(this.indent + JSON.stringify(setting.key) + ': ' + valueString);
this._contentByLines.push(preValueContent + valueString);
}
result[result.length - 1] += ',';
setting.valueRange = { startLineNumber: valueStart, startColumn: preValueContent.length + 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length + 1 };
this._contentByLines[this._contentByLines.length - 1] += ',';
lastSetting = setting;
result.push('');
setting.valueRange = { startLineNumber: valueStart, startColumn: 1, endLineNumber: result.length, endColumn: result[result.length - 1].length };
setting.range = { startLineNumber: settingStart, startColumn: 1, endLineNumber: result.length, endColumn: result[result.length - 1].length };
this._contentByLines.push('');
setting.range = { startLineNumber: settingStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
}
}
group.range = { startLineNumber: groupTitleStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
}
if (lastSetting) {
const content = result[lastSetting.range.endLineNumber - 2];
result[lastSetting.range.endLineNumber - 2] = content.substring(0, content.length - 1);
const content = this._contentByLines[lastSetting.range.endLineNumber - 2];
this._contentByLines[lastSetting.range.endLineNumber - 2] = content.substring(0, content.length - 1);
}
result.push('}');
return result.join('\n');
this._contentByLines.push('}');
return this._contentByLines.join('\n');
}
private addTitleOrDescription(description: string, indent: string, result: string[]) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册