summaryrefslogtreecommitdiff
path: root/src/normal.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 15:59:00 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit767aefd1e1cfd79e2a240a59d2d16bfb326f062d (patch)
tree113c66e3abda3548056fc480d7c7eeedbdaeb025 /src/normal.zig
parentab1c353f65efe8741b9a4d1aaef065af0aee885a (diff)
downloadpardes-767aefd1e1cfd79e2a240a59d2d16bfb326f062d.tar.gz
pardes-767aefd1e1cfd79e2a240a59d2d16bfb326f062d.zip
Registers hold a value per range, and "<reg> names one
Registers.zig replaces the one yank buffer: every register keeps a value per range, y fills them in document order, and p, P, R and insert Ctrl-r put value i at range i, repeating the last (helix paste_impl). "<reg> names the register for the next command; _ swallows, # numbers the ranges, . is each range's text, % the file's name, / the last s/S pattern, and + and * are the system clipboard through the ClipYank and ClipPaste paths. SPC y now writes + alone, as helix's does. The acme chords and a paste into a terminal take the default register joined by newlines. The msel-yank-paste waiver is gone. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/normal.zig')
-rw-r--r--src/normal.zig17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/normal.zig b/src/normal.zig
index 5a6c1cd5..f5e868a4 100644
--- a/src/normal.zig
+++ b/src/normal.zig
@@ -35,6 +35,7 @@ fn roleBindingName(comptime role: modal.Normal.Role) []const u8 {
.prefix_replace => "replace_prefix",
.prefix_next => "next_prefix",
.prefix_prev => "prev_prefix",
+ .prefix_register => "register_prefix",
else => @tagName(role),
};
}
@@ -149,6 +150,7 @@ const KeyState = struct {
find_op: u8,
find_ch: u21,
append_at: @FieldType(Text, "append_at"),
+ reg_wait: bool,
fn of(t: *Text) KeyState {
return .{
@@ -158,6 +160,7 @@ const KeyState = struct {
.find_op = t.find_op,
.find_ch = t.find_ch,
.append_at = t.append_at,
+ .reg_wait = t.reg_wait,
};
}
@@ -168,6 +171,7 @@ const KeyState = struct {
t.find_op = s.find_op;
t.find_ch = s.find_ch;
t.append_at = s.append_at;
+ t.reg_wait = s.reg_wait;
}
};
@@ -227,6 +231,8 @@ pub fn replaySels(p: *Pardes, t: *Text, what: Replay) void {
while (i > 0) {
i -= 1;
p.multi_first = passes == 0;
+ p.multi_index = i;
+ p.multi_count = n;
passes += 1;
saved.into(t);
t.nsel = 0; // the handler underneath sees ONE selection
@@ -284,11 +290,16 @@ pub fn replaySels(p: *Pardes, t: *Text, what: Replay) void {
}
pub fn handleNormal(p: *Pardes, t: *Text, key: Key) void {
+ // `"<reg>` is held by the parser until the command it names arrives
+ const named = t.normal.register;
const parsed = modal.Normal.parse(&t.normal, normalInput(key));
const semantic = switch (parsed) {
.pending, .ignored, .unbound => return,
.action => |value| value,
};
+ t.normal.register = 0;
+ p.register = named;
+ defer p.register = 0;
if (t.nsel == 0 or semantic.scope() == .once)
return executeNormalAction(p, t, semantic);
replaySels(p, t, .{ .normal = semantic });
@@ -534,9 +545,9 @@ fn executeNormalAction(p: *Pardes, t: *Text, semantic: modal.Normal.Action) void
.delete_noyank => return edit.normalDelete(p, t, false),
.change => return edit.normalChange(p, t),
.yank => return edit.normalYank(p, t),
- .replace_with_yank => return edit.normalReplaceYank(p, t),
- .paste_after => return edit.pasteText(p, t, p.yank orelse return, false, op.count),
- .paste_before => return edit.pasteText(p, t, p.yank orelse return, true, op.count),
+ .replace_with_yank => return edit.pasteRegister(p, t, .replace, op.count),
+ .paste_after => return edit.pasteRegister(p, t, .after, op.count),
+ .paste_before => return edit.pasteRegister(p, t, .before, op.count),
.switch_case => return edit.normalCase(p, t, .toggle),
.lowercase => return edit.normalCase(p, t, .lower),
.uppercase => return edit.normalCase(p, t, .upper),