提交 092f92d8 编写于 作者: S Sandeep Somavarapu

Merge branch

......@@ -272,10 +272,11 @@ export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[]
}
// Matches beginning of words supporting non-ASCII languages
// E.g. "gp" or "g p" will match "Git: Pull"
// If `contiguous` is true then matches word with beginnings of the words in the target. E.g. "pul" will match "Git: Pull"
// Otherwise also matches sub string of the word with beginnings of the words in the target. E.g. "gp" or "g p" will match "Git: Pull"
// Useful in cases where the target is words (e.g. command labels)
export function matchesWords(word: string, target: string): IMatch[] {
export function matchesWords(word: string, target: string, contiguous: boolean = false): IMatch[] {
if (!target || target.length === 0) {
return null;
}
......@@ -283,14 +284,14 @@ export function matchesWords(word: string, target: string): IMatch[] {
let result: IMatch[] = null;
let i = 0;
while (i < target.length && (result = _matchesWords(word.toLowerCase(), target, 0, i)) === null) {
while (i < target.length && (result = _matchesWords(word.toLowerCase(), target, 0, i, contiguous)) === null) {
i = nextWord(target, i + 1);
}
return result;
}
function _matchesWords(word: string, target: string, i: number, j: number): IMatch[] {
function _matchesWords(word: string, target: string, i: number, j: number, contiguous: boolean): IMatch[] {
if (i === word.length) {
return [];
} else if (j === target.length) {
......@@ -300,10 +301,12 @@ function _matchesWords(word: string, target: string, i: number, j: number): IMat
} else {
let result: IMatch[] = null;
let nextWordIndex = j + 1;
result = _matchesWords(word, target, i + 1, j + 1);
while (!result && (nextWordIndex = nextWord(target, nextWordIndex)) < target.length) {
result = _matchesWords(word, target, i + 1, nextWordIndex);
nextWordIndex++;
result = _matchesWords(word, target, i + 1, j + 1, contiguous);
if (!contiguous) {
while (!result && (nextWordIndex = nextWord(target, nextWordIndex)) < target.length) {
result = _matchesWords(word, target, i + 1, nextWordIndex, contiguous);
nextWordIndex++;
}
}
return result === null ? null : join({ start: j, end: j + 1 }, result);
}
......
......@@ -62,7 +62,8 @@ export class RangeHighlightDecorations implements IDisposable {
this.editor = editor;
this.editorDisposables.push(this.editor.onDidChangeCursorPosition((e: editorCommon.ICursorPositionChangedEvent) => {
if (
e.reason === editorCommon.CursorChangeReason.Explicit
e.reason === editorCommon.CursorChangeReason.NotSet
|| e.reason === editorCommon.CursorChangeReason.Explicit
|| e.reason === editorCommon.CursorChangeReason.Undo
|| e.reason === editorCommon.CursorChangeReason.Redo
) {
......
......@@ -147,19 +147,16 @@
background: url(collapsed-dark.svg) 50% 50% no-repeat;
}
.monaco-editor .view-line:hover .copySetting:after {
cursor: pointer;
content:" ";
.monaco-editor .edit-preferences-widget {
background: url('edit.svg') center center no-repeat;
margin-left: 1em;
display:inline-block;
position: absolute;
height:100%;
transform: rotate(-90deg);
width:16px;
height: 16px;
cursor: pointer;
}
.monaco-editor.hc-black .view-line:hover .copySetting:after,
.monaco-editor.vs-dark .view-line:hover .copySetting:after {
.monaco-editor.hc-black .edit-preferences-widget,
.monaco-editor.vs-dark .edit-preferences-widget {
background: url('edit_inverse.svg') center center no-repeat;
}
......
......@@ -10,8 +10,7 @@ import URI from 'vs/base/common/uri';
import { LinkedMap as Map } from 'vs/base/common/map';
import * as labels from 'vs/base/common/labels';
import { Disposable } from 'vs/base/common/lifecycle';
import { parseTree, findNodeAtLocation } from 'vs/base/common/json';
import { toResource, SideBySideEditorInput, EditorInput } from 'vs/workbench/common/editor';
import { SideBySideEditorInput, EditorInput } from 'vs/workbench/common/editor';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceConfigurationService, WORKSPACE_CONFIG_DEFAULT_PATH } from 'vs/workbench/services/configuration/common/configuration';
......@@ -23,9 +22,7 @@ import { IMessageService, Severity, IChoiceService } from 'vs/platform/message/c
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
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 { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IPreferencesService, IPreferencesEditorModel } from 'vs/workbench/parts/preferences/common/preferences';
import { SettingsEditorModel, DefaultSettingsEditorModel, DefaultKeybindingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
......@@ -44,9 +41,6 @@ interface IWorkbenchSettingsConfiguration {
export class PreferencesService extends Disposable implements IPreferencesService {
static DEFAULT_SETTINGS_URI: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/settings.json' });
static DEFAULT_KEY_BINDINGS_URI: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' });
_serviceBrand: any;
// TODO:@sandy merge these models into editor inputs by extending resource editor model
......@@ -74,13 +68,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic
this.defaultPreferencesEditorModels = new Map<URI, IPreferencesEditorModel>();
}
readonly defaultSettingsResource = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/settings.json' });
readonly defaultKeybindingsResource = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' });
createDefaultPreferencesEditorModel(uri: URI): TPromise<IPreferencesEditorModel> {
const editorModel = this.defaultPreferencesEditorModels.get(uri);
if (editorModel) {
return TPromise.as(editorModel);
}
if (PreferencesService.DEFAULT_SETTINGS_URI.fsPath === uri.fsPath) {
if (this.defaultSettingsResource.fsPath === uri.fsPath) {
return TPromise.join<any>([this.extensionService.onReady(), this.fetchMostCommonlyUsedSettings()])
.then(result => {
const mostCommonSettings = result[1];
......@@ -90,7 +87,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
});
}
if (PreferencesService.DEFAULT_KEY_BINDINGS_URI.fsPath === uri.fsPath) {
if (this.defaultKeybindingsResource.fsPath === uri.fsPath) {
const model = this.instantiationService.createInstance(DefaultKeybindingsEditorModel, uri);
this.defaultPreferencesEditorModels.set(uri, model);
return TPromise.wrap(model);
......@@ -135,7 +132,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
openGlobalKeybindingSettings(): TPromise<void> {
const emptyContents = '// ' + nls.localize('emptyKeybindingsHeader', "Place your key bindings in this file to overwrite the defaults") + '\n[\n]';
return this.openTwoEditors(PreferencesService.DEFAULT_KEY_BINDINGS_URI, URI.file(this.environmentService.appKeybindingsPath), emptyContents).then(() => null);
return this.openTwoEditors(this.defaultKeybindingsResource, URI.file(this.environmentService.appKeybindingsPath), emptyContents).then(() => null);
}
private openEditableSettings(configurationTarget: ConfigurationTarget): TPromise<IEditor> {
......@@ -147,19 +144,6 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}));
}
public copyConfiguration(configurationValue: IConfigurationValue): void {
const configurationTarget = this.getConfigurationTargetForCurrentActiveEditor();
if (configurationTarget !== null) {
this.telemetryService.publicLog('defaultSettingsActions.copySetting', { userConfigurationKeys: [configurationValue.key] });
const editorControl = <ICodeEditor>this.editorService.getActiveEditor().getControl();
this.configurationEditingService.writeConfiguration(configurationTarget, configurationValue, { writeToBuffer: true, autoSave: true })
.then(() => {
editorControl.focus();
editorControl.setSelection(this.getSelectionRange(configurationValue.key, editorControl.getModel()));
}, error => this.messageService.show(Severity.Error, error));
}
}
private resolveSettingsEditorModel(configurationTarget: ConfigurationTarget): TPromise<SettingsEditorModel> {
const settingsUri = this.getEditableSettingsURI(configurationTarget);
if (settingsUri) {
......@@ -225,12 +209,12 @@ export class PreferencesService extends Disposable implements IPreferencesServic
switch (configurationTarget) {
case ConfigurationTarget.USER:
if (!this.defaultSettingsEditorInputForUser) {
this.defaultSettingsEditorInputForUser = this._register(this.instantiationService.createInstance(DefaultPreferencesEditorInput, PreferencesService.DEFAULT_SETTINGS_URI));
this.defaultSettingsEditorInputForUser = this._register(this.instantiationService.createInstance(DefaultPreferencesEditorInput, this.defaultSettingsResource));
}
return this.defaultSettingsEditorInputForUser;
case ConfigurationTarget.WORKSPACE:
if (!this.defaultSettingsEditorInputForWorkspace) {
this.defaultSettingsEditorInputForWorkspace = this._register(this.instantiationService.createInstance(DefaultPreferencesEditorInput, PreferencesService.DEFAULT_SETTINGS_URI));
this.defaultSettingsEditorInputForWorkspace = this._register(this.instantiationService.createInstance(DefaultPreferencesEditorInput, this.defaultSettingsResource));
}
return this.defaultSettingsEditorInputForWorkspace;
}
......@@ -271,40 +255,6 @@ export class PreferencesService extends Disposable implements IPreferencesServic
});
}
private getConfigurationTargetForCurrentActiveEditor(): ConfigurationTarget {
const activeEditor = this.editorService.getActiveEditor();
if (activeEditor) {
const file = toResource(activeEditor.input, { supportSideBySide: true, filter: 'file' });
if (file) {
return this.getConfigurationTarget(file);
}
}
return null;
}
private getConfigurationTarget(resource: URI): ConfigurationTarget {
if (this.getEditableSettingsURI(ConfigurationTarget.USER).fsPath === resource.fsPath) {
return ConfigurationTarget.USER;
}
const workspaceSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE);
if (workspaceSettingsUri && workspaceSettingsUri.fsPath === resource.fsPath) {
return ConfigurationTarget.WORKSPACE;
}
return null;
}
private getSelectionRange(setting: string, model: editorCommon.IModel): editorCommon.IRange {
const tree = parseTree(model.getValue());
const node = findNodeAtLocation(tree, [setting]);
const position = model.getPositionAt(node.offset);
return {
startLineNumber: position.lineNumber,
startColumn: position.column,
endLineNumber: position.lineNumber,
endColumn: position.column + node.length
};
}
private fetchMostCommonlyUsedSettings(): TPromise<string[]> {
return TPromise.wrap([
'editor.fontSize',
......
......@@ -344,4 +344,92 @@ export class SettingsCountWidget extends Widget implements IOverlayWidget {
preference: null
};
}
}
export class EditPreferenceWidget<T> extends Widget implements IOverlayWidget {
private static counter: number = 1;
private _domNode: HTMLElement;
private _visible: boolean;
private _line: number;
private _id: string;
private _preferences: T[];
private _onClick: Emitter<void> = new Emitter<void>();
public get onClick(): Event<void> { return this._onClick.event; }
private _onMouseOver: Emitter<void> = new Emitter<void>();
public get onMouseOver(): Event<void> { return this._onMouseOver.event; }
constructor(private editor: ICodeEditor,
@IContextMenuService contextMenuService: IContextMenuService
) {
super();
this._id = 'preferences.editPreferenceWidget' + EditPreferenceWidget.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 = 'edit-preferences-widget hidden';
this.onclick(this._domNode, e => this._onClick.fire());
this.onmouseover(this._domNode, e => this._onMouseOver.fire());
}
return this._domNode;
}
getPosition(): IOverlayWidgetPosition {
return null;
}
getLine(): number {
return this._line;
}
show(line: number, preferences: T[]): void {
this._preferences = preferences;
if (!this._visible || this._line !== line) {
this._line = line;
this._visible = true;
this._layout();
}
}
get preferences(): T[] {
return this._preferences;
}
hide(): void {
if (this._visible) {
this._visible = false;
this._domNode.classList.add('hidden');
}
}
private _layout(): void {
const topForLineNumber = this.editor.getTopForLineNumber(this._line);
const editorScrollTop = this.editor.getScrollTop();
this._domNode.style.top = `${topForLineNumber - editorScrollTop - 2}px`;
this._domNode.style.left = '0px';
this._domNode.classList.remove('hidden');
}
}
\ No newline at end of file
......@@ -8,7 +8,6 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { LinkedMap as Map } from 'vs/base/common/map';
import { IRange } from 'vs/editor/common/editorCommon';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationValue } from 'vs/workbench/services/configuration/common/configurationEditing';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
export interface ISettingsGroup {
......@@ -20,8 +19,8 @@ export interface ISettingsGroup {
}
export interface ISettingsSection {
descriptionRange?: IRange;
description?: string;
titleRange?: IRange;
title?: string;
settings: ISetting[];
}
......@@ -31,8 +30,8 @@ export interface ISetting {
keyRange: IRange;
value: any;
valueRange: IRange;
description: string;
descriptionRange: IRange;
description: string[];
descriptionRanges: IRange[];
}
export interface IFilterResult {
......@@ -49,6 +48,7 @@ export interface IPreferencesEditorModel {
export interface ISettingsEditorModel extends IPreferencesEditorModel {
settingsGroups: ISettingsGroup[];
groupsTerms: string[];
getSetting(key: string): ISetting;
filterSettings(filter: string): IFilterResult;
}
......@@ -60,14 +60,15 @@ export const IPreferencesService = createDecorator<IPreferencesService>('prefere
export interface IPreferencesService {
_serviceBrand: any;
defaultSettingsResource: URI;
defaultKeybindingsResource: URI;
createDefaultPreferencesEditorModel(uri: URI): TPromise<IPreferencesEditorModel>;
resolvePreferencesEditorModel(uri: URI): TPromise<IPreferencesEditorModel>;
openGlobalSettings(): TPromise<void>;
openWorkspaceSettings(): TPromise<void>;
openGlobalKeybindingSettings(): TPromise<void>;
copyConfiguration(configurationValue: IConfigurationValue): void;
}
export const CONTEXT_DEFAULT_SETTINGS_EDITOR = new RawContextKey<boolean>('defaultSettingsEditor', false);
......
......@@ -12,16 +12,15 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { Registry } from 'vs/platform/platform';
import { visit, JSONVisitor } from 'vs/base/common/json';
import { IModel, IRange } from 'vs/editor/common/editorCommon';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { IConfigurationNode, IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { ISettingsEditorModel, IKeybindingsEditorModel, ISettingsGroup, ISetting, IFilterResult, ISettingsSection } from 'vs/workbench/parts/preferences/common/preferences';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IFilter, IMatch, or, matchesContiguousSubString, matchesPrefix, matchesFuzzy, matchesWords } from 'vs/base/common/filters';
import { IMatch, or, matchesContiguousSubString, matchesPrefix, matchesCamelCase, matchesWords } from 'vs/base/common/filters';
export abstract class AbstractSettingsModel extends Disposable {
static _fuzzyFilter: IFilter = or(matchesPrefix, matchesContiguousSubString, matchesWords, matchesFuzzy);
public get groupsTerms(): string[] {
return this.settingsGroups.map(group => '@' + group.id);
}
......@@ -53,7 +52,7 @@ export abstract class AbstractSettingsModel extends Disposable {
for (const section of group.sections) {
const settings: ISetting[] = [];
for (const setting of section.settings) {
const settingMatches = this._findMatchesInSetting(filter, regex, setting);
const settingMatches = this._findMatchesInSetting(filter, setting);
if (groupMatched || settingMatches.length > 0) {
settings.push(setting);
}
......@@ -61,9 +60,9 @@ export abstract class AbstractSettingsModel extends Disposable {
}
if (settings.length) {
sections.push({
description: section.description,
title: section.title,
settings,
descriptionRange: section.descriptionRange
titleRange: section.titleRange
});
}
}
......@@ -88,7 +87,113 @@ export abstract class AbstractSettingsModel extends Disposable {
return null;
}
protected abstract _findMatchesInSetting(searchString: string, searchRegex: RegExp, setting: ISetting): IRange[];
public getSetting(key: string): ISetting {
for (const group of this.settingsGroups) {
for (const section of group.sections) {
for (const setting of section.settings) {
if (key === setting.key) {
return setting;
}
}
}
}
return null;
}
private _findMatchesInSetting(searchString: string, setting: ISetting): IRange[] {
const registry: { [qualifiedKey: string]: IJSONSchema } = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();
const schema: IJSONSchema = registry[setting.key];
let words = searchString.split(' ');
let descriptionMatchingWords: Map<string, IRange[]> = new Map<string, IRange[]>();
let keyMatchingWords: Map<string, IRange[]> = new Map<string, IRange[]>();
let valueMatchingWords: Map<string, IRange[]> = new Map<string, IRange[]>();
const settingKeyAsWords: string = setting.key.split('.').join(' ');
for (const word of words) {
for (let lineIndex = 0; lineIndex < setting.description.length; lineIndex++) {
const descriptionMatches = matchesWords(word, setting.description[lineIndex], true);
if (descriptionMatches) {
descriptionMatchingWords.set(word, descriptionMatches.map(match => this.toDescriptionRange(setting, match, lineIndex)));
}
}
const keyMatches = or(matchesWords, matchesCamelCase)(word, settingKeyAsWords);
if (keyMatches) {
keyMatchingWords.set(word, keyMatches.map(match => this.toKeyRange(setting, match)));
}
if (schema.type === 'string' || schema.enum) {
const valueMatches = matchesContiguousSubString(word, setting.value);
if (valueMatches) {
valueMatchingWords.set(word, valueMatches.map(match => this.toValueRange(setting, match)));
} else if (schema.enum && schema.enum.some(enumValue => !!matchesContiguousSubString(word, enumValue))) {
valueMatchingWords.set(word, []);
}
}
}
const descriptionRanges: IRange[] = [];
for (let lineIndex = 0; lineIndex < setting.description.length; lineIndex++) {
const matches = or(matchesContiguousSubString)(searchString, setting.description[lineIndex]) || [];
descriptionRanges.push(...matches.map(match => this.toDescriptionRange(setting, match, lineIndex)));
}
if (descriptionRanges.length === 0) {
descriptionRanges.push(...this.getRangesForWords(words, descriptionMatchingWords, [keyMatchingWords, valueMatchingWords]));
}
const keyMatches = or(matchesPrefix, matchesContiguousSubString)(searchString, setting.key);
const keyRanges: IRange[] = keyMatches ? keyMatches.map(match => this.toKeyRange(setting, match)) : this.getRangesForWords(words, keyMatchingWords, [descriptionMatchingWords, valueMatchingWords]);
let valueRanges: IRange[] = [];
if (typeof setting.value === 'string') {
const valueMatches = or(matchesPrefix, matchesContiguousSubString)(searchString, setting.value);
valueRanges = valueMatches ? valueMatches.map(match => this.toValueRange(setting, match)) : this.getRangesForWords(words, valueMatchingWords, [keyMatchingWords, descriptionMatchingWords]);
}
return [...descriptionRanges, ...keyRanges, ...valueRanges];
}
private getRangesForWords(words: string[], from: Map<string, IRange[]>, others: Map<string, IRange[]>[]): IRange[] {
const result: IRange[] = [];
for (const word of words) {
const ranges = from.get(word);
if (ranges) {
result.push(...ranges);
} else if (others.every(o => !o.has(word))) {
return [];
}
}
return result;
}
private toKeyRange(setting: ISetting, match: IMatch): IRange {
return {
startLineNumber: setting.keyRange.startLineNumber,
startColumn: setting.keyRange.startColumn + match.start,
endLineNumber: setting.keyRange.startLineNumber,
endColumn: setting.keyRange.startColumn + match.end
};
}
private toDescriptionRange(setting: ISetting, match: IMatch, lineIndex: number): IRange {
return {
startLineNumber: setting.descriptionRanges[lineIndex].startLineNumber + lineIndex,
startColumn: setting.descriptionRanges[lineIndex].startColumn + match.start,
endLineNumber: setting.descriptionRanges[lineIndex].startLineNumber + lineIndex,
endColumn: setting.descriptionRanges[lineIndex].startColumn + match.end
};
}
private toValueRange(setting: ISetting, match: IMatch): IRange {
return {
startLineNumber: setting.valueRange.startLineNumber,
startColumn: setting.valueRange.startColumn + match.start + 1,
endLineNumber: setting.valueRange.startLineNumber,
endColumn: setting.valueRange.startColumn + match.end + 1
};
}
public abstract settingsGroups: ISettingsGroup[];
}
......@@ -183,7 +288,7 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
// setting started
let settingStartPosition = model.getPositionAt(offset);
settings.push({
description: '',
description: [],
key: name,
keyRange: {
startLineNumber: settingStartPosition.lineNumber,
......@@ -199,7 +304,7 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
},
value: null,
valueRange: null,
descriptionRange: null,
descriptionRanges: null,
});
}
},
......@@ -248,6 +353,10 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
},
onLiteralValue: onValue,
onError: (error) => {
const setting = settings[settings.length - 1];
if (!setting.range || !setting.keyRange || !setting.valueRange) {
settings.pop();
}
}
};
visit(model.getValue(), visitor);
......@@ -262,20 +371,6 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti
range
}] : [];
}
protected _findMatchesInSetting(searchString: string, searchRegex: RegExp, setting: ISetting): IRange[] {
const result: IRange[] = [];
for (let lineNumber = setting.range.startLineNumber; lineNumber <= setting.range.endLineNumber; lineNumber++) {
result.push(...this._findMatchesInLine(searchString, lineNumber));
}
return result;
}
private _findMatchesInLine(searchString: string, lineNumber: number): IRange[] {
return this.model.findMatches(searchString, {
startLineNumber: lineNumber, startColumn: this.model.getLineMinColumn(lineNumber), endLineNumber: lineNumber, endColumn: this.model.getLineMaxColumn(lineNumber),
}, false, false, false);
}
}
export class DefaultSettingsEditorModel extends AbstractSettingsModel implements ISettingsEditorModel {
......@@ -383,7 +478,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
result.push(settingsGroup);
}
} else {
settingsGroup.sections[settingsGroup.sections.length - 1].description = config.title;
settingsGroup.sections[settingsGroup.sections.length - 1].title = config.title;
}
}
if (config.properties) {
......@@ -394,8 +489,8 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
const configurationSettings: ISetting[] = Object.keys(config.properties).map((key) => {
const prop = config.properties[key];
const value = prop.default;
const description = prop.description || '';
return { key, value, description, range: null, keyRange: null, valueRange: null, descriptionRange: null };
const description = (prop.description || '').split('\n');
return { key, value, description, range: null, keyRange: null, valueRange: null, descriptionRanges: [] };
});
settingsGroup.sections[settingsGroup.sections.length - 1].settings.push(...configurationSettings);
}
......@@ -449,16 +544,20 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
this._contentByLines.push('');
let groupStart = this._contentByLines.length + 1;
for (const section of group.sections) {
if (section.description) {
if (section.title) {
let sectionTitleStart = this._contentByLines.length + 1;
this.addDescription(section.description, this.indent, this._contentByLines);
section.descriptionRange = { startLineNumber: sectionTitleStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
this.addDescription([section.title], this.indent, this._contentByLines);
section.titleRange = { startLineNumber: sectionTitleStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
}
for (const setting of section.settings) {
const settingStart = this._contentByLines.length + 1;
this.addDescription(setting.description, this.indent, this._contentByLines);
setting.descriptionRange = { startLineNumber: settingStart, startColumn: 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length };
setting.descriptionRanges = [];
const descriptionPreValue = this.indent + '// ';
for (const line of setting.description) {
this._contentByLines.push(descriptionPreValue + line);
setting.descriptionRanges.push({ startLineNumber: this._contentByLines.length, startColumn: this._contentByLines[this._contentByLines.length - 1].indexOf(line) + 1, endLineNumber: this._contentByLines.length, endColumn: this._contentByLines[this._contentByLines.length - 1].length });
}
let preValueConent = this.indent;
const keyString = JSON.stringify(setting.key);
......@@ -489,41 +588,13 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
return lastSetting;
}
private addDescription(description: string, indent: string, result: string[]) {
const multiLines = description.split('\n');
for (const line of multiLines) {
private addDescription(description: string[], indent: string, result: string[]) {
for (const line of description) {
result.push(indent + '// ' + line);
}
}
protected _findMatchesInSetting(searchString: string, searchRegex: RegExp, setting: ISetting): IRange[] {
const result: IRange[] = [...this._findMatchesInDescription(searchString, setting)];
for (let lineNumber = setting.valueRange.startLineNumber; lineNumber <= setting.valueRange.endLineNumber; lineNumber++) {
result.push(...this._findMatchesInLine(searchRegex, lineNumber));
}
return result;
}
private _findMatchesInDescription(searchString: string, setting: ISetting): IRange[] {
const result: IRange[] = [];
for (let lineNumber = setting.descriptionRange.startLineNumber; lineNumber <= setting.descriptionRange.endLineNumber; lineNumber++) {
const content = this._contentByLines[lineNumber - 1];
const matches: IMatch[] = AbstractSettingsModel._fuzzyFilter(searchString, content);
if (matches) {
result.push(...matches.map(match => {
return <IRange>{
startLineNumber: lineNumber,
startColumn: match.start + 1,
endLineNumber: lineNumber,
endColumn: match.end + 1
};
}));
}
}
return result;
}
private _findMatchesInLine(searchRegex: RegExp, lineNumber: number): IRange[] {
/*private _findMatchesInLine(searchRegex: RegExp, lineNumber: number): IRange[] {
const result: IRange[] = [];
const text = this._contentByLines[lineNumber - 1];
var m: RegExpExecArray;
......@@ -541,7 +612,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements
}
} while (m);
return result;
}
}*/
}
export class DefaultKeybindingsEditorModel implements IKeybindingsEditorModel {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册