summaryrefslogtreecommitdiff
path: root/src/edit.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/edit.zig')
-rw-r--r--src/edit.zig15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/edit.zig b/src/edit.zig
index 2dc79ab5..5ba46ca7 100644
--- a/src/edit.zig
+++ b/src/edit.zig
@@ -694,8 +694,19 @@ pub fn insertKey(p: *Pardes, t: *Text, key: Key) void {
Key.backspace => {
if (t.cur_col > 0) {
const line = modal.lineSlice(text, c.row);
- const prev = modal.prevGrapheme(line, c.col);
- const new = modal.deleteChar(p.gpa, text, .{ .row = c.row, .col = prev }) catch return;
+ var prev = modal.prevGrapheme(line, c.col);
+ // in leading blanks, back to the previous indent stop (helix
+ // dedent): a whole unit when on one, else the part past it
+ const lead = line[0..@min(c.col, line.len)];
+ if (std.mem.indexOfNone(u8, lead, " \t") == null and prev < line.len and line[prev] != '\t') {
+ var width: usize = 0;
+ for (lead) |ch| width += if (ch == '\t') modal.INDENT_W else 1;
+ var drop = width % modal.INDENT_W;
+ if (drop == 0) drop = modal.INDENT_W;
+ prev = c.col;
+ while (drop > 0 and prev > 0 and line[prev - 1] == ' ') : (drop -= 1) prev -= 1;
+ }
+ const new = modal.deleteSpan(p.gpa, text, .{ .row = c.row, .col = prev }, c) catch return;
setEditText(p, t, new);
t.cur_col = @intCast(prev);
t.cur_pinned = true;