101 lines
4.2 KiB
TypeScript
101 lines
4.2 KiB
TypeScript
// *****************************************************************************
|
|
// Copyright (C) 2019 TypeFox and others.
|
|
//
|
|
// This program and the accompanying materials are made available under the
|
|
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
// http://www.eclipse.org/legal/epl-2.0.
|
|
//
|
|
// This Source Code may also be made available under the following Secondary
|
|
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
// with the GNU Classpath Exception which is available at
|
|
// https://www.gnu.org/software/classpath/license.html.
|
|
//
|
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
// *****************************************************************************
|
|
|
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
import URI from '@theia/core/lib/common/uri';
|
|
import { PreferenceScope } from '@theia/core/lib/common/preferences';
|
|
import { WorkspaceService, WorkspaceData } from '@theia/workspace/lib/browser/workspace-service';
|
|
import { AbstractResourcePreferenceProvider } from '../common/abstract-resource-preference-provider';
|
|
|
|
@injectable()
|
|
export class WorkspaceFilePreferenceProviderOptions {
|
|
workspaceUri: URI;
|
|
}
|
|
|
|
export const WorkspaceFilePreferenceProviderFactory = Symbol('WorkspaceFilePreferenceProviderFactory');
|
|
export type WorkspaceFilePreferenceProviderFactory = (options: WorkspaceFilePreferenceProviderOptions) => WorkspaceFilePreferenceProvider;
|
|
|
|
@injectable()
|
|
export class WorkspaceFilePreferenceProvider extends AbstractResourcePreferenceProvider {
|
|
|
|
@inject(WorkspaceService)
|
|
protected readonly workspaceService: WorkspaceService;
|
|
|
|
@inject(WorkspaceFilePreferenceProviderOptions)
|
|
protected readonly options: WorkspaceFilePreferenceProviderOptions;
|
|
|
|
protected sectionsInsideSettings = new Set<string>();
|
|
|
|
protected getUri(): URI {
|
|
return this.options.workspaceUri;
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
protected override parse(content: string): any {
|
|
const data = super.parse(content);
|
|
if (WorkspaceData.is(data)) {
|
|
const settings = { ...data.settings };
|
|
for (const key of this.configurations.getSectionNames().filter(name => name !== 'settings')) {
|
|
// If the user has written configuration inside the "settings" object, we will respect that.
|
|
if (settings[key]) {
|
|
this.sectionsInsideSettings.add(key);
|
|
}
|
|
// Favor sections outside the "settings" object to agree with VSCode behavior
|
|
if (data[key]) {
|
|
settings[key] = data[key];
|
|
this.sectionsInsideSettings.delete(key);
|
|
}
|
|
}
|
|
return settings;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
protected override getPath(preferenceName: string): string[] {
|
|
const firstSegment = preferenceName.split('.', 1)[0];
|
|
const remainder = preferenceName.slice(firstSegment.length + 1);
|
|
if (this.belongsInSection(firstSegment, remainder)) {
|
|
// Default to writing sections outside the "settings" object.
|
|
const path = [firstSegment];
|
|
if (remainder) {
|
|
path.push(remainder);
|
|
}
|
|
// If the user has already written this section inside the "settings" object, modify it there.
|
|
if (this.sectionsInsideSettings.has(firstSegment)) {
|
|
path.unshift('settings');
|
|
}
|
|
return path;
|
|
}
|
|
return ['settings'].concat(super.getPath(preferenceName) ?? []);
|
|
}
|
|
|
|
/**
|
|
* @returns `true` if `firstSegment` is a section name (e.g. `tasks`, `launch`)
|
|
*/
|
|
protected belongsInSection(firstSegment: string, remainder: string): boolean {
|
|
return this.configurations.isSectionName(firstSegment);
|
|
}
|
|
|
|
getScope(): PreferenceScope {
|
|
return PreferenceScope.Workspace;
|
|
}
|
|
|
|
override getDomain(): string[] {
|
|
// workspace file is treated as part of the workspace
|
|
return this.workspaceService.tryGetRoots().map(r => r.resource.toString()).concat([this.options.workspaceUri.toString()]);
|
|
}
|
|
}
|