summaryrefslogtreecommitdiff
path: root/src/File.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/File.zig')
-rw-r--r--src/File.zig15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/File.zig b/src/File.zig
index 78c84287..a89db613 100644
--- a/src/File.zig
+++ b/src/File.zig
@@ -352,11 +352,18 @@ pub fn byteAtDisplayFrom(line_text: []const u8, from_raw: usize, display_col: us
return from +| rawAtDisplay(line_text[from..], display_col);
}
+/// The display columns from `from_raw` to `to_raw` on a line. Widths add
+/// (a tab is `tab_width` wherever it stands), so only the text between
+/// the two is measured, never the line from its start: a selection a
+/// million bytes into a line draws as fast as one at its start.
pub fn lineDisplayOffset(line_text: []const u8, from_raw: usize, to_raw: usize) i32 {
- const from_display = rawDisplayCol(line_text, from_raw);
- const to_display = rawDisplayCol(line_text, to_raw);
- if (to_display >= from_display) return @intCast(to_display - from_display);
- return -@as(i32, @intCast(from_display - to_display));
+ const lo = @min(from_raw, to_raw);
+ const hi = @max(from_raw, to_raw);
+ const a = modal.graphemeStart(line_text, @min(lo, line_text.len));
+ const b = modal.graphemeStart(line_text, @min(hi, line_text.len));
+ const past = (hi -| line_text.len) - (lo -| line_text.len);
+ const width: usize = displayWidth(line_text[a..b]) +| past;
+ return if (to_raw >= from_raw) @intCast(width) else -@as(i32, @intCast(width));
}
pub fn lineDisplayEndOffset(line_text: []const u8, from_raw: usize, at_raw: usize) i32 {