mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-25 19:03:30 +04:00
lsp: Improve line ending handling when generating TextEdit
This commit is contained in:
parent
08967baef6
commit
57ed5180e0
@ -3,7 +3,7 @@
|
|||||||
Call, Error, OffsetEncoding, Result,
|
Call, Error, OffsetEncoding, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
use helix_core::{chars::char_is_line_ending, find_root, ChangeSet, Rope};
|
use helix_core::{find_root, ChangeSet, Rope};
|
||||||
use jsonrpc_core as jsonrpc;
|
use jsonrpc_core as jsonrpc;
|
||||||
use lsp_types as lsp;
|
use lsp_types as lsp;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@ -356,7 +356,6 @@ pub fn changeset_to_changes(
|
|||||||
//
|
//
|
||||||
// Calculation is therefore a bunch trickier.
|
// Calculation is therefore a bunch trickier.
|
||||||
|
|
||||||
// TODO: stolen from syntax.rs, share
|
|
||||||
use helix_core::RopeSlice;
|
use helix_core::RopeSlice;
|
||||||
fn traverse(pos: lsp::Position, text: RopeSlice) -> lsp::Position {
|
fn traverse(pos: lsp::Position, text: RopeSlice) -> lsp::Position {
|
||||||
let lsp::Position {
|
let lsp::Position {
|
||||||
@ -366,7 +365,12 @@ fn traverse(pos: lsp::Position, text: RopeSlice) -> lsp::Position {
|
|||||||
|
|
||||||
let mut chars = text.chars().peekable();
|
let mut chars = text.chars().peekable();
|
||||||
while let Some(ch) = chars.next() {
|
while let Some(ch) = chars.next() {
|
||||||
if char_is_line_ending(ch) && !(ch == '\r' && chars.peek() == Some(&'\n')) {
|
// LSP only considers \n, \r or \r\n as line endings
|
||||||
|
if ch == '\n' || ch == '\r' {
|
||||||
|
// consume a \r\n
|
||||||
|
if chars.peek() == Some(&'\n') {
|
||||||
|
chars.next();
|
||||||
|
}
|
||||||
line += 1;
|
line += 1;
|
||||||
character = 0;
|
character = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -891,6 +891,40 @@ fn default() -> Self {
|
|||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn changeset_to_changes_ignore_line_endings() {
|
||||||
|
use helix_lsp::{lsp, Client, OffsetEncoding};
|
||||||
|
let text = Rope::from("hello\r\nworld");
|
||||||
|
let mut doc = Document::from(text, None);
|
||||||
|
let view = ViewId::default();
|
||||||
|
doc.set_selection(view, Selection::single(0, 0));
|
||||||
|
|
||||||
|
let transaction =
|
||||||
|
Transaction::change(doc.text(), vec![(5, 7, Some("\n".into()))].into_iter());
|
||||||
|
let old_doc = doc.text().clone();
|
||||||
|
doc.apply(&transaction, view);
|
||||||
|
let changes = Client::changeset_to_changes(
|
||||||
|
&old_doc,
|
||||||
|
doc.text(),
|
||||||
|
transaction.changes(),
|
||||||
|
OffsetEncoding::Utf8,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(doc.text(), "hello\nworld");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
changes,
|
||||||
|
&[lsp::TextDocumentContentChangeEvent {
|
||||||
|
range: Some(lsp::Range::new(
|
||||||
|
lsp::Position::new(0, 5),
|
||||||
|
lsp::Position::new(1, 0)
|
||||||
|
)),
|
||||||
|
text: "\n".into(),
|
||||||
|
range_length: None,
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn changeset_to_changes() {
|
fn changeset_to_changes() {
|
||||||
use helix_lsp::{lsp, Client, OffsetEncoding};
|
use helix_lsp::{lsp, Client, OffsetEncoding};
|
||||||
|
Loading…
Reference in New Issue
Block a user