How to access selected cells in notebook from extension

I’m trying to write an extension that would let me bind some convenience helper tools to keyboard shortcuts
like, e.g. bind “ctrl-9” to “set the hide-input tag on all selected cells” or “set all text in lowercase in all selected cells”, this kind of random productivity business

I have managed to write something that works on the active cell through notebookTracker.activeCell, and was kind of expecting to do similarly notebookTracker.selectedCells but to no avail (I have much more experience in the classic notebook extension model…)

What’s the right way to iterate over the selected cells in a notebook ?

thanks !

The notebookTracker.currentWidget gives access to the underlying method Notebook.getContiguousSelection().

As this is notebook level, and not tracker level, one might need to listen for signals in a few places, which also need to be cleaned up to avoid possible memory leaks.

So something like this (untested, incomplete) example, which would go inside an plugin’s activate:


function doSomethingCool(cells: Cell[]): void {
  // be cool
}

function onSelectionChanged(panel: NotebookPanel): void {
  const notebook = panel.content;
  const { anchor, head } = notebook.getContiguousSelection();
  const selectedCells = notebook.widgets.slice(anchor, head + 1);
  doSomethingCool(selectedCells);
}

function onNewNotebook(tracker: NotebookTracker, panel: NotebookPanel): void {
  panel.content.selectionChanged.connect(onSelectionChanged);
  panel.disposed.connect(
    (panel) => panel.selectionChanged.disconnect(onSelectionChanged)
  );
}

notebookTracker.widgetAdded.connect(onNewNotebook);

thank you !

in case anybody would look for the same thing, here’s how I ended up factoring in my specific need, again: applying some function on all selected cells

feel free to review and comment, I’m really not a typescript expert

const apply_on_selected_or_active_cells = (
  notebookTracker: INotebookTracker,
  to_apply: (cell: Cell) => void,
) => {
  const panel = notebookTracker.currentWidget
  // please typescript
  if (panel === null)
    return
  const activeCell = notebookTracker.activeCell
  // please typescript
  if (activeCell === null)
    return
  const notebook = panel.content
  const { anchor, head } = notebook.getContiguousSelection()
  let actionCells
  // when only one cell is selected/active, both are null
  if (anchor === null || head === null)
    actionCells = [activeCell]
  else
    actionCells = notebook.widgets.slice(anchor, head + 1)
  actionCells.forEach(to_apply)
}