mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-29 00:46:00 +01:00
Vendored
+40
@@ -1613,6 +1613,35 @@ declare module 'vscode' {
|
||||
resolveKernel?(kernel: T, document: NotebookDocument, webview: NotebookCommunication, token: CancellationToken): ProviderResult<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the alignment of status bar items.
|
||||
*/
|
||||
export enum NotebookCellStatusBarAlignment {
|
||||
|
||||
/**
|
||||
* Aligned to the left side.
|
||||
*/
|
||||
Left = 1,
|
||||
|
||||
/**
|
||||
* Aligned to the right side.
|
||||
*/
|
||||
Right = 2
|
||||
}
|
||||
|
||||
export interface NotebookCellStatusBarItem {
|
||||
readonly cell: NotebookCell;
|
||||
readonly alignment: NotebookCellStatusBarAlignment;
|
||||
readonly priority?: number;
|
||||
text: string;
|
||||
tooltip: string | undefined;
|
||||
command: string | Command | undefined;
|
||||
accessibilityInformation?: AccessibilityInformation;
|
||||
show(): void;
|
||||
hide(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export namespace notebook {
|
||||
export function registerNotebookContentProvider(
|
||||
notebookType: string,
|
||||
@@ -1670,6 +1699,17 @@ declare module 'vscode' {
|
||||
export function createConcatTextDocument(notebook: NotebookDocument, selector?: DocumentSelector): NotebookConcatTextDocument;
|
||||
|
||||
export const onDidChangeActiveNotebookKernel: Event<{ document: NotebookDocument, kernel: NotebookKernel | undefined }>;
|
||||
|
||||
/**
|
||||
* Creates a notebook cell status bar [item](#NotebookCellStatusBarItem).
|
||||
* It will be disposed automatically when the notebook document is closed or the cell is deleted.
|
||||
*
|
||||
* @param cell The cell on which this item should be shown.
|
||||
* @param alignment The alignment of the item.
|
||||
* @param priority The priority of the item. Higher values mean the item should be shown more to the left.
|
||||
* @return A new status bar item.
|
||||
*/
|
||||
export function createCellStatusBarItem(cell: NotebookCell, alignment?: NotebookCellStatusBarAlignment, priority?: number): NotebookCellStatusBarItem;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -4,23 +4,23 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IExtHostContext, ExtHostNotebookShape, ExtHostContext, INotebookDocumentsAndEditorsDelta } from '../common/extHost.protocol';
|
||||
import { Disposable, IDisposable, combinedDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { NOTEBOOK_DISPLAY_ORDER, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType, CellKind, INotebookKernelInfo, INotebookKernelInfoDto, IEditor, INotebookDocumentFilter, DisplayOrderKey, TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { combinedDisposable, Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
|
||||
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType, CellKind, DisplayOrderKey, ICellEditOperation, IEditor, INotebookDocumentFilter, INotebookKernelInfo, INotebookKernelInfoDto, NotebookCellMetadata, NotebookCellOutputsSplice, NotebookDocumentMetadata, NOTEBOOK_DISPLAY_ORDER, TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, INotebookCellStatusBarEntryDto, INotebookDocumentsAndEditorsDelta, MainContext, MainThreadNotebookShape, NotebookExtensionDescription } from '../common/extHost.protocol';
|
||||
|
||||
class DocumentAndEditorState {
|
||||
static ofSets<T>(before: Set<T>, after: Set<T>): { removed: T[], added: T[] } {
|
||||
@@ -137,6 +137,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
private _toDisposeOnEditorRemove = new Map<string, IDisposable>();
|
||||
private _currentState?: DocumentAndEditorState;
|
||||
private _editorEventListenersMapping: Map<string, DisposableStore> = new Map();
|
||||
private readonly _cellStatusBarEntries: Map<number, IDisposable> = new Map();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@@ -144,8 +145,8 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@INotebookCellStatusBarService private readonly cellStatusBarService: INotebookCellStatusBarService
|
||||
) {
|
||||
super();
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebook);
|
||||
@@ -603,6 +604,24 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
const textModel = this._notebookService.getNotebookTextModel(URI.from(resource));
|
||||
textModel?.handleUnknownChange();
|
||||
}
|
||||
|
||||
async $setStatusBarEntry(id: number, rawStatusBarEntry: INotebookCellStatusBarEntryDto): Promise<void> {
|
||||
const statusBarEntry = {
|
||||
...rawStatusBarEntry,
|
||||
...{ cellResource: URI.revive(rawStatusBarEntry.cellResource) }
|
||||
};
|
||||
|
||||
const existingEntry = this._cellStatusBarEntries.get(id);
|
||||
if (existingEntry) {
|
||||
existingEntry.dispose();
|
||||
}
|
||||
|
||||
if (statusBarEntry.visible) {
|
||||
this._cellStatusBarEntries.set(
|
||||
id,
|
||||
this.cellStatusBarService.addEntry(statusBarEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class MainThreadNotebookKernel implements INotebookKernelInfo {
|
||||
|
||||
@@ -992,6 +992,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
createConcatTextDocument(notebook, selector) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return new ExtHostNotebookConcatDocument(extHostNotebook, extHostDocuments, notebook, selector);
|
||||
},
|
||||
createCellStatusBarItem(cell: vscode.NotebookCell, alignment?: vscode.NotebookCellStatusBarAlignment, priority?: number): vscode.NotebookCellStatusBarItem {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.createNotebookCellStatusBarItemInternal(cell, alignment, priority);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1126,7 +1130,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
CellKind: extHostTypes.CellKind,
|
||||
CellOutputKind: extHostTypes.CellOutputKind,
|
||||
NotebookCellRunState: extHostTypes.NotebookCellRunState,
|
||||
NotebookRunState: extHostTypes.NotebookRunState
|
||||
NotebookRunState: extHostTypes.NotebookRunState,
|
||||
NotebookCellStatusBarAlignment: extHostTypes.NotebookCellStatusBarAlignment
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
|
||||
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
|
||||
import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { IProcessedOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent, NotebookDataDto, INotebookKernelInfoDto, IMainCellDto, INotebookDocumentFilter, INotebookKernelInfoDto2, TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IProcessedOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent, NotebookDataDto, INotebookKernelInfoDto, IMainCellDto, INotebookDocumentFilter, INotebookKernelInfoDto2, TransientMetadata, INotebookCellStatusBarEntry } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
import { Dto } from 'vs/base/common/types';
|
||||
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||
@@ -719,6 +719,8 @@ export type NotebookCellOutputsSplice = [
|
||||
IProcessedOutput[]
|
||||
];
|
||||
|
||||
export type INotebookCellStatusBarEntryDto = Dto<INotebookCellStatusBarEntry>;
|
||||
|
||||
export interface MainThreadNotebookShape extends IDisposable {
|
||||
$registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, supportBackup: boolean, kernelInfoDto: INotebookKernelInfoDto | undefined, options: { transientOutputs: boolean; transientMetadata: TransientMetadata }): Promise<void>;
|
||||
$onNotebookChange(viewType: string, resource: UriComponents): Promise<void>;
|
||||
@@ -734,6 +736,7 @@ export interface MainThreadNotebookShape extends IDisposable {
|
||||
$updateNotebookCellMetadata(viewType: string, resource: UriComponents, handle: number, metadata: NotebookCellMetadata | undefined): Promise<void>;
|
||||
$spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[]): Promise<void>;
|
||||
$postMessage(editorId: string, forRendererId: string | undefined, value: any): Promise<boolean>;
|
||||
$setStatusBarEntry(id: number, statusBarEntry: INotebookCellStatusBarEntryDto): Promise<void>;
|
||||
|
||||
$onDidEdit(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
|
||||
$onContentChange(resource: UriComponents, viewType: string): void;
|
||||
|
||||
@@ -14,15 +14,15 @@ import { ISplice } from 'vs/base/common/sequence';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import * as UUID from 'vs/base/common/uuid';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { CellKind, ExtHostNotebookShape, IMainContext, IModelAddedData, INotebookDocumentsAndEditorsDelta, INotebookEditorPropertiesChangeData, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { CellKind, ExtHostNotebookShape, ICommandDto, IMainContext, IModelAddedData, INotebookDocumentsAndEditorsDelta, INotebookEditorPropertiesChangeData, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { ExtHostDocumentsAndEditors, IExtHostModelAddedData } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
|
||||
import { CellEditType, CellOutputKind, diff, ICellDeleteEdit, ICellDto2, ICellEditOperation, ICellInsertEdit, IMainCellDto, INotebookDisplayOrder, INotebookEditData, INotebookKernelInfoDto2, IProcessedOutput, IRawOutput, NotebookCellMetadata, NotebookCellsChangedEvent, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellEditType, CellOutputKind, CellStatusbarAlignment, CellUri, diff, ICellDeleteEdit, ICellDto2, ICellEditOperation, ICellInsertEdit, IMainCellDto, INotebookCellStatusBarEntry, INotebookDisplayOrder, INotebookEditData, INotebookKernelInfoDto2, IProcessedOutput, IRawOutput, NotebookCellMetadata, NotebookCellsChangedEvent, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import * as vscode from 'vscode';
|
||||
import { Cache } from './cache';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
@@ -72,6 +72,9 @@ export class ExtHostCell extends Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
private _onDidDispose = new Emitter<void>();
|
||||
readonly onDidDispose: Event<void> = this._onDidDispose.event;
|
||||
|
||||
private _onDidChangeOutputs = new Emitter<ISplice<IProcessedOutput>[]>();
|
||||
readonly onDidChangeOutputs: Event<ISplice<IProcessedOutput>[]> = this._onDidChangeOutputs.event;
|
||||
|
||||
@@ -134,6 +137,11 @@ export class ExtHostCell extends Disposable {
|
||||
return this._cell;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
super.dispose();
|
||||
this._onDidDispose.fire();
|
||||
}
|
||||
|
||||
private _updateOutputs(newOutputs: vscode.CellOutput[]) {
|
||||
const rawDiffs = diff<vscode.CellOutput>(this._outputs || [], newOutputs || [], (a) => {
|
||||
return this._outputMapping.has(a);
|
||||
@@ -345,7 +353,9 @@ export class ExtHostNotebookDocument extends Disposable {
|
||||
}
|
||||
|
||||
if (!this._cellDisposableMapping.has(extCell.handle)) {
|
||||
this._cellDisposableMapping.set(extCell.handle, new DisposableStore());
|
||||
const store = new DisposableStore();
|
||||
store.add(extCell);
|
||||
this._cellDisposableMapping.set(extCell.handle, store);
|
||||
}
|
||||
|
||||
const store = this._cellDisposableMapping.get(extCell.handle)!;
|
||||
@@ -880,6 +890,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
private readonly _unInitializedDocuments = new ResourceMap<ExtHostNotebookDocument>();
|
||||
private readonly _editors = new Map<string, { editor: ExtHostNotebookEditor; }>();
|
||||
private readonly _webviewComm = new Map<string, ExtHostWebviewCommWrapper>();
|
||||
private readonly _commandsConverter: CommandsConverter;
|
||||
private readonly _onDidChangeNotebookCells = new Emitter<vscode.NotebookCellsChangeEvent>();
|
||||
readonly onDidChangeNotebookCells = this._onDidChangeNotebookCells.event;
|
||||
private readonly _onDidChangeCellOutputs = new Emitter<vscode.NotebookCellOutputsChangeEvent>();
|
||||
@@ -928,6 +939,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
private readonly _extensionStoragePaths: IExtensionStoragePaths,
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadNotebook);
|
||||
this._commandsConverter = commands.converter;
|
||||
|
||||
commands.registerArgumentProcessor({
|
||||
// Serialized INotebookCellActionContext
|
||||
@@ -1542,6 +1554,24 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
this._onDidChangeActiveNotebookEditor.fire(this._activeNotebookEditor);
|
||||
}
|
||||
}
|
||||
|
||||
createNotebookCellStatusBarItemInternal(cell: vscode.NotebookCell, alignment: extHostTypes.NotebookCellStatusBarAlignment | undefined, priority: number | undefined) {
|
||||
const statusBarItem = new NotebookCellStatusBarItemInternal(this._proxy, this._commandsConverter, cell, alignment, priority);
|
||||
|
||||
// Look up the ExtHostCell for this NotebookCell URI, bind to its disposable lifecycle
|
||||
const parsedUri = CellUri.parse(cell.uri);
|
||||
if (parsedUri) {
|
||||
const document = this._documents.get(parsedUri.notebook);
|
||||
if (document) {
|
||||
const cell = document.getCell(parsedUri.handle);
|
||||
if (cell) {
|
||||
Event.once(cell.onDidDispose)(() => statusBarItem.dispose());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return statusBarItem;
|
||||
}
|
||||
}
|
||||
|
||||
function hashPath(resource: URI): string {
|
||||
@@ -1553,3 +1583,178 @@ function isEditEvent(e: vscode.NotebookDocumentEditEvent | vscode.NotebookDocume
|
||||
return typeof (e as vscode.NotebookDocumentEditEvent).undo === 'function'
|
||||
&& typeof (e as vscode.NotebookDocumentEditEvent).redo === 'function';
|
||||
}
|
||||
|
||||
export class NotebookCellStatusBarItemInternal extends Disposable {
|
||||
private static NEXT_ID = 0;
|
||||
|
||||
private readonly _id = NotebookCellStatusBarItemInternal.NEXT_ID++;
|
||||
private readonly _internalCommandRegistration: DisposableStore;
|
||||
|
||||
private _isDisposed = false;
|
||||
private _alignment: extHostTypes.NotebookCellStatusBarAlignment;
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: MainThreadNotebookShape,
|
||||
private readonly _commands: CommandsConverter,
|
||||
private readonly _cell: vscode.NotebookCell,
|
||||
alignment: extHostTypes.NotebookCellStatusBarAlignment | undefined,
|
||||
private _priority: number | undefined) {
|
||||
super();
|
||||
this._internalCommandRegistration = this._register(new DisposableStore());
|
||||
this._alignment = alignment ?? extHostTypes.NotebookCellStatusBarAlignment.Left;
|
||||
}
|
||||
|
||||
private _apiItem: vscode.NotebookCellStatusBarItem | undefined;
|
||||
get apiItem(): vscode.NotebookCellStatusBarItem {
|
||||
if (!this._apiItem) {
|
||||
this._apiItem = createNotebookCellStatusBarApiItem(this);
|
||||
}
|
||||
|
||||
return this._apiItem;
|
||||
}
|
||||
|
||||
get cell(): vscode.NotebookCell {
|
||||
return this._cell;
|
||||
}
|
||||
|
||||
get alignment(): extHostTypes.NotebookCellStatusBarAlignment {
|
||||
return this._alignment;
|
||||
}
|
||||
|
||||
set alignment(v: extHostTypes.NotebookCellStatusBarAlignment) {
|
||||
this._alignment = v;
|
||||
this.update();
|
||||
}
|
||||
|
||||
get priority(): number | undefined {
|
||||
return this._priority;
|
||||
}
|
||||
|
||||
set priority(v: number | undefined) {
|
||||
this._priority = v;
|
||||
this.update();
|
||||
}
|
||||
|
||||
private _text: string = '';
|
||||
get text(): string {
|
||||
return this._text;
|
||||
}
|
||||
|
||||
set text(v: string) {
|
||||
this._text = v;
|
||||
this.update();
|
||||
}
|
||||
|
||||
private _tooltip: string | undefined;
|
||||
get tooltip(): string | undefined {
|
||||
return this._tooltip;
|
||||
}
|
||||
|
||||
set tooltip(v: string | undefined) {
|
||||
this._tooltip = v;
|
||||
this.update();
|
||||
}
|
||||
|
||||
private _command?: {
|
||||
readonly fromApi: string | vscode.Command,
|
||||
readonly internal: ICommandDto,
|
||||
};
|
||||
get command(): string | vscode.Command | undefined {
|
||||
return this._command?.fromApi;
|
||||
}
|
||||
|
||||
set command(command: string | vscode.Command | undefined) {
|
||||
if (this._command?.fromApi === command) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._internalCommandRegistration.clear();
|
||||
if (typeof command === 'string') {
|
||||
this._command = {
|
||||
fromApi: command,
|
||||
internal: this._commands.toInternal({ title: '', command }, this._internalCommandRegistration),
|
||||
};
|
||||
} else if (command) {
|
||||
this._command = {
|
||||
fromApi: command,
|
||||
internal: this._commands.toInternal(command, this._internalCommandRegistration),
|
||||
};
|
||||
} else {
|
||||
this._command = undefined;
|
||||
}
|
||||
this.update();
|
||||
}
|
||||
|
||||
private _accessibilityInformation: vscode.AccessibilityInformation | undefined;
|
||||
get accessibilityInformation(): vscode.AccessibilityInformation | undefined {
|
||||
return this._accessibilityInformation;
|
||||
}
|
||||
|
||||
set accessibilityInformation(v: vscode.AccessibilityInformation | undefined) {
|
||||
this._accessibilityInformation = v;
|
||||
this.update();
|
||||
}
|
||||
|
||||
private _visible: boolean = false;
|
||||
show(): void {
|
||||
this._visible = true;
|
||||
this.update();
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
this._visible = false;
|
||||
this.update();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.hide();
|
||||
this._isDisposed = true;
|
||||
this._internalCommandRegistration.dispose();
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entry: INotebookCellStatusBarEntry = {
|
||||
alignment: this.alignment === extHostTypes.NotebookCellStatusBarAlignment.Left ? CellStatusbarAlignment.LEFT : CellStatusbarAlignment.RIGHT,
|
||||
cellResource: this.cell.uri,
|
||||
command: this._command?.internal,
|
||||
text: this.text,
|
||||
tooltip: this.tooltip,
|
||||
accessibilityInformation: this.accessibilityInformation,
|
||||
priority: this.priority,
|
||||
visible: this._visible
|
||||
};
|
||||
|
||||
this._proxy.$setStatusBarEntry(this._id, entry);
|
||||
}
|
||||
}
|
||||
|
||||
function createNotebookCellStatusBarApiItem(internalItem: NotebookCellStatusBarItemInternal): vscode.NotebookCellStatusBarItem {
|
||||
return Object.freeze({
|
||||
cell: internalItem.cell,
|
||||
get alignment() { return internalItem.alignment; },
|
||||
set alignment(v: NotebookCellStatusBarItemInternal['alignment']) { internalItem.alignment = v; },
|
||||
|
||||
get priority() { return internalItem.priority; },
|
||||
set priority(v: NotebookCellStatusBarItemInternal['priority']) { internalItem.priority = v; },
|
||||
|
||||
get text() { return internalItem.text; },
|
||||
set text(v: NotebookCellStatusBarItemInternal['text']) { internalItem.text = v; },
|
||||
|
||||
get tooltip() { return internalItem.tooltip; },
|
||||
set tooltip(v: NotebookCellStatusBarItemInternal['tooltip']) { internalItem.tooltip = v; },
|
||||
|
||||
get command() { return internalItem.command; },
|
||||
set command(v: NotebookCellStatusBarItemInternal['command']) { internalItem.command = v; },
|
||||
|
||||
get accessibilityInformation() { return internalItem.accessibilityInformation; },
|
||||
set accessibilityInformation(v: NotebookCellStatusBarItemInternal['accessibilityInformation']) { internalItem.accessibilityInformation = v; },
|
||||
|
||||
show() { internalItem.show(); },
|
||||
hide() { internalItem.hide(); },
|
||||
dispose() { internalItem.dispose(); }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2757,6 +2757,12 @@ export enum NotebookRunState {
|
||||
Idle = 2
|
||||
}
|
||||
|
||||
export enum NotebookCellStatusBarAlignment {
|
||||
Left = 1,
|
||||
Right = 2
|
||||
}
|
||||
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Timeline
|
||||
|
||||
@@ -362,11 +362,29 @@
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-status-right {
|
||||
padding-right: 12px;
|
||||
z-index: 26;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-status-right .cell-contributed-items-right {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: pre;
|
||||
|
||||
height: 21px; /* Editor outline is -1px in, don't overlap */
|
||||
padding: 0px 6px;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-status-item.cell-status-item-has-command {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-language-picker {
|
||||
height: 21px; /* Editor outline is -1px in, don't overlap */
|
||||
padding: 0px 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -380,6 +398,10 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-status-message {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-run-status {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
@@ -46,6 +46,8 @@ import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/n
|
||||
import { NotebookTextDiffEditor } from 'vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor';
|
||||
import { INotebookEditorWorkerService } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerService';
|
||||
import { NotebookEditorWorkerServiceImpl } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerServiceImpl';
|
||||
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
|
||||
import { NotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/browser/notebookCellStatusBarServiceImpl';
|
||||
|
||||
// Editor Contribution
|
||||
|
||||
@@ -445,6 +447,7 @@ workbenchContributionsRegistry.registerWorkbenchContribution(CellContentProvider
|
||||
registerSingleton(INotebookService, NotebookService);
|
||||
registerSingleton(INotebookEditorWorkerService, NotebookEditorWorkerServiceImpl);
|
||||
registerSingleton(INotebookEditorModelResolverService, NotebookModelResolverService, true);
|
||||
registerSingleton(INotebookCellStatusBarService, NotebookCellStatusBarService, true);
|
||||
|
||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
|
||||
@@ -27,10 +27,10 @@ import { Webview } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { IMenu } from 'vs/platform/actions/common/actions';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { CellLanguageStatusBarItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/commonViewComponents';
|
||||
import { EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CellEditorStatusBar } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
|
||||
export const KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED = new RawContextKey<boolean>('notebookFindWidgetFocused', false);
|
||||
|
||||
@@ -525,8 +525,7 @@ export interface BaseCellRenderTemplate {
|
||||
elementDisposables: DisposableStore;
|
||||
bottomCellContainer: HTMLElement;
|
||||
currentRenderedCell?: ICellViewModel;
|
||||
statusBarContainer: HTMLElement;
|
||||
languageStatusBarItem: CellLanguageStatusBarItem;
|
||||
statusBar: CellEditorStatusBar;
|
||||
titleMenu: IMenu;
|
||||
toJSON: () => object;
|
||||
}
|
||||
@@ -539,7 +538,6 @@ export interface MarkdownCellRenderTemplate extends BaseCellRenderTemplate {
|
||||
|
||||
export interface CodeCellRenderTemplate extends BaseCellRenderTemplate {
|
||||
cellRunState: RunStateRenderer;
|
||||
cellStatusMessageContainer: HTMLElement;
|
||||
runToolbar: ToolBar;
|
||||
runButtonContainer: HTMLElement;
|
||||
executionOrderLabel: HTMLElement;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
|
||||
import { INotebookCellStatusBarEntry } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
export class NotebookCellStatusBarService extends Disposable implements INotebookCellStatusBarService {
|
||||
|
||||
private _onDidChangeEntriesForCell = new Emitter<URI>();
|
||||
readonly onDidChangeEntriesForCell: Event<URI> = this._onDidChangeEntriesForCell.event;
|
||||
|
||||
private _entries = new ResourceMap<Set<INotebookCellStatusBarEntry>>();
|
||||
|
||||
private removeEntry(entry: INotebookCellStatusBarEntry) {
|
||||
const existingEntries = this._entries.get(entry.cellResource);
|
||||
if (existingEntries) {
|
||||
existingEntries.delete(entry);
|
||||
if (!existingEntries.size) {
|
||||
this._entries.delete(entry.cellResource);
|
||||
}
|
||||
}
|
||||
|
||||
this._onDidChangeEntriesForCell.fire(entry.cellResource);
|
||||
}
|
||||
|
||||
addEntry(entry: INotebookCellStatusBarEntry): IDisposable {
|
||||
const existingEntries = this._entries.get(entry.cellResource) ?? new Set();
|
||||
existingEntries.add(entry);
|
||||
this._entries.set(entry.cellResource, existingEntries);
|
||||
|
||||
this._onDidChangeEntriesForCell.fire(entry.cellResource);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
this.removeEntry(entry);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getEntries(cell: URI): INotebookCellStatusBarEntry[] {
|
||||
const existingEntries = this._entries.get(cell);
|
||||
return existingEntries ?
|
||||
Array.from(existingEntries.values()) :
|
||||
[];
|
||||
}
|
||||
|
||||
readonly _serviceBrand: undefined;
|
||||
}
|
||||
@@ -1928,7 +1928,8 @@ registerThemingParticipant((theme, collector) => {
|
||||
|
||||
const cellStatusBarHoverBg = theme.getColor(cellStatusBarItemHover);
|
||||
if (cellStatusBarHoverBg) {
|
||||
collector.addRule(`.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-language-picker:hover { background-color: ${cellStatusBarHoverBg}; }`);
|
||||
collector.addRule(`.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-language-picker:hover,
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-container .cell-status-item.cell-status-item-has-command:hover { background-color: ${cellStatusBarHoverBg}; }`);
|
||||
}
|
||||
|
||||
const cellInsertionIndicatorColor = theme.getColor(cellInsertionIndicator);
|
||||
|
||||
@@ -40,15 +40,16 @@ import { CancelCellAction, DeleteCellAction, ExecuteCellAction, INotebookCellAct
|
||||
import { BaseCellRenderTemplate, CellEditState, CodeCellRenderTemplate, EXPAND_CELL_CONTENT_COMMAND_ID, ICellViewModel, INotebookEditor, isCodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys';
|
||||
import { CellMenus } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellMenus';
|
||||
import { CellEditorStatusBar } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { CodeCell } from 'vs/workbench/contrib/notebook/browser/view/renderers/codeCell';
|
||||
import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/commonViewComponents';
|
||||
import { CellDragAndDropController, DRAGGING_CLASS } from 'vs/workbench/contrib/notebook/browser/view/renderers/dnd';
|
||||
import { StatefulMarkdownCell } from 'vs/workbench/contrib/notebook/browser/view/renderers/markdownCell';
|
||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
|
||||
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { CellKind, NotebookCellMetadata, NotebookCellRunState, ShowCellStatusbarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { createAndFillInActionBarActionsWithVerticalSeparators, VerticalSeparator, VerticalSeparatorViewItem } from './cellActionView';
|
||||
import { CodiconActionViewItem, CellLanguageStatusBarItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/commonViewComponents';
|
||||
import { CellDragAndDropController, DRAGGING_CLASS } from 'vs/workbench/contrib/notebook/browser/view/renderers/dnd';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -403,7 +404,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
|
||||
const bottomCellContainer = DOM.append(container, $('.cell-bottom-toolbar-container'));
|
||||
const betweenCellToolbar = disposables.add(this.createBetweenCellToolbar(bottomCellContainer, disposables, contextKeyService));
|
||||
|
||||
const statusBar = this.instantiationService.createInstance(CellEditorStatusBar, editorPart);
|
||||
const statusBar = disposables.add(this.instantiationService.createInstance(CellEditorStatusBar, editorPart));
|
||||
const titleMenu = disposables.add(this.cellMenus.getCellTitleMenu(contextKeyService));
|
||||
|
||||
const templateData: MarkdownCellRenderTemplate = {
|
||||
@@ -422,9 +423,8 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
|
||||
deleteToolbar,
|
||||
betweenCellToolbar,
|
||||
bottomCellContainer,
|
||||
statusBarContainer: statusBar.statusBarContainer,
|
||||
languageStatusBarItem: statusBar.languageStatusBarItem,
|
||||
titleMenu,
|
||||
statusBar,
|
||||
toJSON: () => { return {}; }
|
||||
};
|
||||
this.dndController.registerDragHandle(templateData, rootContainer, container, () => this.getDragImage(templateData));
|
||||
@@ -493,7 +493,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
|
||||
elementDisposables.add(this.editorOptions.onDidChange(newValue => markdownCell.updateEditorOptions(newValue)));
|
||||
elementDisposables.add(markdownCell);
|
||||
|
||||
templateData.languageStatusBarItem.update(element, this.notebookEditor);
|
||||
templateData.statusBar.update(toolbarContext);
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: MarkdownCellRenderTemplate): void {
|
||||
@@ -605,27 +605,6 @@ class CodeCellDragImageRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
class CellEditorStatusBar {
|
||||
readonly cellStatusMessageContainer: HTMLElement;
|
||||
readonly cellRunStatusContainer: HTMLElement;
|
||||
readonly statusBarContainer: HTMLElement;
|
||||
readonly languageStatusBarItem: CellLanguageStatusBarItem;
|
||||
readonly durationContainer: HTMLElement;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
) {
|
||||
this.statusBarContainer = DOM.append(container, $('.cell-statusbar-container'));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
export class CodeCellRenderer extends AbstractCellRenderer implements IListRenderer<CodeCellViewModel, CodeCellRenderTemplate> {
|
||||
static readonly TEMPLATE_ID = 'code_cell';
|
||||
|
||||
@@ -692,7 +671,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
||||
progressBar.hide();
|
||||
disposables.add(progressBar);
|
||||
|
||||
const statusBar = this.instantiationService.createInstance(CellEditorStatusBar, editorPart);
|
||||
const statusBar = disposables.add(this.instantiationService.createInstance(CellEditorStatusBar, editorPart));
|
||||
const timer = new TimerRenderer(statusBar.durationContainer);
|
||||
const cellRunState = new RunStateRenderer(statusBar.cellRunStatusContainer, runToolbar, this.instantiationService);
|
||||
|
||||
@@ -715,11 +694,9 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
||||
contextKeyService,
|
||||
container,
|
||||
cellContainer,
|
||||
statusBarContainer: statusBar.statusBarContainer,
|
||||
cellRunState,
|
||||
cellStatusMessageContainer: statusBar.cellStatusMessageContainer,
|
||||
languageStatusBarItem: statusBar.languageStatusBarItem,
|
||||
progressBar,
|
||||
statusBar,
|
||||
focusIndicatorLeft: focusIndicator,
|
||||
focusIndicatorRight,
|
||||
focusIndicatorBottom,
|
||||
@@ -766,7 +743,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
||||
const metadata = element.getEvaluatedMetadata(this.notebookEditor.viewModel!.notebookDocument.metadata);
|
||||
DOM.toggleClass(templateData.container, 'runnable', !!metadata.runnable);
|
||||
this.updateExecutionOrder(metadata, templateData);
|
||||
templateData.cellStatusMessageContainer.textContent = metadata?.statusMessage || '';
|
||||
templateData.statusBar.cellStatusMessageContainer.textContent = metadata?.statusMessage || '';
|
||||
|
||||
templateData.cellRunState.renderState(element.metadata?.runState);
|
||||
|
||||
@@ -880,7 +857,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
||||
|
||||
this.setBetweenCellToolbarContext(templateData, element, toolbarContext);
|
||||
|
||||
templateData.languageStatusBarItem.update(element, this.notebookEditor);
|
||||
templateData.statusBar.update(toolbarContext);
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: CodeCellRenderTemplate): void {
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
|
||||
import { WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from 'vs/base/common/actions';
|
||||
import { stripCodicons } from 'vs/base/common/codicons';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { extUri } from 'vs/base/common/resources';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ChangeCellLanguageAction, INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { ICellViewModel, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
|
||||
import { CellKind, CellStatusbarAlignment, INotebookCellStatusBarEntry } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
export class CellEditorStatusBar extends Disposable {
|
||||
readonly cellStatusMessageContainer: HTMLElement;
|
||||
readonly cellRunStatusContainer: HTMLElement;
|
||||
readonly statusBarContainer: HTMLElement;
|
||||
readonly languageStatusBarItem: CellLanguageStatusBarItem;
|
||||
readonly durationContainer: HTMLElement;
|
||||
|
||||
private readonly leftContributedItemsContainer: HTMLElement;
|
||||
private readonly rightContributedItemsContainer: HTMLElement;
|
||||
private readonly itemsDisposable: DisposableStore;
|
||||
|
||||
private currentContext: INotebookCellActionContext | undefined;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@INotebookCellStatusBarService private readonly notebookCellStatusBarService: INotebookCellStatusBarService
|
||||
) {
|
||||
super();
|
||||
this.statusBarContainer = DOM.append(container, $('.cell-statusbar-container'));
|
||||
const leftItemsContainer = DOM.append(this.statusBarContainer, $('.cell-status-left'));
|
||||
const rightItemsContainer = DOM.append(this.statusBarContainer, $('.cell-status-right'));
|
||||
this.cellRunStatusContainer = DOM.append(leftItemsContainer, $('.cell-run-status'));
|
||||
this.durationContainer = DOM.append(leftItemsContainer, $('.cell-run-duration'));
|
||||
this.cellStatusMessageContainer = DOM.append(leftItemsContainer, $('.cell-status-message'));
|
||||
this.leftContributedItemsContainer = DOM.append(leftItemsContainer, $('.cell-contributed-items-left'));
|
||||
this.rightContributedItemsContainer = DOM.append(rightItemsContainer, $('.cell-contributed-items-right'));
|
||||
this.languageStatusBarItem = instantiationService.createInstance(CellLanguageStatusBarItem, rightItemsContainer);
|
||||
|
||||
this.itemsDisposable = this._register(new DisposableStore());
|
||||
this._register(this.notebookCellStatusBarService.onDidChangeEntriesForCell(e => {
|
||||
if (this.currentContext && extUri.isEqual(e, this.currentContext.cell.uri)) {
|
||||
this.updateStatusBarItems();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
update(context: INotebookCellActionContext) {
|
||||
this.currentContext = context;
|
||||
this.languageStatusBarItem.update(context.cell, context.notebookEditor);
|
||||
this.updateStatusBarItems();
|
||||
}
|
||||
|
||||
layout(width: number): void {
|
||||
this.statusBarContainer.style.width = `${width}px`;
|
||||
}
|
||||
|
||||
private updateStatusBarItems() {
|
||||
if (!this.currentContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.leftContributedItemsContainer.innerHTML = '';
|
||||
this.rightContributedItemsContainer.innerHTML = '';
|
||||
this.itemsDisposable.clear();
|
||||
|
||||
const items = this.notebookCellStatusBarService.getEntries(this.currentContext.cell.uri);
|
||||
items.sort((itemA, itemB) => {
|
||||
return (itemB.priority ?? 0) - (itemA.priority ?? 0);
|
||||
});
|
||||
items.forEach(item => {
|
||||
const itemView = this.itemsDisposable.add(this.instantiationService.createInstance(CellStatusBarItem, this.currentContext!, item));
|
||||
if (item.alignment === CellStatusbarAlignment.LEFT) {
|
||||
this.leftContributedItemsContainer.appendChild(itemView.container);
|
||||
} else {
|
||||
this.rightContributedItemsContainer.appendChild(itemView.container);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class CellStatusBarItem extends Disposable {
|
||||
|
||||
readonly container = $('.cell-status-item');
|
||||
|
||||
constructor(
|
||||
private readonly _context: INotebookCellActionContext,
|
||||
private readonly _itemModel: INotebookCellStatusBarEntry,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
new CodiconLabel(this.container).text = this._itemModel.text;
|
||||
|
||||
let ariaLabel: string;
|
||||
let role: string | undefined;
|
||||
if (this._itemModel.accessibilityInformation) {
|
||||
ariaLabel = this._itemModel.accessibilityInformation.label;
|
||||
role = this._itemModel.accessibilityInformation.role;
|
||||
} else {
|
||||
ariaLabel = this._itemModel.text ? stripCodicons(this._itemModel.text).trim() : '';
|
||||
}
|
||||
|
||||
if (ariaLabel) {
|
||||
this.container.setAttribute('aria-label', ariaLabel);
|
||||
}
|
||||
|
||||
if (role) {
|
||||
this.container.setAttribute('role', role);
|
||||
}
|
||||
|
||||
this.container.title = this._itemModel.tooltip ?? '';
|
||||
|
||||
if (this._itemModel.command) {
|
||||
this.container.classList.add('cell-status-item-has-command');
|
||||
this.container.tabIndex = 0;
|
||||
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.CLICK, _e => {
|
||||
this.executeCommand();
|
||||
}));
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_UP, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.Space) || event.equals(KeyCode.Enter)) {
|
||||
this.executeCommand();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private async executeCommand(): Promise<void> {
|
||||
const command = this._itemModel.command;
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
|
||||
const id = typeof command === 'string' ? command : command.id;
|
||||
const args = typeof command === 'string' ? [] : command.arguments ?? [];
|
||||
|
||||
args.unshift(this._context);
|
||||
|
||||
this.telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', { id, from: 'cell status bar' });
|
||||
try {
|
||||
await this.commandService.executeCommand(id, ...args);
|
||||
} catch (error) {
|
||||
this.notificationService.error(toErrorMessage(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class CellLanguageStatusBarItem extends Disposable {
|
||||
private readonly labelElement: HTMLElement;
|
||||
|
||||
private cell: ICellViewModel | undefined;
|
||||
private editor: INotebookEditor | undefined;
|
||||
|
||||
private cellDisposables: DisposableStore;
|
||||
|
||||
constructor(
|
||||
readonly container: HTMLElement,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
this.labelElement = DOM.append(container, $('.cell-language-picker.cell-status-item'));
|
||||
this.labelElement.tabIndex = 0;
|
||||
|
||||
this._register(DOM.addDisposableListener(this.labelElement, DOM.EventType.CLICK, () => {
|
||||
this.run();
|
||||
}));
|
||||
this._register(DOM.addDisposableListener(this.labelElement, DOM.EventType.KEY_UP, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.Space) || event.equals(KeyCode.Enter)) {
|
||||
this.run();
|
||||
}
|
||||
}));
|
||||
this._register(this.cellDisposables = new DisposableStore());
|
||||
}
|
||||
|
||||
private run() {
|
||||
this.instantiationService.invokeFunction(accessor => {
|
||||
new ChangeCellLanguageAction().run(accessor, { notebookEditor: this.editor!, cell: this.cell! });
|
||||
});
|
||||
}
|
||||
|
||||
update(cell: ICellViewModel, editor: INotebookEditor): void {
|
||||
this.cellDisposables.clear();
|
||||
this.cell = cell;
|
||||
this.editor = editor;
|
||||
|
||||
this.render();
|
||||
this.cellDisposables.add(this.cell.model.onDidChangeLanguage(() => this.render()));
|
||||
}
|
||||
|
||||
private render(): void {
|
||||
const modeId = this.cell?.cellKind === CellKind.Markdown ? 'markdown' : this.modeService.getModeIdForLanguageName(this.cell!.language) || this.cell!.language;
|
||||
this.labelElement.textContent = this.modeService.getLanguageName(modeId) || this.modeService.getLanguageName('plaintext');
|
||||
this.labelElement.title = localize('notebook.cell.status.language', "Select Cell Language Mode");
|
||||
}
|
||||
}
|
||||
@@ -401,7 +401,7 @@ export class CodeCell extends Disposable {
|
||||
|
||||
private layoutEditor(dimension: IDimension): void {
|
||||
this.templateData.editor?.layout(dimension);
|
||||
this.templateData.statusBarContainer.style.width = `${dimension.width}px`;
|
||||
this.templateData.statusBar.layout(dimension.width);
|
||||
}
|
||||
|
||||
private onCellWidthChange(): void {
|
||||
|
||||
@@ -3,22 +3,12 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { renderCodicons } from 'vs/base/common/codicons';
|
||||
import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { renderCodicons } from 'vs/base/common/codicons';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ICellViewModel, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ChangeCellLanguageAction } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
export class CodiconActionViewItem extends MenuEntryActionViewItem {
|
||||
constructor(
|
||||
@@ -35,45 +25,3 @@ export class CodiconActionViewItem extends MenuEntryActionViewItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class CellLanguageStatusBarItem extends Disposable {
|
||||
private readonly labelElement: HTMLElement;
|
||||
|
||||
private cell: ICellViewModel | undefined;
|
||||
private editor: INotebookEditor | undefined;
|
||||
|
||||
private cellDisposables: DisposableStore;
|
||||
|
||||
constructor(
|
||||
readonly container: HTMLElement,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
this.labelElement = DOM.append(container, $('.cell-language-picker'));
|
||||
this.labelElement.tabIndex = 0;
|
||||
|
||||
this._register(DOM.addDisposableListener(this.labelElement, DOM.EventType.CLICK, () => {
|
||||
this.instantiationService.invokeFunction(accessor => {
|
||||
new ChangeCellLanguageAction().run(accessor, { notebookEditor: this.editor!, cell: this.cell! });
|
||||
});
|
||||
}));
|
||||
this._register(this.cellDisposables = new DisposableStore());
|
||||
}
|
||||
|
||||
update(cell: ICellViewModel, editor: INotebookEditor): void {
|
||||
this.cellDisposables.clear();
|
||||
this.cell = cell;
|
||||
this.editor = editor;
|
||||
|
||||
this.render();
|
||||
this.cellDisposables.add(this.cell.model.onDidChangeLanguage(() => this.render()));
|
||||
}
|
||||
|
||||
private render(): void {
|
||||
const modeId = this.cell?.cellKind === CellKind.Markdown ? 'markdown' : this.modeService.getModeIdForLanguageName(this.cell!.language) || this.cell!.language;
|
||||
this.labelElement.textContent = this.modeService.getLanguageName(modeId) || this.modeService.getLanguageName('plaintext');
|
||||
this.labelElement.title = localize('notebook.cell.status.language', "Select Cell Language Mode");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
|
||||
private layoutEditor(dimension: DOM.IDimension): void {
|
||||
this.editor?.layout(dimension);
|
||||
this.templateData.statusBarContainer.style.width = `${dimension.width}px`;
|
||||
this.templateData.statusBar.layout(dimension.width);
|
||||
}
|
||||
|
||||
private onCellEditorWidthChange(): void {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotebookCellStatusBarEntry } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
export const INotebookCellStatusBarService = createDecorator<INotebookCellStatusBarService>('notebookCellStatusBarService');
|
||||
|
||||
export interface INotebookCellStatusBarService {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
onDidChangeEntriesForCell: Event<URI>;
|
||||
|
||||
addEntry(entry: INotebookCellStatusBarEntry): IDisposable;
|
||||
getEntries(cell: URI): INotebookCellStatusBarEntry[];
|
||||
}
|
||||
@@ -3,22 +3,24 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IDiffResult, ISequence } from 'vs/base/common/diff/diff';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { ISplice } from 'vs/base/common/sequence';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { Command } from 'vs/editor/common/modes';
|
||||
import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IRevertOptions } from 'vs/workbench/common/editor';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { IDiffResult, ISequence } from 'vs/base/common/diff/diff';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
|
||||
export enum CellKind {
|
||||
Markdown = 1,
|
||||
@@ -744,7 +746,6 @@ export interface INotebookKernelProvider {
|
||||
cancelNotebook(uri: URI, kernelId: string, handle: number | undefined): Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
export class CellSequence implements ISequence {
|
||||
|
||||
constructor(readonly textModel: NotebookTextModel) {
|
||||
@@ -764,6 +765,23 @@ export interface INotebookDiffResult {
|
||||
cellsDiff: IDiffResult,
|
||||
linesDiff?: { originalCellhandle: number, modifiedCellhandle: number, lineChanges: editorCommon.ILineChange[] }[];
|
||||
}
|
||||
|
||||
export interface INotebookCellStatusBarEntry {
|
||||
readonly cellResource: URI;
|
||||
readonly alignment: CellStatusbarAlignment;
|
||||
readonly priority?: number;
|
||||
readonly text: string;
|
||||
readonly tooltip: string | undefined;
|
||||
readonly command: string | Command | undefined;
|
||||
readonly accessibilityInformation?: IAccessibilityInformation;
|
||||
readonly visible: boolean;
|
||||
}
|
||||
|
||||
export const DisplayOrderKey = 'notebook.displayOrder';
|
||||
export const CellToolbarLocKey = 'notebook.cellToolbarLocation';
|
||||
export const ShowCellStatusbarKey = 'notebook.showCellStatusbar';
|
||||
|
||||
export const enum CellStatusbarAlignment {
|
||||
LEFT,
|
||||
RIGHT
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user