diff options
Diffstat (limited to 'src/File.zig')
| -rw-r--r-- | src/File.zig | 15 |
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 { |
