Make marks and counts work, and the completion popup a setting

Marks: the engine read `ma` and `'a`, but the canvas example only said
they'd come later. It now sets and jumps to marks, and `''` goes back to
where the cursor was before the last jump (a mark, gg, G or :find).
Which-key lists `'` after `'`.

Counts on operators now mean something on nodes: `3dd` deletes this node
and the next two siblings, with their branches, the way vim's `3dd`
deletes three lines (Document::siblings_from). Counts before the operator
and before the target still multiply, and which-key now says what they
add up to: after `2d3`, the `d` entry reads "6 nodes: this one and the
next 5 siblings, with their branches".

The completion popup can now wait for Tab, like vim's wildmenu: the
`completion_popup` setting is "as-you-type" (the default) or "on-tab".
The config file comes with the app core; until then the example takes
`:set completion_popup=on-tab`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
skkeyeandClaude Opus 5.5 committed 2026-10-01 04:17:41 -04:00
1 parent bfc184f5ef
commit 57ba2c275d
6 files changed
+199 -35

No files matched your search

+17 -2
View File
@@ -186,10 +186,19 @@ impl KeyEngine {
let entries = next_keys(&self.keys, &tables.commands_starting_with(&self.keys), tables);
Some(Hints { title, entries })
}
Stage::Target { operator, operator_keys, .. } => {
Stage::Target { operator, operator_keys, count } => {
let mut entries = Vec::new();
if self.keys.is_empty() {
let help = "this node, with its branch".to_string();
// A count takes in the next siblings, as `3dd` takes three
// lines in vim: say exactly how many.
let help = match multiply(*count, self.count).unwrap_or(1) {
1 => "this node, with its branch".to_string(),
2 => "2 nodes: this one and the next sibling, with their branches".to_string(),
many => format!(
"{many} nodes: this one and the next {} siblings, with their branches",
many - 1
),
};
entries.push(Hint { keys: notation(operator_keys), help, group: false });
}
let targets = tables.targets_starting_with(&self.keys);
@@ -430,6 +439,12 @@ mod tests {
assert_eq!(keys, ["d", "a", "i"]);
assert!(hints.entries[1].group);
engine.reset();
type_keys(&mut engine, &keymap, "2d3");
let hints = engine.hints(&tables).unwrap();
assert_eq!(hints.title, "2d3 · delete");
assert_eq!(hints.entries[0].help, "6 nodes: this one and the next 5 siblings, with their branches");
engine.reset();
type_keys(&mut engine, &keymap, "\"");
assert_eq!(engine.hints(&tables).unwrap().title, "\" · register");