summaryrefslogtreecommitdiff
path: root/src/modal.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 16:43:59 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit71c5b400ced873cddd77497b7a9fd06184954813 (patch)
tree76e0d64e9e73f55aa1eea5a357c3cc2c8345a253 /src/modal.zig
parent78daa25e5c99cc0d71da36b6e0dcdd362b0cb284 (diff)
downloadpardes-71c5b400ced873cddd77497b7a9fd06184954813.tar.gz
pardes-71c5b400ced873cddd77497b7a9fd06184954813.zip
Z arms the view keys until Esc, and zm puts the cursor's column mid-view
Z is helix's sticky view mode: the z keys stay armed after each until Esc, which leaves the mode and does nothing else (no pane hop). zm is align_view_middle: an unwrapped view scrolls sideways so the cursor's column is in its middle. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/modal.zig')
-rw-r--r--src/modal.zig21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/modal.zig b/src/modal.zig
index 0171da93..16196b4f 100644
--- a/src/modal.zig
+++ b/src/modal.zig
@@ -16,6 +16,7 @@ pub const Normal = struct {
prefix_next,
prefix_prev,
prefix_register,
+ prefix_view_sticky,
goto_file_start,
goto_last_line,
@@ -38,6 +39,7 @@ pub const Normal = struct {
view_top,
view_center,
view_bottom,
+ view_middle,
view_scroll_down,
view_scroll_up,
@@ -196,9 +198,12 @@ pub const Normal = struct {
held_char: u21 = 0,
/// `"<reg>`: the register the next command names, 0 for none
register: u21 = 0,
+ /// `Z`: the view keys stay armed until Esc (helix's sticky view)
+ sticky: bool = false,
+ /// Drop what is pending; sticky view mode stays armed through it.
pub fn clear(state: *State) void {
- state.* = .{};
+ state.* = if (state.sticky) .{ .sticky = true, .prefix = .view } else .{};
}
};
@@ -254,7 +259,7 @@ pub const Normal = struct {
view_bottom,
last_modification,
};
- pub const View = enum { top, center, bottom, scroll_down, scroll_up };
+ pub const View = enum { top, center, bottom, middle, scroll_down, scroll_up };
pub const Find = enum { forward, backward, till_forward, till_backward };
pub const Line = enum { start, end, first_nonws };
pub const Page = enum { half_down, half_up, down, up };
@@ -407,7 +412,10 @@ pub const Normal = struct {
pub fn parse(state: *State, key: Input) Result {
if (key.has(.escape)) {
- state.clear();
+ // Esc out of sticky view mode leaves that mode and nothing else
+ const sticky = state.sticky;
+ state.* = .{};
+ if (sticky) return .ignored;
return resultAction(.escape);
}
@@ -448,8 +456,9 @@ pub const Normal = struct {
return .ignored;
},
.view => {
- state.prefix = .none;
+ if (!state.sticky) state.prefix = .none;
if (key.has(.view_top)) return resultAction(.{ .view = .top });
+ if (key.has(.view_middle)) return resultAction(.{ .view = .middle });
if (key.has(.view_center)) return resultAction(.{ .view = .center });
if (key.has(.view_bottom)) return resultAction(.{ .view = .bottom });
if (key.has(.view_scroll_down)) return resultAction(.{ .view = .scroll_down });
@@ -543,6 +552,10 @@ pub const Normal = struct {
// Prefix setters retain the count for their continuation.
if (key.has(.prefix_goto)) return armPrefix(state, .goto, if (counted.explicit) count else 0);
if (key.has(.prefix_view)) return armPrefix(state, .view, if (counted.explicit) count else 0);
+ if (key.has(.prefix_view_sticky)) {
+ state.sticky = true;
+ return armPrefix(state, .view, 0);
+ }
if (key.has(.prefix_find_fwd)) return armPrefix(state, .find_fwd, if (counted.explicit) count else 0);
if (key.has(.prefix_find_back)) return armPrefix(state, .find_back, if (counted.explicit) count else 0);
if (key.has(.prefix_till_fwd)) return armPrefix(state, .till_fwd, if (counted.explicit) count else 0);