diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/panes.zig | 75 | ||||
| -rw-r--r-- | test/snapshots/tagpath.golden | 23 | ||||
| -rw-r--r-- | test/snapshots/tagpath.snap | 33 |
3 files changed, 91 insertions, 40 deletions
diff --git a/test/panes.zig b/test/panes.zig index d8ed517f..d0551cfc 100644 --- a/test/panes.zig +++ b/test/panes.zig @@ -12,12 +12,6 @@ const image = pardes.image; const syntax = pardes.syntax; const filesystem = pardes.filesystem; -/// The tag's caret as a byte offset into the tag as it is shown, prefix -/// included. -fn tagCaret(p: *Pardes, pane: *Pane) !usize { - return (try pardes.tagline.tagPrefix(p, pane)).len + @as(usize, @intCast(pane.tag.cur_col)); -} - fn setTag(pane: *Pane, text: []const u8) !void { if (pane.tag.own) |own| pane.gpa.free(own); pane.tag.own = try pane.gpa.dupe(u8, text); @@ -67,7 +61,7 @@ const TagLayerTests = struct { p.update(.{ .mouse = mouse(layer, x, .press) }); p.update(.{ .mouse = mouse(layer, x, .release) }); try std.testing.expect(pane.focus == .tag); - try std.testing.expectEqual(at, try tagCaret(p, pane)); + try std.testing.expectEqual(at, @as(usize, @intCast(pane.tag.cur_col))); p.update(.{ .key = .{ .cp = 'X', .text = "X" } }); _ = try p.render(frame.allocator()); const edited = try pardes.tagline.tagText(p, frame.allocator(), pane); @@ -99,7 +93,7 @@ const TagLayerTests = struct { event.row = @intFromFloat(painted_y); p.update(.{ .mouse = event }); } - try std.testing.expectEqual(at, try tagCaret(p, pane)); + try std.testing.expectEqual(at, @as(usize, @intCast(pane.tag.cur_col))); } } @@ -148,7 +142,7 @@ const TagLayerTests = struct { p.update(.{ .mouse = mouse(layer, beyond_x, .release) }); try std.testing.expectEqual(@as(usize, 0), p.active); const end_col = left_layer.capacity(p.row_metrics) - 1; - try std.testing.expectEqual(panes.File.rawAtDisplay(left_text, end_col), try tagCaret(p, left)); + try std.testing.expectEqual(panes.File.rawAtDisplay(left_text, end_col), @as(usize, @intCast(left.tag.cur_col))); try std.testing.expect(left.sel[0].state == .done and left.sel[0].r0 == 0); p.update(.{ .key = .{ .cp = Key.escape } }); const long = "a" ** 60 ++ "界END"; @@ -320,6 +314,44 @@ const TagNavigationTests = struct { try std.testing.expect(pane.prompt == .none and pane.focus == .body); } + test "the keyboard reaches a tag's path, which it can select and yank but not edit" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 20 }); + defer p.deinit(); + const pane = try p.setTestFile("body\n"); + p.update(.tick); + key(p, ':'); + // `0` is the line's start, as in acme, where the name is ordinary text + key(p, '0'); + try std.testing.expectEqual(@as(i32, 0), pane.tag.cur_col); + key(p, 'E'); + key(p, 'y'); + try std.testing.expectEqualStrings("/test.txt", p.yank.?); + // an edit that reaches into it is refused, the cursor with it + const before = try std.testing.allocator.dupe(u8, try pardes.edit.flatSurface(p, &pane.tag)); + defer std.testing.allocator.free(before); + const cursor = pane.tag.cur_col; + key(p, 'd'); + try std.testing.expectEqualStrings(before, try pardes.edit.flatSurface(p, &pane.tag)); + try std.testing.expectEqual(cursor, pane.tag.cur_col); + try std.testing.expect(pane.tag.vsel.active); + // typed into, the path drafts a name there, as a click on it does + key(p, ';'); + key(p, '0'); + key(p, 'i'); + p.update(.{ .key = .{ .cp = 'x', .text = "x" } }); + try std.testing.expect(pane.prompt == .name); + try std.testing.expectEqualStrings("x/test.txt", pane.input.own.?); + key(p, Key.escape); + try std.testing.expect(pane.prompt == .none); + try std.testing.expectEqualStrings("/test.txt", pane.file.?.path); + // after the path, the text is the tag's own to edit + key(p, ':'); + key(p, 'A'); + p.update(.{ .key = .{ .cp = '!', .text = "!" } }); + try std.testing.expect(std.mem.endsWith(u8, pardes.tagline.curTail(pane), "!")); + try std.testing.expectEqualStrings("body\n", pane.file.?.content); + } + fn window(p: *Pardes, letter: u21) void { p.update(.{ .key = .{ .cp = 'w', .ctrl = true } }); key(p, letter); @@ -339,8 +371,9 @@ const TagNavigationTests = struct { // Nothing to remember yet: `:` lands on Save, in normal mode. key(p, ':'); try std.testing.expect(first.focus == .tag and first.tag.mode == .normal); - const tail = pardes.tagline.curTail(first); - try std.testing.expectEqualStrings("Save", tail[@intCast(first.tag.cur_col)..][0..4]); + const shown = try pardes.edit.flatSurface(p, &first.tag); + try std.testing.expectEqualStrings("Save", shown[@intCast(first.tag.cur_col)..][0..4]); + // Home is the line's start, the path's: the keyboard reaches it. key(p, Key.home); for (0..3) |_| key(p, Key.right); try std.testing.expectEqual(@as(i32, 3), first.tag.cur_col); @@ -369,13 +402,13 @@ const TagNavigationTests = struct { ClickCursorTests.click(p, .left, rect.x + pardes.TAG_TEXT_INSET + prefix + 6, y); try std.testing.expectEqual(@as(usize, 0), p.active); try std.testing.expect(first.focus == .tag and first.tag.mode == .insert); - try std.testing.expectEqual(@as(i32, 6), first.tag.cur_col); + try std.testing.expectEqual(@as(i32, prefix + 6), first.tag.cur_col); key(p, Key.escape); key(p, ':'); p.startPrompt(first, &first.body, .{ .search = config.search_marker }); key(p, Key.escape); key(p, ':'); - try std.testing.expectEqual(@as(i32, 6), first.tag.cur_col); + try std.testing.expectEqual(@as(i32, prefix + 6), first.tag.cur_col); key(p, ':'); try std.testing.expectEqualStrings("body\n", first.file.?.content); } @@ -403,26 +436,28 @@ const TagNavigationTests = struct { try std.testing.expectEqual(chord == Key.tab, saved); // ...and the tag still knows where it was. key(p, ':'); - try std.testing.expectEqualStrings("Save", pardes.tagline.curTail(pane)[@intCast(pane.tag.cur_col)..][0..4]); + try std.testing.expectEqualStrings("Save", (try pardes.edit.flatSurface(p, &pane.tag))[@intCast(pane.tag.cur_col)..][0..4]); } } - test "a renamed path never moves the tag's cursor and a shorter tag pulls it back" { + test "a renamed path moves the tag's cursor with the text after it and a shorter tag pulls it back" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 14 }); defer p.deinit(); const pane = try p.setTestFile("body\n"); - key(p, ':'); - key(p, Key.home); - for (0..3) |_| key(p, Key.right); + key(p, ':'); // on Save key(p, ':'); p.gpa.free(pane.file.?.path); pane.file.?.path = try p.gpa.dupe(u8, "/界.zig"); + p.update(.tick); key(p, ':'); - try std.testing.expectEqual(@as(i32, 3), pane.tag.cur_col); + const shown = try pardes.edit.flatSurface(p, &pane.tag); + try std.testing.expectEqualStrings("Save", shown[@intCast(pane.tag.cur_col)..][0..4]); key(p, ':'); try setTag(pane, "é"); + p.update(.tick); key(p, ':'); - try std.testing.expectEqual(@as(i32, 2), pane.tag.cur_col); + // `/界.zig é`: the cursor is pulled back onto the last character + try std.testing.expectEqual(@as(i32, "/界.zig ".len), pane.tag.cur_col); try std.testing.expectEqualStrings("body\n", pane.file.?.content); } diff --git a/test/snapshots/tagpath.golden b/test/snapshots/tagpath.golden index 2ba1a2e6..a2ea32fc 100644 --- a/test/snapshots/tagpath.golden +++ b/test/snapshots/tagpath.golden @@ -8,12 +8,12 @@ | 4 line 4 | 5 == snap colon grid=100x31 cursor=38,2 -== snap col0 grid=100x31 cursor=37,2 -== snap drag-cross grid=100x31 cursor=41,2 -== style drag-cross grid=100x31 +== snap col0 grid=100x31 cursor=3,2 +== snap sel-path grid=100x31 cursor=36,2 +== style sel-path grid=100x31 |0: 0-70 #b2c3b8,#1d2824, 71-99 d,#1d2824, |1: 0-1 #ffffff,#887455, 2-2 d,#26362d, 3-34 #becfc4,#26362d, 35-99 d,#26362d, -|2: 0-1 #000000,#add38a, 2-2 d,#26362d, 3-10 #becfc4,#26362d, 11-41 #f5f7ee,#3c614a, 42-58 #becfc4,#26362d, 59-99 d,#26362d, +|2: 0-1 #000000,#add38a, 2-2 d,#26362d, 3-36 #f5f7ee,#3c614a, 37-58 #becfc4,#26362d, 59-99 d,#26362d, |3: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-12 #e5eee5,#0d1410, 13-99 d,#0d1410, |4: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-12 #e5eee5,#0d1410, 13-99 d,#0d1410, |5: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-12 #e5eee5,#0d1410, 13-99 d,#0d1410, @@ -42,9 +42,16 @@ |28: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-99 d,#0d1410, |29: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-99 d,#0d1410, |30: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-99 d,#0d1410, +== snap yanked-path grid=100x31 cursor=41,3 +|2: /tmp/pardes-snap/tagpath/cwd/c.txt * Save Tty Collapse Del +|3: 1 l/tmp/pardes-snap/tagpath/cwd/c.txtine 1 +== snap drag-cross grid=100x31 cursor=41,2 +== style drag-cross grid=100x31 +|2: 0-1 #000000,#add38a, 2-2 d,#26362d, 3-10 #becfc4,#26362d, 11-41 #f5f7ee,#3c614a, 42-60 #becfc4,#26362d, 61-99 d,#26362d, +|3: 0-0 d,#608269, 1-1 d,#0d1410, 2-6 #59675c,#0d1410, 7-7 #e5eee5,#0d1410, 8-41 #f5f7ee,#3c614a, 42-46 #e5eee5,#0d1410, 47-99 d,#0d1410, == snap name-draft grid=100x31 cursor=11,2 -|2: /renamed/tmp/pardes-snap/tagpath/cwd/c.txt Save Tty Collapse Del -== snap name-cancelled grid=100x31 cursor=7,3 -|2: /tmp/pardes-snap/tagpath/cwd/c.txt Save Tty Collapse Del -== snap name-committed grid=100x31 cursor=7,3 +|2: /renamed/tmp/pardes-snap/tagpath/cwd/c.txt * Save Tty Collapse Del +== snap name-cancelled grid=100x31 cursor=41,3 +|2: /tmp/pardes-snap/tagpath/cwd/c.txt * Save Tty Collapse Del +== snap name-committed grid=100x31 cursor=41,3 |2: /renamed/tmp/pardes-snap/tagpath/cwd/c.txt * Save Tty Collapse Del diff --git a/test/snapshots/tagpath.snap b/test/snapshots/tagpath.snap index b9ef80e6..f02769d9 100644 --- a/test/snapshots/tagpath.snap +++ b/test/snapshots/tagpath.snap @@ -1,8 +1,7 @@ -# The path is part of the tag's text for the mouse -- a sweep selects across -# the path and the commands after it -- but never for the keyboard: the tag's -# cursor lives in its own text, so `0` goes to the start of that, not of the -# path. A click on the path drafts a new name there instead. Escape cancels; -# Enter changes buffer identity, never renames a disk file. +# The path is part of the tag's text for the keyboard as for the mouse: `0` +# goes to its start, `E` selects it and `y` yanks it. It is read-only, but +# typing into it drafts a new name there, as a click on it does. Escape +# cancels; Enter changes buffer identity, never renames a disk file. lines c.txt 4 start 31 100 c.txt wait 8000 Newcol Joincol @@ -15,6 +14,16 @@ snap colon key 0 stable 400 5000 snap col0 +key E +stable 400 5000 +snap sel-path +snapstyle sel-path +key y +# `:` gives the keyboard back to the body, and `p` puts the path there +key : +key p +stable 400 5000 +snap yanked-path # Sweep across the path / command boundary without injected padding. press left 12 3 drag left 30 3 @@ -23,21 +32,21 @@ release left 42 3 stable 400 5000 snap drag-cross snapstyle drag-cross +# Esc is the tag's normal mode; typed at the path's start, `/renamed` drafts +# a name key esc settle 100 -key : -stable 400 5000 -# a click on the path is a name draft, the caret where it was clicked -press left 4 3 -release left 4 3 +key 0 +key i text /renamed stable 400 5000 snap name-draft key esc stable 400 5000 snap name-cancelled -press left 4 3 -release left 4 3 +key : +key 0 +key i text /renamed key enter stable 400 5000 |
