From fcbe73ec1caad761eb6cf1a641fa667ac920076b Mon Sep 17 00:00:00 2001 From: Ariel Davis Date: Sat, 6 May 2023 00:52:32 -0700 Subject: [PATCH] Refactor position --- .../rust-analyzer/src/diagnostics/to_proto.rs | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index c8b2c4edb8..e1d1130ff1 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs @@ -79,36 +79,33 @@ fn position( position_encoding: &PositionEncoding, span: &DiagnosticSpan, line_offset: usize, - column_offset: usize, + column_offset_utf32: usize, ) -> lsp_types::Position { let line_index = line_offset - span.line_start; - let mut true_column_offset = column_offset; - if let Some(line) = span.text.get(line_index) { - if line.text.chars().count() == line.text.len() { - // all one byte utf-8 char - return lsp_types::Position { - line: (line_offset as u32).saturating_sub(1), - character: (column_offset as u32).saturating_sub(1), - }; - } - let mut char_offset = 0; - for c in line.text.chars() { - char_offset += 1; - if char_offset > column_offset { - break; + let column_offset_encoded = match span.text.get(line_index) { + // Fast path. + Some(line) if line.text.is_ascii() => column_offset_utf32, + Some(line) => { + let line_prefix_len = line + .text + .char_indices() + .take(column_offset_utf32) + .last() + .map(|(pos, c)| pos + c.len_utf8()) + .unwrap_or(0); + let line_prefix = &line.text[..line_prefix_len]; + match position_encoding { + PositionEncoding::Utf8 => line_prefix.len(), + PositionEncoding::Wide(enc) => enc.measure(line_prefix), } - let len = match position_encoding { - PositionEncoding::Utf8 => c.len_utf8(), - PositionEncoding::Wide(w) => w.measure(&c.to_string()), - }; - true_column_offset += len - 1; } - } + None => column_offset_utf32, + }; lsp_types::Position { line: (line_offset as u32).saturating_sub(1), - character: (true_column_offset as u32).saturating_sub(1), + character: (column_offset_encoded as u32).saturating_sub(1), } }