on master help sign in
lsp: generate_transaction_from_text_edits
commitcd16df19c1f951e1ef0c560ae5e084b18bd2c713 authorBlaž Hrastnik <blaz@mxxn.io> dateWed 23 Dec 2020, 17:03 (6 years ago) parent56f2193
5 files changed+57−5
Cargo.lock+11 helix-lsp/src/lib.rs+27−2 helix-lsp/src/transport.rs+2−2 helix-term/Cargo.toml+1 helix-term/src/commands.rs+16−1
Cargo.lock+11
@@ -594,6 +594,7 @@ dependencies = [
594594 "num_cpus",
595595 "once_cell",
596596 "smol",
597+ "smol-timeout",
597598 "tui",
598599]
599600
@@ -1142,6 +1143,16 @@ dependencies = [
11421143 "once_cell",
11431144]
11441145
1146+[[package]]
1147+name = "smol-timeout"
1148+version = "0.6.0"
1149+source = "registry+https://github.com/rust-lang/crates.io-index"
1150+checksum = "847d777e2c6c166bad26264479e80a9820f3d364fcb4a0e23cd57bbfa8e94961"
1151+dependencies = [
1152+ "async-io",
1153+ "pin-project-lite",
1154+]
1155+
11451156[[package]]
11461157name = "socket2"
11471158version = "0.3.18"
helix-lsp/src/lib.rs+27−2
@@ -28,19 +28,44 @@ pub enum Error {
2828
2929pub mod util {
3030 use super::*;
31+ use helix_core::{RopeSlice, State, Transaction};
3132
32− pub fn lsp_pos_to_pos(doc: &helix_core::RopeSlice, pos: lsp::Position) -> usize {
33+ pub fn lsp_pos_to_pos(doc: &RopeSlice, pos: lsp::Position) -> usize {
3334 let line = doc.line_to_char(pos.line as usize);
3435 let line_start = doc.char_to_utf16_cu(line);
3536 doc.utf16_cu_to_char(pos.character as usize + line_start)
3637 }
37− pub fn pos_to_lsp_pos(doc: &helix_core::RopeSlice, pos: usize) -> lsp::Position {
38+ pub fn pos_to_lsp_pos(doc: &RopeSlice, pos: usize) -> lsp::Position {
3839 let line = doc.char_to_line(pos);
3940 let line_start = doc.char_to_utf16_cu(line);
4041 let col = doc.char_to_utf16_cu(pos) - line_start;
4142
4243 lsp::Position::new(line as u32, col as u32)
4344 }
45+
46+ pub fn generate_transaction_from_edits(
47+ state: &State,
48+ edits: Vec<lsp::TextEdit>,
49+ ) -> Transaction {
50+ let doc = state.doc.slice(..);
51+ Transaction::change(
52+ state,
53+ edits.into_iter().map(|edit| {
54+ // simplify "" into None for cleaner changesets
55+ let replacement = if !edit.new_text.is_empty() {
56+ Some(edit.new_text.into())
57+ } else {
58+ None
59+ };
60+
61+ let start = lsp_pos_to_pos(&doc, edit.range.start);
62+ let end = lsp_pos_to_pos(&doc, edit.range.end);
63+ (start, end, replacement)
64+ }),
65+ )
66+ }
67+
68+ // apply_insert_replace_edit
4469}
4570
4671#[derive(Debug, PartialEq, Clone)]
helix-lsp/src/transport.rs+2−2
@@ -107,6 +107,8 @@ impl Transport {
107107
108108 // read data
109109
110+ debug!("<- {}", msg);
111+
110112 // try parsing as output (server response) or call (server request)
111113 let output: serde_json::Result<Message> = serde_json::from_str(&msg);
112114
@@ -201,8 +203,6 @@ impl Transport {
201203 }
202204 let msg = msg.unwrap();
203205
204− debug!("<- {:?}", msg);
205−
206206 self.recv_msg(msg).await.unwrap();
207207 }
208208 }
helix-term/Cargo.toml+1
@@ -20,6 +20,7 @@ anyhow = "1"
2020once_cell = "1.4"
2121
2222smol = "1"
23+smol-timeout = "0.6"
2324num_cpus = "1"
2425# tui = { version = "0.12", default-features = false, features = ["crossterm"] }
2526tui = { git = "https://github.com/fdehau/tui-rs", default-features = false, features = ["crossterm"] }
helix-term/src/commands.rs+16−1
@@ -837,17 +837,32 @@ pub fn completion(cx: &mut Context) {
837837 let language_server = cx.language_servers.get("rust", &cx.executor).unwrap();
838838 use log::info;
839839
840+ use smol_timeout::TimeoutExt;
841+ use std::time::Duration;
842+
840843 // TODO: blocking here is not ideal
841− let res = smol::block_on(language_server.completion(&cx.view.doc)).expect("completion failed!");
844+ let res = smol::block_on(
845+ language_server
846+ .completion(&cx.view.doc)
847+ .timeout(Duration::from_secs(2)),
848+ )
849+ .expect("completion failed!")
850+ .expect("completion failed!");
842851
843852 let picker = ui::Picker::new(
844853 res,
845854 |item| {
846855 // format_fn
847856 item.label.as_str().into()
857+
858+ // TODO: use item.filter_text for filtering
848859 },
849860 |editor: &mut Editor, item| {
861+ // if item.text_edit is Some we use that, else
862+ // let insert_text = &item.insert_text.unwrap_or(item.label);
863+ // and we insert at position.
850864 //
865+ // merge this with additional_text_edits
851866 },
852867 );
853868