Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-db/src/tests/line_index.rs9
-rw-r--r--crates/rust-analyzer/src/caps.rs11
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs12
-rw-r--r--lib/line-index/src/lib.rs11
4 files changed, 24 insertions, 19 deletions
diff --git a/crates/ide-db/src/tests/line_index.rs b/crates/ide-db/src/tests/line_index.rs
index c12936071d..c41b0de563 100644
--- a/crates/ide-db/src/tests/line_index.rs
+++ b/crates/ide-db/src/tests/line_index.rs
@@ -28,16 +28,11 @@ fn test_every_chars() {
let got_lin_col = line_index.line_col(got_offset);
assert_eq!(got_lin_col, lin_col);
- for enc in [WideEncoding::Utf16, WideEncoding::Utf32] {
+ for (enc, col) in [(WideEncoding::Utf16, col_utf16), (WideEncoding::Utf32, col_utf32)] {
let wide_lin_col = line_index.to_wide(enc, lin_col);
let got_lin_col = line_index.to_utf8(enc, wide_lin_col);
assert_eq!(got_lin_col, lin_col);
-
- let want_col = match enc {
- WideEncoding::Utf16 => col_utf16,
- WideEncoding::Utf32 => col_utf32,
- };
- assert_eq!(wide_lin_col.col, want_col)
+ assert_eq!(wide_lin_col.col, col)
}
if c == '\n' {
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 3628670ac9..ab06b96814 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -23,13 +23,14 @@ use crate::semantic_tokens;
pub fn server_capabilities(config: &Config) -> ServerCapabilities {
ServerCapabilities {
- position_encoding: Some(match negotiated_encoding(config.caps()) {
- PositionEncoding::Utf8 => PositionEncodingKind::UTF8,
+ position_encoding: match negotiated_encoding(config.caps()) {
+ PositionEncoding::Utf8 => Some(PositionEncodingKind::UTF8),
PositionEncoding::Wide(wide) => match wide {
- WideEncoding::Utf16 => PositionEncodingKind::UTF16,
- WideEncoding::Utf32 => PositionEncodingKind::UTF32,
+ WideEncoding::Utf16 => Some(PositionEncodingKind::UTF16),
+ WideEncoding::Utf32 => Some(PositionEncodingKind::UTF32),
+ _ => None,
},
- }),
+ },
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::INCREMENTAL),
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 415fa4e02f..c8b2c4edb8 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -3,7 +3,6 @@
use std::collections::HashMap;
use flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan};
-use ide_db::line_index::WideEncoding;
use itertools::Itertools;
use stdx::format_to;
use vfs::{AbsPath, AbsPathBuf};
@@ -94,17 +93,16 @@ fn position(
};
}
let mut char_offset = 0;
- let len_func = match position_encoding {
- PositionEncoding::Utf8 => char::len_utf8,
- PositionEncoding::Wide(WideEncoding::Utf16) => char::len_utf16,
- PositionEncoding::Wide(WideEncoding::Utf32) => |_| 1,
- };
for c in line.text.chars() {
char_offset += 1;
if char_offset > column_offset {
break;
}
- true_column_offset += len_func(c) - 1;
+ let len = match position_encoding {
+ PositionEncoding::Utf8 => c.len_utf8(),
+ PositionEncoding::Wide(w) => w.measure(&c.to_string()),
+ };
+ true_column_offset += len - 1;
}
}
diff --git a/lib/line-index/src/lib.rs b/lib/line-index/src/lib.rs
index 61f907f060..40815bdcf1 100644
--- a/lib/line-index/src/lib.rs
+++ b/lib/line-index/src/lib.rs
@@ -20,6 +20,7 @@ pub struct LineCol {
/// A kind of wide character encoding.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[non_exhaustive]
pub enum WideEncoding {
/// UTF-16.
Utf16,
@@ -27,6 +28,16 @@ pub enum WideEncoding {
Utf32,
}
+impl WideEncoding {
+ /// Returns the number of units it takes to encode `text` in this encoding.
+ pub fn measure(&self, text: &str) -> usize {
+ match self {
+ WideEncoding::Utf16 => text.encode_utf16().count(),
+ WideEncoding::Utf32 => text.chars().count(),
+ }
+ }
+}
+
/// Line/Column information in legacy encodings.
//
// Deliberately not a generic type and different from `LineCol`.