summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/edit.zig34
-rw-r--r--src/modal.zig8
-rw-r--r--test/snapshots/layout-open.golden2
-rw-r--r--test/snapshots/shrinktag.golden10
4 files changed, 41 insertions, 13 deletions
diff --git a/src/edit.zig b/src/edit.zig
index 3e3ba341..bf65935e 100644
--- a/src/edit.zig
+++ b/src/edit.zig
@@ -899,11 +899,18 @@ fn insertEdit(p: *Pardes, t: *Text, key: Key) void {
t.show();
return;
}
- const indent = modal.newlineIndentWidth(line, c.col);
+ // The line's own indent, as it is (tabs stay tabs), and a
+ // level more after an opening delimiter: a tab where the
+ // indent is tabs, else spaces.
+ const lead = modal.indentText(line);
+ const more = modal.newlineIndentWidth(line, c.col) - lead.len;
+ const tabbed = std.mem.indexOfScalar(u8, lead, '\t') != null;
+ const indent = lead.len + (if (more == 0) 0 else if (tabbed) 1 else more);
const arena = p.scratch.allocator();
const block = arena.alloc(u8, 1 + indent) catch return;
block[0] = '\n';
- @memset(block[1..], ' ');
+ @memcpy(block[1..][0..lead.len], lead);
+ @memset(block[1 + lead.len ..], if (tabbed) '\t' else ' ');
// a tag keeps its blanks: they part its words, and the last
// may be its read-only prefix's
const kept = if (t.what == .body) std.mem.trimEnd(u8, before, " \t").len else c.col;
@@ -2136,6 +2143,29 @@ test "insert newline adds one indent level after a closing call" {
try std.testing.expectEqual(@as(i32, 8), pane.body.cur_col);
}
+test "Enter in insert mode keeps a tab-indented line's tabs, as o and O do" {
+ const gpa = std.testing.allocator;
+ const p = try Pardes.init(gpa, .{ .tty_only = true });
+ defer p.deinit();
+ while (p.nextEffect()) |_| {}
+ const pane = try p.setTestFile("\t\tvalue = 1;\n\tif (x) {\n");
+ pane.body.mode = .insert;
+ pane.body.cur_col = 12;
+ p.update(.{ .key = .{ .cp = Key.enter } });
+ try std.testing.expectEqualStrings("\t\tvalue = 1;\n\t\t\n\tif (x) {\n", pane.file.?.content);
+ try std.testing.expectEqual(@as(i32, 2), pane.body.cur_col);
+ // After an opening brace, a level more: a tab, as the indent is tabs.
+ pane.body.cur_row = 2;
+ pane.body.cur_col = 9;
+ p.update(.{ .key = .{ .cp = Key.enter } });
+ try std.testing.expectEqualStrings("\t\tvalue = 1;\n\t\t\n\tif (x) {\n\t\t\n", pane.file.?.content);
+ // o opens a line with the indent as it is.
+ p.update(.{ .key = .{ .cp = Key.escape } });
+ pane.body.cur_row = 0;
+ p.update(.{ .key = .{ .cp = 'o' } });
+ try std.testing.expect(std.mem.startsWith(u8, pane.file.?.content, "\t\tvalue = 1;\n\t\t\n"));
+}
+
test "insert and normal modes edit complete Unicode graphemes" {
const gpa = std.testing.allocator;
const p = try Pardes.init(gpa, .{ .cols = 60, .rows = 12 });
diff --git a/src/modal.zig b/src/modal.zig
index 11eda7b9..316a66fa 100644
--- a/src/modal.zig
+++ b/src/modal.zig
@@ -1773,12 +1773,10 @@ pub fn indentWidth(line: []const u8) usize {
return w;
}
-/// full indent LEVELS of a line as spaces (helix indent_level_for_line:
-/// partial levels round down) — what o/O/insert-newline copy.
+/// A line's indent as it is, tabs and spaces both, as acme's autoindent
+/// copies it: what o/O/insert-newline give the new line.
pub fn indentText(line: []const u8) []const u8 {
- const level = indentWidth(line) / INDENT_W;
- const max = " "; // 8 levels is plenty (ponytail)
- return max[0..@min(level * INDENT_W, max.len)];
+ return line[0 .. std.mem.indexOfNone(u8, line, " \t") orelse line.len];
}
/// Copy full indent levels and add one after (, [, {, or ), without parsing.
diff --git a/test/snapshots/layout-open.golden b/test/snapshots/layout-open.golden
index a3d9dfdd..d2cbb9a9 100644
--- a/test/snapshots/layout-open.golden
+++ b/test/snapshots/layout-open.golden
@@ -1,4 +1,4 @@
-== snap before grid=100x31 cursor=2,9
+== snap before grid=100x31 cursor=4,9
|Newcol Joincol Find Grep Help Changelog Tutor Dump Themes Config Debug Exit
| New Tty Find Grep Joincol Delcol New Tty Find Grep Joincol Delcol
| /tmp/pardes-snap/layout-open/cwd Tty+bash Save /tmp/pardes-snap/layout-open/cwd Tty+bash Save
diff --git a/test/snapshots/shrinktag.golden b/test/snapshots/shrinktag.golden
index d73c0072..6e64d89b 100644
--- a/test/snapshots/shrinktag.golden
+++ b/test/snapshots/shrinktag.golden
@@ -1,4 +1,4 @@
-== snap before grid=100x31 cursor=2,9
+== snap before grid=100x31 cursor=4,9
|Newcol Joincol Find Grep Help Changelog Tutor Dump Themes Config Debug Exit
| New Tty Find Grep Joincol Delcol New Tty Find Grep Joincol Delcol
| /tmp/pardes-snap/shrinktag/cwd Tty+bash Save Mo /tmp/pardes-snap/shrinktag/cwd Tty+bash Save Mo
@@ -20,7 +20,7 @@
| de Filter Collapse Del
| ls
| w.txt
-== snap shrunk grid=100x31 cursor=2,9
+== snap shrunk grid=100x31 cursor=4,9
|4: w.txt ls
|5: w.txt
|6: /tmp/pardes-snap/shrinktag/cwd Tty+bash Save Mo
@@ -31,9 +31,9 @@
|18:
|19:
|20:
-== snap move-preview grid=100x31 cursor=2,9
+== snap move-preview grid=100x31 cursor=4,9
|8: ls ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
-== snap restored grid=100x31 cursor=2,9
+== snap restored grid=100x31 cursor=4,9
|4: ls ls
|5: w.txt w.txt
|6:
@@ -44,7 +44,7 @@
|18: de Filter Collapse Del
|19: ls
|20: w.txt
-== snap bottom-shrunk grid=100x31 cursor=2,9
+== snap bottom-shrunk grid=100x31 cursor=4,9
|17:
|18:
|19: