@@ -8,11 +8,9 @@ import { parse } from 'vs/base/common/json';
88import { Disposable } from 'vs/base/common/lifecycle' ;
99import * as network from 'vs/base/common/network' ;
1010import { assign } from 'vs/base/common/objects' ;
11- import * as strings from 'vs/base/common/strings' ;
1211import { URI } from 'vs/base/common/uri' ;
1312import { 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' ;
1614import { ITextModel } from 'vs/editor/common/model' ;
1715import { IModelService } from 'vs/editor/common/services/modelService' ;
1816import { IModeService } from 'vs/editor/common/services/modeService' ;
@@ -39,6 +37,10 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
3937import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService' ;
4038import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles' ;
4139import { 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
4345const 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 {
0 commit comments