From 4612901858b229533c8e2ffc36db3da6bbadaa32 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 7 Jul 2026 21:32:24 -0300 Subject: clicks in a shell pane never change its mode: the body-press exitTagEdit no longer force-drops to normal (it only restores the mode a tag edit hijacked, remembered in pane.tag_mode), and the left-release cursor pin keeps the terminal's mode (files still click into normal). New ttyclick.snap covers tty body click, tty tag round trip, insert body click. --- src/pardes.zig | 18 ++++++++++++++---- src/tutor.txt | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/pardes.zig b/src/pardes.zig index 53ec4172..8fb0b43d 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -525,6 +525,9 @@ pub const Pane = struct { tag_init: bool = false, tag_edit: bool = false, tag_sel: bool = false, + /// the body mode a tag edit hijacked (tags are always insert); terminals + /// restore it on exit so clicking the tag never changes the pane's mode + tag_mode: Mode = .normal, tag_col: u16 = 0, tag_anchor: u16 = 0, ed_undo: std.ArrayList(EditSnap) = .empty, @@ -1001,6 +1004,7 @@ pub const Pardes = struct { pane.tag_tail.appendSlice(p.gpa, if (pane.file != null) file_pane_tail else pane_tail) catch return; pane.tag_init = true; } + if (!pane.tag_edit) pane.tag_mode = pane.mode; pane.tag_edit = true; pane.tag_sel = false; // a one-line tag has no use for normal mode: always insert @@ -1011,10 +1015,15 @@ pub const Pardes = struct { } fn exitTagEdit(pane: *Pane) void { + // tags are always insert; leaving one restores the body mode: files + // back to normal, terminals to whatever they had — a click (this runs + // on every body press) must never change a shell pane's mode + if (pane.isTerminal()) { + if (pane.tag_edit) pane.mode = pane.tag_mode; + } else pane.mode = .normal; pane.tag_edit = false; pane.tag_sel = false; pane.search_edit = false; // an abandoned `/` input stays as tag text - pane.mode = .normal; // tags are always insert; leaving one never is } fn tagSelBounds(pane: *Pane) struct { lo: usize, hi: usize } { @@ -3705,8 +3714,9 @@ pub const Pardes = struct { pane.sel[b].state = .done; if (s.button == .left) { // keep a dragged selection highlighted; a plain click clears - // it. Either way pin the cursor + enter normal mode on text - // panes (tty keeps the mouse usable without dropping modes). + // it. Either way pin the cursor; files also enter normal + // mode, terminals keep the mode they had (tty keeps the + // mouse usable, insert keeps typing where you clicked). const sl = pane.sel[0]; const dragged = sl.c0 != sl.c1 or sl.r0 != sl.r1; if (!dragged) pane.sel[0].state = .none; @@ -3716,7 +3726,7 @@ pub const Pardes = struct { pane.cur_col = if (pane.file != null) @max(0, sl.c1 - @as(i32, PREFIX_W)) + pane.hscroll else sl.c1; pane.cur_off = if (pane.runAt(pane.cur_row, pane.cur_col)) |i| pane.edits[i].len else 0; pane.cur_pinned = true; - pane.mode = .normal; + if (!pane.isTerminal()) pane.mode = .normal; pane.msel.active = false; pane.pending = 0; } diff --git a/src/tutor.txt b/src/tutor.txt index 4c162b97..815cd4f7 100644 --- a/src/tutor.txt +++ b/src/tutor.txt @@ -58,6 +58,7 @@ L select a plain click also FOCUSES the pane and PINS the modal cursor where you click, so you can edit there next. + A click never changes a pane's MODE (tty stays tty). M execute run the selected text: a builtin name runs it, anything else is SENT to the shell the pane runs. This is how you run a command you typed in a text mode. -- cgit v1.3