summaryrefslogtreecommitdiff
path: root/src/ninep/addr.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 02:14:54 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit5492da0ba1d5f1c1cc0a880f82107961627c9ba6 (patch)
tree0230c6b9896d773c1e93722aa944a306184dd6a2 /src/ninep/addr.zig
parent69b6d714b7fc7788a1bf1c2305262a6e861253e8 (diff)
downloadpardes-5492da0ba1d5f1c1cc0a880f82107961627c9ba6.tar.gz
pardes-5492da0ba1d5f1c1cc0a880f82107961627c9ba6.zip
Addresses snap to runes, not grapheme clusters
sam and acme address runes; pardes snapped #n, line:col, dot and data's reads to grapheme clusters, so a lone combining mark or a CRLF's \r could not be addressed. #n, line:col, a search's match, dot (both ways) and data now land on rune boundaries (modal.runeStart and friends), and the tty's cell drawing is untouched. The README, fs.md and the skill say so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/addr.zig')
-rw-r--r--src/ninep/addr.zig9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/ninep/addr.zig b/src/ninep/addr.zig
index e1d6da0f..e731ba24 100644
--- a/src/ninep/addr.zig
+++ b/src/ninep/addr.zig
@@ -94,7 +94,7 @@ pub const Addr = struct {
// pardes's `line:col`, Look's `file:12:5` spelling (look.zig
// parsePathLine): the point at that column of that line, the
// column in bytes from 1, clamped to the line's end and snapped
- // to a character's start as Look's cursor is. Not sam's.
+ // to a rune's start, as every address is. Not sam's.
if (size == .line and dir == 0 and a.i + 1 < a.expr.len and a.expr[a.i] == ':' and
a.expr[a.i + 1] >= '0' and a.expr[a.i + 1] <= '9')
{
@@ -107,7 +107,7 @@ pub const Addr = struct {
a.err = e_range;
return null;
}
- const q = clip(modal.offsetAt(a.text, .{ .row = @intCast(n - 1), .col = @intCast(col - 1) }));
+ const q = clip(modal.runeOffsetAt(a.text, .{ .row = @intCast(n - 1), .col = @intCast(col - 1) }));
r = .{ .q0 = q, .q1 = q };
continue;
}
@@ -162,7 +162,7 @@ pub const Addr = struct {
a.err = e_range;
return null;
}
- const g = clip(modal.graphemeStart(a.text, @intCast(off)));
+ const g = clip(modal.runeStart(a.text, @intCast(off)));
return .{ .q0 = g, .q1 = g };
}
var line: i64 = n;
@@ -267,6 +267,9 @@ pub const Addr = struct {
}) orelse break :found null;
break :found Range{ .q0 = clip(m.start), .q1 = clip(m.end) };
};
+ // A byte pattern may match inside a rune: the match covers the
+ // runes it touches.
+ if (found) |f| return .{ .q0 = clip(modal.runeStart(a.text, f.q0)), .q1 = clip(modal.runeEnd(a.text, f.q1)) };
return found orelse {
a.err = e_no_match;
return null;