Path: blob/main/src/vs/editor/common/services/textResourceConfigurationService.ts
3294 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Emitter, Event } from '../../../base/common/event.js';6import { Disposable } from '../../../base/common/lifecycle.js';7import { URI } from '../../../base/common/uri.js';8import { IPosition, Position } from '../core/position.js';9import { ILanguageService } from '../languages/language.js';10import { IModelService } from './model.js';11import { ITextResourceConfigurationService, ITextResourceConfigurationChangeEvent } from './textResourceConfiguration.js';12import { IConfigurationService, ConfigurationTarget, IConfigurationValue, IConfigurationChangeEvent } from '../../../platform/configuration/common/configuration.js';1314export class TextResourceConfigurationService extends Disposable implements ITextResourceConfigurationService {1516public _serviceBrand: undefined;1718private readonly _onDidChangeConfiguration: Emitter<ITextResourceConfigurationChangeEvent> = this._register(new Emitter<ITextResourceConfigurationChangeEvent>());19public readonly onDidChangeConfiguration: Event<ITextResourceConfigurationChangeEvent> = this._onDidChangeConfiguration.event;2021constructor(22@IConfigurationService private readonly configurationService: IConfigurationService,23@IModelService private readonly modelService: IModelService,24@ILanguageService private readonly languageService: ILanguageService,25) {26super();27this._register(this.configurationService.onDidChangeConfiguration(e => this._onDidChangeConfiguration.fire(this.toResourceConfigurationChangeEvent(e))));28}2930getValue<T>(resource: URI | undefined, section?: string): T;31getValue<T>(resource: URI | undefined, at?: IPosition, section?: string): T;32getValue<T>(resource: URI | undefined, arg2?: unknown, arg3?: unknown): T {33if (typeof arg3 === 'string') {34return this._getValue(resource, Position.isIPosition(arg2) ? arg2 : null, arg3);35}36return this._getValue(resource, null, typeof arg2 === 'string' ? arg2 : undefined);37}3839updateValue(resource: URI | undefined, key: string, value: unknown, configurationTarget?: ConfigurationTarget): Promise<void> {40const language = resource ? this.getLanguage(resource, null) : null;41const configurationValue = this.configurationService.inspect(key, { resource, overrideIdentifier: language });42if (configurationTarget === undefined) {43configurationTarget = this.deriveConfigurationTarget(configurationValue, language);44}45const overrideIdentifier = language && configurationValue.overrideIdentifiers?.includes(language) ? language : undefined;46return this.configurationService.updateValue(key, value, { resource, overrideIdentifier }, configurationTarget);47}4849private deriveConfigurationTarget(configurationValue: IConfigurationValue<unknown>, language: string | null): ConfigurationTarget {50if (language) {51if (configurationValue.memory?.override !== undefined) {52return ConfigurationTarget.MEMORY;53}54if (configurationValue.workspaceFolder?.override !== undefined) {55return ConfigurationTarget.WORKSPACE_FOLDER;56}57if (configurationValue.workspace?.override !== undefined) {58return ConfigurationTarget.WORKSPACE;59}60if (configurationValue.userRemote?.override !== undefined) {61return ConfigurationTarget.USER_REMOTE;62}63if (configurationValue.userLocal?.override !== undefined) {64return ConfigurationTarget.USER_LOCAL;65}66}67if (configurationValue.memory?.value !== undefined) {68return ConfigurationTarget.MEMORY;69}70if (configurationValue.workspaceFolder?.value !== undefined) {71return ConfigurationTarget.WORKSPACE_FOLDER;72}73if (configurationValue.workspace?.value !== undefined) {74return ConfigurationTarget.WORKSPACE;75}76if (configurationValue.userRemote?.value !== undefined) {77return ConfigurationTarget.USER_REMOTE;78}79return ConfigurationTarget.USER_LOCAL;80}8182private _getValue<T>(resource: URI | undefined, position: IPosition | null, section: string | undefined): T {83const language = resource ? this.getLanguage(resource, position) : undefined;84if (typeof section === 'undefined') {85return this.configurationService.getValue<T>({ resource, overrideIdentifier: language });86}87return this.configurationService.getValue<T>(section, { resource, overrideIdentifier: language });88}8990inspect<T>(resource: URI | undefined, position: IPosition | null, section: string): IConfigurationValue<Readonly<T>> {91const language = resource ? this.getLanguage(resource, position) : undefined;92return this.configurationService.inspect<T>(section, { resource, overrideIdentifier: language });93}9495private getLanguage(resource: URI, position: IPosition | null): string | null {96const model = this.modelService.getModel(resource);97if (model) {98return position ? model.getLanguageIdAtPosition(position.lineNumber, position.column) : model.getLanguageId();99}100return this.languageService.guessLanguageIdByFilepathOrFirstLine(resource);101}102103private toResourceConfigurationChangeEvent(configurationChangeEvent: IConfigurationChangeEvent): ITextResourceConfigurationChangeEvent {104return {105affectedKeys: configurationChangeEvent.affectedKeys,106affectsConfiguration: (resource: URI | undefined, configuration: string) => {107const overrideIdentifier = resource ? this.getLanguage(resource, null) : undefined;108if (configurationChangeEvent.affectsConfiguration(configuration, { resource, overrideIdentifier })) {109return true;110}111if (overrideIdentifier) {112//TODO@sandy081 workaround for https://github.com/microsoft/vscode/issues/240410113return configurationChangeEvent.affectedKeys.has(`[${overrideIdentifier}]`);114}115return false;116}117};118}119}120121122