Spectral M2
Spectral M2 is a terminal shell for Macaulay2. It keeps the familiar numbered input and output flow while adding syntax-aware editing, structured output, local diagnostics, selectable transcripts, previews, and two independent workspaces.
R = QQ[x, y]
I = ideal(x^2, x*y, y^2)
betti res I
The input is parsed and highlighted locally with m2-syn. Complete cells are sent to a real Macaulay2 process, so package loading, state, values, printed text, warnings, and errors retain their ordinary M2 semantics.
The shell is organized around three parts:
- the feed contains submitted code and its results;
- the input area is a multiline, syntax-aware editor;
- the status line shows context-sensitive shortcuts and preview state.
The rest of this book describes the currently implemented interface.
Getting started
Requirements
Spectral M2 needs:
- Macaulay2 available as
M2onPATH; - a Rust toolchain with Cargo for building from this repository;
- a terminal with mouse events and OSC 52 clipboard support for the full interface.
Run the shell
Build and run directly through Cargo:
cargo run --release
Spectral starts a Macaulay2 process immediately. If M2 cannot be found or started, it exits with an explanation instead of opening an unusable interface.
Serve this book locally
Install the documentation tools through Cargo once:
cargo install mdbook --version 0.5.3 --locked
cargo install mdbook-tsitter
Build the Macaulay2 parser from its Cargo crate, then serve the book:
cargo build --release \
--manifest-path docs/parser/Cargo.toml \
--target-dir target/docs-parser
mdbook serve docs --hostname 127.0.0.1 --port 3000
Open http://127.0.0.1:3000. The server rebuilds the book when its Markdown changes. A one-off build is written to target/mdbook:
mdbook build docs
mdbook-tsitter highlights every fenced m2 or macaulay2 block at build time. The parser is built from the published tree-sitter-macaulay2 crate; no compiled parser is stored in the repository.
Editing and evaluation
Syntax-aware submission
Press Enter to submit. Spectral first asks m2-syn whether the buffer is complete:
- complete input is split into cells and queued for Macaulay2;
- input that ended while a construct was still open receives another line;
- invalid input stays in the editor with a local diagnostic and source range.
For example, pressing Enter after the first line keeps editing because the parenthesized expression is unfinished:
f = x -> (
x^2 + 1)
Use Shift+Space, Shift+Enter, or Alt+Enter when you want a newline regardless of completeness.
Pending and completed cells
Submitted code moves into the feed immediately. As Macaulay2 answers, Spectral appends printed text, values, types, warnings, or errors; consecutive values share one border. Cell numbers remain session metadata but are not displayed until cells become focusable.
Only one submission can evaluate in a workspace at a time. Trying to submit another while it is busy produces an input diagnostic and does not disturb the running evaluation.
Semicolons remain part of their cell, so M2 still controls whether a value is printed:
R = QQ[x, y];
I = ideal(x^2, x*y, y^2);
degree I
History and navigation
Up and Down move inside multiline input. At the first or last line they recall older or newer submissions. Commands chosen after typing / are recorded in the same history; opening the full command picker with Ctrl+/ does not add a history entry.
The usual editing keys are available for horizontal movement, line boundaries, deletion, and tabs. Ctrl+L clears the current input without clearing the feed.
Selection and clipboard
Hold Shift with Left, Right, Home, or End to extend an input selection. Ctrl+Y copies it. Typing or deleting replaces the selected range.
You can also drag over input, feed, code previews, or syntax trees with the mouse. Releasing a real drag copies the selectable text through OSC 52. UI markers, borders, type annotations, and picker rows are excluded where appropriate so copied text stays useful.
Commands and pickers
Type / into an empty input to open the filtered command picker. Continue typing to narrow it, use Up and Down to select, then press Enter. Esc closes the picker. Ctrl+/ opens the full picker without changing the current draft; typing from that picker returns to ordinary input.
Commands are handled by Spectral rather than sent to Macaulay2.
| Command | Key | Effect |
|---|---|---|
/settings | Ctrl+O | Open shell settings. |
/style | Alt+S | Open the separate colorscheme picker. |
/keymaps | Alt+K | Show and edit the remappable bindings. |
/clear | Alt+L | Clear the focused workspace’s feed. |
/code | Alt+C | Preview all committed input cells. |
/output | Alt+O | Preview structured output without input cells. |
/syntax tree | Alt+T | Preview the m2-syn tree of committed cells. |
/new | Alt+N | Start a fresh, independent M2 workspace. |
/restart | Alt+R | Restart the focused workspace’s M2 process and reset its state. |
/debug | Ctrl+D | Toggle the highlight inspector; opening it posts a live value/muted/null probe. |
/quit | Ctrl+C | Leave Spectral. |
/close focused window | Alt+W | Close the focused pane; shown only while split. |
Alt+V is not a command keymap. On a selected new, code, output, or syntax tree row, it opens that command in an alternative pane instead of replacing the focused one. The command’s own keymap remains visible beside it.
Exact commands submitted from input are opened locally, including commands recalled from history. The bare inputs exit, quit, and restart are also intercepted locally, with an optional trailing semicolon.
Nested pickers preserve their parent. For example, /settings can open style, and Esc returns from style to settings before returning to the shell.
Workspaces and split view
Spectral supports two panes and up to two independent workspaces.
Open a second pane
Choose new, code, output, or syntax tree in the command picker with Alt+V:
newstarts another Macaulay2 process with its own state, transcript, draft, history, and committed syntax trees;- the three previews remain linked to the focused workspace’s committed cells but have their own view and scroll position.
Ordinary Enter opens the chosen item in the focused pane. In a preview, Ctrl+Q or Ctrl+C returns to the shell; if the preview is the second pane, leaving it closes that pane.
Focus and resize
Use Ctrl+Left and Ctrl+Right to focus the left or right pane. On a wide terminal, drag the divider or use Ctrl+Shift+Left and Ctrl+Shift+Right to resize it one column at a time.
Each visible pane keeps at least 40 columns. Two side-by-side panes therefore require 81 columns including the divider. Below that width Spectral keeps both panes alive but displays only the focused one. Ctrl+Left and Ctrl+Right then toggle which workspace or view is visible.
Settings, keymaps, and style are application-wide: changing them in one workspace updates the other. Evaluation state and feed contents remain independent.
A practical split
One pane can develop an object while the other tests a separate idea:
R = QQ[a..d]
I = minors(2, genericMatrix(R, 2, 2))
Or keep the shell on the left and open its syntax tree or collected outputs on the right. Because preview navigation is independent, scrolling the preview never moves the shell feed.
Preview modes
Previews contain committed cells only. They update from the workspace they reference while keeping an independent scroll position. Use Up, Down, PageUp, PageDown, or the mouse wheel to navigate, and drag to select text.
Ctrl+Q and Ctrl+C leave a preview. The command and settings pickers remain available with Ctrl+/ and Ctrl+O.
Code
/code combines committed input into one syntax-highlighted view. Pending and rejected input is not included.
R = ZZ/101[x, y, z]
I = ideal(x^2-y*z, y^2-x*z, z^2-x*y)
dim I
Output
/output starts with evaluation output: printed text, warnings, and errors. Use Left and Right to cycle through:
- evaluation output;
- values and types;
- everything except input.
The active projection is shown in the status line. Previewing does not change or remove the original feed.
Syntax tree
/syntax tree renders the m2-syn pretty tree for every committed cell and opens at the newest tree. Each section has a centered cell-number separator, highlighted source, and its structural tree.
The presentation keeps semantic structure compact:
- node types precede optional field labels;
- nonterminal rows include trimmed source text when it fits;
- delimiter rows enclose and indent their contents;
Token![…]displays its source character only inside the brackets;- virtual tokens are named without pretending that their marker text occurred in the source;
- absent optionals and empty or purely mechanical collection wrappers are hidden.
The syntax-tree canvas is centered as a whole, and its status line marks Syntax Tree Preview Mode in the middle.
Settings and style
Open settings with Ctrl+O or /settings. Use Up and Down to choose a row and Left or Right to adjust it.
| Setting | Choices |
|---|---|
| Max input height | Percentage of the pane available to growing multiline input, in 5% steps. |
| Scrolloff | Context rows retained above and below the input cursor. |
| Status line | Below input, above input, or off. |
| Style | Opens the separate style picker. |
| Restore default | Resets settings, keymaps, and appearance. |
Style
/style opens the same style picker directly. Its three ordered axes are:
- colorscheme — cycles every scheme variant of the current brightness, keeping each scheme’s variants adjacent and deterministic;
- brightness — switches between the dark and light variants available for the current scheme;
- background — chooses an opaque or transparent empty canvas.
Transparent background affects only otherwise empty feed or preview canvas cells. Code bands, output boxes, selections, pickers, and other explicitly styled UI keep their backgrounds.
The installed families are Catppuccin, Tokyo Night, Gruvbox, Gruvbox Material, Everforest, Rosé Pine, and Kanagawa. Each variant uses its own source palette names internally rather than being flattened into one universal color namespace.
Highlight debug view
Press Ctrl+D or run /debug to open the one-column inspector at the lower right. It lists all active UI and Macaulay2 highlight groups, followed by the current variant’s native palette names and colors. Opening it submits a real three-cell value/muted/null probe through the active Macaulay2 session and leaves that post in the feed. Scroll the inspector with arrow or page keys. Esc closes only the inspector; Ctrl+D toggles it from any shell, preview, or picker.
Keymaps
Run /keymaps to inspect and edit every command shortcut plus clear input and copy selection. Selecting one and pressing a new modified key updates both dispatch and displayed hints. Movement, submission, and other form-editing keys remain fixed.
Key reference
Shell
| Key | Action |
|---|---|
Enter | Submit complete input, or continue an incomplete construct. |
Shift+Space, Shift+Enter, Alt+Enter | Insert a newline. |
Up, Down | Move vertically or recall history at the input boundary. |
PageUp, PageDown | Scroll the feed. |
Shift+Left, Shift+Right | Extend the input selection. |
Shift+Home, Shift+End | Extend selection to a line boundary. |
Ctrl+Y | Copy selected input or screen text. |
Ctrl+L | Clear the input. |
Ctrl+/ | Toggle commands. |
Ctrl+O | Toggle settings. |
Alt+S, Alt+K | Toggle style or keymaps. |
Alt+L | Clear the feed. |
Alt+C, Alt+O, Alt+T | Open code, output, or syntax-tree preview. |
Alt+N | Open a new workspace. |
Alt+R, Alt+W | Restart Macaulay2 or close the focused pane. |
Ctrl+D | Toggle highlight debug. |
Ctrl+C | Quit from the shell. |
Split and previews
| Key | Action |
|---|---|
Alt+V | Open a splittable command in an alternative pane. |
Ctrl+Left, Ctrl+Right | Focus a pane, including in a collapsed narrow split. |
Ctrl+Shift+Left, Ctrl+Shift+Right | Resize a visible split. |
Up, Down, PageUp, PageDown | Scroll a preview. |
Left, Right | Cycle output projections in output preview. |
Ctrl+Q, Ctrl+C | Leave a preview instead of quitting Spectral. |
Pickers
| Key | Action |
|---|---|
Up, Down | Change the selected row. |
Left, Right | Adjust a settings or style row. |
Enter | Open or run the selected row. |
Alt+V | Open the selected splittable command in an alternative pane. |
Esc | Close the current picker or debug overlay. |