Add visual mode, node registers, search and the jump list (stage 8c)
The rest of vim, on nodes. Visual mode takes in what lies between where it started and the cursor: on the canvas, every node the rectangle from one end's box to the other's touches; in the outline and the Note view, the nodes in between in reading order. V takes whole branches, Ctrl+click and Ctrl+drag pick with the mouse, and the operators take exactly what's selected: d, y, > and <, M, and the pickers on every node at once. Registers now hold text or nodes, so yy, dd and x keep what they take and p, P and ]p paste it, layout and links included. "+ is the system clipboard through arboard: nodes go there as Markdown in the user's format (## headings, a --- tag list, the body), and come back whole while the clipboard still holds them. clipboard = "unnamedplus" makes plain yanks use it, as in vim. . repeats the last change made with keys, with the text typed after it. / opens a Telescope-style search: fuzzy matches over titles, tags and bodies, best first, with the note of the one you're on beside them; n and N go on with it, and :find searches straight away. Each pane keeps a jump list for Ctrl-o and Ctrl-i that crosses documents and reopens closed ones. Capital marks lead into any document and, like the small ones, are kept in memory.ron. gd follows a cross-link, and :marks, :jumps and :registers list what they hold. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
abe3dc1d84
commit
7bec5bf3fc
45 files changed
+3922
-272
No files matched your search
@@ -32,7 +32,8 @@ align · branch out · export (Markdown, plain text) and import (indented lists)
|
||||
|
||||
**Later**: peeking into portals and pulling a document back in · branches that
|
||||
keep themselves tidy · the Links map · backlinks inside a document · picking
|
||||
single nodes in visual mode · `Alt+hjkl` · opening a body in `$EDITOR` ·
|
||||
single nodes in visual mode with keys (Ctrl+click does it with the mouse) ·
|
||||
`Alt+hjkl` · opening a body in `$EDITOR` ·
|
||||
persistent undo · sessions · operator + motion and macros · a tutorial
|
||||
document · checkbox, link and date fields · Graphviz and Mermaid export · a
|
||||
Settings view · vim tab pages.
|
||||
@@ -122,10 +123,8 @@ lines.
|
||||
- A title left empty comes back as it was, with a note saying so; a new idea
|
||||
left empty goes away.
|
||||
- Registers are shared by the whole app, as in vim: text yanked in one title
|
||||
pastes into another. `"+` stays inside cumulus until part 8c connects it to
|
||||
the system clipboard.
|
||||
- `.` inside the text repeats the last change there, typing included. `.` on
|
||||
nodes comes with node yank and paste, in part 8c.
|
||||
pastes into another. `"+` is the system clipboard (part 8c).
|
||||
- `.` inside the text repeats the last change there, typing included.
|
||||
- As in vim: `cw` changes to the end of the word, `dw` stops at the end of the
|
||||
line, `j` and `k` move by lines of text rather than wrapped rows, Esc steps
|
||||
back onto the last letter typed.
|
||||
@@ -140,6 +139,62 @@ lines.
|
||||
editor: Enter starts a new line, Tab types four spaces. `cc`, `C` and `s`
|
||||
start typing on an empty line too, as in vim (bodies are often empty).
|
||||
|
||||
**The rest of vim** (settled in part 8c)
|
||||
- Visual mode takes in what lies between where it started and the cursor:
|
||||
on the canvas, every node on show that the rectangle from one end's box to
|
||||
the other's touches; in the outline and the Note view, the nodes in
|
||||
between in reading order. `V` takes each with its whole branch; `v` in a
|
||||
`V` selection (and `V` in a `v` one) switches, and the same key again
|
||||
stops. Ctrl+click adds or takes out one node; Ctrl+drag on empty canvas
|
||||
adds every node its rectangle touches. The selection is drawn thick in
|
||||
the theme's visual color, and the status bar counts it.
|
||||
- Operators take exactly what's selected (the user's pick): `d` deletes the
|
||||
selected nodes, and with `v` their unselected children move up, as with
|
||||
`x`; `y` yanks them with their shape among them; `>` and `<` move nodes
|
||||
that share a parent; `M` moves them on the canvas (with their branches, or
|
||||
just them after `M` again); the pickers set every one of them, as one undo
|
||||
step.
|
||||
- A register holds text or nodes, and either pastes anywhere: nodes pasted
|
||||
into a text give their titles, text pasted on nodes becomes nodes. `yy`,
|
||||
`yab`, `yib` yank nodes; every delete (`dd`, `x`, `dib`, `d` on a
|
||||
selection) keeps what it took, so `dd` then `p` moves a branch. `p` `P`
|
||||
`]p` paste after, before, or as the last children, keeping the yanked
|
||||
layout, where a new node would go; a count pastes copies. Links between
|
||||
the pasted nodes come along, and so do links to nodes still there when
|
||||
they go back into the document they came from.
|
||||
- `"+` is the system clipboard. Nodes go there as Markdown, the user's
|
||||
format: a heading per node (`##` for the nodes yanked, `###` for their
|
||||
children, `####` for anything deeper), its tags as a list between two
|
||||
`---` lines, then its body. While the clipboard still holds what cumulus
|
||||
put there, `"+p` gives back everything (colors, bodies, links, the
|
||||
layout); text from elsewhere becomes nodes (Markdown headings, or a node
|
||||
per line nested by its indent). `clipboard = "unnamedplus"` makes every
|
||||
yank, delete and paste use the clipboard, as vim's setting does.
|
||||
- `.` repeats the last change made with keys in normal or visual mode: the
|
||||
command with its count and register, plus everything typed in the text
|
||||
edit it started (`aMulch` then Esc adds another Mulch). A value picked in a
|
||||
picker repeats on the cursor's node. A change made on a selection repeats
|
||||
on the cursor's node (`d` as `x`, or `dd` after `V`; `>` as `>>`).
|
||||
- `/` opens a search in the middle of the screen, as Telescope does (the
|
||||
user's pick): what's typed at the top, the matches below it, fuzzy, best
|
||||
first (titles before tags before bodies), with the letters that matched
|
||||
standing out, and the note of the match you're on beside them. Case only
|
||||
matters once there's a capital (smartcase). Enter goes there, Esc goes
|
||||
back; `n` and `N` then go through the same matches, going round, and
|
||||
`:find` searches straight away.
|
||||
- Each pane keeps a jump list, as vim's windows do: `gg`, `G`, marks, a
|
||||
search, `gd`, a link followed in the Note view and switching documents are
|
||||
jumps. `Ctrl-o` goes back (into another document, opened again if it was
|
||||
closed), `Ctrl-i` or Tab forward. `''` still goes back to before the last
|
||||
jump.
|
||||
- Capital marks (`mA`, `'A`) lead into any document, opening it if it isn't
|
||||
open; they're kept in the data folder's `memory.ron`, and the small ones
|
||||
(`ma`) are kept there with each document, so both last from one run to
|
||||
the next.
|
||||
- `gd` follows the cursor's cross-link; with several, a list of them pops up
|
||||
beside the node. `:marks`, `:jumps` and `:registers` list them; Enter goes
|
||||
to the mark or the place, or pastes the register.
|
||||
|
||||
**Views, panes and popups** (settled in stage 7)
|
||||
- The Note view is made of parts: the title, the tags, the body, each link
|
||||
(out, then in) and each child. `j` and `k` step through them, with a bar
|
||||
@@ -378,7 +433,7 @@ text).
|
||||
| **Inside text** | `h j k l w b e 0 ^ $ gg G` (and arrows, Home, End) · `f t F T ; ,` · `d` `c` `y` with any motion and `iw aw i" a" i( a(` · `x X s S D C Y` · `r ~ J p P` · `u Ctrl-r .` · `i a I A` back to typing · `o O` (title: a new sibling; body: a new line) · Esc done |
|
||||
| **Move mode** | `hjkl` 1 cell · `HJKL` 5 cells · `M` branch ↔ node · Enter or Esc done |
|
||||
| **Connect mode** | move to the target as usual · Enter link · `d` remove · `>` attach as child · `<Space>` style menu (`s` named, `a` arrows, `l` line, `c` color, `t` label) · Esc cancel |
|
||||
| **Visual** | `d y > < M C` and `<Space>c` `<Space>s` `<Space>t` act on the whole selection · `o` swaps ends |
|
||||
| **Visual** | `d` `x` `y` `>` `<` `M` and `<Space>c` `<Space>s` `<Space>B` `<Space>t` act on the whole selection · `o` swaps ends · `v` `V` switch, or stop · Ctrl+click, Ctrl+drag pick with the mouse |
|
||||
|
||||
## Files
|
||||
|
||||
@@ -471,6 +526,7 @@ max_node_width = 30
|
||||
glyphs = "unicode" # "ascii" for fonts without box-drawing characters
|
||||
completion_popup = "as-you-type" # "on-tab": only after Tab, like vim's wildmenu
|
||||
editor = "" # what :config opens files in ("nvim", "code --wait")
|
||||
clipboard = "cumulus" # "unnamedplus": plain y, d and p use the system clipboard
|
||||
|
||||
# keys.toml: sections motions, normal, canvas, outline, note, visual, move,
|
||||
# connect, list, card, text (vim keys inside text), insert (typing: one key each,
|
||||
@@ -518,10 +574,10 @@ question = "question" # a #question node gets the "question" style
|
||||
```
|
||||
|
||||
**Data folder** (`%APPDATA%\cumulus\data`, `~/.local/share/cumulus` on Linux):
|
||||
`memory.ron` (where you left off in each document, keyed by `uid`, the command
|
||||
history, recent documents; capital marks come in part 8c), `backups/` and
|
||||
`locks/`. If a second cumulus opens a document that's already open, it opens
|
||||
it read-only.
|
||||
`memory.ron` (where you left off in each document, keyed by `uid`, with its
|
||||
marks; the capital marks; the command history; recent documents), `backups/`
|
||||
and `locks/`. If a second cumulus opens a document that's already open, it
|
||||
opens it read-only.
|
||||
|
||||
**Command line**
|
||||
- `cumulus` opens `./ideas.cum`, or `~/ideas.cum` if the current folder doesn't
|
||||
@@ -546,7 +602,7 @@ cumulus/
|
||||
├─ main.rs command-line arguments, then app::run
|
||||
├─ lib.rs the module list
|
||||
├─ model/ ids, text, geometry, look, node, portal, link, document, edit, op (edits as
|
||||
│ data), history, fold
|
||||
│ data), history, fold, clip (nodes taken out, to paste)
|
||||
├─ input/ key (vim notation), command (Command enum + names), bindings (default tables),
|
||||
│ keymap (+ keys.toml), engine (counts, registers, operators), mouse
|
||||
├─ command/ registry, parse, complete, history
|
||||
@@ -559,21 +615,25 @@ cumulus/
|
||||
├─ config/ paths (the config and data folders), settings (config.toml, `:set`), keys_file
|
||||
│ (keys.toml's template), theme_file (themes laid over the built-in one)
|
||||
├─ storage/ document_file (RON), write_atomically, names (file names from titles), backup,
|
||||
│ lock, stamp (noticing changes made outside), memory (memory.ron)
|
||||
│ lock, stamp (noticing changes made outside), memory (memory.ron), markdown
|
||||
│ (nodes as Markdown, for the clipboard)
|
||||
└─ app/ mod.rs (App), input (keys and the mouse, routed), update (carrying actions out),
|
||||
render, terminal (the main loop, setup, teardown, panic hook), startup (what
|
||||
`cumulus` opens), documents (the open documents and their files), files
|
||||
(saving, reloading, locks, where you left off), configure (settings, keys and
|
||||
themes applied; `:config`), action, mode, buffer, commands
|
||||
(keys every view shares), calls (`:` commands), text_edit (a node's text being
|
||||
edited, rapid entry), registers, panes (the split tree), popup (help, menu,
|
||||
pickers, card, questions); later jumps, portals (cache, backlinks, renames)
|
||||
edited, rapid entry), registers (text or nodes), clipboard (the system's, for
|
||||
"+), yank (nodes into registers and back), visual (selections), repeat (`.`),
|
||||
search (`/`), jumps (each pane's jump list), marks (capital marks, `:marks`),
|
||||
panes (the split tree), popup (help, menu, pickers, card, questions); later
|
||||
portals (cache, backlinks, renames)
|
||||
```
|
||||
|
||||
The end-to-end tests are in `app/tests.rs` (with `app/tests/files.rs` and
|
||||
`app/tests/config.rs`): they copy the sample documents to a temporary folder,
|
||||
type keys and click on a test terminal, and check the screen, the documents
|
||||
and the files.
|
||||
The end-to-end tests are in `app/tests.rs` (with `app/tests/files.rs`,
|
||||
`app/tests/config.rs` and `app/tests/vim.rs`): they copy the sample
|
||||
documents to a temporary folder, type keys and click on a test terminal, and
|
||||
check the screen, the documents and the files.
|
||||
|
||||
**Flow:** a terminal event comes in → the key engine turns keys into a typed
|
||||
`Command` (with its count and register) → the focused view answers it with
|
||||
|
||||
Reference in new issue
Block a user