diff --git a/src/lsp.rs b/src/lsp.rs index db26709..963501a 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -141,7 +141,7 @@ impl Backend { async fn get_completions(&self, uri: Url, position: Position) -> Option { // get new input let rope = self.documents.get(uri.as_str())?; - let encoding = self.encoding.read().await.clone(); + let encoding = *self.encoding.read().await; let line_begin = { let line_pos = Position::new(position.line, 0); utils::position_to_offset(&rope, line_pos, encoding)? @@ -184,7 +184,8 @@ impl Backend { .and_then(utils::option_string) .and_then(|rime_raw_input| new_input.borrow_pinyin().rfind(&rime_raw_input)) .unwrap_or(0); - let range = Range::new(utils::offset_to_position(&rope, real_offset)?, position); + let start_position = utils::offset_to_position(&rope, real_offset, encoding)?; + let range = Range::new(start_position, position); let filter_prefix = (self.config.read().await.long_filter_text).then_some( utils::surrounding_word(&Cow::from(rope.slice(line_begin..real_offset))), ); @@ -356,7 +357,7 @@ impl LanguageServer for Backend { } async fn did_change(&self, params: DidChangeTextDocumentParams) { - let encoding = self.encoding.read().await.clone(); + let encoding = *self.encoding.read().await; let url = params.text_document.uri; if let Some(mut rope) = self.documents.get_mut(url.as_str()) { for change in params.content_changes { diff --git a/src/utils.rs b/src/utils.rs index b058170..d9c8c4a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,9 +4,10 @@ use tower_lsp::lsp_types::{Position, PositionEncodingKind}; use crate::consts::AUTO_TRIGGER_RE; -#[derive(Clone, Copy)] +#[derive(Default, Debug, Clone, Copy)] pub enum Encoding { UTF8, + #[default] UTF16, UTF32, } @@ -21,22 +22,16 @@ impl Encoding { } } -impl Default for Encoding { - fn default() -> Self { - Encoding::UTF16 - } -} - pub fn select_encoding(options: Option>) -> Encoding { match options { - // prefer utf-32 because of no conversion cost + // we prefer utf-32 here because there are no conversion costs Some(v) if v.contains(&PositionEncodingKind::new("utf-32")) => Encoding::UTF32, Some(v) if v.contains(&PositionEncodingKind::new("utf-8")) => Encoding::UTF8, _ => Encoding::default(), } } -/// UTF-16 Position -> char index +/// UTF-8/16/32 Position -> char index pub fn position_to_offset(rope: &Rope, position: Position, encoding: Encoding) -> Option { let (line, col) = (position.line as usize, position.character as usize); // position is at the end of rope @@ -55,7 +50,7 @@ pub fn position_to_offset(rope: &Rope, position: Position, encoding: Encoding) - }) } -/// char index -> UTF-16 Position +/// char index -> UTF-8/16/32 Position pub fn offset_to_position(rope: &Rope, offset: usize, encoding: Encoding) -> Option { let line = rope.try_char_to_line(offset).ok()?; let col_offset = offset - rope.try_line_to_char(line).ok()?;