diff options
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index a85c97ab..992311a2 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -5319,6 +5319,12 @@ pub const Pardes = struct { return; } const pane = p.panes[p.active] orelse return; + // Alt-Down and Alt-Up in a pane's tag expand and collapse it, in + // either mode: acme's Tagdown and Tagup (plan9port text.c:776). + if (pane.focus == .tag and key.alt and !key.ctrl and (key.cp == Key.down or key.cp == Key.up) and tagline.focusedHeader(p) == null) { + pane.tag_expanded = key.cp == Key.down; + return; + } // An open prompt takes the keys even when it answers for a header. const header = if (pane.prompt != .none) null else tagline.focusedHeader(p); if (header == null and pane.isTerminal() and pane.body.mode == .tty and pane.focus == .body and pane.prompt == .none) { @@ -6142,11 +6148,30 @@ pub const Pardes = struct { } pane.tag_lead = lead; } - const lines = std.mem.count(u8, tagline.curTail(pane), "\n") + 1; - pane.tag_rows = @intCast(@min(lines, MAX_TAG_ROWS, @max(BOX_H, r.h -| 1))); + // A row per shown row: the tag's lines wrapped at its width. + var wrap_room: [32 * 1024]u8 = undefined; + var wrap_fba = std.heap.FixedBufferAllocator.init(&wrap_room); + const wa = wrap_fba.allocator(); + var lines = std.mem.count(u8, tagline.curTail(pane), "\n") + 1; + var wanted = lines; + var caret_row: usize = @intCast(@max(0, pane.tag.cur_row)); + if (tagline.prefixIn(wa, pane)) |prefix| { + if (std.mem.concat(wa, u8, &.{ prefix, tagline.curTail(pane) })) |whole| { + if (tagline.wrapTag(wa, whole, tagline.tagWidth(p, id))) |shown| { + lines = shown.rows(); + // Collapsed, one row, as acme's Tagup sets taglines to 1 + // (plan9port text.c:786). + wanted = if (pane.tag_expanded) lines else 1; + const cur = modal.offsetAt(whole, .{ .row = caret_row, .col = @intCast(@max(0, pane.tag.cur_col)) }); + caret_row = std.mem.count(u8, shown.text[0..@min(shown.fromReal(cur), shown.text.len)], "\n"); + } else |_| {} + } else |_| {} + } else |_| {} + if (!pane.tag_expanded) wanted = 1; + pane.tag_rows = @intCast(@min(wanted, MAX_TAG_ROWS, @max(BOX_H, r.h -| 1))); if (pane.collapsed) pane.tag_rows = BOX_H; if (pane.focus == .tag and pane.prompt != .name) { - const cur: usize = @intCast(@max(0, pane.tag.cur_row)); + const cur: usize = caret_row; var top: usize = pane.tag_top; if (cur < top) top = cur; if (cur >= top + pane.tag_rows) top = cur + 1 - pane.tag_rows; |
