12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import {
- ILayoutRestorer, JupyterLab, JupyterLabPlugin
- } from '@jupyterlab/application';
- import {
- Dialog, ICommandPalette, showDialog
- } from '@jupyterlab/apputils';
- import {
- IEditorServices
- } from '@jupyterlab/codeeditor';
- import {
- IStateDB, PageConfig, URLExt, uuid
- } from '@jupyterlab/coreutils';
- import {
- IFileBrowserFactory
- } from '@jupyterlab/filebrowser';
- import {
- ILauncher
- } from '@jupyterlab/launcher';
- import {
- IMainMenu, IEditMenu, IFileMenu, IKernelMenu, IRunMenu, IViewMenu
- } from '@jupyterlab/mainmenu';
- import {
- CellTools, ICellTools, INotebookTracker, NotebookActions,
- NotebookModelFactory, NotebookPanel, NotebookTracker, NotebookWidgetFactory
- } from '@jupyterlab/notebook';
- import {
- ServiceManager
- } from '@jupyterlab/services';
- import {
- ReadonlyJSONObject
- } from '@phosphor/coreutils';
- import {
- Message, MessageLoop
- } from '@phosphor/messaging';
- import {
- Menu, Panel, Widget
- } from '@phosphor/widgets';
- /**
- * The command IDs used by the notebook plugin.
- */
- namespace CommandIDs {
- export
- const createNew = 'notebook:create-new';
- export
- const interrupt = 'notebook:interrupt-kernel';
- export
- const restart = 'notebook:restart-kernel';
- export
- const restartClear = 'notebook:restart-clear-output';
- export
- const restartRunAll = 'notebook:restart-run-all';
- export
- const reconnectToKernel = 'notebook:reconnect-to-kernel';
- export
- const changeKernel = 'notebook:change-kernel';
- export
- const createConsole = 'notebook:create-console';
- export
- const createCellView = 'notebook:create-cell-view';
- export
- const clearAllOutputs = 'notebook:clear-all-cell-outputs';
- export
- const closeAndShutdown = 'notebook:close-and-shutdown';
- export
- const trust = 'notebook:trust';
- export
- const exportToFormat = 'notebook:export-to-format';
- export
- const run = 'notebook:run-cell';
- export
- const runAndAdvance = 'notebook:run-cell-and-select-next';
- export
- const runAndInsert = 'notebook:run-cell-and-insert-below';
- export
- const runAll = 'notebook:run-all-cells';
- export
- const toCode = 'notebook:change-cell-to-code';
- export
- const toMarkdown = 'notebook:change-cell-to-markdown';
- export
- const toRaw = 'notebook:change-cell-to-raw';
- export
- const cut = 'notebook:cut-cell';
- export
- const copy = 'notebook:copy-cell';
- export
- const paste = 'notebook:paste-cell';
- export
- const moveUp = 'notebook:move-cell-up';
- export
- const moveDown = 'notebook:move-cell-down';
- export
- const clearOutputs = 'notebook:clear-cell-output';
- export
- const deleteCell = 'notebook:delete-cell';
- export
- const insertAbove = 'notebook:insert-cell-above';
- export
- const insertBelow = 'notebook:insert-cell-below';
- export
- const selectAbove = 'notebook:move-cursor-up';
- export
- const selectBelow = 'notebook:move-cursor-down';
- export
- const extendAbove = 'notebook:extend-marked-cells-above';
- export
- const extendBelow = 'notebook:extend-marked-cells-below';
- export
- const editMode = 'notebook:enter-edit-mode';
- export
- const merge = 'notebook:merge-cells';
- export
- const split = 'notebook:split-cell-at-cursor';
- export
- const commandMode = 'notebook:enter-command-mode';
- export
- const toggleAllLines = 'notebook:toggle-all-cell-line-numbers';
- export
- const undoCellAction = 'notebook:undo-cell-action';
- export
- const redoCellAction = 'notebook:redo-cell-action';
- export
- const markdown1 = 'notebook:change-cell-to-heading-1';
- export
- const markdown2 = 'notebook:change-cell-to-heading-2';
- export
- const markdown3 = 'notebook:change-cell-to-heading-3';
- export
- const markdown4 = 'notebook:change-cell-to-heading-4';
- export
- const markdown5 = 'notebook:change-cell-to-heading-5';
- export
- const markdown6 = 'notebook:change-cell-to-heading-6';
- export
- const hideCode = 'notebook:hide-cell-code';
- export
- const showCode = 'notebook:show-cell-code';
- export
- const hideAllCode = 'notebook:hide-all-cell-code';
- export
- const showAllCode = 'notebook:show-all-cell-code';
- export
- const hideOutput = 'notebook:hide-cell-outputs';
- export
- const showOutput = 'notebook:show-cell-outputs';
- export
- const hideAllOutputs = 'notebook:hide-all-cell-outputs';
- export
- const showAllOutputs = 'notebook:show-all-cell-outputs';
- }
- /**
- * The class name for the notebook icon from the default theme.
- */
- const NOTEBOOK_ICON_CLASS = 'jp-NotebookRunningIcon';
- /**
- * The name of the factory that creates notebooks.
- */
- const FACTORY = 'Notebook';
- /**
- * The allowed Export To ... formats and their human readable labels.
- */
- const EXPORT_TO_FORMATS = [
- { 'format': 'html', 'label': 'HTML' },
- { 'format': 'latex', 'label': 'LaTeX' },
- { 'format': 'markdown', 'label': 'Markdown' },
- { 'format': 'pdf', 'label': 'PDF' },
- { 'format': 'rst', 'label': 'ReStructured Text' },
- { 'format': 'script', 'label': 'Executable Script' },
- { 'format': 'slides', 'label': 'Reveal JS' }
- ];
- /**
- * The notebook widget tracker provider.
- */
- const tracker: JupyterLabPlugin<INotebookTracker> = {
- id: '@jupyterlab/notebook-extension:tracker',
- provides: INotebookTracker,
- requires: [
- IMainMenu,
- ICommandPalette,
- NotebookPanel.IContentFactory,
- IEditorServices,
- ILayoutRestorer
- ],
- optional: [IFileBrowserFactory, ILauncher],
- activate: activateNotebookHandler,
- autoStart: true
- };
- /**
- * The notebook cell factory provider.
- */
- const factory: JupyterLabPlugin<NotebookPanel.IContentFactory> = {
- id: '@jupyterlab/notebook-extension:factory',
- provides: NotebookPanel.IContentFactory,
- requires: [IEditorServices],
- autoStart: true,
- activate: (app: JupyterLab, editorServices: IEditorServices) => {
- let editorFactory = editorServices.factoryService.newInlineEditor.bind(
- editorServices.factoryService);
- return new NotebookPanel.ContentFactory({ editorFactory });
- }
- };
- /**
- * The cell tools extension.
- */
- const tools: JupyterLabPlugin<ICellTools> = {
- activate: activateCellTools,
- provides: ICellTools,
- id: '@jupyterlab/notebook-extension:tools',
- autoStart: true,
- requires: [INotebookTracker, IEditorServices, IStateDB]
- };
- /**
- * Export the plugins as default.
- */
- const plugins: JupyterLabPlugin<any>[] = [factory, tracker, tools];
- export default plugins;
- /**
- * Activate the cell tools extension.
- */
- function activateCellTools(app: JupyterLab, tracker: INotebookTracker, editorServices: IEditorServices, state: IStateDB): Promise<ICellTools> {
- const id = 'cell-tools';
- const celltools = new CellTools({ tracker });
- const activeCellTool = new CellTools.ActiveCellTool();
- const slideShow = CellTools.createSlideShowSelector();
- const nbConvert = CellTools.createNBConvertSelector();
- const editorFactory = editorServices.factoryService.newInlineEditor
- .bind(editorServices.factoryService);
- const metadataEditor = new CellTools.MetadataEditorTool({ editorFactory });
- // Create message hook for triggers to save to the database.
- const hook = (sender: any, message: Message): boolean => {
- switch (message) {
- case Widget.Msg.ActivateRequest:
- state.save(id, { open: true });
- break;
- case Widget.Msg.AfterHide:
- case Widget.Msg.CloseRequest:
- state.remove(id);
- break;
- default:
- break;
- }
- return true;
- };
- celltools.title.label = 'Cell Tools';
- celltools.id = id;
- celltools.addItem({ tool: activeCellTool, rank: 1 });
- celltools.addItem({ tool: slideShow, rank: 2 });
- celltools.addItem({ tool: nbConvert, rank: 3 });
- celltools.addItem({ tool: metadataEditor, rank: 4 });
- MessageLoop.installMessageHook(celltools, hook);
- // Wait until the application has finished restoring before rendering.
- Promise.all([state.fetch(id), app.restored]).then(([args]) => {
- const open = !!(args && (args as ReadonlyJSONObject)['open'] as boolean);
- // After initial restoration, check if the cell tools should render.
- if (tracker.size) {
- app.shell.addToLeftArea(celltools);
- if (open) {
- app.shell.activateById(celltools.id);
- }
- }
- // For all subsequent widget changes, check if the cell tools should render.
- app.shell.currentChanged.connect((sender, args) => {
- // If there are any open notebooks, add cell tools to the side panel if
- // it is not already there.
- if (tracker.size) {
- if (!celltools.isAttached) {
- app.shell.addToLeftArea(celltools);
- }
- return;
- }
- // If there are no notebooks, close cell tools.
- celltools.close();
- });
- });
- return Promise.resolve(celltools);
- }
- /**
- * Activate the notebook handler extension.
- */
- function activateNotebookHandler(app: JupyterLab, mainMenu: IMainMenu, palette: ICommandPalette, contentFactory: NotebookPanel.IContentFactory, editorServices: IEditorServices, restorer: ILayoutRestorer, browserFactory: IFileBrowserFactory | null, launcher: ILauncher | null): INotebookTracker {
- const services = app.serviceManager;
- const factory = new NotebookWidgetFactory({
- name: FACTORY,
- fileTypes: ['notebook'],
- modelName: 'notebook',
- defaultFor: ['notebook'],
- preferKernel: true,
- canStartKernel: true,
- rendermime: app.rendermime,
- contentFactory,
- mimeTypeService: editorServices.mimeTypeService
- });
- const { commands } = app;
- const tracker = new NotebookTracker({ namespace: 'notebook' });
- // Handle state restoration.
- restorer.restore(tracker, {
- command: 'docmanager:open',
- args: panel => ({ path: panel.context.path, factory: FACTORY }),
- name: panel => panel.context.path,
- when: services.ready
- });
- let registry = app.docRegistry;
- registry.addModelFactory(new NotebookModelFactory({}));
- registry.addWidgetFactory(factory);
- addCommands(app, services, tracker);
- populatePalette(palette);
- let id = 0; // The ID counter for notebook panels.
- factory.widgetCreated.connect((sender, widget) => {
- // If the notebook panel does not have an ID, assign it one.
- widget.id = widget.id || `notebook-${++id}`;
- widget.title.icon = NOTEBOOK_ICON_CLASS;
- // Notify the instance tracker if restore data needs to update.
- widget.context.pathChanged.connect(() => { tracker.save(widget); });
- // Add the notebook panel to the tracker.
- tracker.add(widget);
- });
- // Add main menu notebook menu.
- populateMenus(app, mainMenu, tracker);
- // Utility function to create a new notebook.
- const createNew = (cwd: string, kernelName?: string) => {
- return commands.execute(
- 'docmanager:new-untitled', { path: cwd, type: 'notebook' }
- ).then(model => {
- return commands.execute('docmanager:open', {
- path: model.path, factory: FACTORY,
- kernel: { name: kernelName }
- });
- });
- };
- // Add a command for creating a new notebook in the File Menu.
- commands.addCommand(CommandIDs.createNew, {
- label: 'Notebook',
- caption: 'Create a new notebook',
- execute: () => {
- let cwd = browserFactory ?
- browserFactory.defaultBrowser.model.path : '';
- return createNew(cwd);
- }
- });
- // Add a launcher item if the launcher is available.
- if (launcher) {
- services.ready.then(() => {
- const specs = services.specs;
- const baseUrl = PageConfig.getBaseUrl();
- for (let name in specs.kernelspecs) {
- let displayName = specs.kernelspecs[name].display_name;
- let rank = name === specs.default ? 0 : Infinity;
- let kernelIconUrl = specs.kernelspecs[name].resources['logo-64x64'];
- if (kernelIconUrl) {
- let index = kernelIconUrl.indexOf('kernelspecs');
- kernelIconUrl = baseUrl + kernelIconUrl.slice(index);
- }
- launcher.add({
- displayName,
- category: 'Notebook',
- name,
- iconClass: 'jp-NotebookRunningIcon',
- callback: createNew,
- rank,
- kernelIconUrl
- });
- }
- });
- }
- app.contextMenu.addItem({
- command: CommandIDs.clearOutputs,
- selector: '.jp-Notebook .jp-Cell'
- });
- app.contextMenu.addItem({
- command: CommandIDs.split,
- selector: '.jp-Notebook .jp-Cell'
- });
- app.contextMenu.addItem({
- command: CommandIDs.createCellView,
- selector: '.jp-Notebook .jp-Cell'
- });
- app.contextMenu.addItem({
- type: 'separator',
- selector: '.jp-Notebook',
- rank: 0
- });
- app.contextMenu.addItem({
- command: CommandIDs.undoCellAction,
- selector: '.jp-Notebook',
- rank: 1
- });
- app.contextMenu.addItem({
- command: CommandIDs.redoCellAction,
- selector: '.jp-Notebook',
- rank: 2
- });
- app.contextMenu.addItem({
- type: 'separator',
- selector: '.jp-Notebook',
- rank: 0
- });
- app.contextMenu.addItem({
- command: CommandIDs.createConsole,
- selector: '.jp-Notebook',
- rank: 3
- });
- app.contextMenu.addItem({
- command: CommandIDs.clearAllOutputs,
- selector: '.jp-Notebook',
- rank: 3
- });
- return tracker;
- }
- /**
- * Add the notebook commands to the application's command registry.
- */
- function addCommands(app: JupyterLab, services: ServiceManager, tracker: NotebookTracker): void {
- const { commands, shell } = app;
- // Get the current widget and activate unless the args specify otherwise.
- function getCurrent(args: ReadonlyJSONObject): NotebookPanel | null {
- const widget = tracker.currentWidget;
- const activate = args['activate'] !== false;
- if (activate && widget) {
- shell.activateById(widget.id);
- }
- return widget;
- }
- /**
- * Whether there is an active notebook.
- */
- function isEnabled(): boolean {
- return tracker.currentWidget !== null &&
- tracker.currentWidget === app.shell.currentWidget;
- }
- /**
- * The name of the current notebook widget.
- */
- function currentName(): string {
- if (tracker.currentWidget && tracker.currentWidget.title.label) {
- return `"${tracker.currentWidget.title.label}"`;
- }
- return 'Notebook';
- }
- commands.addCommand(CommandIDs.runAndAdvance, {
- label: 'Run Cell(s) and Select Below',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { context, notebook } = current;
- return NotebookActions.runAndAdvance(notebook, context.session);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.run, {
- label: 'Run Cell(s)',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { context, notebook } = current;
- return NotebookActions.run(notebook, context.session);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.runAndInsert, {
- label: 'Run Cell(s) and Insert Below',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { context, notebook } = current;
- return NotebookActions.runAndInsert(notebook, context.session);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.runAll, {
- label: 'Run All Cells',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { context, notebook } = current;
- return NotebookActions.runAll(notebook, context.session);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.restart, {
- label: 'Restart Kernel',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return current.session.restart();
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.closeAndShutdown, {
- label: 'Close and Shutdown',
- execute: args => {
- const current = getCurrent(args);
- if (!current) {
- return;
- }
- const fileName = current.title.label;
- return showDialog({
- title: 'Shutdown the notebook?',
- body: `Are you sure you want to close "${fileName}"?`,
- buttons: [Dialog.cancelButton(), Dialog.warnButton()]
- }).then(result => {
- if (result.button.accept) {
- return current.context.session.shutdown()
- .then(() => { current.dispose(); });
- }
- });
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.trust, {
- label: () => `Trust ${currentName()}`,
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { context, notebook } = current;
- return NotebookActions.trust(notebook).then(() => context.save());
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.exportToFormat, {
- label: args => {
- const formatLabel = (args['label']) as string;
- const name = currentName();
- return (args['isPalette'] ? `Export ${name} to ` : '') + formatLabel;
- },
- execute: args => {
- const current = getCurrent(args);
- if (!current) {
- return;
- }
- const notebookPath = URLExt.encodeParts(current.context.path);
- const url = URLExt.join(
- services.serverSettings.baseUrl,
- 'nbconvert',
- (args['format']) as string,
- notebookPath
- ) + '?download=true';
- const child = window.open('', '_blank');
- const { context } = current;
- if (context.model.dirty && !context.model.readOnly) {
- return context.save().then(() => { child.location.assign(url); });
- }
- return new Promise<void>((resolve) => {
- child.location.assign(url);
- resolve(undefined);
- });
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.restartClear, {
- label: 'Restart Kernel & Clear Outputs',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { notebook, session } = current;
- return session.restart()
- .then(() => { NotebookActions.clearAllOutputs(notebook); });
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.restartRunAll, {
- label: 'Restart Kernel & Run All',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- const { context, notebook, session } = current;
- return session.restart()
- .then(() => { NotebookActions.runAll(notebook, context.session); });
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.clearAllOutputs, {
- label: 'Clear All Outputs',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.clearAllOutputs(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.clearOutputs, {
- label: 'Clear Output(s)',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.clearOutputs(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.interrupt, {
- label: 'Interrupt Kernel',
- execute: args => {
- const current = getCurrent(args);
- if (!current) {
- return;
- }
- const kernel = current.context.session.kernel;
- if (kernel) {
- return kernel.interrupt();
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.toCode, {
- label: 'Change to Code Cell Type',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.changeCellType(current.notebook, 'code');
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.toMarkdown, {
- label: 'Change to Markdown Cell Type',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.changeCellType(current.notebook, 'markdown');
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.toRaw, {
- label: 'Change to Raw Cell Type',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.changeCellType(current.notebook, 'raw');
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.cut, {
- label: 'Cut Cell(s)',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.cut(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.copy, {
- label: 'Copy Cell(s)',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.copy(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.paste, {
- label: 'Paste Cell(s) Below',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.paste(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.deleteCell, {
- label: 'Delete Cell(s)',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.deleteCells(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.split, {
- label: 'Split Cell',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.splitCell(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.merge, {
- label: 'Merge Selected Cell(s)',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.mergeCells(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.insertAbove, {
- label: 'Insert Cell Above',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.insertAbove(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.insertBelow, {
- label: 'Insert Cell Below',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.insertBelow(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.selectAbove, {
- label: 'Select Cell Above',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.selectAbove(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.selectBelow, {
- label: 'Select Cell Below',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.selectBelow(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.extendAbove, {
- label: 'Extend Selection Above',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.extendSelectionAbove(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.extendBelow, {
- label: 'Extend Selection Below',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.extendSelectionBelow(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.moveUp, {
- label: 'Move Cell(s) Up',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.moveUp(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.moveDown, {
- label: 'Move Cell(s) Down',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.moveDown(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.toggleAllLines, {
- label: 'Toggle All Line Numbers',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.toggleAllLineNumbers(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.commandMode, {
- label: 'Enter Command Mode',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- current.notebook.mode = 'command';
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.editMode, {
- label: 'Enter Edit Mode',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- current.notebook.mode = 'edit';
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.undoCellAction, {
- label: 'Undo Cell Operation',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.undo(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.redoCellAction, {
- label: 'Redo Cell Operation',
- execute: args => {
- const current = getCurrent(args);
- if (!current) {
- return NotebookActions.redo(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.changeKernel, {
- label: 'Change Kernel',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return current.context.session.selectKernel();
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.reconnectToKernel, {
- label: 'Reconnect To Kernel',
- execute: args => {
- const current = getCurrent(args);
- if (!current) {
- return;
- }
- const kernel = current.context.session.kernel;
- if (kernel) {
- return kernel.reconnect();
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.createCellView, {
- label: 'Create New View for Cell',
- execute: args => {
- const current = getCurrent(args);
- const nb = current.notebook;
- const newCell = nb.activeCell.clone();
- const CellPanel = class extends Panel {
- protected onCloseRequest(msg: Message): void {
- this.dispose();
- }
- };
- const p = new CellPanel();
- p.id = `Cell-${uuid()}`;
- p.title.closable = true;
- p.title.label = current.title.label ? `Cell: ${current.title.label}` : 'Cell';
- p.addWidget(newCell);
- shell.addToMainArea(p);
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.createConsole, {
- label: 'Create Console for Notebook',
- execute: args => {
- const current = getCurrent(args);
- const widget = tracker.currentWidget;
- if (!current || !widget) {
- return;
- }
- const options: ReadonlyJSONObject = {
- path: widget.context.path,
- preferredLanguage: widget.context.model.defaultKernelLanguage,
- activate: args['activate']
- };
- return commands.execute('console:create', options);
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.markdown1, {
- label: 'Change to Heading 1',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.setMarkdownHeader(current.notebook, 1);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.markdown2, {
- label: 'Change to Heading 2',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.setMarkdownHeader(current.notebook, 2);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.markdown3, {
- label: 'Change to Heading 3',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.setMarkdownHeader(current.notebook, 3);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.markdown4, {
- label: 'Change to Heading 4',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.setMarkdownHeader(current.notebook, 4);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.markdown5, {
- label: 'Change to Heading 5',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.setMarkdownHeader(current.notebook, 5);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.markdown6, {
- label: 'Change to Heading 6',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.setMarkdownHeader(current.notebook, 6);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.hideCode, {
- label: 'Hide Code',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.hideCode(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.showCode, {
- label: 'Show Code',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.showCode(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.hideAllCode, {
- label: 'Hide All Code',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.hideAllCode(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.showAllCode, {
- label: 'Show All Code',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.showAllCode(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.hideOutput, {
- label: 'Hide Output',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.hideOutput(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.showOutput, {
- label: 'Show Output',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.showOutput(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.hideAllOutputs, {
- label: 'Hide All Outputs',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.hideAllOutputs(current.notebook);
- }
- },
- isEnabled
- });
- commands.addCommand(CommandIDs.showAllOutputs, {
- label: 'Show All Outputs',
- execute: args => {
- const current = getCurrent(args);
- if (current) {
- return NotebookActions.showAllOutputs(current.notebook);
- }
- },
- isEnabled
- });
- }
- /**
- * Populate the application's command palette with notebook commands.
- */
- function populatePalette(palette: ICommandPalette): void {
- let category = 'Notebook Operations';
- [
- CommandIDs.interrupt,
- CommandIDs.restart,
- CommandIDs.restartClear,
- CommandIDs.restartRunAll,
- CommandIDs.runAll,
- CommandIDs.clearAllOutputs,
- CommandIDs.toggleAllLines,
- CommandIDs.editMode,
- CommandIDs.commandMode,
- CommandIDs.changeKernel,
- CommandIDs.reconnectToKernel,
- CommandIDs.createConsole,
- CommandIDs.closeAndShutdown,
- CommandIDs.trust
- ].forEach(command => { palette.addItem({ command, category }); });
- EXPORT_TO_FORMATS.forEach(exportToFormat => {
- let args = { 'format': exportToFormat['format'], 'label': exportToFormat['label'], 'isPalette': true };
- palette.addItem({ command: CommandIDs.exportToFormat, category: category, args: args });
- });
- category = 'Notebook Cell Operations';
- [
- CommandIDs.run,
- CommandIDs.runAndAdvance,
- CommandIDs.runAndInsert,
- CommandIDs.clearOutputs,
- CommandIDs.toCode,
- CommandIDs.toMarkdown,
- CommandIDs.toRaw,
- CommandIDs.cut,
- CommandIDs.copy,
- CommandIDs.paste,
- CommandIDs.deleteCell,
- CommandIDs.split,
- CommandIDs.merge,
- CommandIDs.insertAbove,
- CommandIDs.insertBelow,
- CommandIDs.selectAbove,
- CommandIDs.selectBelow,
- CommandIDs.extendAbove,
- CommandIDs.extendBelow,
- CommandIDs.moveDown,
- CommandIDs.moveUp,
- CommandIDs.undoCellAction,
- CommandIDs.redoCellAction,
- CommandIDs.markdown1,
- CommandIDs.markdown2,
- CommandIDs.markdown3,
- CommandIDs.markdown4,
- CommandIDs.markdown5,
- CommandIDs.markdown6,
- CommandIDs.hideCode,
- CommandIDs.showCode,
- CommandIDs.hideAllCode,
- CommandIDs.showAllCode,
- CommandIDs.hideOutput,
- CommandIDs.showOutput,
- CommandIDs.hideAllOutputs,
- CommandIDs.showAllOutputs,
- ].forEach(command => { palette.addItem({ command, category }); });
- }
- /**
- * Populates the application menus for the notebook.
- */
- function populateMenus(app: JupyterLab, mainMenu: IMainMenu, tracker: INotebookTracker): void {
- let { commands } = app;
- // Add undo/redo hooks to the edit menu.
- mainMenu.editMenu.undoers.set('Notebook', {
- tracker,
- undo: widget => { widget.notebook.activeCell.editor.undo(); },
- redo: widget => { widget.notebook.activeCell.editor.redo(); }
- } as IEditMenu.IUndoer<NotebookPanel>);
- // Add editor view options.
- // Add a clearer to the edit menu
- mainMenu.editMenu.clearers.set('Notebook', {
- tracker,
- noun: 'All Cell Outputs',
- clear: (current: NotebookPanel) => {
- return NotebookActions.clearAllOutputs(current.notebook);
- }
- } as IEditMenu.IClearer<NotebookPanel>);
- // Add new notebook creation to the file menu.
- mainMenu.fileMenu.newMenu.addItem({ command: CommandIDs.createNew });
- // Add a close and shutdown command to the file menu.
- mainMenu.fileMenu.closeAndCleaners.set('Notebook', {
- tracker,
- action: 'Shutdown',
- closeAndCleanup: (current: NotebookPanel) => {
- const fileName = current.title.label;
- return showDialog({
- title: 'Shutdown the notebook?',
- body: `Are you sure you want to close "${fileName}"?`,
- buttons: [Dialog.cancelButton(), Dialog.warnButton()]
- }).then(result => {
- if (result.button.accept) {
- return current.context.session.shutdown()
- .then(() => { current.dispose(); });
- }
- });
- }
- } as IFileMenu.ICloseAndCleaner<NotebookPanel>);
- // Add a notebook group to the File menu.
- let exportTo = new Menu({ commands } );
- exportTo.title.label = 'Export to ...';
- EXPORT_TO_FORMATS.forEach(exportToFormat => {
- exportTo.addItem({ command: CommandIDs.exportToFormat, args: exportToFormat });
- });
- const fileGroup = [
- { command: CommandIDs.trust },
- { type: 'submenu', submenu: exportTo } as Menu.IItemOptions
- ];
- mainMenu.fileMenu.addGroup(fileGroup, 10);
- // Add a kernel user to the Kernel menu
- mainMenu.kernelMenu.kernelUsers.set('Notebook', {
- tracker,
- interruptKernel: current => {
- let kernel = current.session.kernel;
- if (kernel) {
- return kernel.interrupt();
- }
- return Promise.resolve(void 0);
- },
- restartKernel: current => current.session.restart(),
- changeKernel: current => current.session.selectKernel(),
- shutdownKernel: current => current.session.shutdown(),
- } as IKernelMenu.IKernelUser<NotebookPanel>);
- // Add a console creator the the Kernel menu
- mainMenu.kernelMenu.consoleCreators.set('Notebook', {
- tracker,
- createConsole: current => {
- const options: ReadonlyJSONObject = {
- path: current.context.path,
- preferredLanguage: current.context.model.defaultKernelLanguage
- };
- return commands.execute('console:create', options);
- }
- } as IKernelMenu.IConsoleCreator<NotebookPanel>);
- // Add some commands to the application view menu.
- const viewGroup = [
- CommandIDs.hideAllCode,
- CommandIDs.showAllCode,
- CommandIDs.hideAllOutputs,
- CommandIDs.showAllOutputs
- ].map(command => { return { command }; });
- mainMenu.viewMenu.addGroup(viewGroup, 10);
- // Add an IEditorViewer to the application view menu
- mainMenu.viewMenu.editorViewers.set('Notebook', {
- tracker,
- toggleLineNumbers: widget => {
- NotebookActions.toggleAllLineNumbers(widget.notebook);
- },
- toggleMatchBrackets: widget => {
- NotebookActions.toggleAllMatchBrackets(widget.notebook);
- },
- lineNumbersToggled: widget =>
- widget.notebook.activeCell.editor.getOption('lineNumbers'),
- matchBracketsToggled: widget =>
- widget.notebook.activeCell.editor.getOption('matchBrackets'),
- } as IViewMenu.IEditorViewer<NotebookPanel>);
- // Add an ICodeRunner to the application run menu
- mainMenu.runMenu.codeRunners.set('Notebook', {
- tracker,
- noun: 'Cell',
- run: current => {
- const { context, notebook } = current;
- return NotebookActions.runAndAdvance(notebook, context.session)
- .then(() => void 0);
- },
- runAll: current => {
- const { context, notebook } = current;
- return NotebookActions.runAll(notebook, context.session)
- .then(() => void 0);
- },
- runAbove: current => {
- const { context, notebook } = current;
- return NotebookActions.runAllAbove(notebook, context.session)
- .then(() => void 0);
- },
- runBelow: current => {
- const { context, notebook } = current;
- return NotebookActions.runAllBelow(notebook, context.session)
- .then(() => void 0);
- }
- } as IRunMenu.ICodeRunner<NotebookPanel>);
- // Add commands to the application edit menu.
- const undoCellActionGroup = [
- CommandIDs.undoCellAction,
- CommandIDs.redoCellAction
- ].map(command => { return { command }; });
- const editGroup = [
- CommandIDs.cut,
- CommandIDs.copy,
- CommandIDs.paste,
- CommandIDs.deleteCell,
- CommandIDs.split,
- CommandIDs.merge
- ].map(command => { return { command }; });
- mainMenu.editMenu.addGroup(undoCellActionGroup, 4);
- mainMenu.editMenu.addGroup(editGroup, 5);
- }
|