on master help sign in
lsp: Improve line ending handling when generating TextEdit
commit57ed5180e0e1af3b3ddcb478c4a6d6ecd969cd40 authorBlaž Hrastnik <blaz@mxxn.io> dateMon 6 Sep 2021, 11:00 (5 years ago) parent08967ba
2 files changed+41−3
helix-lsp/src/client.rs+7−3 helix-view/src/document.rs+34
helix-lsp/src/client.rs+7−3
@@ -3,7 +3,7 @@ use crate::{
33 Call, Error, OffsetEncoding, Result,
44};
55
6−use helix_core::{chars::char_is_line_ending, find_root, ChangeSet, Rope};
6+use helix_core::{find_root, ChangeSet, Rope};
77use jsonrpc_core as jsonrpc;
88use lsp_types as lsp;
99use serde_json::Value;
@@ -356,7 +356,6 @@ impl Client {
356356 //
357357 // Calculation is therefore a bunch trickier.
358358
359− // TODO: stolen from syntax.rs, share
360359 use helix_core::RopeSlice;
361360 fn traverse(pos: lsp::Position, text: RopeSlice) -> lsp::Position {
362361 let lsp::Position {
@@ -366,7 +365,12 @@ impl Client {
366365
367366 let mut chars = text.chars().peekable();
368367 while let Some(ch) = chars.next() {
369− if char_is_line_ending(ch) && !(ch == '\r' && chars.peek() == Some(&'\n')) {
368+ // LSP only considers \n, \r or \r\n as line endings
369+ if ch == '\n' || ch == '\r' {
370+ // consume a \r\n
371+ if chars.peek() == Some(&'\n') {
372+ chars.next();
373+ }
370374 line += 1;
371375 character = 0;
372376 } else {
helix-view/src/document.rs+34
@@ -891,6 +891,40 @@ impl Default for Document {
891891mod test {
892892 use super::*;
893893
894+ #[test]
895+ fn changeset_to_changes_ignore_line_endings() {
896+ use helix_lsp::{lsp, Client, OffsetEncoding};
897+ let text = Rope::from("hello\r\nworld");
898+ let mut doc = Document::from(text, None);
899+ let view = ViewId::default();
900+ doc.set_selection(view, Selection::single(0, 0));
901+
902+ let transaction =
903+ Transaction::change(doc.text(), vec![(5, 7, Some("\n".into()))].into_iter());
904+ let old_doc = doc.text().clone();
905+ doc.apply(&transaction, view);
906+ let changes = Client::changeset_to_changes(
907+ &old_doc,
908+ doc.text(),
909+ transaction.changes(),
910+ OffsetEncoding::Utf8,
911+ );
912+
913+ assert_eq!(doc.text(), "hello\nworld");
914+
915+ assert_eq!(
916+ changes,
917+ &[lsp::TextDocumentContentChangeEvent {
918+ range: Some(lsp::Range::new(
919+ lsp::Position::new(0, 5),
920+ lsp::Position::new(1, 0)
921+ )),
922+ text: "\n".into(),
923+ range_length: None,
924+ }]
925+ );
926+ }
927+
894928 #[test]
895929 fn changeset_to_changes() {
896930 use helix_lsp::{lsp, Client, OffsetEncoding};