diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts index 360bc205add..aff65718781 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts @@ -19,7 +19,7 @@ import { IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/ import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import * as nls from 'vs/nls'; import { ConfigurationTarget, IConfigurationService, overrideIdentifierFromKey } from 'vs/platform/configuration/common/configuration'; -import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; +import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -29,6 +29,8 @@ import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/ran import { DefaultSettingsHeaderWidget, EditPreferenceWidget, SettingsGroupTitleWidget, SettingsHeaderWidget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; import { IFilterResult, IPreferencesEditorModel, IPreferencesService, ISetting, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; import { DefaultSettingsEditorModel, SettingsEditorModel, WorkspaceConfigurationEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { IMarkerService, IMarkerData, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; export interface IPreferencesRenderer extends IDisposable { readonly preferencesModel: IPreferencesEditorModel; @@ -65,6 +67,8 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend private readonly _onUpdatePreference = this._register(new Emitter<{ key: string, value: any, source: IIndexedSetting }>()); readonly onUpdatePreference: Event<{ key: string, value: any, source: IIndexedSetting }> = this._onUpdatePreference.event; + private unsupportedSettingsRenderer: UnsupportedSettingsRenderer; + private filterResult: IFilterResult | undefined; constructor(protected editor: ICodeEditor, readonly preferencesModel: SettingsEditorModel, @@ -78,7 +82,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend this.editSettingActionRenderer = this._register(this.instantiationService.createInstance(EditSettingRenderer, this.editor, this.preferencesModel, this.settingHighlighter)); this._register(this.editSettingActionRenderer.onUpdateSetting(({ key, value, source }) => this._updatePreference(key, value, source))); this._register(this.editor.getModel()!.onDidChangeContent(() => this.modelChangeDelayer.trigger(() => this.onModelChanged()))); - + this.unsupportedSettingsRenderer = this._register(instantiationService.createInstance(UnsupportedSettingsRenderer, editor, preferencesModel)); } getAssociatedPreferencesModel(): IPreferencesEditorModel { @@ -102,6 +106,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend if (this.filterResult) { this.filterPreferences(this.filterResult); } + this.unsupportedSettingsRenderer.render(); } private _updatePreference(key: string, value: any, source: IIndexedSetting): void { @@ -946,6 +951,151 @@ class SettingHighlighter extends Disposable { } } +class UnsupportedSettingsRenderer extends Disposable { + + private renderingDelayer: Delayer = new Delayer(200); + + constructor( + private editor: ICodeEditor, + private settingsEditorModel: SettingsEditorModel, + @IMarkerService private markerService: IMarkerService, + @IWorkbenchEnvironmentService private workbenchEnvironmentService: IWorkbenchEnvironmentService, + ) { + super(); + this._register(this.editor.getModel()!.onDidChangeContent(() => this.renderingDelayer.trigger(() => this.render()))); + } + + public render(): void { + const markerData: IMarkerData[] = this.generateMarkerData(); + if (markerData.length) { + this.markerService.changeOne('preferencesEditor', this.settingsEditorModel.uri, markerData); + } else { + this.markerService.remove('preferencesEditor', [this.settingsEditorModel.uri]); + } + } + + private generateMarkerData(): IMarkerData[] { + const markerData: IMarkerData[] = []; + const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties(); + for (const settingsGroup of this.settingsEditorModel.settingsGroups) { + for (const section of settingsGroup.sections) { + for (const setting of section.settings) { + const configuration = configurationRegistry[setting.key]; + if (configuration) { + switch (this.settingsEditorModel.configurationTarget) { + case ConfigurationTarget.USER_LOCAL: + this.handleLocalUserConfiguration(setting, configuration, markerData); + break; + case ConfigurationTarget.USER_REMOTE: + this.handleRemoteUserConfiguration(setting, configuration, markerData); + break; + case ConfigurationTarget.WORKSPACE: + this.handleWorkspaceConfiguration(setting, configuration, markerData); + break; + case ConfigurationTarget.WORKSPACE_FOLDER: + this.handleWorkspaceFolderConfiguration(setting, configuration, markerData); + break; + } + } else { + markerData.push({ + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + startLineNumber: setting.keyRange.startLineNumber, + startColumn: setting.keyRange.startColumn, + endLineNumber: setting.valueRange.endLineNumber, + endColumn: setting.valueRange.endColumn, + message: nls.localize('unknown configuration setting', "Unknown Configuration Setting") + }); + } + } + } + } + return markerData; + } + + private handleLocalUserConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void { + if (this.workbenchEnvironmentService.configuration.remote && configuration.scope === ConfigurationScope.MACHINE) { + markerData.push({ + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + startLineNumber: setting.keyRange.startLineNumber, + startColumn: setting.keyRange.startColumn, + endLineNumber: setting.valueRange.endLineNumber, + endColumn: setting.valueRange.endColumn, + message: nls.localize('unsupportedRemoteMachineSetting', "This setting can be applied only in remote machine settings") + }); + } + } + + private handleRemoteUserConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void { + if (configuration.scope === ConfigurationScope.APPLICATION) { + markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); + } + } + + private handleWorkspaceConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void { + if (configuration.scope === ConfigurationScope.APPLICATION) { + markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); + } + + if (configuration.scope === ConfigurationScope.MACHINE) { + markerData.push(this.generateUnsupportedMachineSettingMarker(setting)); + } + } + + private handleWorkspaceFolderConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void { + if (configuration.scope === ConfigurationScope.APPLICATION) { + markerData.push(this.generateUnsupportedApplicationSettingMarker(setting)); + } + + if (configuration.scope === ConfigurationScope.MACHINE) { + markerData.push(this.generateUnsupportedMachineSettingMarker(setting)); + } + + if (configuration.scope === ConfigurationScope.WINDOW) { + markerData.push({ + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + startLineNumber: setting.keyRange.startLineNumber, + startColumn: setting.keyRange.startColumn, + endLineNumber: setting.valueRange.endLineNumber, + endColumn: setting.valueRange.endColumn, + message: nls.localize('unsupportedWindowSetting', "This setting cannot be applied now. It will be applied when you open this folder directly.") + }); + } + } + + private generateUnsupportedApplicationSettingMarker(setting: ISetting): IMarkerData { + return { + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + startLineNumber: setting.keyRange.startLineNumber, + startColumn: setting.keyRange.startColumn, + endLineNumber: setting.keyRange.endLineNumber, + endColumn: setting.keyRange.endColumn, + message: nls.localize('unsupportedApplicationSetting', "This setting can be applied only in application user settings") + }; + } + + private generateUnsupportedMachineSettingMarker(setting: ISetting): IMarkerData { + return { + severity: MarkerSeverity.Hint, + tags: [MarkerTag.Unnecessary], + startLineNumber: setting.keyRange.startLineNumber, + startColumn: setting.keyRange.startColumn, + endLineNumber: setting.valueRange.endLineNumber, + endColumn: setting.valueRange.endColumn, + message: nls.localize('unsupportedMachineSetting', "This setting can be applied only in user settings") + }; + } + + public dispose(): void { + this.markerService.remove('preferencesEditor', [this.settingsEditorModel.uri]); + super.dispose(); + } + +} + class WorkspaceConfigurationRenderer extends Disposable { private decorationIds: string[] = []; diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index a95764ba5ca..4deec1e6057 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -23,7 +23,6 @@ import { ConfigurationEditingService, EditableConfigurationTarget } from 'vs/wor import { WorkspaceConfiguration, FolderConfiguration, RemoteUserConfiguration, UserConfiguration } from 'vs/workbench/services/configuration/browser/configuration'; import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; -import { localize } from 'vs/nls'; import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; @@ -507,29 +506,29 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private registerConfigurationSchemas(): void { if (this.workspace) { const jsonRegistry = Registry.as(JSONExtensions.JSONContribution); - const convertToNotSuggestedProperties = (properties: IJSONSchemaMap, errorMessage: string): IJSONSchemaMap => { + const convertToNotSuggestedProperties = (properties: IJSONSchemaMap): IJSONSchemaMap => { return Object.keys(properties).reduce((result: IJSONSchemaMap, property) => { result[property] = deepClone(properties[property]); - result[property].deprecationMessage = errorMessage; + result[property].doNotSuggest = true; return result; }, {}); }; - const unsupportedApplicationSettings = convertToNotSuggestedProperties(applicationSettings.properties, localize('unsupportedApplicationSetting', "This setting can be applied only in application user settings")); - const unsupportedMachineSettings = convertToNotSuggestedProperties(machineSettings.properties, localize('unsupportedMachineSetting', "This setting can be applied only in user settings")); - const unsupportedRemoteMachineSettings = convertToNotSuggestedProperties(machineSettings.properties, localize('unsupportedRemoteMachineSetting', "This setting can be applied only in remote machine settings")); - const allSettingsSchema: IJSONSchema = { properties: allSettings.properties, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; - const userSettingsSchema: IJSONSchema = this.remoteUserConfiguration ? { properties: { ...applicationSettings.properties, ...unsupportedRemoteMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' } : allSettingsSchema; - const machineSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; - const workspaceSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; + const unsupportedApplicationSettings = convertToNotSuggestedProperties(applicationSettings.properties); + const unsupportedMachineSettings = convertToNotSuggestedProperties(machineSettings.properties); + const unsupportedRemoteMachineSettings = convertToNotSuggestedProperties(machineSettings.properties); + const allSettingsSchema: IJSONSchema = { properties: allSettings.properties, patternProperties: allSettings.patternProperties, additionalProperties: true }; + const userSettingsSchema: IJSONSchema = this.remoteUserConfiguration ? { properties: { ...applicationSettings.properties, ...unsupportedRemoteMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: true } : allSettingsSchema; + const machineSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: true }; + const workspaceSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: true }; jsonRegistry.registerSchema(defaultSettingsSchemaId, allSettingsSchema); jsonRegistry.registerSchema(userSettingsSchemaId, userSettingsSchema); jsonRegistry.registerSchema(machineSettingsSchemaId, machineSettingsSchema); if (WorkbenchState.WORKSPACE === this.getWorkbenchState()) { - const unsupportedWindowSettings = convertToNotSuggestedProperties(windowSettings.properties, localize('unsupportedWindowSetting', "This setting cannot be applied now. It will be applied when you open this folder directly.")); - const folderSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...unsupportedWindowSettings, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; + const unsupportedWindowSettings = convertToNotSuggestedProperties(windowSettings.properties); + const folderSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...unsupportedWindowSettings, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: true }; jsonRegistry.registerSchema(workspaceSettingsSchemaId, workspaceSettingsSchema); jsonRegistry.registerSchema(folderSettingsSchemaId, folderSettingsSchema); } else {