diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-24 09:45:50 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | a39fb20cb770c3adb911cec7d1f3d033669ed1bb (patch) | |
| tree | e7bb88af15990e502b5f4deac5493ea2957e8b24 /test | |
| parent | 39cdba439c1ae47dbc7c3243a9273aa011c6affa (diff) | |
| download | pardes-a39fb20cb770c3adb911cec7d1f3d033669ed1bb.tar.gz pardes-a39fb20cb770c3adb911cec7d1f3d033669ed1bb.zip | |
Light a held column grip, and rail its landing beside the rule where the GUI shows it
The column grip worked in the GUI but showed nothing anyone could see.
Driving the real SDL window with pixel mouse events, press, drag and
release all reach the core and reorder or resize the column; the feedback
is what failed. The grip kept its muted color while held, and a reorder's
insertion rail was drawn in the gutter cell at the destination edge. The
GUI paints that cell as the column's scroll rail, and at the window's left
edge, the common case of moving the right column first, the dashes were
lost in it. From the leftmost column, a drag short of a neighbour's middle
shows no rail, rightly, since nothing would move, but nothing said the
grip was even held.
A held grip now lights in column_box, the accent its muted color is mixed
from, and the rail takes that color. The rail runs in the seam cell left of
where the column's rule will land, where a border drag's rail runs, for a
reorder and a left-edge move alike; at the window's left edge, which has no
seam, it runs just past the scroll rail, leaving column 0's grip and pane
boxes whole. A carried column's pointer aims at a place, not a word, so the
column tags no longer light the word under it, and a release snaps the
layout as a border drag's does rather than animating it. The preview and the release both
ask layout.columnDrop where the column goes, so the rail stands where the
release puts the edge, and the drag no longer carries its unused column
index.
The GUI test feed takes ESC]777;mouse;<down|up|motion>;<button>;<x>;<y> in
window pixels and dispatches it as an SDL event. test/column_grip.py uses
it to drive the grip through the same pixel-to-cell and tag hit path as a
hand on the mouse, and checks the grip, the rail and the result against
GPU captures and the 9P grid.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Diffstat (limited to 'test')
| -rw-r--r-- | test/column_drag.zig | 89 | ||||
| -rw-r--r-- | test/column_grip.py | 132 | ||||
| -rw-r--r-- | test/snapshots/colgrip.golden | 170 | ||||
| -rw-r--r-- | test/snapshots/colgrip.snap | 35 |
4 files changed, 424 insertions, 2 deletions
diff --git a/test/column_drag.zig b/test/column_drag.zig index 85dca66b..b2b8f35d 100644 --- a/test/column_drag.zig +++ b/test/column_drag.zig @@ -176,7 +176,7 @@ test "column grip is separate from compact text and the resize seam" { p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = seam, .row = body_row } }); } -test "column grips stay blank and muted across focus hover and drag" { +test "column grips stay blank, and muted across focus and hover until grabbed" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 20 }); defer p.deinit(); _ = try p.setTestFile("left\n"); @@ -198,11 +198,12 @@ test "column grips stay blank and muted across focus hover and drag" { _ = frame.reset(.retain_capacity); const surface = try p.render(frame.allocator()); const muted: pardes.Color = .{ .rgb = p.chromeTheme().column_box_dim }; + const lit: pardes.Color = .{ .rgb = p.chromeTheme().column_box }; for (0..p.ncol) |column| { for (0..config.GUTTER) |offset| { const cell = surface.at(p.col_x[column] + @as(u16, @intCast(offset)), pardes.TOPBAR_H); try std.testing.expectEqualStrings(" ", cell.grapheme()); - try std.testing.expectEqual(muted, cell.style.bg); + try std.testing.expectEqual(if (dragging and column == active_column) lit else muted, cell.style.bg); try std.testing.expectEqual(pardes.FontRole.tagline, cell.style.font_role); } try std.testing.expectEqual(p.col_x[column] + pardes.TAG_TEXT_INSET, (try tagLayer(p, column)).viewport.x); @@ -252,3 +253,87 @@ test "column grip dropped in its own place moves the column's left edge" { try std.testing.expectEqual(serials[1], p.col_serial[0]); try std.testing.expectEqual(serials[0], p.col_serial[1]); } + +/// The column of the drag preview's rail, checked to run the full height +/// below the workspace tag in the grabbed grip's color, except through the +/// grip and pane boxes at the window's left edge. +fn previewRail(p: *Pardes, frame: *std.heap.ArenaAllocator) !?u16 { + _ = frame.reset(.retain_capacity); + const surface = try p.render(frame.allocator()); + const lit: pardes.Color = .{ .rgb = p.chromeTheme().column_box }; + var found: ?u16 = null; + for (0..surface.cols) |x| { + if (!std.mem.eql(u8, surface.at(@intCast(x), surface.rows - 1).grapheme(), "╎")) continue; + try std.testing.expect(found == null); + found = @intCast(x); + for (p.topBarHeight()..surface.rows) |row| { + const cell = surface.at(@intCast(x), @intCast(row)); + if (x < config.GUTTER and cell.style.font_role == .tagline) { + try std.testing.expect(!std.mem.eql(u8, cell.grapheme(), "╎")); + continue; + } + try std.testing.expectEqualStrings("╎", cell.grapheme()); + try std.testing.expectEqual(lit, cell.style.fg); + } + } + return found; +} + +test "column grip drag previews where the column lands, in the seam beside its rule" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 120, .rows = 24 }); + defer p.deinit(); + _ = try p.setTestFile("body\n"); + p.presentation.enabled = false; + p.settings.column_tags = true; + for (0..2) |_| { + try std.testing.expect(p.executeBuiltinLine(p.active, "New")); + try std.testing.expect(layout.splitColumn(p, p.active, p.active, false)); + } + try std.testing.expectEqual(@as(usize, 3), p.ncol); + p.update(.tick); + var frame = std.heap.ArenaAllocator.init(p.gpa); + defer frame.deinit(); + _ = try p.render(frame.allocator()); + const serials = .{ p.col_serial[0], p.col_serial[1], p.col_serial[2] }; + + // Held on its own grip it lands nowhere new: no rail. + mouse(p, .press, p.col_x[1]); + mouse(p, .drag, p.col_x[1] + 1); + try std.testing.expectEqual(@as(?u16, null), try previewRail(p, &frame)); + // Over the first column's left half it goes first. The window edge has + // no seam, and the gutter there is the GUI's scroll rail, so the rail + // runs in the gutter's last cell. + mouse(p, .drag, 3); + try std.testing.expectEqual(@as(?u16, config.GUTTER - 1), try previewRail(p, &frame)); + // The pointer is over the first column's "New", but a carried column + // aims at a place: no word lights under it. + for (0..p.screen_w) |x| try std.testing.expect(!std.meta.eql(p.surface.at(@intCast(x), pardes.TOPBAR_H).style.bg, pardes.Color{ .rgb = p.theme().sel_bg })); + mouse(p, .release, 3); + try std.testing.expectEqual(serials[1], p.col_serial[0]); + try std.testing.expectEqual(serials[0], p.col_serial[1]); + + // Past the middle column's middle it lands after it: the rail is in the + // seam cell left of the last column's rule, where a border drag's is. + mouse(p, .press, p.col_x[0]); + const past = p.col_x[1] + p.col_w[1] - 2; + mouse(p, .drag, past); + try std.testing.expectEqual(@as(?u16, p.col_x[2] - 1), try previewRail(p, &frame)); + // Past the last column's middle: the window's last cell. + mouse(p, .drag, p.col_x[2] + p.col_w[2] - 1); + try std.testing.expectEqual(@as(?u16, p.screen_w - 1), try previewRail(p, &frame)); + mouse(p, .release, p.col_x[2] + p.col_w[2] - 1); + try std.testing.expectEqual(serials[0], p.col_serial[0]); + try std.testing.expectEqual(serials[2], p.col_serial[1]); + try std.testing.expectEqual(serials[1], p.col_serial[2]); + + // Short of a neighbour's middle the left edge moves, and the preview + // is the seam that edge will have: exactly where the release puts it. + const edge = p.col_x[2]; + mouse(p, .press, edge + 1); + mouse(p, .drag, edge + 1 - 6); + try std.testing.expectEqual(@as(?u16, edge - 6 - 1), try previewRail(p, &frame)); + mouse(p, .release, edge + 1 - 6); + _ = try p.render(frame.allocator()); + try std.testing.expectEqual(edge - 6, p.col_x[2]); + try std.testing.expectEqual(@as(?u16, null), try previewRail(p, &frame)); +} diff --git a/test/column_grip.py b/test/column_grip.py new file mode 100644 index 00000000..ac0341c3 --- /dev/null +++ b/test/column_grip.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Drag a column grip in the real SDL window with pixel mouse events. + +WAYLAND_DISPLAY=/run/user/1000/wayland-1 \\ + python3 -B test/column_grip.py zig-out/bin/pardes-gui /tmp/pardes-column-grip [--pad 7] + +The window is hidden (PARDES_TEST). Mouse events enter as ESC]777;mouse +sequences on stdin, which the GUI builds into SDL events and dispatches like +its own, so pixel-to-cell and tag hit testing run as they do under a hand. +9P observes the grid; each step leaves a PNG of the GPU frame in the output +directory: grip-rest, grip-resize-drag, grip-reorder-drag, grip-done. +""" +import argparse +import os +from pathlib import Path +import shutil +import subprocess +import time + +from fs import session +from ui_review import require, wait_for + + +def rows(client): + frame = client.screen() + cols = frame['cols'] + return [''.join(cell[0] for cell in frame['cells'][at:at + cols]) for at in range(0, len(frame['cells']), cols)] + + +def rail(client): + """The one column the drag preview's rail runs down, if any.""" + bottom = rows(client)[-1] + found = [x for x, ch in enumerate(bottom) if ch == '╎'] + require(len(found) <= 1, f'more than one rail: {found}') + return found[0] if found else None + + +def grab(root, label): + time.sleep(.5) + def convert(): + shutil.copyfile(root / 'latest.ppm', root / (label + '.ppm')) + return subprocess.run(['magick', str(root / (label + '.ppm')), str(root / (label + '.png'))], + stderr=subprocess.DEVNULL).returncode == 0 + require(wait_for(convert, 8), 'GPU capture did not contain a complete image') + return root / (label + '.png') + + +def pixel(path, x, y): + out = subprocess.run(['magick', str(path), '-format', f'%[pixel:p{{{x},{y}}}]', 'info:'], + capture_output=True, text=True, check=True) + return out.stdout.strip() + + +def run(args): + root = args.output.resolve() + shutil.rmtree(root, ignore_errors=True) + root.mkdir(parents=True, mode=0o700) + (root / 'config/pardes').mkdir(parents=True) + (root / 'config/pardes/init').write_text('Shell /bin/sh\n') + (root / 'w.txt').write_text('alpha\nbeta\n') + name = 'column-grip-' + str(os.getpid()) + launch = ['-c', 'stty cols 100 rows 30; exec "$@"', 'column-grip', + str(args.binary.resolve()), '--9p=' + name, str(root / 'w.txt')] + env = {'PARDES_TEST': '1', 'PARDES_TEST_CAPTURE_DIR': str(root), 'PARDES_TEST_COLS': '100', + 'PARDES_TEST_ROWS': '30', 'PARDES_TEST_PAD': str(args.pad)} + handles = {} + with session('/bin/sh', root, name, socket_name=name, tty=True, launch=launch, + inherited=env, terminal=handles) as (client, _): + def send(data): + os.write(handles['input_fd'], data.encode()) + + def mouse(kind, button, col, row): + # the middle of a grid cell, in window pixels + send(f'\x1b]777;mouse;{kind};{button};{(col + .5) * cw};{(row + .5) * ch}\x07') + time.sleep(.15) + + require(wait_for(lambda: 'Newcol' in rows(client)[0]), 'workspace tag never drew') + send('\x1bn') + time.sleep(.3) + send('\x1bc') + require(wait_for(lambda: rows(client)[1].count('New Tty') == 2), 'no second column') + require(wait_for(lambda: (root / 'latest.ppm').exists(), 8), 'GPU capture missing') + time.sleep(.5) + with open(root / 'latest.ppm', 'rb') as ppm: + ppm.readline() + width, height = map(int, ppm.readline().split()) + frame = client.screen() + cw = (width - args.pad) // frame['cols'] + ch = (height - args.pad) // frame['rows'] + edge = rows(client)[1].index('New Tty', 10) - 3 + + rest = grab(root, 'grip-rest') + mouse('down', 1, edge, 1) + held = grab(root, 'grip-held') + require(pixel(held, int((edge + 1) * cw), int(1.5 * ch)) != pixel(rest, int((edge + 1) * cw), int(1.5 * ch)), + 'a grabbed grip looks the same as a resting one') + require(rail(client) is None, 'a grip held in place previews a move') + + # Short of the left column's middle: the left edge follows, and the + # rail is the seam cell left of where the rule will be. + for col in range(edge, edge - 11, -1): + mouse('motion', 1, col, 1) + require(rail(client) == edge - 11, f'resize rail at {rail(client)}, wanted {edge - 11}') + grab(root, 'grip-resize-drag') + mouse('up', 1, edge - 10, 1) + require(wait_for(lambda: rows(client)[1].index('New Tty', 10) - 3 == edge - 10), 'left edge did not follow the grip') + edge -= 10 + + # Over the left column's left half: it goes first, and the rail runs + # just past the left window edge's scroll rail. + mouse('down', 1, edge, 1) + for col in range(edge, 4, -5): + mouse('motion', 1, col, 10) + require(rail(client) == 1, f'reorder rail at {rail(client)}, wanted 1') + grab(root, 'grip-reorder-drag') + mouse('up', 1, 5, 10) + require(wait_for(lambda: 'alpha' in rows(client)[3][50:]), 'the column did not move first') + require(rail(client) is None, 'the rail outlived the drag') + grab(root, 'grip-done') + print('ok', root) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('binary', type=Path) + parser.add_argument('output', type=Path) + parser.add_argument('--pad', type=int, default=0, help='leftover pixels past the grid (PARDES_TEST_PAD)') + run(parser.parse_args()) + + +if __name__ == '__main__': + main() diff --git a/test/snapshots/colgrip.golden b/test/snapshots/colgrip.golden new file mode 100644 index 00000000..e096a665 --- /dev/null +++ b/test/snapshots/colgrip.golden @@ -0,0 +1,170 @@ +== style rest grid=100x24 +|0: 0-70 #b2c3b8,#1d2824, 71-99 d,#1d2824, +|1: 0-1 #ffffff,#887455, 2-2 d,#1d2824, 3-34 #b2c3b8,#1d2824, 35-49 d,#1d2824, 50-51 #ffffff,#887455, 52-52 d,#26362d, 53-84 #becfc4,#26362d, 85-99 d,#26362d, +|2: 0-1 #ffffff,#496656, 2-2 d,#1d2824, 3-31 #b2c3b8,#1d2824, 32-36 #d3b0d9,#1d2824, 37-49 #b2c3b8,#1d2824, 50-51 #000000,#add38a, 52-52 d,#26362d, 53-81 #becfc4,#26362d, 82-84 #dfbce5,#26362d, 85-99 #becfc4,#26362d, +|3: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-7 #e5eee5,#0d1410, 8-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|4: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|5: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-99 d,#0d1410, +|6: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|7: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|8: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|9: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|10: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|11: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|12: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|13: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|14: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|15: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|16: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|17: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|18: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|19: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|20: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|21: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|22: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|23: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +== style held grid=100x24 +|1: 0-1 #ffffff,#887455, 2-2 d,#1d2824, 3-34 #b2c3b8,#1d2824, 35-49 d,#1d2824, 50-51 #000000,#f4c086, 52-52 d,#26362d, 53-84 #becfc4,#26362d, 85-99 d,#26362d, +== snap resize-drag grid=100x24 cursor=54,5 +|Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill +| New Tty Find Grep Joincol Delcol ╎ New Tty Find Grep Joincol Delcol +| /tmp/pardes-snap/colgrip/cwd/w.txt S╎ve Tty Col /tmp/pardes-snap/colgrip/cwd Tty Save Mode Filt +| 1 x ╎ ls +| ╎ w.txt +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +| ╎ +== style resize-drag grid=100x24 +|1: 0-1 #ffffff,#887455, 2-2 d,#1d2824, 3-34 #b2c3b8,#1d2824, 35-38 d,#1d2824, 39-39 #f4c086,#1d2824, 40-49 d,#1d2824, 50-51 #000000,#f4c086, 52-52 d,#26362d, 53-84 #becfc4,#26362d, 85-99 d,#26362d, +|2: 0-1 #ffffff,#496656, 2-2 d,#1d2824, 3-31 #b2c3b8,#1d2824, 32-36 #d3b0d9,#1d2824, 37-38 #b2c3b8,#1d2824, 39-39 #f4c086,#1d2824, 40-49 #b2c3b8,#1d2824, 50-51 #000000,#add38a, 52-52 d,#26362d, 53-81 #becfc4,#26362d, 82-84 #dfbce5,#26362d, 85-99 #becfc4,#26362d, +|3: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-7 #e5eee5,#0d1410, 8-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|4: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|5: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-99 d,#0d1410, +|6: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|7: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|8: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|9: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|10: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|11: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|12: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|13: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|14: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|15: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|16: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|17: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|18: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|19: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|20: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|21: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|22: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +|23: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-38 d,#0d1410, 39-39 #f4c086,#0d1410, 40-49 d,#0d1410, 50-50 d,#608269, 51-51 d,#0d1410, 52-99 #e5eee5,#0d1410, +== snap resize-done grid=100x24 cursor=44,5 +|1: New Tty Find Grep Joincol Delcol New Tty Find Grep Joincol Delcol +|2: /tmp/pardes-snap/colgrip/cwd/w.txt Sa /tmp/pardes-snap/colgrip/cwd Tty Save Mode Filter Collaps +|3: 1 x ls +|4: w.txt +|5: +|6: +|7: +|8: +|9: +|10: +|11: +|12: +|13: +|14: +|15: +|16: +|17: +|18: +|19: +|20: +|21: +|22: +|23: +== snap reorder-drag grid=100x24 cursor=44,5 +|3: ╎ 1 x ls +|4: ╎ w.txt +|5: ╎ +|6: ╎ +|7: ╎ +|8: ╎ +|9: ╎ +|10: ╎ +|11: ╎ +|12: ╎ +|13: ╎ +|14: ╎ +|15: ╎ +|16: ╎ +|17: ╎ +|18: ╎ +|19: ╎ +|20: ╎ +|21: ╎ +|22: ╎ +|23: ╎ +== style reorder-drag grid=100x24 +|1: 0-1 #ffffff,#887455, 2-2 d,#1d2824, 3-34 #b2c3b8,#1d2824, 35-39 d,#1d2824, 40-41 #000000,#f4c086, 42-42 d,#26362d, 43-74 #becfc4,#26362d, 75-99 d,#26362d, +|2: 0-1 #ffffff,#496656, 2-2 d,#1d2824, 3-31 #b2c3b8,#1d2824, 32-36 #d3b0d9,#1d2824, 37-39 #b2c3b8,#1d2824, 40-41 #000000,#add38a, 42-42 d,#26362d, 43-71 #becfc4,#26362d, 72-74 #dfbce5,#26362d, 75-99 #becfc4,#26362d, +|3: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-7 #e5eee5,#0d1410, 8-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|4: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|5: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-99 d,#0d1410, +|6: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|7: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|8: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|9: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|10: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|11: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|12: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|13: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|14: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|15: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|16: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|17: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|18: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|19: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|20: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|21: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|22: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +|23: 0-0 d,#608269, 1-1 #f4c086,#0d1410, 2-6 #59675c,#0d1410, 7-39 d,#0d1410, 40-40 d,#608269, 41-41 d,#0d1410, 42-99 #e5eee5,#0d1410, +== snap reorder-done grid=100x24 cursor=4,5 +|1: New Tty Find Grep Joincol Delcol New Tty Find Grep Joincol Delcol +|2: /tmp/pardes-snap/colgrip/cwd Tty Save Mode Filter Collaps /tmp/pardes-snap/colgrip/cwd/w.txt Sa +|3: ls 1 x +|4: w.txt +|5: +|6: +|7: +|8: +|9: +|10: +|11: +|12: +|13: +|14: +|15: +|16: +|17: +|18: +|19: +|20: +|21: +|22: +|23: diff --git a/test/snapshots/colgrip.snap b/test/snapshots/colgrip.snap new file mode 100644 index 00000000..c2b403ed --- /dev/null +++ b/test/snapshots/colgrip.snap @@ -0,0 +1,35 @@ +# Column grips: the two cells left of a column tag carry the column. A grabbed +# grip lights, and a rail in its color stands where the column will land. +# The right column is at x 50; its grip is cells 51-52 (1-based) on row 2. +file w.txt x +start 24 100 w.txt +wait 8000 Newcol Joincol +wait 8000 w.txt +stable 700 20000 +key a-n +key a-c +stable 700 15000 +snapstyle rest +# held on its own grip: lit, and no rail, since it lands where it is +press left 51 2 +stable 400 5000 +snapstyle held +# dropped short of the left column's middle, the left edge moves: the rail is +# in the seam cell left of where the column's rule will be +drag left 41 2 +stable 400 5000 +snap resize-drag +snapstyle resize-drag +release left 41 2 +stable 700 15000 +snap resize-done +# carried over the left column's left half it goes first; the window edge +# has no seam, so the rail runs in the gutter's last cell +press left 41 2 +drag left 10 2 +stable 400 5000 +snap reorder-drag +snapstyle reorder-drag +release left 10 2 +stable 700 15000 +snap reorder-done |
