diff --git a/src/sql/workbench/parts/notebook/browser/models/notebookInput.ts b/src/sql/workbench/parts/notebook/browser/models/notebookInput.ts index 8f60deb397..a986574f15 100644 --- a/src/sql/workbench/parts/notebook/browser/models/notebookInput.ts +++ b/src/sql/workbench/parts/notebook/browser/models/notebookInput.ts @@ -28,6 +28,7 @@ import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/c import { Deferred } from 'sql/base/common/promise'; import { NotebookTextFileModel } from 'sql/workbench/parts/notebook/browser/models/notebookTextFileModel'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; +import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; export type ModeViewSaveHandler = (handle: number) => Thenable; @@ -38,7 +39,7 @@ export class NotebookEditorModel extends EditorModel { private readonly _onDidChangeDirty: Emitter = this._register(new Emitter()); private _lastEditFullReplacement: boolean; constructor(public readonly notebookUri: URI, - private textEditorModel: TextFileEditorModel | UntitledEditorModel, + private textEditorModel: TextFileEditorModel | UntitledEditorModel | ResourceEditorModel, @INotebookService private notebookService: INotebookService, @ITextFileService private textFileService: ITextFileService, @ITextResourcePropertiesService private textResourcePropertiesService: ITextResourcePropertiesService @@ -63,18 +64,23 @@ export class NotebookEditorModel extends EditorModel { }, err => undefined); } })); - if (this.textEditorModel instanceof UntitledEditorModel) { - this._register(this.textEditorModel.onDidChangeDirty(e => this.setDirty(this.textEditorModel.isDirty()))); - } else { - this._register(this.textEditorModel.onDidStateChange(change => { - this.setDirty(this.textEditorModel.isDirty()); - if (change === StateChange.SAVED) { - this.sendNotebookSerializationStateChange(); - } + this._register(this.textEditorModel.onDidChangeDirty(e => { + let dirty = this.textEditorModel instanceof ResourceEditorModel ? false : this.textEditorModel.isDirty(); + this.setDirty(dirty); })); + } else { + if (this.textEditorModel instanceof TextFileEditorModel) { + this._register(this.textEditorModel.onDidStateChange(change => { + let dirty = this.textEditorModel instanceof ResourceEditorModel ? false : this.textEditorModel.isDirty(); + this.setDirty(dirty); + if (change === StateChange.SAVED) { + this.sendNotebookSerializationStateChange(); + } + })); + } } - this._dirty = this.textEditorModel.isDirty(); + this._dirty = this.textEditorModel instanceof ResourceEditorModel ? false : this.textEditorModel.isDirty(); } public get contentString(): string { @@ -87,7 +93,7 @@ export class NotebookEditorModel extends EditorModel { } isDirty(): boolean { - return this.textEditorModel.isDirty(); + return this.textEditorModel instanceof ResourceEditorModel ? false : this.textEditorModel.isDirty(); } public setDirty(dirty: boolean): void { diff --git a/src/sql/workbench/parts/notebook/browser/models/notebookTextFileModel.ts b/src/sql/workbench/parts/notebook/browser/models/notebookTextFileModel.ts index 355b74e860..25014807e8 100644 --- a/src/sql/workbench/parts/notebook/browser/models/notebookTextFileModel.ts +++ b/src/sql/workbench/parts/notebook/browser/models/notebookTextFileModel.ts @@ -7,8 +7,10 @@ import { Range, IRange } from 'vs/editor/common/core/range'; import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { FindMatch } from 'vs/editor/common/model'; +import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; import { NotebookContentChange, INotebookModel } from 'sql/workbench/parts/notebook/browser/models/modelInterfaces'; import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts'; +import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; export class NotebookTextFileModel { // save active cell's line/column in editor model for the beginning of the source property @@ -33,7 +35,7 @@ export class NotebookTextFileModel { } } - public transformAndApplyEditForSourceUpdate(contentChange: NotebookContentChange, textEditorModel: TextFileEditorModel | UntitledEditorModel): boolean { + public transformAndApplyEditForSourceUpdate(contentChange: NotebookContentChange, textEditorModel: BaseTextEditorModel): boolean { let cellGuidRange = this.getCellNodeByGuid(textEditorModel, contentChange.cells[0].cellGuid); // convert the range to leverage offsets in the json @@ -109,7 +111,7 @@ export class NotebookTextFileModel { return false; } - public transformAndApplyEditForOutputUpdate(contentChange: NotebookContentChange, textEditorModel: TextFileEditorModel | UntitledEditorModel): boolean { + public transformAndApplyEditForOutputUpdate(contentChange: NotebookContentChange, textEditorModel: BaseTextEditorModel): boolean { if (Array.isArray(contentChange.cells[0].outputs) && contentChange.cells[0].outputs.length > 0) { let newOutput = JSON.stringify(contentChange.cells[0].outputs[contentChange.cells[0].outputs.length - 1], undefined, ' '); if (contentChange.cells[0].outputs.length > 1) { @@ -136,7 +138,7 @@ export class NotebookTextFileModel { return false; } - public transformAndApplyEditForCellUpdated(contentChange: NotebookContentChange, textEditorModel: TextFileEditorModel | UntitledEditorModel): boolean { + public transformAndApplyEditForCellUpdated(contentChange: NotebookContentChange, textEditorModel: BaseTextEditorModel): boolean { let executionCountMatch = this.getExecutionCountRange(textEditorModel, contentChange.cells[0].cellGuid); if (executionCountMatch && executionCountMatch.range) { // Execution count can be between 0 and n characters long @@ -161,7 +163,7 @@ export class NotebookTextFileModel { return true; } - public transformAndApplyEditForClearOutput(contentChange: NotebookContentChange, textEditorModel: TextFileEditorModel | UntitledEditorModel): boolean { + public transformAndApplyEditForClearOutput(contentChange: NotebookContentChange, textEditorModel: BaseTextEditorModel): boolean { if (!textEditorModel || !contentChange || !contentChange.cells || !contentChange.cells[0] || !contentChange.cells[0].cellGuid) { return false; } @@ -178,7 +180,7 @@ export class NotebookTextFileModel { return false; } - public replaceEntireTextEditorModel(notebookModel: INotebookModel, type: NotebookChangeType, textEditorModel: TextFileEditorModel | UntitledEditorModel) { + public replaceEntireTextEditorModel(notebookModel: INotebookModel, type: NotebookChangeType, textEditorModel: BaseTextEditorModel) { let content = JSON.stringify(notebookModel.toJSON(type), undefined, ' '); let model = textEditorModel.textEditorModel; let endLine = model.getLineCount(); @@ -190,7 +192,7 @@ export class NotebookTextFileModel { } // Find the beginning of a cell's source in the text editor model - private updateSourceBeginRange(textEditorModel: TextFileEditorModel | UntitledEditorModel, cellGuid: string): void { + private updateSourceBeginRange(textEditorModel: BaseTextEditorModel, cellGuid: string): void { if (!cellGuid) { return; } @@ -210,7 +212,7 @@ export class NotebookTextFileModel { } // Find the beginning of a cell's outputs in the text editor model - private updateOutputBeginRange(textEditorModel: TextFileEditorModel | UntitledEditorModel, cellGuid: string): void { + private updateOutputBeginRange(textEditorModel: BaseTextEditorModel, cellGuid: string): void { if (!cellGuid) { return undefined; } @@ -230,7 +232,7 @@ export class NotebookTextFileModel { // Find the end of a cell's outputs in the text editor model // This will be used as a starting point for any future outputs - private getEndOfOutputs(textEditorModel: TextFileEditorModel | UntitledEditorModel, cellGuid: string) { + private getEndOfOutputs(textEditorModel: BaseTextEditorModel, cellGuid: string) { let outputsBegin; if (this._activeCellGuid === cellGuid) { outputsBegin = this._outputBeginRange; @@ -272,7 +274,7 @@ export class NotebookTextFileModel { } // Determine what text needs to be replaced when execution counts are updated - private getExecutionCountRange(textEditorModel: TextFileEditorModel | UntitledEditorModel, cellGuid: string) { + private getExecutionCountRange(textEditorModel: BaseTextEditorModel, cellGuid: string) { let endOutputRange = this.getEndOfOutputs(textEditorModel, cellGuid); if (endOutputRange && endOutputRange.endLineNumber) { return textEditorModel.textEditorModel.findNextMatch('"execution_count": ', { lineNumber: endOutputRange.endLineNumber, column: endOutputRange.endColumn }, false, true, undefined, true); @@ -282,14 +284,14 @@ export class NotebookTextFileModel { // Find a cell's location, given its cellGuid // If it doesn't exist (e.g. it's not the active cell), attempt to find it - private getCellNodeByGuid(textEditorModel: TextFileEditorModel | UntitledEditorModel, guid: string) { + private getCellNodeByGuid(textEditorModel: BaseTextEditorModel, guid: string) { if (this._activeCellGuid !== guid || !this._sourceBeginRange) { this.updateSourceBeginRange(textEditorModel, guid); } return this._sourceBeginRange; } - private getOutputNodeByGuid(textEditorModel: TextFileEditorModel | UntitledEditorModel, guid: string) { + private getOutputNodeByGuid(textEditorModel: BaseTextEditorModel, guid: string) { if (this._activeCellGuid !== guid) { this.updateOutputBeginRange(textEditorModel, guid); } @@ -302,7 +304,7 @@ function areRangePropertiesPopulated(range: Range) { return range && range.startLineNumber !== 0 && range.startColumn !== 0 && range.endLineNumber !== 0 && range.endColumn !== 0; } -function findOrSetCellGuidMatch(textEditorModel: TextFileEditorModel | UntitledEditorModel, cellGuid: string): FindMatch[] { +function findOrSetCellGuidMatch(textEditorModel: BaseTextEditorModel, cellGuid: string): FindMatch[] { if (!textEditorModel || !cellGuid) { return undefined; }