diff options
Diffstat (limited to 'src/modal.zig')
| -rw-r--r-- | src/modal.zig | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/modal.zig b/src/modal.zig index 424421f6..33c63c52 100644 --- a/src/modal.zig +++ b/src/modal.zig @@ -1171,6 +1171,27 @@ pub fn hxIndentString(line: []const u8) []const u8 { return max[0..@min(level * INDENT_W, max.len)]; } +/// Indent width for an inserted newline. Keep the current full indent levels, +/// then add one logical tab after a simple delimiter-shaped line ending. +/// `)` intentionally includes both ordinary calls and the requested `})` +/// continuation shape; this is syntax-agnostic and does not try to parse. +pub fn hxNewlineIndentWidth(line: []const u8, col: usize) usize { + const prefix = std.mem.trimEnd(u8, line[0..@min(col, line.len)], " \t"); + const extra = if (prefix.len == 0) false else switch (prefix[prefix.len - 1]) { + '(', '[', '{', ')' => true, + else => false, + }; + return hxIndentString(line).len + @as(usize, if (extra) INDENT_W else 0); +} + +test "newline indent keeps levels and adds one after delimiters" { + try std.testing.expectEqual(@as(usize, 4), hxNewlineIndentWidth(" value", 9)); + try std.testing.expectEqual(@as(usize, 8), hxNewlineIndentWidth(" call()", 10)); + try std.testing.expectEqual(@as(usize, 8), hxNewlineIndentWidth(" callback({}) ", 16)); + try std.testing.expectEqual(@as(usize, 4), hxNewlineIndentWidth("work(", 5)); + try std.testing.expectEqual(@as(usize, 4), hxNewlineIndentWidth("list[tail", 5)); +} + /// helix Ctrl-a / Ctrl-x: increment the SELECTED text as a decimal integer. /// Zero-padding is preserved (width follows sign flips, helix-style). /// Ponytail: no 0x/0o/0b bases, no '_' separators — decimal only. @@ -1530,8 +1551,13 @@ fn stepInsertFile(alloc: std.mem.Allocator, content: []const u8, st: *FileState, return new; }, .enter => { - const new = try insertAt(alloc, content, st.cur, "\n"); - st.cur = .{ .row = st.cur.row + 1, .col = 0 }; + const indent = hxNewlineIndentWidth(lineSlice(content, st.cur.row), st.cur.col); + const block = try alloc.alloc(u8, 1 + indent); + defer alloc.free(block); + block[0] = '\n'; + @memset(block[1..], ' '); + const new = try insertAt(alloc, content, st.cur, block); + st.cur = .{ .row = st.cur.row + 1, .col = indent }; st.pending = 0; return new; }, |
