aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaž Hrastnik2020-12-23 08:03:20 +0000
committerBlaž Hrastnik2020-12-23 09:16:17 +0000
commitcd16df19c1f951e1ef0c560ae5e084b18bd2c713 (patch)
tree82b1431a96c914033fff8b79fcdcda9f535a16f9
parent56f2193811fca2fa20284442c2042fa271464445 (diff)
lsp: generate_transaction_from_text_edits
-rw-r--r--Cargo.lock11
-rw-r--r--helix-lsp/src/lib.rs29
-rw-r--r--helix-lsp/src/transport.rs4
-rw-r--r--helix-term/Cargo.toml1
-rw-r--r--helix-term/src/commands.rs17
5 files changed, 57 insertions, 5 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7d94a38b..33b7002a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -594,6 +594,7 @@ dependencies = [
"num_cpus",
"once_cell",
"smol",
+ "smol-timeout",
"tui",
]
@@ -1143,6 +1144,16 @@ dependencies = [
]
[[package]]
+name = "smol-timeout"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "847d777e2c6c166bad26264479e80a9820f3d364fcb4a0e23cd57bbfa8e94961"
+dependencies = [
+ "async-io",
+ "pin-project-lite",
+]
+
+[[package]]
name = "socket2"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs
index c56721a5..27a5e046 100644
--- a/helix-lsp/src/lib.rs
+++ b/helix-lsp/src/lib.rs
@@ -28,19 +28,44 @@ pub enum Error {
pub mod util {
use super::*;
+ use helix_core::{RopeSlice, State, Transaction};
- pub fn lsp_pos_to_pos(doc: &helix_core::RopeSlice, pos: lsp::Position) -> usize {
+ pub fn lsp_pos_to_pos(doc: &RopeSlice, pos: lsp::Position) -> usize {
let line = doc.line_to_char(pos.line as usize);
let line_start = doc.char_to_utf16_cu(line);
doc.utf16_cu_to_char(pos.character as usize + line_start)
}
- pub fn pos_to_lsp_pos(doc: &helix_core::RopeSlice, pos: usize) -> lsp::Position {
+ pub fn pos_to_lsp_pos(doc: &RopeSlice, pos: usize) -> lsp::Position {
let line = doc.char_to_line(pos);
let line_start = doc.char_to_utf16_cu(line);
let col = doc.char_to_utf16_cu(pos) - line_start;
lsp::Position::new(line as u32, col as u32)
}
+
+ pub fn generate_transaction_from_edits(
+ state: &State,
+ edits: Vec<lsp::TextEdit>,
+ ) -> Transaction {
+ let doc = state.doc.slice(..);
+ Transaction::change(
+ state,
+ edits.into_iter().map(|edit| {
+ // simplify "" into None for cleaner changesets
+ let replacement = if !edit.new_text.is_empty() {
+ Some(edit.new_text.into())
+ } else {
+ None
+ };
+
+ let start = lsp_pos_to_pos(&doc, edit.range.start);
+ let end = lsp_pos_to_pos(&doc, edit.range.end);
+ (start, end, replacement)
+ }),
+ )
+ }
+
+ // apply_insert_replace_edit
}
#[derive(Debug, PartialEq, Clone)]
diff --git a/helix-lsp/src/transport.rs b/helix-lsp/src/transport.rs
index 22af1b40..07c89fdd 100644
--- a/helix-lsp/src/transport.rs
+++ b/helix-lsp/src/transport.rs
@@ -107,6 +107,8 @@ impl Transport {
// read data
+ debug!("<- {}", msg);
+
// try parsing as output (server response) or call (server request)
let output: serde_json::Result<Message> = serde_json::from_str(&msg);
@@ -201,8 +203,6 @@ impl Transport {
}
let msg = msg.unwrap();
- debug!("<- {:?}", msg);
-
self.recv_msg(msg).await.unwrap();
}
}
diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml
index 645ed155..67e8f443 100644
--- a/helix-term/Cargo.toml
+++ b/helix-term/Cargo.toml
@@ -20,6 +20,7 @@ anyhow = "1"
once_cell = "1.4"
smol = "1"
+smol-timeout = "0.6"
num_cpus = "1"
# tui = { version = "0.12", default-features = false, features = ["crossterm"] }
tui = { git = "https://github.com/fdehau/tui-rs", default-features = false, features = ["crossterm"] }
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index eb23041c..862cf312 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -837,17 +837,32 @@ pub fn completion(cx: &mut Context) {
let language_server = cx.language_servers.get("rust", &cx.executor).unwrap();
use log::info;
+ use smol_timeout::TimeoutExt;
+ use std::time::Duration;
+
// TODO: blocking here is not ideal
- let res = smol::block_on(language_server.completion(&cx.view.doc)).expect("completion failed!");
+ let res = smol::block_on(
+ language_server
+ .completion(&cx.view.doc)
+ .timeout(Duration::from_secs(2)),
+ )
+ .expect("completion failed!")
+ .expect("completion failed!");
let picker = ui::Picker::new(
res,
|item| {
// format_fn
item.label.as_str().into()
+
+ // TODO: use item.filter_text for filtering
},
|editor: &mut Editor, item| {
+ // if item.text_edit is Some we use that, else
+ // let insert_text = &item.insert_text.unwrap_or(item.label);
+ // and we insert at position.
//
+ // merge this with additional_text_edits
},
);