diff options
author | Aleksey Kladov <[email protected]> | 2021-02-12 21:55:27 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-02-16 16:17:32 +0000 |
commit | c8b9ec8e62d9f560a6557496bc4b579019ccb509 (patch) | |
tree | e3fdf968a8fcfb018319c94f524b0cb1b9ba3e67 /crates | |
parent | 0025836f262ee410050ba79b6ea09d75f76449ac (diff) |
Implement utf8 offsets
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rust-analyzer/src/from_proto.rs | 19 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/line_endings.rs | 7 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_utils.rs | 5 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 25 |
5 files changed, 45 insertions, 15 deletions
diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs index c671b5f64..4f3ae8cc3 100644 --- a/crates/rust-analyzer/src/from_proto.rs +++ b/crates/rust-analyzer/src/from_proto.rs | |||
@@ -1,13 +1,16 @@ | |||
1 | //! Conversion lsp_types types to rust-analyzer specific ones. | 1 | //! Conversion lsp_types types to rust-analyzer specific ones. |
2 | use std::convert::TryFrom; | 2 | use std::convert::TryFrom; |
3 | 3 | ||
4 | use ide::{Annotation, AnnotationKind, AssistKind, LineColUtf16}; | 4 | use ide::{Annotation, AnnotationKind, AssistKind, LineCol, LineColUtf16}; |
5 | use ide_db::base_db::{FileId, FilePosition, FileRange}; | 5 | use ide_db::base_db::{FileId, FilePosition, FileRange}; |
6 | use syntax::{TextRange, TextSize}; | 6 | use syntax::{TextRange, TextSize}; |
7 | use vfs::AbsPathBuf; | 7 | use vfs::AbsPathBuf; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | from_json, global_state::GlobalStateSnapshot, line_endings::LineIndex, lsp_ext, Result, | 10 | from_json, |
11 | global_state::GlobalStateSnapshot, | ||
12 | line_endings::{LineIndex, OffsetEncoding}, | ||
13 | lsp_ext, Result, | ||
11 | }; | 14 | }; |
12 | 15 | ||
13 | pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> { | 16 | pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> { |
@@ -20,8 +23,16 @@ pub(crate) fn vfs_path(url: &lsp_types::Url) -> Result<vfs::VfsPath> { | |||
20 | } | 23 | } |
21 | 24 | ||
22 | pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize { | 25 | pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize { |
23 | let line_col = LineColUtf16 { line: position.line as u32, col: position.character as u32 }; | 26 | let line_col = match line_index.encoding { |
24 | let line_col = line_index.index.to_utf8(line_col); | 27 | OffsetEncoding::Utf8 => { |
28 | LineCol { line: position.line as u32, col: position.character as u32 } | ||
29 | } | ||
30 | OffsetEncoding::Utf16 => { | ||
31 | let line_col = | ||
32 | LineColUtf16 { line: position.line as u32, col: position.character as u32 }; | ||
33 | line_index.index.to_utf8(line_col) | ||
34 | } | ||
35 | }; | ||
25 | line_index.index.offset(line_col) | 36 | line_index.index.offset(line_col) |
26 | } | 37 | } |
27 | 38 | ||
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index ffef33430..d26e5ef48 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | diagnostics::{CheckFixes, DiagnosticCollection}, | 22 | diagnostics::{CheckFixes, DiagnosticCollection}, |
23 | document::DocumentData, | 23 | document::DocumentData, |
24 | from_proto, | 24 | from_proto, |
25 | line_endings::{LineEndings, LineIndex}, | 25 | line_endings::{LineEndings, LineIndex, OffsetEncoding}, |
26 | main_loop::Task, | 26 | main_loop::Task, |
27 | op_queue::OpQueue, | 27 | op_queue::OpQueue, |
28 | reload::SourceRootConfig, | 28 | reload::SourceRootConfig, |
@@ -274,7 +274,7 @@ impl GlobalStateSnapshot { | |||
274 | pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancelable<LineIndex> { | 274 | pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancelable<LineIndex> { |
275 | let endings = self.vfs.read().1[&file_id]; | 275 | let endings = self.vfs.read().1[&file_id]; |
276 | let index = self.analysis.file_line_index(file_id)?; | 276 | let index = self.analysis.file_line_index(file_id)?; |
277 | let res = LineIndex { index, endings }; | 277 | let res = LineIndex { index, endings, encoding: OffsetEncoding::Utf16 }; |
278 | Ok(res) | 278 | Ok(res) |
279 | } | 279 | } |
280 | 280 | ||
diff --git a/crates/rust-analyzer/src/line_endings.rs b/crates/rust-analyzer/src/line_endings.rs index cc152c529..7b6cba43e 100644 --- a/crates/rust-analyzer/src/line_endings.rs +++ b/crates/rust-analyzer/src/line_endings.rs | |||
@@ -4,9 +4,16 @@ | |||
4 | 4 | ||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | pub(crate) enum OffsetEncoding { | ||
8 | #[allow(unused)] | ||
9 | Utf8, | ||
10 | Utf16, | ||
11 | } | ||
12 | |||
7 | pub(crate) struct LineIndex { | 13 | pub(crate) struct LineIndex { |
8 | pub(crate) index: Arc<ide::LineIndex>, | 14 | pub(crate) index: Arc<ide::LineIndex>, |
9 | pub(crate) endings: LineEndings, | 15 | pub(crate) endings: LineEndings, |
16 | pub(crate) encoding: OffsetEncoding, | ||
10 | } | 17 | } |
11 | 18 | ||
12 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 19 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs index 25162185e..6b8e347b9 100644 --- a/crates/rust-analyzer/src/lsp_utils.rs +++ b/crates/rust-analyzer/src/lsp_utils.rs | |||
@@ -7,7 +7,7 @@ use lsp_server::Notification; | |||
7 | use crate::{ | 7 | use crate::{ |
8 | from_proto, | 8 | from_proto, |
9 | global_state::GlobalState, | 9 | global_state::GlobalState, |
10 | line_endings::{LineEndings, LineIndex}, | 10 | line_endings::{LineEndings, LineIndex, OffsetEncoding}, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool { | 13 | pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool { |
@@ -95,8 +95,9 @@ pub(crate) fn apply_document_changes( | |||
95 | ) { | 95 | ) { |
96 | let mut line_index = LineIndex { | 96 | let mut line_index = LineIndex { |
97 | index: Arc::new(ide::LineIndex::new(old_text)), | 97 | index: Arc::new(ide::LineIndex::new(old_text)), |
98 | // We don't care about line endings here. | 98 | // We don't care about line endings or offset encoding here. |
99 | endings: LineEndings::Unix, | 99 | endings: LineEndings::Unix, |
100 | encoding: OffsetEncoding::Utf16, | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | // The changes we got must be applied sequentially, but can cross lines so we | 103 | // The changes we got must be applied sequentially, but can cross lines so we |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 43e29ef04..368d916e7 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -17,14 +17,19 @@ use serde_json::to_value; | |||
17 | use crate::{ | 17 | use crate::{ |
18 | cargo_target_spec::CargoTargetSpec, | 18 | cargo_target_spec::CargoTargetSpec, |
19 | global_state::GlobalStateSnapshot, | 19 | global_state::GlobalStateSnapshot, |
20 | line_endings::{LineEndings, LineIndex}, | 20 | line_endings::{LineEndings, LineIndex, OffsetEncoding}, |
21 | lsp_ext, semantic_tokens, Result, | 21 | lsp_ext, semantic_tokens, Result, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { | 24 | pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { |
25 | let line_col = line_index.index.line_col(offset); | 25 | let line_col = line_index.index.line_col(offset); |
26 | let line_col = line_index.index.to_utf16(line_col); | 26 | match line_index.encoding { |
27 | lsp_types::Position::new(line_col.line, line_col.col) | 27 | OffsetEncoding::Utf8 => lsp_types::Position::new(line_col.line, line_col.col), |
28 | OffsetEncoding::Utf16 => { | ||
29 | let line_col = line_index.index.to_utf16(line_col); | ||
30 | lsp_types::Position::new(line_col.line, line_col.col) | ||
31 | } | ||
32 | } | ||
28 | } | 33 | } |
29 | 34 | ||
30 | pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Range { | 35 | pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Range { |
@@ -1068,8 +1073,11 @@ mod tests { | |||
1068 | }"#; | 1073 | }"#; |
1069 | 1074 | ||
1070 | let (offset, text) = test_utils::extract_offset(fixture); | 1075 | let (offset, text) = test_utils::extract_offset(fixture); |
1071 | let line_index = | 1076 | let line_index = LineIndex { |
1072 | LineIndex { index: Arc::new(ide::LineIndex::new(&text)), endings: LineEndings::Unix }; | 1077 | index: Arc::new(ide::LineIndex::new(&text)), |
1078 | endings: LineEndings::Unix, | ||
1079 | encoding: OffsetEncoding::Utf16, | ||
1080 | }; | ||
1073 | let (analysis, file_id) = Analysis::from_single_file(text); | 1081 | let (analysis, file_id) = Analysis::from_single_file(text); |
1074 | let completions: Vec<(String, Option<String>)> = analysis | 1082 | let completions: Vec<(String, Option<String>)> = analysis |
1075 | .completions( | 1083 | .completions( |
@@ -1125,8 +1133,11 @@ fn main() { | |||
1125 | let folds = analysis.folding_ranges(file_id).unwrap(); | 1133 | let folds = analysis.folding_ranges(file_id).unwrap(); |
1126 | assert_eq!(folds.len(), 4); | 1134 | assert_eq!(folds.len(), 4); |
1127 | 1135 | ||
1128 | let line_index = | 1136 | let line_index = LineIndex { |
1129 | LineIndex { index: Arc::new(ide::LineIndex::new(&text)), endings: LineEndings::Unix }; | 1137 | index: Arc::new(ide::LineIndex::new(&text)), |
1138 | endings: LineEndings::Unix, | ||
1139 | encoding: OffsetEncoding::Utf16, | ||
1140 | }; | ||
1130 | let converted: Vec<lsp_types::FoldingRange> = | 1141 | let converted: Vec<lsp_types::FoldingRange> = |
1131 | folds.into_iter().map(|it| folding_range(&text, &line_index, true, it)).collect(); | 1142 | folds.into_iter().map(|it| folding_range(&text, &line_index, true, it)).collect(); |
1132 | 1143 | ||