NotebookDiffEditorInput extends DiffEditorInput.
This commit is contained in:
parent
75484f617b
commit
952bcbd666
|
@ -25,7 +25,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||
*/
|
||||
export class DiffEditorInput extends SideBySideEditorInput {
|
||||
|
||||
static override readonly ID = 'workbench.editors.diffEditorInput';
|
||||
static override readonly ID: string = 'workbench.editors.diffEditorInput';
|
||||
|
||||
override get typeId(): string {
|
||||
return DiffEditorInput.ID;
|
||||
|
|
|
@ -48,9 +48,9 @@ registerAction2(class extends Action2 {
|
|||
|
||||
await editorService.openEditor(
|
||||
{
|
||||
originalInput: { resource: diffEditorInput.originalResource },
|
||||
originalInput: { resource: diffEditorInput.originalInput.resource },
|
||||
modifiedInput: { resource: diffEditorInput.resource },
|
||||
label: diffEditorInput.textDiffName,
|
||||
label: diffEditorInput.getName(),
|
||||
options: {
|
||||
preserveFocus: false,
|
||||
override: EditorOverride.DISABLED
|
||||
|
|
|
@ -122,10 +122,10 @@ class NotebookDiffEditorSerializer implements IEditorInputSerializer {
|
|||
assertType(input instanceof NotebookDiffEditorInput);
|
||||
return JSON.stringify({
|
||||
resource: input.resource,
|
||||
originalResource: input.originalResource,
|
||||
name: input.name,
|
||||
originalName: input.originalName,
|
||||
textDiffName: input.textDiffName,
|
||||
originalResource: input.originalInput.resource,
|
||||
name: input.getName(),
|
||||
originalName: input.originalInput.getName(),
|
||||
textDiffName: input.getName(),
|
||||
viewType: input.viewType,
|
||||
});
|
||||
}
|
||||
|
@ -136,14 +136,12 @@ class NotebookDiffEditorSerializer implements IEditorInputSerializer {
|
|||
if (!data) {
|
||||
return undefined;
|
||||
}
|
||||
const { resource, originalResource, name, originalName, textDiffName, viewType } = data;
|
||||
if (!data || !URI.isUri(resource) || !URI.isUri(originalResource) || typeof name !== 'string' || typeof originalName !== 'string' || typeof viewType !== 'string') {
|
||||
const { resource, originalResource, name, viewType } = data;
|
||||
if (!data || !URI.isUri(resource) || !URI.isUri(originalResource) || typeof name !== 'string' || typeof viewType !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const input = NotebookDiffEditorInput.create(instantiationService, resource, name, originalResource, originalName,
|
||||
textDiffName || nls.localize('diffLeftRightLabel', "{0} ⟷ {1}", originalResource.toString(true), resource.toString(true)),
|
||||
viewType);
|
||||
const input = NotebookDiffEditorInput.create(instantiationService, resource, name, undefined, originalResource, viewType);
|
||||
return input;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,24 +3,16 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { IEditorInput, GroupIdentifier, ISaveOptions, IMoveResult, IRevertOptions, EditorInputCapabilities, IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { GroupIdentifier, IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
|
||||
import { IReference } from 'vs/base/common/lifecycle';
|
||||
import { INotebookDiffEditorModel, IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
|
||||
|
||||
interface NotebookEditorInputOptions {
|
||||
startDirty?: boolean;
|
||||
}
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
|
||||
class NotebookDiffEditorModel extends EditorModel implements INotebookDiffEditorModel {
|
||||
constructor(
|
||||
|
@ -50,174 +42,73 @@ class NotebookDiffEditorModel extends EditorModel implements INotebookDiffEditor
|
|||
}
|
||||
}
|
||||
|
||||
export class NotebookDiffEditorInput extends EditorInput {
|
||||
static create(instantiationService: IInstantiationService, resource: URI, name: string, originalResource: URI, originalName: string, textDiffName: string, viewType: string | undefined, options: NotebookEditorInputOptions = {}) {
|
||||
return instantiationService.createInstance(NotebookDiffEditorInput, resource, name, originalResource, originalName, textDiffName, viewType, options);
|
||||
export class NotebookDiffEditorInput extends DiffEditorInput {
|
||||
static create(instantiationService: IInstantiationService, resource: URI, name: string | undefined, description: string | undefined, originalResource: URI, viewType: string) {
|
||||
const originalInput = NotebookEditorInput.create(instantiationService, originalResource, viewType);
|
||||
const modifiedInput = NotebookEditorInput.create(instantiationService, resource, viewType);
|
||||
return instantiationService.createInstance(NotebookDiffEditorInput, name, description, originalInput, modifiedInput, viewType);
|
||||
}
|
||||
|
||||
static readonly ID: string = 'workbench.input.diffNotebookInput';
|
||||
static override readonly ID: string = 'workbench.input.diffNotebookInput';
|
||||
|
||||
private _modifiedTextModel: IReference<IResolvedNotebookEditorModel> | null = null;
|
||||
private _originalTextModel: IReference<IResolvedNotebookEditorModel> | null = null;
|
||||
private _defaultDirtyState: boolean = false;
|
||||
private _modifiedTextModel: IResolvedNotebookEditorModel | null = null;
|
||||
private _originalTextModel: IResolvedNotebookEditorModel | null = null;
|
||||
|
||||
override get resource() {
|
||||
return this.modifiedInput.resource;
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly resource: URI,
|
||||
public readonly name: string,
|
||||
public readonly originalResource: URI,
|
||||
public readonly originalName: string,
|
||||
public readonly textDiffName: string,
|
||||
public readonly viewType: string | undefined,
|
||||
public readonly options: NotebookEditorInputOptions,
|
||||
@INotebookService private readonly _notebookService: INotebookService,
|
||||
@INotebookEditorModelResolverService private readonly _notebookModelResolverService: INotebookEditorModelResolverService,
|
||||
@IFileDialogService private readonly _fileDialogService: IFileDialogService,
|
||||
@IFileService private readonly _fileService: IFileService
|
||||
name: string | undefined,
|
||||
description: string | undefined,
|
||||
override readonly originalInput: NotebookEditorInput,
|
||||
override readonly modifiedInput: NotebookEditorInput,
|
||||
public readonly viewType: string,
|
||||
@IFileService fileService: IFileService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
) {
|
||||
super();
|
||||
this._defaultDirtyState = !!options.startDirty;
|
||||
super(
|
||||
name,
|
||||
description,
|
||||
originalInput,
|
||||
modifiedInput,
|
||||
undefined,
|
||||
labelService,
|
||||
fileService
|
||||
);
|
||||
}
|
||||
|
||||
override get typeId(): string {
|
||||
return NotebookDiffEditorInput.ID;
|
||||
}
|
||||
|
||||
override get capabilities(): EditorInputCapabilities {
|
||||
let capabilities = EditorInputCapabilities.None;
|
||||
override async resolve(): Promise<NotebookDiffEditorModel> {
|
||||
|
||||
if (this._modifiedTextModel?.object.resource.scheme === Schemas.untitled) {
|
||||
capabilities |= EditorInputCapabilities.Untitled;
|
||||
const [originalEditorModel, modifiedEditorModel] = await Promise.all([
|
||||
this.originalInput.resolve(),
|
||||
this.modifiedInput.resolve(),
|
||||
]);
|
||||
|
||||
this._originalTextModel?.dispose();
|
||||
this._modifiedTextModel?.dispose();
|
||||
|
||||
// TODO@rebornix check how we restore the editor in text diff editor
|
||||
if (!modifiedEditorModel) {
|
||||
throw new Error(`Fail to resolve modified editor model for resource ${this.modifiedInput.resource} with notebookType ${this.viewType}`);
|
||||
}
|
||||
|
||||
if (this._modifiedTextModel) {
|
||||
if (this._modifiedTextModel.object.isReadonly()) {
|
||||
capabilities |= EditorInputCapabilities.Readonly;
|
||||
}
|
||||
} else {
|
||||
if (this._fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly)) {
|
||||
capabilities |= EditorInputCapabilities.Readonly;
|
||||
}
|
||||
if (!originalEditorModel) {
|
||||
throw new Error(`Fail to resolve original editor model for resource ${this.originalInput.resource} with notebookType ${this.viewType}`);
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
override getName(): string {
|
||||
return this.textDiffName;
|
||||
}
|
||||
|
||||
override isDirty() {
|
||||
if (!this._modifiedTextModel) {
|
||||
return this._defaultDirtyState;
|
||||
}
|
||||
return this._modifiedTextModel.object.isDirty();
|
||||
}
|
||||
|
||||
override async save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
|
||||
if (this._modifiedTextModel) {
|
||||
|
||||
if (this.hasCapability(EditorInputCapabilities.Untitled)) {
|
||||
return this.saveAs(group, options);
|
||||
} else {
|
||||
await this._modifiedTextModel.object.save();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override async saveAs(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
|
||||
if (!this._modifiedTextModel || !this.viewType) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const provider = this._notebookService.getContributedNotebookType(this.viewType!);
|
||||
|
||||
if (!provider) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const dialogPath = this._modifiedTextModel.object.resource;
|
||||
const target = await this._fileDialogService.pickFileToSave(dialogPath, options?.availableFileSystems);
|
||||
if (!target) {
|
||||
return undefined; // save cancelled
|
||||
}
|
||||
|
||||
if (!provider.matches(target)) {
|
||||
const patterns = provider.selectors.map(pattern => {
|
||||
if (typeof pattern === 'string') {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
if (glob.isRelativePattern(pattern)) {
|
||||
return `${pattern} (base ${pattern.base})`;
|
||||
}
|
||||
|
||||
return `${pattern.include} (exclude: ${pattern.exclude})`;
|
||||
}).join(', ');
|
||||
throw new Error(`File name ${target} is not supported by ${provider.providerDisplayName}.
|
||||
|
||||
Please make sure the file name matches following patterns:
|
||||
${patterns}
|
||||
`);
|
||||
}
|
||||
|
||||
if (!await this._modifiedTextModel.object.saveAs(target)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this._move(group, target)?.editor;
|
||||
}
|
||||
|
||||
// called when users rename a notebook document
|
||||
override rename(group: GroupIdentifier, target: URI): IMoveResult | undefined {
|
||||
if (this._modifiedTextModel) {
|
||||
const contributedNotebookProviders = this._notebookService.getContributedNotebookTypes(target);
|
||||
|
||||
if (contributedNotebookProviders.find(provider => provider.id === this._modifiedTextModel!.object.viewType)) {
|
||||
return this._move(group, target);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _move(group: GroupIdentifier, newResource: URI): { editor: IEditorInput } | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
|
||||
if (this._modifiedTextModel && this._modifiedTextModel.object.isDirty()) {
|
||||
await this._modifiedTextModel.object.revert(options);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
override async resolve(): Promise<INotebookDiffEditorModel | null> {
|
||||
if (!await this._notebookService.canResolve(this.viewType!)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this._modifiedTextModel) {
|
||||
this._modifiedTextModel = await this._notebookModelResolverService.resolve(this.resource, this.viewType!);
|
||||
this._register(this._modifiedTextModel.object.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
||||
if (this._modifiedTextModel.object.isDirty() !== this._defaultDirtyState) {
|
||||
this._onDidChangeDirty.fire();
|
||||
}
|
||||
|
||||
}
|
||||
if (!this._originalTextModel) {
|
||||
this._originalTextModel = await this._notebookModelResolverService.resolve(this.originalResource, this.viewType!);
|
||||
}
|
||||
|
||||
return new NotebookDiffEditorModel(this._originalTextModel.object, this._modifiedTextModel.object);
|
||||
this._originalTextModel = originalEditorModel;
|
||||
this._modifiedTextModel = modifiedEditorModel;
|
||||
return new NotebookDiffEditorModel(this._originalTextModel, this._modifiedTextModel);
|
||||
}
|
||||
|
||||
override asResourceEditorInput(group: GroupIdentifier): IResourceDiffEditorInput {
|
||||
return {
|
||||
originalInput: { resource: this.originalResource },
|
||||
originalInput: { resource: this.originalInput.resource },
|
||||
modifiedInput: { resource: this.resource },
|
||||
options: {
|
||||
override: this.viewType
|
||||
|
|
|
@ -21,7 +21,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
|||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol';
|
||||
|
@ -59,7 +58,6 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ILabelService private readonly _labelService: ILabelService,
|
||||
@IFileService private readonly _fileService: IFileService,
|
||||
) {
|
||||
super();
|
||||
|
@ -167,9 +165,7 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||
const notebookEditorDiffFactory: DiffEditorInputFactoryFunction = diffEditorInput => {
|
||||
const modifiedInput = diffEditorInput.modifiedInput;
|
||||
const originalInput = diffEditorInput.originalInput;
|
||||
const notebookUri = modifiedInput.resource!;
|
||||
const originalNotebookUri = originalInput.resource!;
|
||||
return { editor: NotebookDiffEditorInput.create(this._instantiationService, notebookUri, modifiedInput.resource ? this._labelService.getUriBasenameLabel(modifiedInput.resource) : '', originalNotebookUri, originalInput.resource ? this._labelService.getUriBasenameLabel(originalInput.resource) : '', this._labelService.getUriBasenameLabel(notebookUri), notebookProviderInfo.id) };
|
||||
return { editor: NotebookDiffEditorInput.create(this._instantiationService, modifiedInput.resource!, undefined, undefined, originalInput.resource!, notebookProviderInfo.id) };
|
||||
};
|
||||
// Register the notebook editor
|
||||
disposables.add(this._editorOverrideService.registerEditor(
|
||||
|
|
|
@ -10,7 +10,6 @@ import { mock } from 'vs/base/test/common/mock';
|
|||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { NotebookProviderInfoStore } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl';
|
||||
import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
|
||||
|
@ -24,11 +23,6 @@ suite('NotebookProviderInfoStore', function () {
|
|||
test('Can\'t open untitled notebooks in test #119363', function () {
|
||||
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
const labelService = new class extends mock<ILabelService>() {
|
||||
override getUriBasenameLabel(uri: URI) {
|
||||
return uri.toString();
|
||||
}
|
||||
};
|
||||
const store = new NotebookProviderInfoStore(
|
||||
new class extends mock<IStorageService>() {
|
||||
override get() { return ''; }
|
||||
|
@ -41,7 +35,6 @@ suite('NotebookProviderInfoStore', function () {
|
|||
new TestConfigurationService(),
|
||||
new class extends mock<IAccessibilityService>() { },
|
||||
instantiationService,
|
||||
labelService,
|
||||
new class extends mock<IFileService>() {
|
||||
override canHandleResource() { return true; }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue