提交 e2785c32 编写于 作者: R Rob Lourens

Make vscode own cell execution duration

上级 a1566100
......@@ -1580,6 +1580,16 @@ declare module 'vscode' {
* The cell's current run state
*/
runState?: NotebookCellRunState;
/**
* If the cell is running, the time at which the cell started running
*/
runStartTime?: number;
/**
* The total duration of the cell's last run
*/
lastRunDuration?: number;
}
export interface NotebookCell {
......
......@@ -254,6 +254,10 @@
background-color: rgba(255, 255, 255, 0.2);
}
.notebookOverlay .cell-statusbar-container .cell-run-duration {
margin-right: 8px;
}
.notebookOverlay .cell-statusbar-container .cell-status-message {
display: flex;
align-items: center;
......
......@@ -20,7 +20,7 @@ import { Range } from 'vs/editor/common/core/range';
import { FindMatch, IReadonlyTextBuffer, ITextModel } from 'vs/editor/common/model';
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
import { CellLanguageStatusBarItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer';
import { CellLanguageStatusBarItem, TimerRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer';
import { CellViewModel, IModelDecorationsChangeAccessor, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { CellKind, IOutput, IRenderOutput, NotebookCellMetadata, NotebookDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
......@@ -434,6 +434,7 @@ export interface CodeCellRenderTemplate extends BaseCellRenderTemplate {
outputContainer: HTMLElement;
editor: ICodeEditor;
progressBar: ProgressBar;
timer: TimerRenderer;
}
export interface IOutputTransformContribution {
......
......@@ -18,7 +18,7 @@ import { renderCodicons } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { deepClone } from 'vs/base/common/objects';
import * as platform from 'vs/base/common/platform';
import { escape } from 'vs/base/common/strings';
......@@ -32,7 +32,6 @@ import { ITextModel } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer';
import { IModeService } from 'vs/editor/common/services/modeService';
import * as nls from 'vs/nls';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, MenuItemAction } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
......@@ -830,6 +829,7 @@ class CellEditorStatusBar {
readonly cellRunStatusContainer: HTMLElement;
readonly statusBarContainer: HTMLElement;
readonly languageStatusBarItem: CellLanguageStatusBarItem;
readonly durationContainer: HTMLElement;
constructor(
container: HTMLElement,
......@@ -839,6 +839,7 @@ class CellEditorStatusBar {
const leftStatusBarItems = DOM.append(this.statusBarContainer, $('.cell-status-left'));
const rightStatusBarItems = DOM.append(this.statusBarContainer, $('.cell-status-right'));
this.cellRunStatusContainer = DOM.append(leftStatusBarItems, $('.cell-run-status'));
this.durationContainer = DOM.append(leftStatusBarItems, $('.cell-run-duration'));
this.cellStatusMessageContainer = DOM.append(leftStatusBarItems, $('.cell-status-message'));
this.languageStatusBarItem = instantiationService.createInstance(CellLanguageStatusBarItem, rightStatusBarItems);
}
......@@ -902,6 +903,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
disposables.add(progressBar);
const statusBar = this.instantiationService.createInstance(CellEditorStatusBar, editorPart);
const timer = new TimerRenderer(statusBar.durationContainer);
const outputContainer = DOM.append(container, $('.output'));
const focusSink = DOM.append(container, $('.cell-editor-focus-sink'));
......@@ -926,6 +928,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
disposables,
elementDisposables: new DisposableStore(),
bottomCellContainer,
timer,
toJSON: () => { return {}; }
};
......@@ -970,12 +973,22 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
} else if (metadata.runState === NotebookCellRunState.Error) {
templateData.cellRunStatusContainer.innerHTML = renderCodicons('$(error)');
} else if (metadata.runState === NotebookCellRunState.Running) {
// TODO@roblourens should extensions be able to customize the status message while running to show progress?
templateData.cellStatusMessageContainer.textContent = nls.localize('cellRunningStatus', "Running");
templateData.cellRunStatusContainer.innerHTML = renderCodicons('$(sync~spin)');
} else {
templateData.cellRunStatusContainer.innerHTML = '';
}
if (metadata.runState === NotebookCellRunState.Running) {
if (metadata.runStartTime) {
templateData.elementDisposables.add(templateData.timer.start(metadata.runStartTime));
} else {
templateData.timer.clear();
}
} else if (typeof metadata.lastRunDuration === 'number') {
templateData.timer.show(metadata.lastRunDuration);
} else {
templateData.timer.clear();
}
}
private renderExecutionOrder(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void {
......@@ -1075,3 +1088,52 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
templateData.focusIndicator.style.height = 'initial';
}
}
export class TimerRenderer {
constructor(private readonly container: HTMLElement) {
DOM.hide(container);
}
private intervalTimer: NodeJS.Timeout | undefined;
start(startTime: number): IDisposable {
this.stop();
DOM.show(this.container);
const intervalTimer = setInterval(() => {
const duration = Date.now() - startTime;
this.container.textContent = this.formatDuration(duration);
}, 100);
this.intervalTimer = intervalTimer;
return toDisposable(() => {
clearInterval(intervalTimer);
});
}
stop() {
if (this.intervalTimer) {
clearInterval(this.intervalTimer);
}
}
show(duration: number) {
this.stop();
DOM.show(this.container);
this.container.textContent = this.formatDuration(duration);
}
clear() {
DOM.hide(this.container);
this.stop();
this.container.textContent = '';
}
private formatDuration(duration: number) {
const seconds = Math.floor(duration / 1000);
const tenths = String(duration - seconds * 1000).charAt(0);
return `${seconds}.${tenths}s`;
}
}
......@@ -360,11 +360,11 @@ export abstract class BaseCellViewModel extends Disposable {
: this.metadata?.runnable;
return {
editable,
runnable,
executionOrder: this.metadata?.executionOrder,
runState: this.metadata?.runState,
statusMessage: this.metadata?.statusMessage
...(this.metadata || {}),
...{
editable,
runnable
}
};
}
......
......@@ -80,6 +80,9 @@ export interface NotebookCellMetadata {
executionOrder?: number;
statusMessage?: string;
runState?: NotebookCellRunState;
runStartTime?: number;
lastRunDuration?: number;
}
export interface INotebookDisplayOrder {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册