diff --git a/src/vs/workbench/api/browser/mainThreadCustomEditors.ts b/src/vs/workbench/api/browser/mainThreadCustomEditors.ts index 3016f3a0111..2489c0b5bc8 100644 --- a/src/vs/workbench/api/browser/mainThreadCustomEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadCustomEditors.ts @@ -16,7 +16,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import * as modes from 'vs/editor/common/modes'; import { localize } from 'vs/nls'; import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/files/common/files'; +import { FileChangesEvent, FileChangeType, FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; import { IUndoRedoService, UndoRedoElementType } from 'vs/platform/undoRedo/common/undoRedo'; @@ -451,8 +451,12 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod } } - public isReadonly() { - return !this._editable; + public isEditable(): boolean { + return this._editable; + } + + public isOnReadonlyFileSystem(): boolean { + return this._fileService.hasCapability(this.editorResource, FileSystemProviderCapabilities.Readonly); } public get viewType() { diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index b305b6c280f..bddf88a1207 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -103,13 +103,20 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { } private decorateLabel(label: string): string { - const orphaned = this._modelRef?.object.isOrphaned(); - const readonly = this.isReadonly(); - return decorateFileEditorLabel(label, { orphaned: !!orphaned, readonly }); + const orphaned = !!this._modelRef?.object.isOrphaned(); + + const readonly = this._modelRef + ? !this._modelRef.object.isEditable() || this._modelRef.object.isOnReadonlyFileSystem() + : false; + + return decorateFileEditorLabel(label, { + orphaned, + readonly + }); } public isReadonly(): boolean { - return this._modelRef ? this._modelRef.object.isReadonly() : false; + return this._modelRef ? !this._modelRef.object.isEditable() : false; } public isUntitled(): boolean { diff --git a/src/vs/workbench/contrib/customEditor/common/customEditor.ts b/src/vs/workbench/contrib/customEditor/common/customEditor.ts index 5f7fc9d4ce0..6bb68a6a56a 100644 --- a/src/vs/workbench/contrib/customEditor/common/customEditor.ts +++ b/src/vs/workbench/contrib/customEditor/common/customEditor.ts @@ -63,7 +63,8 @@ export interface ICustomEditorModel extends IDisposable { readonly resource: URI; readonly backupId: string | undefined; - isReadonly(): boolean; + isEditable(): boolean; + isOnReadonlyFileSystem(): boolean; isOrphaned(): boolean; readonly onDidChangeOrphaned: Event; diff --git a/src/vs/workbench/contrib/customEditor/common/customTextEditorModel.ts b/src/vs/workbench/contrib/customEditor/common/customTextEditorModel.ts index eff8a252954..c39fa2ce52c 100644 --- a/src/vs/workbench/contrib/customEditor/common/customTextEditorModel.ts +++ b/src/vs/workbench/contrib/customEditor/common/customTextEditorModel.ts @@ -8,10 +8,11 @@ import { Disposable, IReference } from 'vs/base/common/lifecycle'; import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; +import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor'; import { ICustomEditorModel } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { ITextFileEditorModel, ITextFileService, TextFileEditorModelState } from 'vs/workbench/services/textfile/common/textfiles'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class CustomTextEditorModel extends Disposable implements ICustomEditorModel { @@ -22,9 +23,8 @@ export class CustomTextEditorModel extends Disposable implements ICustomEditorMo ): Promise { return instantiationService.invokeFunction(async accessor => { const textModelResolverService = accessor.get(ITextModelService); - const textFileService = accessor.get(ITextFileService); const model = await textModelResolverService.createModelReference(resource); - return new CustomTextEditorModel(viewType, resource, model, textFileService); + return instantiationService.createInstance(CustomTextEditorModel, viewType, resource, model); }); } @@ -33,11 +33,12 @@ export class CustomTextEditorModel extends Disposable implements ICustomEditorMo private readonly _onDidChangeOrphaned = this._register(new Emitter()); public readonly onDidChangeOrphaned = this._onDidChangeOrphaned.event; - private constructor( + constructor( public readonly viewType: string, private readonly _resource: URI, private readonly _model: IReference, @ITextFileService private readonly textFileService: ITextFileService, + @IFileService private readonly _fileService: IFileService, ) { super(); @@ -60,8 +61,12 @@ export class CustomTextEditorModel extends Disposable implements ICustomEditorMo return this._resource; } - public isReadonly(): boolean { - return this._model.object.isReadonly(); + public isEditable(): boolean { + return !this._model.object.isReadonly(); + } + + public isOnReadonlyFileSystem(): boolean { + return this._fileService.hasCapability(this._resource, FileSystemProviderCapabilities.Readonly); } public get backupId() {