diff options
author | Pascal Kuthe | 2023-02-11 06:50:01 +0000 |
---|---|---|
committer | GitHub | 2023-02-11 06:50:01 +0000 |
commit | 93c7afc4ed2b8d848fa2779f43202ba7f837263b (patch) | |
tree | 866e07e173686a41b5f164ee40b63b585037232a /helix-lsp/src/lib.rs | |
parent | 6929a12f291fa5dee50cde9c89845b206b7333fd (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.rs | 22 |
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) + } } } |