reset dirty state when reverting a notebook, update extension host when dirty state of a notebook (working copy) changes

This commit is contained in:
Johannes Rieken 2021-02-15 11:44:51 +01:00
parent 5236d34460
commit 196bf678a1
6 changed files with 47 additions and 16 deletions

View file

@ -5,7 +5,7 @@
import * as assert from 'assert';
import * as vscode from 'vscode';
import { createRandomFile, disposeAll, asPromise, closeAllEditors, assertNoRpc } from '../utils';
import * as utils from '../utils';
suite('Notebook Document', function () {
@ -33,14 +33,13 @@ suite('Notebook Document', function () {
const disposables: vscode.Disposable[] = [];
suiteTeardown(async function () {
assertNoRpc();
await vscode.commands.executeCommand('workbench.action.files.saveAll');
await closeAllEditors();
disposeAll(disposables);
await utils.revertAllDirty();
await utils.closeAllEditors();
utils.disposeAll(disposables);
disposables.length = 0;
for (let doc of vscode.notebook.notebookDocuments) {
assert.strictEqual(doc.isDirty, false)
assert.strictEqual(doc.isDirty, false, doc.uri.toString());
}
});
@ -64,7 +63,7 @@ suite('Notebook Document', function () {
});
test('document basics', async function () {
const uri = await createRandomFile(undefined, undefined, '.nbdtest');
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const notebook = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(notebook.uri.toString(), uri.toString());
@ -76,9 +75,9 @@ suite('Notebook Document', function () {
});
test('notebook open/close, notebook ready when cell-document open event is fired', async function () {
const uri = await createRandomFile(undefined, undefined, '.nbdtest');
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
let didHappen = false;
const p = asPromise(vscode.workspace.onDidOpenTextDocument).then(doc => {
const p = utils.asPromise(vscode.workspace.onDidOpenTextDocument).then(doc => {
if (doc.uri.scheme !== 'vscode-notebook-cell') {
return;
}
@ -96,9 +95,9 @@ suite('Notebook Document', function () {
});
test('notebook open/close, all cell-documents are ready', async function () {
const uri = await createRandomFile(undefined, undefined, '.nbdtest');
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const p = asPromise(vscode.notebook.onDidOpenNotebookDocument).then(notebook => {
const p = utils.asPromise(vscode.notebook.onDidOpenNotebookDocument).then(notebook => {
for (let cell of notebook.cells) {
const doc = vscode.workspace.textDocuments.find(doc => doc.uri.toString() === cell.uri.toString());
assert.ok(doc);
@ -116,7 +115,7 @@ suite('Notebook Document', function () {
test('workspace edit API (replaceCells)', async function () {
const uri = await createRandomFile(undefined, undefined, '.nbdtest');
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const document = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(document.cells.length, 1);
@ -192,7 +191,7 @@ suite('Notebook Document', function () {
});
test('workspace edit API (replaceCells, event)', async function () {
const uri = await createRandomFile(undefined, undefined, '.nbdtest');
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const document = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(document.cells.length, 1);
@ -211,7 +210,7 @@ suite('Notebook Document', function () {
source: 'new_code'
}]);
const event = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebook.onDidChangeNotebookCells);
const event = utils.asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebook.onDidChangeNotebookCells);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);

View file

@ -48,6 +48,10 @@ export function closeAllEditors(): Thenable<any> {
return vscode.commands.executeCommand('workbench.action.closeAllEditors');
}
export function saveAllEditors(): Thenable<any> {
return vscode.commands.executeCommand('workbench.action.files.saveAll');
}
export async function revertAllDirty(): Promise<void> {
return vscode.commands.executeCommand('_workbench.revertAllDirty');
}

View file

@ -10,7 +10,8 @@ import { Emitter } from 'vs/base/common/event';
import { IRelativePattern } from 'vs/base/common/glob';
import { combinedDisposable, Disposable, DisposableStore, dispose, IDisposable, IReference } from 'vs/base/common/lifecycle';
import { ResourceMap } from 'vs/base/common/map';
import { IExtUri } from 'vs/base/common/resources';
import { Schemas } from 'vs/base/common/network';
import { IExtUri, isEqual } from 'vs/base/common/resources';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@ -30,6 +31,7 @@ import { IEditorGroup, IEditorGroupsService, preferredSideBySideGroupDirection }
import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith';
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, INotebookCellStatusBarEntryDto, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookModelAddedData, MainContext, MainThreadNotebookShape, NotebookEditorRevealType, NotebookExtensionDescription } from '../common/extHost.protocol';
class DocumentAndEditorState {
@ -121,6 +123,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
constructor(
extHostContext: IExtHostContext,
@IWorkingCopyService private readonly _workingCopyService: IWorkingCopyService,
@INotebookService private _notebookService: INotebookService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IEditorService private readonly _editorService: IEditorService,
@ -202,6 +205,22 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
}
registerListeners() {
// forward changes to dirty state
// todo@bpasero this seem way too complicated... is there an easy way to
// the actual resource from a working copy?
this._register(this._workingCopyService.onDidChangeDirty(e => {
if (e.resource.scheme !== Schemas.vscodeNotebook) {
return;
}
for (const notebook of this._notebookService.getNotebookTextModels()) {
if (isEqual(notebook.uri.with({ scheme: Schemas.vscodeNotebook }), e.resource)) {
this._proxy.$acceptDirtyStateChanged(notebook.uri, e.isDirty());
break;
}
}
}));
this._notebookService.listNotebookEditors().forEach((e) => {
this._addNotebookEditor(e);
});

View file

@ -1803,6 +1803,7 @@ export interface ExtHostNotebookShape {
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelFriendlyId: string | undefined }): void;
$onDidReceiveMessage(editorId: string, rendererId: string | undefined, message: unknown): void;
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEventDto, isDirty: boolean): void;
$acceptDirtyStateChanged(uriComponents: UriComponents, isDirty: boolean): void;
$acceptModelSaved(uriComponents: UriComponents): void;
$acceptEditorPropertiesChanged(id: string, data: INotebookEditorPropertiesChangeData): void;
$acceptDocumentPropertiesChanged(uriComponents: UriComponents, data: INotebookDocumentPropertiesChangeData): void;

View file

@ -578,7 +578,14 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
}
}
public $acceptModelSaved(uriComponents: UriComponents): void {
$acceptDirtyStateChanged(resource: UriComponents, isDirty: boolean): void {
const document = this._documents.get(URI.revive(resource));
if (document) {
document.acceptModelChanged({ rawEvents: [], versionId: document.notebookDocument.version }, isDirty);
}
}
$acceptModelSaved(uriComponents: UriComponents): void {
const document = this._documents.get(URI.revive(uriComponents));
if (document) {
// this.$acceptDirtyStateChanged(uriComponents, false);

View file

@ -125,6 +125,7 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM
async revert(options?: IRevertOptions | undefined): Promise<void> {
if (options?.soft) {
await this._backupFileService.discardBackup(this.resource);
this.setDirty(false);
return;
}