提交 6f880b0f 编写于 作者: R rebornix

Tempalte Cell if the document is empty

上级 906729f1
...@@ -199,6 +199,14 @@ export class MainThreadNotebookController implements IMainNotebookController { ...@@ -199,6 +199,14 @@ export class MainThreadNotebookController implements IMainNotebookController {
let notebookHandle = await this._mainThreadNotebook.resolveNotebook(viewType, uri); let notebookHandle = await this._mainThreadNotebook.resolveNotebook(viewType, uri);
if (notebookHandle !== undefined) { if (notebookHandle !== undefined) {
mainthreadNotebook = this._mapping.get(URI.from(uri).toString()); mainthreadNotebook = this._mapping.get(URI.from(uri).toString());
if (mainthreadNotebook && mainthreadNotebook.textModel.cells.length === 0) {
// it's empty, we should create an empty template one
const templateCell = await this._proxy.$createEmptyCell(this._viewType, uri, 0, mainthreadNotebook.textModel.languages.length ? mainthreadNotebook.textModel.languages[0] : '', CellKind.Code);
if (templateCell) {
let mainCell = new NotebookCellTextModel(URI.revive(templateCell.uri), templateCell.handle, templateCell.source, templateCell.language, templateCell.cellKind, templateCell.outputs, templateCell.metadata);
mainthreadNotebook.textModel.insertTemplateCell(mainCell);
}
}
return mainthreadNotebook?.textModel; return mainthreadNotebook?.textModel;
} }
......
...@@ -15,6 +15,7 @@ import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/commo ...@@ -15,6 +15,7 @@ import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/commo
import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService'; import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { EDITOR_TOP_PADDING, EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; import { EDITOR_TOP_PADDING, EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { IModeService } from 'vs/editor/common/services/modeService';
interface IMimeTypeRenderer extends IQuickPickItem { interface IMimeTypeRenderer extends IQuickPickItem {
index: number; index: number;
...@@ -28,7 +29,8 @@ export class CodeCell extends Disposable { ...@@ -28,7 +29,8 @@ export class CodeCell extends Disposable {
private viewCell: CodeCellViewModel, private viewCell: CodeCellViewModel,
private templateData: CellRenderTemplate, private templateData: CellRenderTemplate,
@INotebookService private notebookService: INotebookService, @INotebookService private notebookService: INotebookService,
@IQuickInputService private readonly quickInputService: IQuickInputService @IQuickInputService private readonly quickInputService: IQuickInputService,
@IModeService private readonly _modeService: IModeService
) { ) {
super(); super();
...@@ -85,6 +87,11 @@ export class CodeCell extends Disposable { ...@@ -85,6 +87,11 @@ export class CodeCell extends Disposable {
templateData.editor?.updateOptions({ readOnly: !(viewCell.getEvaluatedMetadata(notebookEditor.viewModel?.metadata).editable) }); templateData.editor?.updateOptions({ readOnly: !(viewCell.getEvaluatedMetadata(notebookEditor.viewModel?.metadata).editable) });
})); }));
this._register(viewCell.onDidChangeLanguage((e) => {
const mode = this._modeService.create(e);
templateData.editor?.getModel()?.setMode(mode.languageIdentifier);
}));
let cellWidthResizeObserver = getResizesObserver(templateData.editorContainer!, { let cellWidthResizeObserver = getResizesObserver(templateData.editorContainer!, {
width: width, width: width,
height: totalHeight height: totalHeight
......
...@@ -34,6 +34,8 @@ export abstract class BaseCellViewModel extends Disposable { ...@@ -34,6 +34,8 @@ export abstract class BaseCellViewModel extends Disposable {
public readonly onDidChangeCursorSelection: Event<void> = this._onDidChangeCursorSelection.event; public readonly onDidChangeCursorSelection: Event<void> = this._onDidChangeCursorSelection.event;
protected readonly _onDidChangeMetadata: Emitter<NotebookCellMetadata | undefined> = this._register(new Emitter<NotebookCellMetadata | undefined>()); protected readonly _onDidChangeMetadata: Emitter<NotebookCellMetadata | undefined> = this._register(new Emitter<NotebookCellMetadata | undefined>());
public readonly onDidChangeMetadata: Event<NotebookCellMetadata | undefined> = this._onDidChangeMetadata.event; public readonly onDidChangeMetadata: Event<NotebookCellMetadata | undefined> = this._onDidChangeMetadata.event;
protected readonly _onDidChangeLanguage: Emitter<string> = this._register(new Emitter<string>());
public readonly onDidChangeLanguage: Event<string> = this._onDidChangeLanguage.event;
get handle() { get handle() {
return this.cell.handle; return this.cell.handle;
} }
...@@ -100,6 +102,10 @@ export abstract class BaseCellViewModel extends Disposable { ...@@ -100,6 +102,10 @@ export abstract class BaseCellViewModel extends Disposable {
constructor(readonly viewType: string, readonly notebookHandle: number, readonly cell: ICell, public id: string) { constructor(readonly viewType: string, readonly notebookHandle: number, readonly cell: ICell, public id: string) {
super(); super();
this._register(cell.onDidChangeLanguage((e) => {
this._onDidChangeLanguage.fire(e);
}));
this._register(cell.onDidChangeMetadata((e) => { this._register(cell.onDidChangeMetadata((e) => {
this._onDidChangeMetadata.fire(e); this._onDidChangeMetadata.fire(e);
})); }));
......
...@@ -89,6 +89,12 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod ...@@ -89,6 +89,12 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
this.layoutChange({ outerWidth: e.value.width, font: e.value.fontInfo }); this.layoutChange({ outerWidth: e.value.width, font: e.value.fontInfo });
} }
})); }));
this._register(this.onDidChangeLanguage((e) => {
if (this._textModel && !this._textModel.isDisposed()) {
}
}));
} }
layoutChange(state: CodeCellLayoutChangeEvent) { layoutChange(state: CodeCellLayoutChangeEvent) {
......
...@@ -18,6 +18,9 @@ export class NotebookCellTextModel implements ICell { ...@@ -18,6 +18,9 @@ export class NotebookCellTextModel implements ICell {
private _onDidChangeMetadata = new Emitter<NotebookCellMetadata | undefined>(); private _onDidChangeMetadata = new Emitter<NotebookCellMetadata | undefined>();
onDidChangeMetadata: Event<NotebookCellMetadata | undefined> = this._onDidChangeMetadata.event; onDidChangeMetadata: Event<NotebookCellMetadata | undefined> = this._onDidChangeMetadata.event;
private _onDidChangeLanguage = new Emitter<string>();
onDidChangeLanguage: Event<string> = this._onDidChangeLanguage.event;
private _outputs: IOutput[]; private _outputs: IOutput[];
get outputs(): IOutput[] { get outputs(): IOutput[] {
...@@ -44,13 +47,22 @@ export class NotebookCellTextModel implements ICell { ...@@ -44,13 +47,22 @@ export class NotebookCellTextModel implements ICell {
this._onDidChangeMetadata.fire(this._metadata); this._onDidChangeMetadata.fire(this._metadata);
} }
get language() {
return this._language;
}
set language(newLanguage: string) {
this._language = newLanguage;
this._onDidChangeLanguage.fire(newLanguage);
}
private _buffer: PieceTreeTextBufferFactory | null = null; private _buffer: PieceTreeTextBufferFactory | null = null;
constructor( constructor(
readonly uri: URI, readonly uri: URI,
public handle: number, public handle: number,
private _source: string[], private _source: string[],
public language: string, private _language: string,
public cellKind: CellKind, public cellKind: CellKind,
outputs: IOutput[], outputs: IOutput[],
metadata: NotebookCellMetadata | undefined metadata: NotebookCellMetadata | undefined
......
...@@ -24,6 +24,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel ...@@ -24,6 +24,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
languages: string[] = []; languages: string[] = [];
metadata: NotebookDocumentMetadata | undefined = { editable: true }; metadata: NotebookDocumentMetadata | undefined = { editable: true };
renderers = new Set<number>(); renderers = new Set<number>();
private _isUntitled: boolean | undefined = undefined;
constructor( constructor(
public handle: number, public handle: number,
...@@ -36,6 +37,11 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel ...@@ -36,6 +37,11 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
updateLanguages(languages: string[]) { updateLanguages(languages: string[]) {
this.languages = languages; this.languages = languages;
// TODO@rebornix metadata: default language for cell
if (this._isUntitled && languages.length && this.cells.length) {
this.cells[0].language = languages[0];
}
} }
updateNotebookMetadata(metadata: NotebookDocumentMetadata) { updateNotebookMetadata(metadata: NotebookDocumentMetadata) {
...@@ -57,7 +63,27 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel ...@@ -57,7 +63,27 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
}); });
} }
insertTemplateCell(cell: NotebookCellTextModel) {
if (this.cells.length > 0 || this._isUntitled !== undefined) {
return;
}
this._isUntitled = true;
this.cells = [cell];
let dirtyStateListener = cell.onDidChangeContent(() => {
this._isUntitled = false;
this._onDidChangeContent.fire();
});
this._cellListeners.set(cell.handle, dirtyStateListener);
this._onDidChangeContent.fire();
return;
}
insertNewCell(index: number, cell: NotebookCellTextModel): void { insertNewCell(index: number, cell: NotebookCellTextModel): void {
this._isUntitled = false;
this._mapping.set(cell.handle, cell); this._mapping.set(cell.handle, cell);
this.cells.splice(index, 0, cell); this.cells.splice(index, 0, cell);
let dirtyStateListener = cell.onDidChangeContent(() => { let dirtyStateListener = cell.onDidChangeContent(() => {
...@@ -70,6 +96,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel ...@@ -70,6 +96,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
} }
removeCell(index: number) { removeCell(index: number) {
this._isUntitled = false;
let cell = this.cells[index]; let cell = this.cells[index];
this._cellListeners.get(cell.handle)?.dispose(); this._cellListeners.get(cell.handle)?.dispose();
this._cellListeners.delete(cell.handle); this._cellListeners.delete(cell.handle);
...@@ -80,6 +108,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel ...@@ -80,6 +108,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
// TODO@rebornix should this trigger content change event? // TODO@rebornix should this trigger content change event?
$spliceNotebookCells(splices: NotebookCellsSplice[]): void { $spliceNotebookCells(splices: NotebookCellsSplice[]): void {
if (!splices.length) {
return;
}
this._isUntitled = false;
splices.reverse().forEach(splice => { splices.reverse().forEach(splice => {
let cellDtos = splice[2]; let cellDtos = splice[2];
let newCells = cellDtos.map(cell => { let newCells = cellDtos.map(cell => {
......
...@@ -136,6 +136,7 @@ export interface ICell { ...@@ -136,6 +136,7 @@ export interface ICell {
metadata?: NotebookCellMetadata; metadata?: NotebookCellMetadata;
onDidChangeOutputs?: Event<NotebookCellOutputsSplice[]>; onDidChangeOutputs?: Event<NotebookCellOutputsSplice[]>;
onDidChangeMetadata: Event<NotebookCellMetadata | undefined>; onDidChangeMetadata: Event<NotebookCellMetadata | undefined>;
onDidChangeLanguage: Event<string>;
resolveTextBufferFactory(): PieceTreeTextBufferFactory; resolveTextBufferFactory(): PieceTreeTextBufferFactory;
// TODO@rebornix it should be later on replaced by moving textmodel resolution into CellTextModel // TODO@rebornix it should be later on replaced by moving textmodel resolution into CellTextModel
contentChange(): void; contentChange(): void;
......
...@@ -27,6 +27,9 @@ export class TestCell implements ICell { ...@@ -27,6 +27,9 @@ export class TestCell implements ICell {
onDidChangeOutputs: Event<NotebookCellOutputsSplice[]> = this._onDidChangeOutputs.event; onDidChangeOutputs: Event<NotebookCellOutputsSplice[]> = this._onDidChangeOutputs.event;
private _onDidChangeMetadata = new Emitter<NotebookCellMetadata>(); private _onDidChangeMetadata = new Emitter<NotebookCellMetadata>();
onDidChangeMetadata: Event<NotebookCellMetadata> = this._onDidChangeMetadata.event; onDidChangeMetadata: Event<NotebookCellMetadata> = this._onDidChangeMetadata.event;
private _onDidChangeLanguage = new Emitter<string>();
onDidChangeLanguage: Event<string> = this._onDidChangeLanguage.event;
private _isDirty: boolean = false; private _isDirty: boolean = false;
private _outputs: IOutput[]; private _outputs: IOutput[];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册