Skip to content

Commit 4f6b676

Browse files
committed
microsoft#89512 support edit setting
1 parent 1d8df42 commit 4f6b676

5 files changed

Lines changed: 72 additions & 59 deletions

File tree

src/vs/workbench/browser/parts/editor/editorStatus.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ export class ChangeModeAction extends Action {
11371137

11381138
// User decided to configure settings for current language
11391139
if (pick === configureModeSettings) {
1140-
this.preferencesService.configureSettingsForLanguage(withUndefinedAsNull(modeId));
1140+
this.preferencesService.openGlobalSettings(true, { editSetting: `[${withUndefinedAsNull(modeId)}]` });
11411141
return;
11421142
}
11431143

src/vs/workbench/contrib/preferences/browser/preferencesActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ export class ConfigureLanguageBasedSettingsAction extends Action {
270270
if (pick) {
271271
const modeId = this.modeService.getModeIdForLanguageName(pick.label.toLowerCase());
272272
if (typeof modeId === 'string') {
273-
return this.preferencesService.configureSettingsForLanguage(modeId);
273+
return this.preferencesService.openGlobalSettings(true, { editSetting: `[${modeId}]` });
274274
}
275275
}
276276
return undefined;

src/vs/workbench/services/configuration/common/jsonEditingService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ export class JSONEditingService implements IJSONEditingService {
4141

4242
private async doWriteConfiguration(resource: URI, values: IJSONValue[], save: boolean): Promise<void> {
4343
const reference = await this.resolveAndValidate(resource, save);
44-
await this.writeToBuffer(reference.object.textEditorModel, values);
44+
await this.writeToBuffer(reference.object.textEditorModel, values, save);
4545

4646
reference.dispose();
4747
}
4848

49-
private async writeToBuffer(model: ITextModel, values: IJSONValue[]): Promise<any> {
49+
private async writeToBuffer(model: ITextModel, values: IJSONValue[], save: boolean): Promise<any> {
5050
let hasEdits: boolean = false;
5151
for (const value of values) {
5252
const edit = this.getEdits(model, value)[0];
5353
hasEdits = this.applyEditsToBuffer(edit, model);
5454
}
55-
if (hasEdits) {
55+
if (hasEdits && save) {
5656
return this.textFileService.save(model.uri);
5757
}
5858
}

src/vs/workbench/services/preferences/browser/preferencesService.ts

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ import { parse } from 'vs/base/common/json';
88
import { Disposable } from 'vs/base/common/lifecycle';
99
import * as network from 'vs/base/common/network';
1010
import { assign } from 'vs/base/common/objects';
11-
import * as strings from 'vs/base/common/strings';
1211
import { URI } from 'vs/base/common/uri';
1312
import { getCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
14-
import { EditOperation } from 'vs/editor/common/core/editOperation';
15-
import { IPosition, Position } from 'vs/editor/common/core/position';
13+
import { IPosition } from 'vs/editor/common/core/position';
1614
import { ITextModel } from 'vs/editor/common/model';
1715
import { IModelService } from 'vs/editor/common/services/modelService';
1816
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -39,6 +37,10 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
3937
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
4038
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
4139
import { withNullAsUndefined } from 'vs/base/common/types';
40+
import { getDefaultValue, IConfigurationRegistry, Extensions, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
41+
import { Registry } from 'vs/platform/registry/common/platform';
42+
import { ICommandService } from 'vs/platform/commands/common/commands';
43+
import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands';
4244

4345
const emptyEditableSettingsContent = '{\n}';
4446

@@ -73,7 +75,8 @@ export class PreferencesService extends Disposable implements IPreferencesServic
7375
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
7476
@IModeService private readonly modeService: IModeService,
7577
@ILabelService private readonly labelService: ILabelService,
76-
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService
78+
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
79+
@ICommandService private readonly commandService: ICommandService,
7780
) {
7881
super();
7982
// The default keybindings.json updates based on keyboard layouts, so here we make sure
@@ -311,33 +314,19 @@ export class PreferencesService extends Disposable implements IPreferencesServic
311314
return this.editorService.openEditor({ resource: this.defaultKeybindingsResource, label: nls.localize('defaultKeybindings', "Default Keybindings") });
312315
}
313316

314-
configureSettingsForLanguage(language: string): void {
315-
this.openGlobalSettings(true)
316-
.then(editor => this.createPreferencesEditorModel(this.userSettingsResource)
317-
.then((settingsModel: IPreferencesEditorModel<ISetting> | null) => {
318-
const codeEditor = editor ? getCodeEditor(editor.getControl()) : null;
319-
if (codeEditor && settingsModel) {
320-
this.addLanguageOverrideEntry(language, settingsModel, codeEditor)
321-
.then(position => {
322-
if (codeEditor && position) {
323-
codeEditor.setPosition(position);
324-
codeEditor.revealLine(position.lineNumber);
325-
codeEditor.focus();
326-
}
327-
});
328-
}
329-
}));
330-
}
331-
332-
private openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise<IEditorPane | undefined> {
317+
private async openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise<IEditorPane | undefined> {
333318
const editorInput = this.getActiveSettingsEditorInput(group);
334319
if (editorInput) {
335320
const editorInputResource = editorInput.master.resource;
336321
if (editorInputResource && editorInputResource.fsPath !== resource.fsPath) {
337322
return this.doSwitchSettings(configurationTarget, resource, editorInput, group, options);
338323
}
339324
}
340-
return this.doOpenSettings(configurationTarget, resource, options, group);
325+
const editor = await this.doOpenSettings(configurationTarget, resource, options, group);
326+
if (editor && options?.editSetting) {
327+
await this.editSetting(options?.editSetting, editor, resource);
328+
}
329+
return editor;
341330
}
342331

343332
private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, folderUri?: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise<IEditorPane | undefined> {
@@ -593,39 +582,62 @@ export class PreferencesService extends Disposable implements IPreferencesServic
593582
];
594583
}
595584

596-
private addLanguageOverrideEntry(language: string, settingsModel: IPreferencesEditorModel<ISetting>, codeEditor: ICodeEditor): Promise<IPosition | null> {
597-
const languageKey = `[${language}]`;
598-
let setting = settingsModel.getPreference(languageKey);
585+
private async editSetting(settingKey: string, editor: IEditorPane, settingsResource: URI): Promise<void> {
586+
const codeEditor = editor ? getCodeEditor(editor.getControl()) : null;
587+
if (!codeEditor) {
588+
return;
589+
}
590+
const settingsModel = await this.createPreferencesEditorModel(settingsResource);
591+
if (!settingsModel) {
592+
return;
593+
}
594+
const position = await this.getPositionToEdit(settingKey, settingsModel, codeEditor);
595+
if (position) {
596+
codeEditor.setPosition(position);
597+
codeEditor.revealPositionNearTop(position);
598+
codeEditor.focus();
599+
await this.commandService.executeCommand('editor.action.triggerSuggest');
600+
}
601+
}
602+
603+
private async getPositionToEdit(settingKey: string, settingsModel: IPreferencesEditorModel<ISetting>, codeEditor: ICodeEditor): Promise<IPosition | null> {
599604
const model = codeEditor.getModel();
600-
if (model) {
601-
const configuration = this.configurationService.getValue<{ editor: { tabSize: number; insertSpaces: boolean } }>();
602-
const eol = model.getEOL();
603-
if (setting) {
604-
if (setting.overrides && setting.overrides.length) {
605-
const lastSetting = setting.overrides[setting.overrides.length - 1];
606-
return Promise.resolve({ lineNumber: lastSetting.valueRange.endLineNumber, column: model.getLineMaxColumn(lastSetting.valueRange.endLineNumber) });
605+
if (!model) {
606+
return null;
607+
}
608+
const schema = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties()[settingKey];
609+
if (!schema && !OVERRIDE_PROPERTY_PATTERN.test(settingKey)) {
610+
return null;
611+
}
612+
613+
let position = null;
614+
const type = schema ? schema.type : 'object' /* Override Identifier */;
615+
let setting = settingsModel.getPreference(settingKey);
616+
if (!setting) {
617+
const defaultValue = type === 'array' ? this.configurationService.inspect(settingKey).defaultValue : getDefaultValue(type);
618+
if (defaultValue !== undefined) {
619+
await this.jsonEditingService.write(settingsModel.uri!, [{ key: settingKey, value: defaultValue }], false);
620+
setting = settingsModel.getPreference(settingKey);
621+
}
622+
}
623+
624+
if (setting) {
625+
position = { lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.startColumn + 1 };
626+
if (type === 'object' || type === 'array') {
627+
codeEditor.setPosition(position);
628+
await CoreEditingCommands.LineBreakInsert.runEditorCommand(null, codeEditor, null);
629+
position = { lineNumber: position.lineNumber + 1, column: model.getLineMaxColumn(position.lineNumber + 1) };
630+
const firstNonWhiteSpaceColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber);
631+
if (firstNonWhiteSpaceColumn) {
632+
// Line has some text. Insert another new line.
633+
codeEditor.setPosition({ lineNumber: position.lineNumber, column: firstNonWhiteSpaceColumn });
634+
await CoreEditingCommands.LineBreakInsert.runEditorCommand(null, codeEditor, null);
635+
position = { lineNumber: position.lineNumber, column: model.getLineMaxColumn(position.lineNumber) };
607636
}
608-
return Promise.resolve({ lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.startColumn + 1 });
609637
}
610-
return this.configurationService.updateValue(languageKey, {}, ConfigurationTarget.USER)
611-
.then(() => {
612-
setting = settingsModel.getPreference(languageKey);
613-
if (setting) {
614-
let content = eol + this.spaces(2, configuration.editor) + eol + this.spaces(1, configuration.editor);
615-
let editOperation = EditOperation.insert(new Position(setting.valueRange.endLineNumber, setting.valueRange.endColumn - 1), content);
616-
model.pushEditOperations([], [editOperation], () => []);
617-
let lineNumber = setting.valueRange.endLineNumber + 1;
618-
settingsModel.dispose();
619-
return { lineNumber, column: model.getLineMaxColumn(lineNumber) };
620-
}
621-
return null;
622-
});
623638
}
624-
return Promise.resolve(null);
625-
}
626639

627-
private spaces(count: number, { tabSize, insertSpaces }: { tabSize: number; insertSpaces: boolean }): string {
628-
return insertSpaces ? strings.repeat(' ', tabSize * count) : strings.repeat('\t', count);
640+
return position;
629641
}
630642

631643
public dispose(): void {

src/vs/workbench/services/preferences/common/preferences.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export interface ISettingsEditorOptions extends IEditorOptions {
155155
target?: ConfigurationTarget;
156156
folderUri?: URI;
157157
query?: string;
158+
editSetting?: string;
158159
}
159160

160161
/**
@@ -165,6 +166,7 @@ export class SettingsEditorOptions extends EditorOptions implements ISettingsEdi
165166
target?: ConfigurationTarget;
166167
folderUri?: URI;
167168
query?: string;
169+
editSetting?: string;
168170

169171
static create(settings: ISettingsEditorOptions): SettingsEditorOptions {
170172
const options = new SettingsEditorOptions();
@@ -173,6 +175,7 @@ export class SettingsEditorOptions extends EditorOptions implements ISettingsEdi
173175
options.target = settings.target;
174176
options.folderUri = settings.folderUri;
175177
options.query = settings.query;
178+
options.editSetting = settings.editSetting;
176179

177180
return options;
178181
}
@@ -203,8 +206,6 @@ export interface IPreferencesService {
203206
switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): Promise<void>;
204207
openGlobalKeybindingSettings(textual: boolean): Promise<void>;
205208
openDefaultKeybindingsFile(): Promise<IEditorPane | undefined>;
206-
207-
configureSettingsForLanguage(language: string | null): void;
208209
}
209210

210211
export function getSettingsTargetName(target: ConfigurationTarget, resource: URI, workspaceContextService: IWorkspaceContextService): string {

0 commit comments

Comments
 (0)