diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 00:13:11 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 42748f92b77367db415c8b4d0f2e537a9e1ddde7 (patch) | |
| tree | 3ff6606d33149581d5954dcc900eb6ab3e4f0f17 /src/mouse.zig | |
| parent | 23f430573efe4f6ef55b0180aa0d742ff4eca1d9 (diff) | |
| download | pardes-42748f92b77367db415c8b4d0f2e537a9e1ddde7.tar.gz pardes-42748f92b77367db415c8b4d0f2e537a9e1ddde7.zip | |
Make the column and workspace tags Texts with the pane tag's keys
The headers had their own one-line editor with its own keys: Enter always
executed, h/l and J/K moved between headers and panes, Ctrl-c/x/v cut and
pasted, and TagLine refused a newline that 9P accepted. They are now Texts
like a pane's tag, with no prefix and a default until edited, so normal and
insert mode, undo and the look and execute keys are the body's. Moving
between them is the window keys' job: Up from a pane with nothing above it
reaches its column's tag and then the workspace's, Down comes back, and
Left and Right walk the column tags.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/mouse.zig')
| -rw-r--r-- | src/mouse.zig | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/mouse.zig b/src/mouse.zig index ae047c58..343051b0 100644 --- a/src/mouse.zig +++ b/src/mouse.zig @@ -292,9 +292,17 @@ pub fn handleMouse(p: *Pardes, m: Mouse) void { } } if (p.header_drag and m.button == config.select_button and (m.kind == .drag or m.kind == .release)) { + const t = p.focusedHeader() orelse { + p.header_drag = false; + return; + }; const x = if (p.header_column) |c| p.col_x[c] + TAG_TEXT_INSET else 0; - const bar = p.headerText(); - p.topbar_col = @intCast(@min(bar.len, panes.File.rawAtDisplay(bar, (tagColumn(p, if (p.header_column != null) .column else .workspace, p.header_column orelse 0, p.pointer_tag_hit, p.header_drag) orelse (mcol -| x)) + p.header_scroll))); + const bar = modal.lineSlice(edit.flatSurface(p, t) catch return, 0); + const at = @min(bar.len, panes.File.rawAtDisplay(bar, (tagColumn(p, if (p.header_column != null) .column else .workspace, p.header_column orelse 0, p.pointer_tag_hit, p.header_drag) orelse (mcol -| x)) + p.header_scroll)); + // the anchor stays where the press put it + t.cur_row = 0; + t.cur_col = @intCast(at); + t.vsel.active = t.vsel.col != t.cur_col; if (m.kind == .release) p.header_drag = false; return; } @@ -318,25 +326,25 @@ pub fn handleMouse(p: *Pardes, m: Mouse) void { }; if (column == null or mcol < x) return; } - if (p.header_column != column) { - p.rememberHeader(); - p.topbar_col = null; - p.header_anchor = null; - p.header_scroll = 0; - } - p.header_column = column; - const bar = p.headerText(); - const at = @min(bar.len, panes.File.rawAtDisplay(bar, (tagColumn(p, if (p.header_column != null) .column else .workspace, p.header_column orelse 0, p.pointer_tag_hit, p.header_drag) orelse (mcol -| x)) + p.header_scroll)); + const t = if (column) |c| &p.col_tags[c] else &p.global_tag; + const focused = p.header_focus and p.header_column == column; + const bar = modal.lineSlice(edit.flatSurface(p, t) catch return, 0); + const scroll = if (focused) p.header_scroll else 0; + const at = @min(bar.len, panes.File.rawAtDisplay(bar, (tagColumn(p, if (column != null) .column else .workspace, column orelse 0, p.pointer_tag_hit, p.header_drag) orelse (mcol -| x)) + scroll)); if (m.button == config.select_button) { - p.topbar_col = @intCast(at); - p.header_anchor = @intCast(at); - p.header_insert = true; + // A clicked header is typed straight into, as a clicked tag is. + if (!focused) p.enterHeader(column); + t.mode = .insert; + t.cur_row = 0; + t.cur_col = @intCast(at); + t.vsel = .{ .active = false, .row = 0, .col = @intCast(at) }; p.header_drag = true; } else { - const selected = if (p.topbar_col) |cur| blk: { - const a = p.header_anchor orelse cur; - break :blk if (at >= @min(a, cur) and at < @max(a, cur)) bar[@min(a, cur)..@max(a, cur)] else wordAtCol(bar, at); - } else wordAtCol(bar, at); + const span = if (focused) Pardes.headerSelection(t, bar) else null; + const selected = if (span) |sp| + (if (at >= sp.lo and at < sp.hi) bar[sp.lo..sp.hi] else wordAtCol(bar, at)) + else + wordAtCol(bar, at); const word = p.scratch.allocator().dupe(u8, selected) catch return; p.exitHeader(); if (word.len > 0) { |
