From 421228ebf77db0d372bfb2c7129d055edbad10d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Vi=E1=BB=87t=20H=C6=B0ng?= Date: Mon, 2 Sep 2019 00:28:16 +1200 Subject: [PATCH 1/5] updated lsp_types + url and added autocomplete --- Cargo.lock | 101 +++++++++++++++++++++++++++++++++++++--------- Cargo.toml | 4 +- autoload/lspc.vim | 7 ++++ src/lspc.rs | 86 +++++++++++++++++++++++++++++++++------ src/neovim.rs | 85 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 244 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3818deb..a7e3d19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,16 @@ dependencies = [ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.4" @@ -124,17 +134,14 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.57.2" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -144,13 +151,13 @@ dependencies = [ "crossbeam 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)", "rmp-serde 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)", "rmpv 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "simple-logging 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -169,16 +176,6 @@ name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "num-derive" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-traits" version = "0.1.43" @@ -200,6 +197,11 @@ name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.30" @@ -208,6 +210,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quote" version = "0.6.12" @@ -216,6 +226,14 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.56" @@ -297,6 +315,16 @@ dependencies = [ "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_repr" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "simple-logging" version = "2.0.2" @@ -322,6 +350,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread-id" version = "3.3.0" @@ -353,6 +391,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.7.2" @@ -363,6 +406,17 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "url_serde" version = "0.2.0" @@ -404,20 +458,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" "checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3" -"checksum lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b62b77309737b1e262b3bbf37ff8faa740562c633b14702afe9be85dbcb6f88a" +"checksum lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa3268fbe8beb2795c2fb327bf44f4f3d24f5fe9ebc18d7e2980afd444d72bcf" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum rmp 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a3d45d7afc9b132b34a2479648863aa95c5c88e98b32285326a6ebadc80ec5c9" "checksum rmp-serde 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "011e1d58446e9fa3af7cdc1fb91295b10621d3ac4cb3a85cc86385ee9ca50cd3" @@ -428,14 +485,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "defbb8a83d7f34cc8380751eeb892b825944222888aff18996ea7901f24aec88" "checksum serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "46a3223d0c9ba936b61c0d2e3e559e3217dbfb8d65d06d26e8b3c25de38bae3e" "checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" +"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" "checksum simple-logging 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b00d48e85675326bb182a2286ea7c1a0b264333ae10f27a937a72be08628b542" "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" "checksum syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)" = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index f4f055c..d4ee8df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,6 @@ url_serde = "0.2.0" serde_json = "*" log = "*" lazy_static = "1.3.0" -lsp-types = { version = "0.57.1", features = ["proposed"] } +lsp-types = { version = "0.61.0", features = ["proposed"] } simple-logging = "*" -url = "*" +url = {version = "2.0.0", features = ["serde"]} diff --git a/autoload/lspc.vim b/autoload/lspc.vim index 2449405..0cdf29c 100644 --- a/autoload/lspc.vim +++ b/autoload/lspc.vim @@ -77,6 +77,13 @@ function! lspc#format_doc() call rpcnotify(s:job_id, 'format_doc', l:lang_id, l:cur_path, l:lines) endfunction +function! lspc#completion() + let l:lang_id = 'rust' + let l:cur_path = lspc#buffer#filename() + let l:position = lspc#buffer#position() + call rpcnotify(s:job_id, 'completion', l:lang_id, l:cur_path, l:position, 1) +endfunction + function! lspc#hello_from_the_other_side() call rpcnotify(s:job_id, 'hello') endfunction diff --git a/src/lspc.rs b/src/lspc.rs index 4d80744..4e7c325 100644 --- a/src/lspc.rs +++ b/src/lspc.rs @@ -4,17 +4,20 @@ pub mod msg; pub mod types; use std::{ + collections::HashMap, io, path::{Path, PathBuf}, - collections::HashMap }; use crossbeam::channel::{Receiver, Select}; use lsp_types::{ notification::ShowMessage, - request::{GotoDefinition, GotoDefinitionResponse, HoverRequest, Initialize, Formatting}, - Hover, Location, Position, ShowMessageParams, TextDocumentIdentifier, DocumentFormattingParams, - FormattingOptions, TextEdit + request::{ + Completion, Formatting, GotoDefinition, GotoDefinitionResponse, HoverRequest, Initialize, + }, + CompletionContext, CompletionItem, CompletionParams, CompletionResponse, CompletionTriggerKind, + DocumentFormattingParams, FormattingOptions, Hover, Location, Position, ShowMessageParams, + TextDocumentIdentifier, TextDocumentPositionParams, TextEdit, }; use serde::{Deserialize, Serialize}; use url::Url; @@ -30,7 +33,7 @@ pub struct LsConfig { pub command: Vec, pub root_markers: Vec, pub indentation: u64, - pub indentation_with_space: bool + pub indentation_with_space: bool, } #[derive(Debug)] @@ -59,7 +62,14 @@ pub enum Event { lang_id: String, text_document_lines: Vec, text_document: TextDocumentIdentifier, - } + }, + RequestCompletion { + lang_id: String, + text_document: TextDocumentIdentifier, + position: Position, + trigger_kind: CompletionTriggerKind, + trigger_character: Option, + }, } #[derive(Debug)] @@ -141,6 +151,11 @@ pub trait Editor: 'static { fn show_message(&self, show_message_params: &ShowMessageParams) -> Result<(), EditorError>; fn goto(&self, location: &Location) -> Result<(), EditorError>; fn apply_edits(&self, lines: &Vec, edits: &Vec) -> Result<(), EditorError>; + fn show_completions( + &self, + column: u64, + completion_items: &Vec, + ) -> Result<(), EditorError>; } pub struct Lspc { @@ -217,11 +232,15 @@ impl Lspc { let capabilities = self.editor.capabilities(); let lang_settings = LangSettings { indentation: config.indentation, - indentation_with_space: config.indentation_with_space + indentation_with_space: config.indentation_with_space, }; - let mut lsp_handler = - LangServerHandler::new(lang_id, &config.command[0], lang_settings, &config.command[1..]) - .map_err(|e| LspcError::LangServer(e))?; + let mut lsp_handler = LangServerHandler::new( + lang_id, + &config.command[0], + lang_settings, + &config.command[1..], + ) + .map_err(|e| LspcError::LangServer(e))?; let cur_path = PathBuf::from(cur_path); let root = find_root_path(&cur_path, &config.root_markers) .map(|path| path.to_str()) @@ -326,7 +345,7 @@ impl Lspc { Event::FormatDoc { lang_id, text_document_lines, - text_document + text_document, } => { let handler = self.handler_for(&lang_id).ok_or(LspcError::NotStarted)?; let options = FormattingOptions { @@ -334,7 +353,10 @@ impl Lspc { insert_spaces: handler.lang_settings.indentation_with_space, properties: HashMap::new(), }; - let params = DocumentFormattingParams { text_document, options }; + let params = DocumentFormattingParams { + text_document, + options, + }; handler.lsp_request::( params, Box::new(move |editor: &mut E, _handler, response| { @@ -343,7 +365,45 @@ impl Lspc { } Ok(()) - }) + }), + )?; + } + Event::RequestCompletion { + lang_id, + text_document, + position, + trigger_kind, + trigger_character, + } => { + let handler = self.handler_for(&lang_id).ok_or(LspcError::NotStarted)?; + let text_document_position = TextDocumentPositionParams { + text_document, + position, + }; + let context = Some(CompletionContext { + trigger_kind, + trigger_character, + }); + let params = CompletionParams { + text_document_position, + context, + }; + handler.lsp_request::( + params, + Box::new(move |editor: &mut E, _handler, response| { + if let Some(completion_list) = response { + match completion_list { + CompletionResponse::Array(items) => { + editor.show_completions(position.character, &items)?; + } + CompletionResponse::List(list) => { + editor.show_completions(position.character, &list.items)?; + } + } + } + + Ok(()) + }), )?; } } diff --git a/src/neovim.rs b/src/neovim.rs index a6059d2..f6b66b2 100644 --- a/src/neovim.rs +++ b/src/neovim.rs @@ -10,9 +10,9 @@ use std::{ use crossbeam::channel::{self, Receiver, Sender}; use lsp_types::{ - GotoCapability, Hover, HoverCapability, HoverContents, Location, MarkedString, MarkupContent, - MarkupKind, Position, ShowMessageParams, TextDocumentClientCapabilities, - TextDocumentIdentifier, TextEdit, + CompletionItem, CompletionTriggerKind, GotoCapability, Hover, HoverCapability, HoverContents, + Location, MarkedString, MarkupContent, MarkupKind, Position, ShowMessageParams, + TextDocumentClientCapabilities, TextDocumentIdentifier, TextEdit, }; use rmp_serde::Deserializer; use rmpv::Value; @@ -191,6 +191,15 @@ fn to_document_offset(lines: &Vec, pos: Position) -> usize { + pos.character as usize } +fn to_trigger_kind(kind: u64) -> Option { + match kind { + 1 => Some(CompletionTriggerKind::Invoked), + 2 => Some(CompletionTriggerKind::TriggerCharacter), + 3 => Some(CompletionTriggerKind::TriggerForIncompleteCompletions), + _ => None, + } +} + fn to_text_document(s: &str) -> Option { let uri = Url::from_file_path(s).ok()?; Some(TextDocumentIdentifier::new(uri)) @@ -375,6 +384,55 @@ fn to_event(msg: NvimMessage) -> Result { }) } } + NvimMessage::RpcNotification { + ref method, + ref params, + } if method == "completion" => { + if params.len() < 1 { + Err(EditorError::Parse("Wrong amount of params for completion")) + } else { + let lang_id = params[0] + .as_str() + .ok_or(EditorError::Parse("Invalid lang_id param for completion"))? + .to_owned(); + let text_document_str = params[1].as_str().ok_or(EditorError::Parse( + "Invalid text_document param for completion", + ))?; + let text_document = to_text_document(text_document_str).ok_or( + EditorError::Parse("Can't parse text_document param for completion"), + )?; + let position_map = params[2] + .as_map() + .ok_or(EditorError::Parse("Invalid position param for completion"))?; + let position = to_position(position_map).ok_or(EditorError::Parse( + "Can't parse position param for completion", + ))?; + + let trigger_kind_u64 = params[3].as_u64().ok_or(EditorError::Parse( + "Invalid trigger_kind param for completion", + ))?; + let trigger_kind = to_trigger_kind(trigger_kind_u64).ok_or(EditorError::Parse( + "Can't parse trigger_kind param for completion", + ))?; + + let mut trigger_character = None; + + if trigger_kind == CompletionTriggerKind::TriggerCharacter { + let trigger_character_str = params[4].as_str().ok_or(EditorError::Parse( + "Invalid trigger_character param for completion", + ))?; + trigger_character = Some(String::from(trigger_character_str)); + } + + Ok(Event::RequestCompletion { + lang_id, + text_document, + position, + trigger_kind, + trigger_character, + }) + } + } _ => Err(EditorError::UnexpectedMessage(format!("{:?}", msg))), } } @@ -628,6 +686,26 @@ impl Editor for Neovim { )?; Ok(()) } + + fn show_completions( + &self, + column: u64, + completion_items: &Vec, + ) -> Result<(), EditorError> { + let mut vim_complete_items = vec![]; + for item in completion_items { + vim_complete_items.push(Value::Map(vec![ + ("icase".into(), 1.into()), + ("word".into(), item.label.clone().into()), + ("abbr".into(), item.label.clone().into()), + ])); + } + self.call_function( + "complete", + vec![column.into(), Value::Array(vim_complete_items)], + )?; + Ok(()) + } } impl Message for NvimMessage { @@ -825,4 +903,3 @@ mod tests { assert_eq!(editted_content, expected_content); } } - From 7028aa5568e3e7b732b3e70e48acee1972b1e989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Vi=E1=BB=87t=20H=C6=B0ng?= Date: Mon, 9 Sep 2019 16:10:56 +1200 Subject: [PATCH 2/5] fixed duplicate deps when merge conflict & update parsing params --- Cargo.lock | 46 -------------------------------- src/lspc.rs | 7 +++-- src/neovim.rs | 72 ++++++++++++++++----------------------------------- 3 files changed, 28 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf6c1d1..71e8e9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,19 +195,6 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro2" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "proc-macro2" version = "1.0.2" @@ -224,14 +211,6 @@ dependencies = [ "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "quote" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "redox_syscall" version = "0.1.56" @@ -334,16 +313,6 @@ dependencies = [ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "serde_repr" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "simple-logging" version = "2.0.2" @@ -369,16 +338,6 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "syn" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread-id" version = "3.3.0" @@ -410,11 +369,6 @@ name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "url" version = "1.7.2" diff --git a/src/lspc.rs b/src/lspc.rs index c4abdb3..2083ae2 100644 --- a/src/lspc.rs +++ b/src/lspc.rs @@ -12,9 +12,12 @@ use std::{ use crossbeam::channel::{Receiver, Select}; use lsp_types::{ notification::ShowMessage, - request::{Formatting, GotoDefinition, GotoDefinitionResponse, HoverRequest, Initialize}, + request::{ + Completion, Formatting, GotoDefinition, GotoDefinitionResponse, HoverRequest, Initialize, + }, + CompletionContext, CompletionItem, CompletionParams, CompletionResponse, CompletionTriggerKind, DocumentFormattingParams, FormattingOptions, Hover, Location, Position, ShowMessageParams, - TextDocumentIdentifier, TextEdit, + TextDocumentIdentifier, TextDocumentPositionParams, TextEdit, }; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/src/neovim.rs b/src/neovim.rs index 529c0b8..a58c4ec 100644 --- a/src/neovim.rs +++ b/src/neovim.rs @@ -250,6 +250,29 @@ fn to_event(msg: NvimMessage) -> Result { text_document: format_doc_params.1, text_document_lines: format_doc_params.2, }) + } else if method == "completion" { + #[derive(Deserialize)] + struct CompletionParams( + String, + #[serde(deserialize_with = "text_document_from_path_str")] + TextDocumentIdentifier, + Position, + CompletionTriggerKind, + Option, + ); + + let completion_params: CompletionParams = + Deserialize::deserialize(Value::from(params)).map_err(|_e| { + EditorError::Parse("failed to parse completion params") + })?; + + Ok(Event::RequestCompletion { + lang_id: completion_params.0, + text_document: completion_params.1, + position: completion_params.2, + trigger_kind: completion_params.3, + trigger_character: completion_params.4, + }) } else { Err(EditorError::UnexpectedMessage(format!( "unexpected notification {:?} {:?}", @@ -257,55 +280,6 @@ fn to_event(msg: NvimMessage) -> Result { ))) } } - NvimMessage::RpcNotification { - ref method, - ref params, - } if method == "completion" => { - if params.len() < 1 { - Err(EditorError::Parse("Wrong amount of params for completion")) - } else { - let lang_id = params[0] - .as_str() - .ok_or(EditorError::Parse("Invalid lang_id param for completion"))? - .to_owned(); - let text_document_str = params[1].as_str().ok_or(EditorError::Parse( - "Invalid text_document param for completion", - ))?; - let text_document = to_text_document(text_document_str).ok_or( - EditorError::Parse("Can't parse text_document param for completion"), - )?; - let position_map = params[2] - .as_map() - .ok_or(EditorError::Parse("Invalid position param for completion"))?; - let position = to_position(position_map).ok_or(EditorError::Parse( - "Can't parse position param for completion", - ))?; - - let trigger_kind_u64 = params[3].as_u64().ok_or(EditorError::Parse( - "Invalid trigger_kind param for completion", - ))?; - let trigger_kind = to_trigger_kind(trigger_kind_u64).ok_or(EditorError::Parse( - "Can't parse trigger_kind param for completion", - ))?; - - let mut trigger_character = None; - - if trigger_kind == CompletionTriggerKind::TriggerCharacter { - let trigger_character_str = params[4].as_str().ok_or(EditorError::Parse( - "Invalid trigger_character param for completion", - ))?; - trigger_character = Some(String::from(trigger_character_str)); - } - - Ok(Event::RequestCompletion { - lang_id, - text_document, - position, - trigger_kind, - trigger_character, - }) - } - } _ => Err(EditorError::UnexpectedMessage(format!("{:?}", msg))), } } From 7429b63115171e09c6bcbc08ae06e02883b0ecb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Vi=E1=BB=87t=20H=C6=B0ng?= Date: Mon, 9 Sep 2019 16:26:56 +1200 Subject: [PATCH 3/5] fixed optional string parameter --- src/neovim.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/neovim.rs b/src/neovim.rs index a58c4ec..bb751af 100644 --- a/src/neovim.rs +++ b/src/neovim.rs @@ -258,13 +258,12 @@ fn to_event(msg: NvimMessage) -> Result { TextDocumentIdentifier, Position, CompletionTriggerKind, - Option, + #[serde(default)] Option, ); let completion_params: CompletionParams = - Deserialize::deserialize(Value::from(params)).map_err(|_e| { - EditorError::Parse("failed to parse completion params") - })?; + Deserialize::deserialize(Value::from(params)) + .map_err(|_e| EditorError::Parse("failed to parse completion params"))?; Ok(Event::RequestCompletion { lang_id: completion_params.0, From 72e2060fd714fe444a6c1ae4cca72ef6d801a580 Mon Sep 17 00:00:00 2001 From: Viet Hung Nguyen Date: Tue, 8 Oct 2019 14:52:56 +1300 Subject: [PATCH 4/5] removed unused use --- src/lspc.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lspc.rs b/src/lspc.rs index 2083ae2..d25fc80 100644 --- a/src/lspc.rs +++ b/src/lspc.rs @@ -2,7 +2,6 @@ pub mod handler; // Custom LSP types pub mod msg; pub mod types; - use std::{ collections::HashMap, io, From 51d7d30c5081ed755cc0f8f60e98208219c03397 Mon Sep 17 00:00:00 2001 From: Viet Hung Nguyen Date: Tue, 8 Oct 2019 15:09:38 +1300 Subject: [PATCH 5/5] fixed some minor bug after merging --- src/lspc.rs | 1 + src/neovim.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lspc.rs b/src/lspc.rs index a29c886..d5b13bb 100644 --- a/src/lspc.rs +++ b/src/lspc.rs @@ -76,6 +76,7 @@ pub enum Event { position: Position, trigger_kind: CompletionTriggerKind, trigger_character: Option, + }, DidOpen { buf_id: B, text_document: TextDocumentIdentifier, diff --git a/src/neovim.rs b/src/neovim.rs index 456483c..74c42e9 100644 --- a/src/neovim.rs +++ b/src/neovim.rs @@ -673,7 +673,7 @@ impl Editor for Neovim { } self.call_function( "complete", - vec![column.into(), Value::Array(vim_complete_items)], + Value::Array(vec![column.into(), Value::Array(vim_complete_items)]), )?; Ok(()) }