Path: blob/main/src/vs/workbench/common/editor/resourceEditorInput.ts
3296 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 { Verbosity, EditorInputWithPreferredResource, EditorInputCapabilities, IFileLimitedEditorInputOptions } from '../editor.js';6import { EditorInput } from './editorInput.js';7import { URI } from '../../../base/common/uri.js';8import { ByteSize, IFileReadLimits, IFileService, getLargeFileConfirmationLimit } from '../../../platform/files/common/files.js';9import { ILabelService } from '../../../platform/label/common/label.js';10import { dirname, isEqual } from '../../../base/common/resources.js';11import { IFilesConfigurationService } from '../../services/filesConfiguration/common/filesConfigurationService.js';12import { IMarkdownString } from '../../../base/common/htmlContent.js';13import { isConfigured } from '../../../platform/configuration/common/configuration.js';14import { ITextResourceConfigurationService } from '../../../editor/common/services/textResourceConfiguration.js';15import { ICustomEditorLabelService } from '../../services/editor/common/customEditorLabelService.js';1617/**18* The base class for all editor inputs that open resources.19*/20export abstract class AbstractResourceEditorInput extends EditorInput implements EditorInputWithPreferredResource {2122override get capabilities(): EditorInputCapabilities {23let capabilities = EditorInputCapabilities.CanSplitInGroup;2425if (this.fileService.hasProvider(this.resource)) {26if (this.filesConfigurationService.isReadonly(this.resource)) {27capabilities |= EditorInputCapabilities.Readonly;28}29} else {30capabilities |= EditorInputCapabilities.Untitled;31}3233if (!(capabilities & EditorInputCapabilities.Readonly)) {34capabilities |= EditorInputCapabilities.CanDropIntoEditor;35}3637return capabilities;38}3940private _preferredResource: URI;41get preferredResource(): URI { return this._preferredResource; }4243constructor(44readonly resource: URI,45preferredResource: URI | undefined,46@ILabelService protected readonly labelService: ILabelService,47@IFileService protected readonly fileService: IFileService,48@IFilesConfigurationService protected readonly filesConfigurationService: IFilesConfigurationService,49@ITextResourceConfigurationService protected readonly textResourceConfigurationService: ITextResourceConfigurationService,50@ICustomEditorLabelService protected readonly customEditorLabelService: ICustomEditorLabelService51) {52super();5354this._preferredResource = preferredResource || resource;5556this.registerListeners();57}5859private registerListeners(): void {6061// Clear our labels on certain label related events62this._register(this.labelService.onDidChangeFormatters(e => this.onLabelEvent(e.scheme)));63this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onLabelEvent(e.scheme)));64this._register(this.fileService.onDidChangeFileSystemProviderCapabilities(e => this.onLabelEvent(e.scheme)));65this._register(this.customEditorLabelService.onDidChange(() => this.updateLabel()));66this._register(this.filesConfigurationService.onDidChangeReadonly(() => this._onDidChangeCapabilities.fire()));67}6869private onLabelEvent(scheme: string): void {70if (scheme === this._preferredResource.scheme) {71this.updateLabel();72}73}7475private updateLabel(): void {7677// Clear any cached labels from before78this._name = undefined;79this._shortDescription = undefined;80this._mediumDescription = undefined;81this._longDescription = undefined;82this._shortTitle = undefined;83this._mediumTitle = undefined;84this._longTitle = undefined;8586// Trigger recompute of label87this._onDidChangeLabel.fire();88}8990setPreferredResource(preferredResource: URI): void {91if (!isEqual(preferredResource, this._preferredResource)) {92this._preferredResource = preferredResource;9394this.updateLabel();95}96}9798private _name: string | undefined = undefined;99override getName(): string {100if (typeof this._name !== 'string') {101this._name = this.customEditorLabelService.getName(this._preferredResource) ?? this.labelService.getUriBasenameLabel(this._preferredResource);102}103104return this._name;105}106107override getDescription(verbosity = Verbosity.MEDIUM): string | undefined {108switch (verbosity) {109case Verbosity.SHORT:110return this.shortDescription;111case Verbosity.LONG:112return this.longDescription;113case Verbosity.MEDIUM:114default:115return this.mediumDescription;116}117}118119private _shortDescription: string | undefined = undefined;120private get shortDescription(): string {121if (typeof this._shortDescription !== 'string') {122this._shortDescription = this.labelService.getUriBasenameLabel(dirname(this._preferredResource));123}124125return this._shortDescription;126}127128private _mediumDescription: string | undefined = undefined;129private get mediumDescription(): string {130if (typeof this._mediumDescription !== 'string') {131this._mediumDescription = this.labelService.getUriLabel(dirname(this._preferredResource), { relative: true });132}133134return this._mediumDescription;135}136137private _longDescription: string | undefined = undefined;138private get longDescription(): string {139if (typeof this._longDescription !== 'string') {140this._longDescription = this.labelService.getUriLabel(dirname(this._preferredResource));141}142143return this._longDescription;144}145146private _shortTitle: string | undefined = undefined;147private get shortTitle(): string {148if (typeof this._shortTitle !== 'string') {149this._shortTitle = this.getName();150}151152return this._shortTitle;153}154155private _mediumTitle: string | undefined = undefined;156private get mediumTitle(): string {157if (typeof this._mediumTitle !== 'string') {158this._mediumTitle = this.labelService.getUriLabel(this._preferredResource, { relative: true });159}160161return this._mediumTitle;162}163164private _longTitle: string | undefined = undefined;165private get longTitle(): string {166if (typeof this._longTitle !== 'string') {167this._longTitle = this.labelService.getUriLabel(this._preferredResource);168}169170return this._longTitle;171}172173override getTitle(verbosity?: Verbosity): string {174switch (verbosity) {175case Verbosity.SHORT:176return this.shortTitle;177case Verbosity.LONG:178return this.longTitle;179default:180case Verbosity.MEDIUM:181return this.mediumTitle;182}183}184185override isReadonly(): boolean | IMarkdownString {186return this.filesConfigurationService.isReadonly(this.resource);187}188189protected ensureLimits(options?: IFileLimitedEditorInputOptions): IFileReadLimits | undefined {190if (options?.limits) {191return options.limits; // respect passed in limits if any192}193194// We want to determine the large file configuration based on the best defaults195// for the resource but also respecting user settings. We only apply user settings196// if explicitly configured by the user. Otherwise we pick the best limit for the197// resource scheme.198199const defaultSizeLimit = getLargeFileConfirmationLimit(this.resource);200let configuredSizeLimit: number | undefined = undefined;201202const configuredSizeLimitMb = this.textResourceConfigurationService.inspect<number>(this.resource, null, 'workbench.editorLargeFileConfirmation');203if (isConfigured(configuredSizeLimitMb)) {204configuredSizeLimit = configuredSizeLimitMb.value * ByteSize.MB; // normalize to MB205}206207return {208size: configuredSizeLimit ?? defaultSizeLimit209};210}211}212213214