aboutsummaryrefslogtreecommitdiff
path: root/helix-lsp/src/lib.rs
diff options
context:
space:
mode:
authorPascal Kuthe2023-02-11 06:50:01 +0000
committerGitHub2023-02-11 06:50:01 +0000
commit93c7afc4ed2b8d848fa2779f43202ba7f837263b (patch)
tree866e07e173686a41b5f164ee40b63b585037232a /helix-lsp/src/lib.rs
parent6929a12f291fa5dee50cde9c89845b206b7333fd (diff)
Negotiate LSP Position Encoding (#5894)
So far LSP always required that `PositionEncoding.characters` is an UTF-16 offset. Now that LSP 3.17 is available in `lsp-types` request the server to send char offsets (UTF-32) or byte offsets (UTF-8) instead. For compatability with old servers, UTF-16 remains as the fallback as required by the standard.
Diffstat (limited to 'helix-lsp/src/lib.rs')
-rw-r--r--helix-lsp/src/lib.rs22
1 files changed, 17 insertions, 5 deletions
diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs
index bcaff10a..72456b37 100644
--- a/helix-lsp/src/lib.rs
+++ b/helix-lsp/src/lib.rs
@@ -20,7 +20,6 @@ use std::{
},
};
-use serde::{Deserialize, Serialize};
use thiserror::Error;
use tokio_stream::wrappers::UnboundedReceiverStream;
@@ -45,13 +44,14 @@ pub enum Error {
Other(#[from] anyhow::Error),
}
-#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+#[derive(Clone, Copy, Debug, Default)]
pub enum OffsetEncoding {
/// UTF-8 code units aka bytes
- #[serde(rename = "utf-8")]
Utf8,
+ /// UTF-32 code units aka chars
+ Utf32,
/// UTF-16 code units
- #[serde(rename = "utf-16")]
+ #[default]
Utf16,
}
@@ -168,6 +168,11 @@ pub mod util {
let line_end = line_end_char_index(&doc.slice(..), pos_line);
doc.char_to_utf16_cu(line_start)..doc.char_to_utf16_cu(line_end)
}
+ OffsetEncoding::Utf32 => {
+ let line_start = doc.line_to_char(pos_line);
+ let line_end = line_end_char_index(&doc.slice(..), pos_line);
+ line_start..line_end
+ }
};
// The LSP spec demands that the offset is capped to the end of the line
@@ -177,10 +182,10 @@ pub mod util {
.unwrap_or(line.end)
.min(line.end);
- // TODO prefer UTF32/char indices to avoid this step
match offset_encoding {
OffsetEncoding::Utf8 => doc.try_byte_to_char(pos).ok(),
OffsetEncoding::Utf16 => doc.try_utf16_cu_to_char(pos).ok(),
+ OffsetEncoding::Utf32 => Some(pos),
}
}
@@ -207,6 +212,13 @@ pub mod util {
lsp::Position::new(line as u32, col as u32)
}
+ OffsetEncoding::Utf32 => {
+ let line = doc.char_to_line(pos);
+ let line_start = doc.line_to_char(line);
+ let col = pos - line_start;
+
+ lsp::Position::new(line as u32, col as u32)
+ }
}
}