-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimizes View::screen_coords_at_pos by not computing char_to_line two times #4896
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,18 +54,15 @@ impl From<Position> for tree_sitter::Point { | |
Self::new(pos.row, pos.col) | ||
} | ||
} | ||
|
||
/// Convert a character index to (line, column) coordinates. | ||
/// | ||
/// column in `char` count which can be used for row:column display in | ||
/// status line. See [`visual_coords_at_pos`] for a visual one. | ||
pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position { | ||
let line = text.char_to_line(pos); | ||
|
||
let line_start = text.line_to_char(line); | ||
let pos = ensure_grapheme_boundary_prev(text, pos); | ||
let col = RopeGraphemes::new(text.slice(line_start..pos)).count(); | ||
|
||
Position::new(line, col) | ||
let row = text.char_to_line(pos); | ||
let col = rope_graphemes(text, pos, row).count(); | ||
Position::new(row, col) | ||
} | ||
|
||
/// Convert a character index to (line, column) coordinates visually. | ||
|
@@ -74,23 +71,25 @@ pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position { | |
/// not in the document in the future. | ||
/// See [`coords_at_pos`] for an "objective" one. | ||
pub fn visual_coords_at_pos(text: RopeSlice, pos: usize, tab_width: usize) -> Position { | ||
let line = text.char_to_line(pos); | ||
|
||
let line_start = text.line_to_char(line); | ||
let pos = ensure_grapheme_boundary_prev(text, pos); | ||
let row = text.char_to_line(pos); | ||
let col = visual_col_position(text, pos, row, tab_width); | ||
Position { row, col } | ||
} | ||
|
||
/// Returns a column position of a character index in a row. | ||
/// | ||
/// Accounts for tab (\t) and double-width characters (CJK). | ||
pub fn visual_col_position(text: RopeSlice, pos: usize, row: usize, tab_width: usize) -> usize { | ||
let mut col = 0; | ||
|
||
for grapheme in RopeGraphemes::new(text.slice(line_start..pos)) { | ||
for grapheme in rope_graphemes(text, pos, row) { | ||
if grapheme == "\t" { | ||
col += tab_width - (col % tab_width); | ||
} else { | ||
let grapheme = Cow::from(grapheme); | ||
col += grapheme_width(&grapheme); | ||
} | ||
} | ||
|
||
Position::new(line, col) | ||
col | ||
} | ||
|
||
/// Convert (line, column) coordinates to a character index. | ||
|
@@ -169,6 +168,12 @@ pub fn pos_at_visual_coords(text: RopeSlice, coords: Position, tab_width: usize) | |
line_start + col_char_offset | ||
} | ||
|
||
fn rope_graphemes(text: RopeSlice, pos: usize, row: usize) -> RopeGraphemes { | ||
let row_start = text.line_to_char(row); | ||
let pos = ensure_grapheme_boundary_prev(text, pos); | ||
RopeGraphemes::new(text.slice(row_start..pos)) | ||
} | ||
Comment on lines
+171
to
+175
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not so much code that it needs a helper function IMO, and it's a bit confusing that there are other calls to RopeGraphemes::new that don't use rope_graphemes in this module. This can be inlined into the two callsites There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Respectfully, I disagree. This function encapsulates an important concept that I don't know why in other places that's not the case, haven't looked deep. Let's close this PR because neither I nor you don't have time to argue. |
||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a small stylistic nit but it's more common in the codebase to see
line
when translating a position to a line number (rather thanrow
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this is just a language barrier but for me it was confusing because there is
row
inPosition
. In any case I'm fine with any name.