From 93c7afc4ed2b8d848fa2779f43202ba7f837263b Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Sat, 11 Feb 2023 07:50:01 +0100 Subject: 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.--- helix-lsp/src/client.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'helix-lsp/src/client.rs') diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index cb6e5d81..2f5b498d 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -6,6 +6,7 @@ use crate::{ use helix_core::{find_root, ChangeSet, Rope}; use helix_loader::{self, VERSION_AND_GIT_HASH}; +use lsp::PositionEncodingKind; use lsp_types as lsp; use serde::Deserialize; use serde_json::Value; @@ -32,7 +33,6 @@ pub struct Client { server_tx: UnboundedSender, request_counter: AtomicU64, pub(crate) capabilities: OnceCell, - offset_encoding: OffsetEncoding, config: Option, root_path: std::path::PathBuf, root_uri: Option, @@ -104,7 +104,6 @@ impl Client { server_tx, request_counter: AtomicU64::new(0), capabilities: OnceCell::new(), - offset_encoding: OffsetEncoding::Utf16, config, req_timeout, @@ -147,7 +146,19 @@ impl Client { } pub fn offset_encoding(&self) -> OffsetEncoding { - self.offset_encoding + self.capabilities() + .position_encoding + .as_ref() + .and_then(|encoding| match encoding.as_str() { + "utf-8" => Some(OffsetEncoding::Utf8), + "utf-16" => Some(OffsetEncoding::Utf16), + "utf-32" => Some(OffsetEncoding::Utf32), + encoding => { + log::error!("Server provided invalid position encording {encoding}, defaulting to utf-16"); + None + }, + }) + .unwrap_or_default() } pub fn config(&self) -> Option<&Value> { @@ -377,6 +388,14 @@ impl Client { work_done_progress: Some(true), ..Default::default() }), + general: Some(lsp::GeneralClientCapabilities { + position_encodings: Some(vec![ + PositionEncodingKind::UTF32, + PositionEncodingKind::UTF8, + PositionEncodingKind::UTF16, + ]), + ..Default::default() + }), ..Default::default() }, trace: None, @@ -577,7 +596,7 @@ impl Client { }] } lsp::TextDocumentSyncKind::INCREMENTAL => { - Self::changeset_to_changes(old_text, new_text, changes, self.offset_encoding) + Self::changeset_to_changes(old_text, new_text, changes, self.offset_encoding()) } lsp::TextDocumentSyncKind::NONE => return None, kind => unimplemented!("{:?}", kind), @@ -1027,7 +1046,7 @@ impl Client { partial_result_params: lsp::PartialResultParams::default(), }; - Some(self.call::(params)) + Some(self.call::(params)) } pub fn code_actions( -- cgit v1.2.3-70-g09d2