diff --git a/kaolinite/src/document/mod.rs b/kaolinite/src/document/mod.rs index 8ecb087..9f30345 100644 --- a/kaolinite/src/document/mod.rs +++ b/kaolinite/src/document/mod.rs @@ -259,9 +259,13 @@ impl Document { // Account for double width characters idx = idx.saturating_sub(self.dbl_map.count(loc, true).unwrap_or(0)); // Account for tab characters - idx = idx.saturating_sub( - self.tab_map.count(loc, true).unwrap_or(0) * self.tab_width.saturating_sub(1), - ); + let tabs_behind = self.tab_map.count(loc, true).unwrap_or(0); + idx = if let Some(inner_idx) = self.tab_map.inside(self.tab_width, loc.x, loc.y) { + let existing_tabs = tabs_behind.saturating_sub(1) * self.tab_width.saturating_sub(1); + idx.saturating_sub(existing_tabs + inner_idx) + } else { + idx.saturating_sub(tabs_behind * self.tab_width.saturating_sub(1)) + }; idx } diff --git a/kaolinite/src/map.rs b/kaolinite/src/map.rs index 476e126..e5abfb8 100644 --- a/kaolinite/src/map.rs +++ b/kaolinite/src/map.rs @@ -4,6 +4,7 @@ use std::collections::HashMap; use unicode_width::UnicodeWidthChar; /// This is a type for making a note of the location of different characters +/// `HashMap`<`y_pos`, Vec<(display, character)>> type CharHashMap = HashMap>; /// Keeps notes of specific characters within a document for the purposes of double width and @@ -166,6 +167,17 @@ impl CharMap { } Some(ctr) } + + /// If all character maps are of size n, then determine if x would be within one, and return their index inside the char + #[must_use] + pub fn inside(&self, n: usize, x: usize, y: usize) -> Option { + for (disp, _) in self.get(y)? { + if ((disp + 1)..(disp + n)).contains(&&x) { + return Some(x.saturating_sub(*disp)); + } + } + None + } } /// Vector that takes two usize values