@@ -1,8 +1,9 @@
1+use std::borrow::Cow;
2+
13use crate::{
24 chars::char_is_line_ending,
3− graphemes::{ensure_grapheme_boundary_prev, RopeGraphemes},
5+ graphemes::{ensure_grapheme_boundary_prev, grapheme_width, RopeGraphemes},
46 line_ending::line_end_char_index,
5− unicode::width::UnicodeWidthChar,
67 RopeSlice,
78};
89
@@ -77,14 +78,17 @@ pub fn visual_coords_at_pos(text: RopeSlice, pos: usize, tab_width: usize) -> Po
7778
7879 let line_start = text.line_to_char(line);
7980 let pos = ensure_grapheme_boundary_prev(text, pos);
80− let col = text
81− .slice(line_start..pos)
82− .chars()
83− .flat_map(|c| match c {
84− '\t' => Some(tab_width),
85− c => UnicodeWidthChar::width(c),
86− })
87− .sum();
81+
82+ let mut col = 0;
83+
84+ for grapheme in RopeGraphemes::new(text.slice(line_start..pos)) {
85+ if grapheme == "\t" {
86+ col += tab_width;
87+ } else {
88+ let grapheme = Cow::from(grapheme);
89+ col += grapheme_width(&grapheme);
90+ }
91+ }
8892
8993 Position::new(line, col)
9094}