I would like to add a new command to JupyterLab. I would like to execute cells below selected cell. There is a command in JupyterLab that execute selected cell and all below, I would like to change this behavior slightly, I dont want to execute the current cell. I would like to call the new command with ipylab package.
Extension code:
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { INotebookTracker } from '@jupyterlab/notebook';
/**
* Initialization data for the myextension extension.
*/
const plugin: JupyterFrontEndPlugin<void> = {
id: 'myextension:plugin',
description: 'A JupyterLab extension.',
autoStart: true,
requires: [INotebookTracker],
activate: (app: JupyterFrontEnd, notebookTracker: INotebookTracker) => {
console.log('Extension is activated!');
const commandID = 'execute-only-below';
app.commands.addCommand(commandID, {
label: 'Execute only below cells',
execute: () => {
console.log(`Execute ${commandID}`);
const nb = notebookTracker.currentWidget;
// how to execute only below cells
// without changing command mode
// without changing selection
if (nb) {
const m = nb.model;
if (m) {
// execute cells below cell that calls command ???
}
}
}
});
}
};
export default plugin;
Code to call the command:
from ipylab import JupyterFrontEnd
app = JupyterFrontEnd()
app.commands.execute("execute-only-below")
I would like to use this extension to write a custom ipwyidgets handler that will re-execute cells after widget update. Something like:
t = ipywidgets.Text("hello")
def handle_slider_change(change):
app.commands.execute("execute-only-below")
t.observe(handle_slider_change, names='value')
Maybe there is a better way to automatically re-execute cells after widget update?
This should be straightforward in JupyterLab 4.1, basically following:
but removing notebook.activeCellIndex = lastIndex; notebook.deselectAll(); and instead of Private.runCells using the public NotebookActions.runCells() method.
this is harder because Private.runCells still modifies the mode internally. I am not sure if it has to modify the mode but for certain we could make it optional. If this is desirable I would suggest opening an issue to discuss
removed node_modules and installed all packages with new versions, and have the following extension code:
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { ISessionContext, ISessionContextDialogs } from '@jupyterlab/apputils';
import {
INotebookTracker,
Notebook,
NotebookActions
} from '@jupyterlab/notebook';
import { ITranslator } from '@jupyterlab/translation';
function runAllBelow(
notebook: Notebook,
sessionContext?: ISessionContext,
sessionDialogs?: ISessionContextDialogs,
translator?: ITranslator
): Promise<boolean> {
if (!notebook.model || !notebook.activeCell) {
return Promise.resolve(false);
}
const promise = NotebookActions.runCells(
notebook,
notebook.widgets.slice(notebook.activeCellIndex),
sessionContext,
sessionDialogs,
translator
);
return promise;
}
/**
* Initialization data for the myextension extension.
*/
const plugin: JupyterFrontEndPlugin<void> = {
id: 'myextension:plugin',
description: 'A JupyterLab extension.',
autoStart: true,
requires: [INotebookTracker],
activate: (app: JupyterFrontEnd, notebookTracker: INotebookTracker) => {
console.log('Extension is activated!');
const commandID = 'execute-only-below';
app.commands.addCommand(commandID, {
label: 'Execute only below cells',
execute: () => {
console.log(`Execute ${commandID}`);
const nb = notebookTracker.currentWidget;
// how to execute only below cells
// without changing command mode
// without changing selection
if (nb) {
runAllBelow(nb.content, nb.context.sessionContext);
}
}
});
}
};
export default plugin;
When calling a new command I got error in js console:
index.ts:24 Uncaught (in promise) TypeError: _jupyterlab_notebook__WEBPACK_IMPORTED_MODULE_0__.NotebookActions.runCells is not a function
at runAllBelow (index.ts:24:35)
at execute (index.ts:55:11)
at g.execute (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1615626)
at m._execute (856.9dc62dfa1fc2e1667e5a.js?v=9dc62dfa1fc2e1667e5a:1:1425)
at m._onMessage (856.9dc62dfa1fc2e1667e5a.js?v=9dc62dfa1fc2e1667e5a:1:1016)
at v (644.558670f1aa9ae5791769.js?v=558670f1aa9ae5791769:1:3083)
at d (644.558670f1aa9ae5791769.js?v=558670f1aa9ae5791769:1:2817)
at c (644.558670f1aa9ae5791769.js?v=558670f1aa9ae5791769:1:740)
at a.trigger (644.558670f1aa9ae5791769.js?v=558670f1aa9ae5791769:1:2710)
at m._handle_comm_msg (595.74686e2543ce21f10975.js?v=74686e2543ce21f10975:1:8842)