mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Allow git to open notebook files (#7403)
* Allow git to open notebook files * pr feedback
This commit is contained in:
@@ -28,6 +28,7 @@ import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/c
|
|||||||
import { Deferred } from 'sql/base/common/promise';
|
import { Deferred } from 'sql/base/common/promise';
|
||||||
import { NotebookTextFileModel } from 'sql/workbench/parts/notebook/browser/models/notebookTextFileModel';
|
import { NotebookTextFileModel } from 'sql/workbench/parts/notebook/browser/models/notebookTextFileModel';
|
||||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
|
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
|
||||||
|
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
|
||||||
|
|
||||||
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
|
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
|
||||||
|
|
||||||
@@ -38,7 +39,7 @@ export class NotebookEditorModel extends EditorModel {
|
|||||||
private readonly _onDidChangeDirty: Emitter<void> = this._register(new Emitter<void>());
|
private readonly _onDidChangeDirty: Emitter<void> = this._register(new Emitter<void>());
|
||||||
private _lastEditFullReplacement: boolean;
|
private _lastEditFullReplacement: boolean;
|
||||||
constructor(public readonly notebookUri: URI,
|
constructor(public readonly notebookUri: URI,
|
||||||
private textEditorModel: TextFileEditorModel | UntitledEditorModel,
|
private textEditorModel: TextFileEditorModel | UntitledEditorModel | ResourceEditorModel,
|
||||||
@INotebookService private notebookService: INotebookService,
|
@INotebookService private notebookService: INotebookService,
|
||||||
@ITextFileService private textFileService: ITextFileService,
|
@ITextFileService private textFileService: ITextFileService,
|
||||||
@ITextResourcePropertiesService private textResourcePropertiesService: ITextResourcePropertiesService
|
@ITextResourcePropertiesService private textResourcePropertiesService: ITextResourcePropertiesService
|
||||||
@@ -63,18 +64,23 @@ export class NotebookEditorModel extends EditorModel {
|
|||||||
}, err => undefined);
|
}, err => undefined);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (this.textEditorModel instanceof UntitledEditorModel) {
|
if (this.textEditorModel instanceof UntitledEditorModel) {
|
||||||
this._register(this.textEditorModel.onDidChangeDirty(e => this.setDirty(this.textEditorModel.isDirty())));
|
this._register(this.textEditorModel.onDidChangeDirty(e => {
|
||||||
} else {
|
let dirty = this.textEditorModel instanceof ResourceEditorModel ? false : this.textEditorModel.isDirty();
|
||||||
this._register(this.textEditorModel.onDidStateChange(change => {
|
this.setDirty(dirty);
|
||||||
this.setDirty(this.textEditorModel.isDirty());
|
|
||||||
if (change === StateChange.SAVED) {
|
|
||||||
this.sendNotebookSerializationStateChange();
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
} 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 {
|
public get contentString(): string {
|
||||||
@@ -87,7 +93,7 @@ export class NotebookEditorModel extends EditorModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isDirty(): boolean {
|
isDirty(): boolean {
|
||||||
return this.textEditorModel.isDirty();
|
return this.textEditorModel instanceof ResourceEditorModel ? false : this.textEditorModel.isDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public setDirty(dirty: boolean): void {
|
public setDirty(dirty: boolean): void {
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import { Range, IRange } from 'vs/editor/common/core/range';
|
|||||||
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
|
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
|
||||||
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
|
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
|
||||||
import { FindMatch } from 'vs/editor/common/model';
|
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 { NotebookContentChange, INotebookModel } from 'sql/workbench/parts/notebook/browser/models/modelInterfaces';
|
||||||
import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
|
import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
|
||||||
|
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||||
|
|
||||||
export class NotebookTextFileModel {
|
export class NotebookTextFileModel {
|
||||||
// save active cell's line/column in editor model for the beginning of the source property
|
// 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);
|
let cellGuidRange = this.getCellNodeByGuid(textEditorModel, contentChange.cells[0].cellGuid);
|
||||||
|
|
||||||
// convert the range to leverage offsets in the json
|
// convert the range to leverage offsets in the json
|
||||||
@@ -109,7 +111,7 @@ export class NotebookTextFileModel {
|
|||||||
return false;
|
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) {
|
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, ' ');
|
let newOutput = JSON.stringify(contentChange.cells[0].outputs[contentChange.cells[0].outputs.length - 1], undefined, ' ');
|
||||||
if (contentChange.cells[0].outputs.length > 1) {
|
if (contentChange.cells[0].outputs.length > 1) {
|
||||||
@@ -136,7 +138,7 @@ export class NotebookTextFileModel {
|
|||||||
return false;
|
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);
|
let executionCountMatch = this.getExecutionCountRange(textEditorModel, contentChange.cells[0].cellGuid);
|
||||||
if (executionCountMatch && executionCountMatch.range) {
|
if (executionCountMatch && executionCountMatch.range) {
|
||||||
// Execution count can be between 0 and n characters long
|
// Execution count can be between 0 and n characters long
|
||||||
@@ -161,7 +163,7 @@ export class NotebookTextFileModel {
|
|||||||
return true;
|
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) {
|
if (!textEditorModel || !contentChange || !contentChange.cells || !contentChange.cells[0] || !contentChange.cells[0].cellGuid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -178,7 +180,7 @@ export class NotebookTextFileModel {
|
|||||||
return false;
|
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 content = JSON.stringify(notebookModel.toJSON(type), undefined, ' ');
|
||||||
let model = textEditorModel.textEditorModel;
|
let model = textEditorModel.textEditorModel;
|
||||||
let endLine = model.getLineCount();
|
let endLine = model.getLineCount();
|
||||||
@@ -190,7 +192,7 @@ export class NotebookTextFileModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the beginning of a cell's source in the text editor model
|
// 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) {
|
if (!cellGuid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -210,7 +212,7 @@ export class NotebookTextFileModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the beginning of a cell's outputs in the text editor model
|
// 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) {
|
if (!cellGuid) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -230,7 +232,7 @@ export class NotebookTextFileModel {
|
|||||||
|
|
||||||
// Find the end of a cell's outputs in the text editor model
|
// 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
|
// 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;
|
let outputsBegin;
|
||||||
if (this._activeCellGuid === cellGuid) {
|
if (this._activeCellGuid === cellGuid) {
|
||||||
outputsBegin = this._outputBeginRange;
|
outputsBegin = this._outputBeginRange;
|
||||||
@@ -272,7 +274,7 @@ export class NotebookTextFileModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine what text needs to be replaced when execution counts are updated
|
// 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);
|
let endOutputRange = this.getEndOfOutputs(textEditorModel, cellGuid);
|
||||||
if (endOutputRange && endOutputRange.endLineNumber) {
|
if (endOutputRange && endOutputRange.endLineNumber) {
|
||||||
return textEditorModel.textEditorModel.findNextMatch('"execution_count": ', { lineNumber: endOutputRange.endLineNumber, column: endOutputRange.endColumn }, false, true, undefined, true);
|
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
|
// 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
|
// 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) {
|
if (this._activeCellGuid !== guid || !this._sourceBeginRange) {
|
||||||
this.updateSourceBeginRange(textEditorModel, guid);
|
this.updateSourceBeginRange(textEditorModel, guid);
|
||||||
}
|
}
|
||||||
return this._sourceBeginRange;
|
return this._sourceBeginRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOutputNodeByGuid(textEditorModel: TextFileEditorModel | UntitledEditorModel, guid: string) {
|
private getOutputNodeByGuid(textEditorModel: BaseTextEditorModel, guid: string) {
|
||||||
if (this._activeCellGuid !== guid) {
|
if (this._activeCellGuid !== guid) {
|
||||||
this.updateOutputBeginRange(textEditorModel, 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;
|
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) {
|
if (!textEditorModel || !cellGuid) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user