diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 08:58:46 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 66c0106691e4de925011f314200e85ee265b7861 (patch) | |
| tree | 8c9172bd1c51de1abea67d0f75c598d32a9ae53f | |
| parent | 590e98bc3a198b86aaeca2168c4ac65d5cd777d0 (diff) | |
| download | pardes-66c0106691e4de925011f314200e85ee265b7861.tar.gz pardes-66c0106691e4de925011f314200e85ee265b7861.zip | |
Run the word under the cursor when Enter is pressed in a header
The workspace and column tags hold nothing but commands, and before they
became texts Enter on one of them ran it: Enter on Newcol made a column.
Since then Enter looked the word up, as it does in a pane's tag, which only
searched for it. It runs it again, and the header lets go of the keyboard
first as a pane tag does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | docs/helix-keys.md | 2 | ||||
| -rw-r--r-- | docs/tags.md | 9 | ||||
| -rw-r--r-- | src/pardes.zig | 18 |
3 files changed, 23 insertions, 6 deletions
diff --git a/docs/helix-keys.md b/docs/helix-keys.md index 64fa2e24..28641a71 100644 --- a/docs/helix-keys.md +++ b/docs/helix-keys.md @@ -117,7 +117,7 @@ language-backend queries, and the shell pipe. | `Esc` (insert) | back to normal mode, cursor right after the insertion (no vim left-step) | | helix-verified | | `Enter` (normal) | acme **look** chord: EXPLICIT selection, else file-ish word under cursor | pardes-specific, keep (helix normal-mode Enter unbound). Covers helix `gf`. Implicit motion residue falls back to the cursor word | pardes-specific | | `Tab` (normal) | acme **execute** chord | pardes-specific, keep; explicit-selection rule as Enter | pardes-specific | -| `:` (normal, body or tag) | in the body, focuses the pane's tag in normal mode at its remembered cursor (the first time, on `Save`); in the tag, goes back to the body; in a column or workspace tag, back to the active pane. The tag's normal and insert modes ARE the body's: every motion, selection, edit and undo works there, `0` meaning the start of the editable text. Enter/Tab Look/Exec the word under the cursor or the selection, and executing hands the keyboard back to the body first. Clicks choose a new cursor position and type into the tag. | Each tag keeps its own cursor during the session. Cursor, selections and undo are offsets in the tag's own text; the computed path/marker/page before it is seen by the mouse, Look and Exec but not by keyboard motions. File-name changes are staged as described in [editable tags](tags.md). | pardes-specific | +| `:` (normal, body or tag) | in the body, focuses the pane's tag in normal mode at its remembered cursor (the first time, on `Save`); in the tag, goes back to the body; in a column or workspace tag, back to the active pane. The tag's normal and insert modes ARE the body's: every motion, selection, edit and undo works there, `0` meaning the start of the editable text. Tab runs the word under the cursor or the selection and Enter looks it up (in a column or workspace tag Enter runs it too), and either hands the keyboard back to the body first. Clicks choose a new cursor position and type into the tag. | Each tag keeps its own cursor during the session. Cursor, selections and undo are offsets in the tag's own text; the computed path/marker/page before it is seen by the mouse, Look and Exec but not by keyboard motions. File-name changes are staged as described in [editable tags](tags.md). | pardes-specific | | `Ctrl-w k` / `SPC w k` (pane with nothing above) | focuses its column's tag, then the workspace tag; with `ColumnTags` disabled it goes directly to the workspace. `Ctrl-w j` walks back to the panes, `Ctrl-w h`/`l` walk the column tags. Headers edit exactly as a pane tag does. | Column commands target that column's active pane, or its first pane when coming from elsewhere. Workspace and column text are independently editable and persist in dumps. See [editable tags](tags.md). | pardes-specific | | `Ctrl-w` + `h/j/k/l`/arrows | directional pane focus prefix — editor normal mode only | pardes' own window handling (helix window mode skipped, section C). Runs the SAME `Left`/`Down`/`Up`/`Right` builtins `SPC w h/j/k/l` runs; Raw **tty** mode forwards Ctrl-w to the child. Insert mode owns `Ctrl-w` = delete-word-back, so a tag being TYPED into swallows it; from a tag in normal mode it moves focus to the neighbour's BODY, as from a body, and from the top pane `Up` reaches the column and workspace tags | pardes-specific | | `Alt-n` | new terminal below (outside raw tty) | shadows helix `Alt-n` TS sibling-select — skipped anyway (tree-sitter) | pardes-specific | diff --git a/docs/tags.md b/docs/tags.md index ecca046a..45a0cb3b 100644 --- a/docs/tags.md +++ b/docs/tags.md @@ -59,10 +59,11 @@ in the tag's own text: `0` goes to its start, not the path's. Left-click a tag or a header to type into it at the click, in insert mode; tags reveal the caret horizontally when text is wider than their column. -Esc is normal mode, where everything a body's normal mode does works, and -Enter looks up and Tab executes the word under the cursor (or an explicit -selection), in either mode. Executing gives the keyboard back to the body -first, so `Del`, `Kill` and `Restore` never return into a tag that is gone. +Esc is normal mode, where everything a body's normal mode does works. There +Tab executes the word under the cursor (or an explicit selection), and Enter +looks it up in a pane's tag but runs it in a column or workspace tag, whose +words are all commands; in insert mode Enter is a new line. Executing gives +the keyboard back to the body first, so `Del`, `Kill` and `Restore` never return into a tag that is gone. Pasted text goes to the focused tag, not to the file or embedded shell beneath it. diff --git a/src/pardes.zig b/src/pardes.zig index b7cf5574..3194b059 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -2911,6 +2911,19 @@ test "a header's execute key runs the word under its cursor and lets go of the k try std.testing.expectEqual(@as(usize, 1), p.col_n[0]); } +test "Enter in a header runs the word under its cursor, as the execute key does" { + const p = try Pardes.init(std.testing.allocator, .{ .cols = 100, .rows = 12, .tty_only = true }); + defer p.deinit(); + _ = try p.setTestFile("body\n"); + try std.testing.expectEqual(@as(usize, 1), p.ncol); + tagline.enterHeader(p, null); + p.global_tag.cur_col = @intCast(std.mem.indexOf(u8, config.topbar_str, "Newcol").?); + p.update(.{ .key = .{ .cp = Key.enter } }); + try std.testing.expectEqual(@as(usize, 2), p.ncol); + // and the header lets go of the keyboard, as a pane tag does + try std.testing.expect(!p.header_focus); +} + test "window keys walk from a pane up through the column and workspace tags and back" { const p = try Pardes.init(std.testing.allocator, .{ .cols = 100, .rows = 20, .tty_only = true }); defer p.deinit(); @@ -4933,7 +4946,10 @@ pub const Pardes = struct { return; } if (t.mode == .normal and (hit(key, config.look_key) or hit(key, config.exec_key))) { - const cmd = if (hit(key, config.look_key)) config.look_cmd else config.exec_cmd; + // A header's words are the workspace's and column's commands, so + // Enter runs them there, as the execute key does. + const header_word = t.what == .column or t.what == .workspace; + const cmd = if (hit(key, config.look_key) and !header_word) config.look_cmd else config.exec_cmd; if (t.what != .body) { // An explicit selection, else the word under the cursor in the // text as it is shown: a tag's prefix is part of what a word is. |
