The board is the user's design: the document as lists and blocks, the
way Scratch nests blocks inside a loop. Each node without a parent (the
root, then each loose node) is a column with its title in the top border;
its children are cards in it, one under the other; a card with children
on show wraps them in a C: a joint at its bottom left, a bracket down the
left two cells further in, and a foot closing it. Blocks nest as deep as
the tree does. The columns by tag or color the first design had are
dropped (the user's pick), and :board takes no arguments any more.
j and k go down and up a column in reading order, into the blocks; h and
l go to the column beside, onto the card nearest the cursor's height.
Titles are typed right in their cards, and visual mode selects in
reading order as the outline does. <Space>vb or :board shows it.
Move mode (M, the user's pick) moves the card through the tree: h and l
to the end of the column beside, j and k past the cards around it, into
an open block and out of one at its end. A column's own node trades
places with the loose column beside it; the root's column stays first.
A drag does the same with the mouse: dropped on a card it goes after it,
on a block's card into it, on a column at its end.
The fallback message for a key a view ignores now names the view ("does
nothing in the board view"). The version goes to 1.1.0: stage 9 is done.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
cumulus
Brainstorm in the terminal: ideas as nodes on a 2D canvas, connected, folded and color-coded, across as many documents as you like. Vim keys first; the mouse works too. Runs on Windows and Linux.
Status: v1.1 is built: everything on DESIGN.md's v1 and v1.1 lists. What comes later is listed there too.
Build and run
You need Rust (rustup.rs). The exact version is pinned in
rust-toolchain.toml, and rustup installs it by itself the first time.
cargo build --release
The program is target/release/cumulus (cumulus.exe on Windows): copy it to
a folder on your PATH.
- Windows: nothing else to install. The
.execarries its own C runtime and runs on any Windows 10 or 11. - Linux (Void, Fedora…): build the same way. You can also build a static
Linux binary from Windows with
cargo linux: it lands intarget/x86_64-unknown-linux-musl/release/cumulusand runs on any distribution.
Starting it
cumulus # ./ideas.cum, or ~/ideas.cum (made the first time)
cumulus garden.cum # that document (a new one if it isn't there yet)
cumulus notes/ # that folder's ideas.cum
cumulus new "Garden plans" # makes ./garden-plans.cum (cumulus new: ./ideas.cum)
cumulus --paths # where cumulus keeps its settings and data
Documents are plain text files (.cum) that live wherever you like. cumulus
saves a second after each change, reloads a file another program changed
(u undoes that), and keeps a copy of each document a day in its data folder.
A document open in another cumulus opens read-only. Each one reopens where you
left it.
A file's name follows its root's title: give the root a new title and the
file is renamed (ideas.cum keeps its name), and the portals leading to it
follow. Portals link documents: a portal shows its document's title, color
and size, Enter goes through it, and each document knows the portals that
lead to it (« 2 on its root, gu goes up to them).
Settings, keys and themes
:config lists the three config files: config.toml (the settings),
keys.toml (your keys) and the theme's file. Enter opens one in your editor
(the editor setting, or $VISUAL / $EDITOR, or notepad / vi); the first
time, it's written with every option at its default behind a #, explained.
Take a # away, save, and cumulus applies it at once. Each file only needs
what it changes, and a mistake only skips its own line (the status bar says
what's wrong).
:set name=valuechanges a setting until cumulus quits (:set name?shows it, Tab lists them).:theme nameswitches tothemes/name.toml, laid over the built-in theme: a theme can say justaccent = "magenta".- The built-in theme has named styles (
<Space>s), also put on by tags:#question(yellow, dashed),#important(red, thick),#done(faded). clipboard = "unnamedplus"makes plainy,dandpuse the system clipboard, as the vim setting of that name does.
Keys
The plan for the everyday keys (all of them are in DESIGN.md):
| Keys | What they do |
|---|---|
hjkl |
move to the nearest node that way |
gh gj gk gl |
parent, next sibling, previous sibling, first child |
o O a |
new sibling below / above, new child: type its title, Enter for the next one |
i or Enter |
edit the title (Esc: vim keys inside it, Esc again: done) |
dd x |
delete the branch / just the node (kept in a register, as in vim) |
yy p P |
yank the branch / paste as children, or as siblings below (dd then p moves a branch) |
"a "+ |
before y, d or p: register a; "+ is the system clipboard (nodes go there as Markdown) |
. |
the last change again |
>> << |
under the node above / out a level |
u Ctrl-r |
undo / redo |
za zf zi |
fold, auto-fold, focus |
+ - |
zoom in / out |
K |
the body in a card beside the node (i edits it there) |
v V |
select: the nodes between here and where you started (V: with their branches); then d y > < M or <Space>c act on all of them |
M |
move the branch with hjkl (M again: just the node) |
<Space>= |
tidy the branch: m a mind map, c an org chart, g a grid (:tidy) |
<Space>a |
in visual mode: line the selection up, h l k j left, right, top, bottom, c middles (:align; : in visual mode runs a command on the selection) |
C |
connect: go to another node, Enter links them (d removes the line, > puts it under that node, <Space> a l c s t style it, Esc takes it all back) |
/ n N |
search: titles, tags and bodies, fuzzily, with the note of each match beside it / the next match / the previous one |
<Space>/ |
search every document (open, recent, this folder, and what portals lead to); n N then go from document to document (:search text) |
Ctrl-o Tab |
back to where you jumped from / forward again (across documents) |
ma 'a mA |
mark a node / go back to it / a capital mark: from any document |
gd |
follow a cross-link |
<Space>p |
a portal to another document (:portal file, or a new document's title) |
<Space>o |
this branch out, into a document of its own, with a portal in its place (:branchout) |
Enter or gf gu |
through a portal / up to the portals that lead here |
<Space> |
the action menu: c color, t tags, b documents, i inbox, vo outline, vn note, vb board… |
| board | <Space>vb or :board: a column per node without a parent, its children as cards, a card with children wrapping them as Scratch's loop blocks do; j k cards, h l columns, M then hjkl (or a drag) moves a card |
Ctrl-w v Ctrl-w s |
split the pane side by side / stacked (Ctrl-w hjkl to move between them) |
gt gT |
the next / previous document |
: ? |
command line, help (search it with /, Enter runs the key or command) |
:e :new :bd |
open a document / make one / close it |
:export md :export txt |
the document (or, from visual mode, the selection) as Markdown or an outline (:export! writes over a file) |
:import file |
the nodes in a Markdown or text file, under this node |
:marks :jumps :registers |
what they hold: Enter goes there (or pastes) |
:w :q ZZ |
save / close the pane (the last one quits) / save and close |
After the first key of a sequence (g, z, d, <Space>…), a popup lists
what can follow. The right mouse button opens a menu of what you can do with
a node. Ctrl+click picks nodes one by one, and Ctrl+drag on the empty canvas
picks the ones in its rectangle. The wheel scrolls; with Shift or Alt held
(or a wheel that tilts), it scrolls sideways.
Development
cargo test # run the tests
cargo lint # clippy, treating warnings as errors
cargo fmt # format the code
To try things without touching your own documents:
cargo run --example canvas # cumulus on copies of two sample documents
cargo test show_canvas -- --ignored --nocapture # print the sample at each zoom, as text
The end-to-end tests (src/app/tests.rs) type keys and click on a test
terminal, with the sample documents copied to a temporary folder, and check
the screen, the documents and the files.