Multiple cursors
multiple-cursors.el works within a notebook, with one exception: a
command that redraws the WHOLE notebook moves its fake cursors to the
start of the buffer, and the next edit lands there instead of at each
cursor. Measured with cursors on three lines of one cell:
| While the cursors are active | Result |
|---|---|
| output arrives in another cell | edits land at every cursor |
| another cell is run, clearing its output | edits land at every cursor |
| a cell is inserted | edits land at every cursor |
a cell's type is changed (C-c C-t) |
cursors collapse to the start |
M-x emjupy-re-render |
cursors collapse to the start |
Rendering a markdown cell and undoing a structural change also redraw the whole notebook, and do the same.
For editing across several cells at once, C-c ' opens every code cell
in one Python buffer, where multiple cursors, and every other editing
tool, work as in any file; C-c C-c there writes the changes back.
A kernel that dies mid-cell leaves the cell running
If the kernel dies while a cell runs – it runs out of memory, or the
code exits the process – the server restarts it but sends nothing over
the notebook's connection to say so, and the cell goes on showing as
running. C-c C-x C-c reconnects to the new kernel and ends the run;
the dead kernel's variables are gone. A connection that drops, by
contrast, is noticed, and the cells running on it are ended.
Language features need the language server beside the kernel
For a kernel on another machine, completion of your own code and M-.
into it need jupyter-lsp and a language server where the kernel runs.
See Language server support.
Rich output: what is drawn in the buffer
In the buffer emjupy draws plain text, images (PNG, JPEG, GIF, SVG) and widget controls. A figure that draws itself in JavaScript is opened in a window of its own (see Interactive output). Everything else is shown by its plain-text fallback, which every Jupyter output carries:
- HTML without a script – a pandas
DataFrameappears as its text table; - Markdown and LaTeX sent through
IPython.displayappear as source.
Images need a graphical Emacs; in a terminal they appear as their text fallback too.
Widgets that draw themselves open in a page, with two gaps
A widget drawn by JavaScript of its own – plotly's FigureWidget, a map
– opens in a page in the figure window (see Interactive output). Two
things do not reach that page: what an Output widget inside it
captures, which is drawn in the notebook instead, and the widget manager
without a network, unless emjupy-widget-scripts names local copies.
Figures open in a window of their own, not inside Emacs
Showing a figure inside Emacs needs an xwidget, and that needs Emacs
built with --with-xwidgets. Emacs 30.1 refuses WebKitGTK 2.41.92 or
newer, and current distributions ship newer (Ubuntu 24.04 has 2.52), so
there Emacs 30.1 has no xwidgets. The refusal is still warranted: built
with the check lifted, against 2.52, Emacs aborts as the figure opens.
So figures open in a window of their own, outside Emacs.
emjupy-figure-viewer can choose an xwidget, for a build known to work
with one.
Python only
Execution speaks the Jupyter protocol and does not care which kernel is
on the other end, so R or Julia kernels may well run. Nothing else is
set up for them: cells borrow python-mode's syntax and comment
settings (emjupy-language-mode changes that), the shadow document the
language server reads is a .py file, and the language-server settings
are written for python-lsp-server. None of it has been tried.
Emacs 30.1 or later
Emacs 29 was supported until Eglot's differences there caused bugs that could not be seen from 30; see Building and development.
Open issues
Faults known but not yet fixed are kept as issues on GitHub.
