diff --git a/Cargo.lock b/Cargo.lock index 98771eed..8e65323e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,11 +71,10 @@ dependencies = [ "bytes", "chrono", "clap", - "dashmap 5.3.2", + "dashmap", "linked-list", "log", "log4rs", - "lspower", "regex", "ropey", "serde", @@ -83,6 +82,7 @@ dependencies = [ "shellexpand", "thiserror", "tokio", + "tower-lsp", "tree-sitter", "tree-sitter-beancount", ] @@ -148,16 +148,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "dashmap" -version = "4.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" -dependencies = [ - "cfg-if", - "num_cpus", -] - [[package]] name = "dashmap" version = "5.3.2" @@ -317,15 +307,6 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "hermit-abi" version = "0.1.19" @@ -374,11 +355,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" -version = "0.2.124" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "linked-hash-map" @@ -446,9 +433,9 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.91.1" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2368312c59425dd133cb9a327afee65be0a633a8ce471d248e2202a48f8f68ae" +checksum = "70c74e2173b2b31f8655d33724b4b45ac13f439386f66290f539c22b144c2212" dependencies = [ "bitflags", "serde", @@ -457,43 +444,6 @@ dependencies = [ "url", ] -[[package]] -name = "lspower" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2242d4cb4071c7b9ae53001c8c658402b55bb8c3669a70d3ce9565f1144b30" -dependencies = [ - "anyhow", - "async-trait", - "auto_impl", - "bytes", - "dashmap 4.0.2", - "futures", - "httparse", - "log", - "lsp-types", - "lspower-macros", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-util", - "tower-service", - "twoway", -] - -[[package]] -name = "lspower-macros" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca1d48da0e4a6100b4afd52fae99f36d47964a209624021280ad9ffdd410e83d" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "matches" version = "0.1.9" @@ -502,9 +452,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mio" @@ -540,9 +490,9 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -600,9 +550,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if", "libc", @@ -617,6 +567,26 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -773,9 +743,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed" dependencies = [ "proc-macro2", "quote", @@ -838,9 +808,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" dependencies = [ "proc-macro2", "quote", @@ -948,16 +918,70 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" + +[[package]] +name = "tower-lsp" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e094780b4447366c59f79acfd65b1375ecaa84e61dddbde1421aa506334024" +dependencies = [ + "async-trait", + "auto_impl", + "bytes", + "dashmap", + "futures", + "httparse", + "log", + "lsp-types", + "memchr", + "serde", + "serde_json", + "tokio", + "tokio-util", + "tower", + "tower-lsp-macros", +] + +[[package]] +name = "tower-lsp-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebd99eec668d0a450c177acbc4d05e0d0d13b1f8d3db13cd706c52cbec4ac04" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -966,6 +990,38 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +[[package]] +name = "tracing" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +dependencies = [ + "lazy_static", +] + [[package]] name = "traitobject" version = "0.1.0" @@ -992,16 +1048,6 @@ dependencies = [ "tree-sitter", ] -[[package]] -name = "twoway" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47" -dependencies = [ - "memchr", - "unchecked-index", -] - [[package]] name = "typemap" version = "0.3.3" @@ -1011,12 +1057,6 @@ dependencies = [ "unsafe-any", ] -[[package]] -name = "unchecked-index" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" - [[package]] name = "unicode-bidi" version = "0.3.8" @@ -1032,12 +1072,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - [[package]] name = "unicode-xid" version = "0.2.2" @@ -1117,9 +1151,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -1130,33 +1164,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_i686_gnu" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_x86_64_gnu" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "yaml-rust" diff --git a/Cargo.toml b/Cargo.toml index 99ea515f..340e0995 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ clap = "3.1" dashmap = "5.3" log4rs = "1" log = "0.4" -lspower = "1.5" +tower-lsp = "0.17.0" regex = "1" ropey = "1.4" thiserror = "1.0" diff --git a/src/core/beancount_data.rs b/src/core/beancount_data.rs index ea930552..8a7e57d9 100644 --- a/src/core/beancount_data.rs +++ b/src/core/beancount_data.rs @@ -1,8 +1,8 @@ use crate::core::RopeExt; use dashmap::DashMap; use log::debug; -use lspower::lsp; use std::collections::HashSet; +use tower_lsp::lsp_types; pub struct FlaggedEntry { _file: String, @@ -16,9 +16,9 @@ pub struct FlaggedEntry { //} pub struct BeancountData { - accounts: DashMap>, - txn_strings: DashMap>, - pub flagged_entries: DashMap>, + accounts: DashMap>, + txn_strings: DashMap>, + pub flagged_entries: DashMap>, } impl BeancountData { @@ -33,7 +33,7 @@ impl BeancountData { } } - pub fn update_data(&self, uri: lsp::Url, tree: &tree_sitter::Tree, content: &ropey::Rope) { + pub fn update_data(&self, uri: lsp_types::Url, tree: &tree_sitter::Tree, content: &ropey::Rope) { let mut cursor = tree.root_node().walk(); // Update account opens diff --git a/src/core/document.rs b/src/core/document.rs index e7d9ac89..5e78c491 100644 --- a/src/core/document.rs +++ b/src/core/document.rs @@ -1,4 +1,4 @@ -use lspower::lsp; +use tower_lsp::lsp_types; #[derive(Clone)] pub struct Document { @@ -7,7 +7,7 @@ pub struct Document { } impl Document { - pub fn open(params: lsp::DidOpenTextDocumentParams) -> Self { + pub fn open(params: lsp_types::DidOpenTextDocumentParams) -> Self { let content = ropey::Rope::from(params.text_document.text); let content = content; Self { content } diff --git a/src/core/error.rs b/src/core/error.rs index 2c440e7e..94294d0c 100644 --- a/src/core/error.rs +++ b/src/core/error.rs @@ -1,21 +1,21 @@ use crate::core; -use lspower::lsp; use thiserror::Error; +use tower_lsp::lsp_types; /// Runtime errors for the LSP server. #[allow(clippy::enum_variant_names)] #[derive(Debug, Error)] pub enum Error { /// Error that occurs when [`core::Session.client`] is accessed and is `None`. - #[error("ClientNotInitialzed")] - ClientNotInitialized, + //#[error("ClientNotInitialzed")] + //ClientNotInitialized, /// Error that occurs when a session resource is requested and does not exist. #[error("core::SessionResourceNotFound: kind={kind:?}, uri={uri:?}")] SessionResourceNotFound { /// The kind of the requested session resource. kind: core::session::SessionResourceKind, /// The URL of the requested session resource. - uri: lsp::Url, + uri: lsp_types::Url, }, #[error("I/O error")] @@ -34,12 +34,12 @@ pub enum Error { UriToPathConversion, } -/// Wrapper struct for converting [`anyhow::Error`] into [`lspower::jsonrpc::Error`]. +/// Wrapper struct for converting [`anyhow::Error`] into [`tower_lsp::jsonrpc::Error`]. pub struct IntoJsonRpcError(pub anyhow::Error); -impl From for lspower::jsonrpc::Error { +impl From for tower_lsp::jsonrpc::Error { fn from(error: IntoJsonRpcError) -> Self { - let mut rpc_error = lspower::jsonrpc::Error::internal_error(); + let mut rpc_error = tower_lsp::jsonrpc::Error::internal_error(); rpc_error.data = Some(serde_json::to_value(format!("{}", error.0)).unwrap()); rpc_error } diff --git a/src/core/rope.rs b/src/core/rope.rs index 7b4c039a..d8cb3f21 100644 --- a/src/core/rope.rs +++ b/src/core/rope.rs @@ -1,9 +1,9 @@ // USED FORM https://github.com/silvanshade/lsp-text use crate::core::{TextEdit, TextPosition}; use bytes::Bytes; -use lspower::lsp; use ropey::{iter::Chunks, Rope}; use std::{convert::TryFrom, sync::Arc}; +use tower_lsp::lsp_types; use std::borrow::Cow; @@ -76,14 +76,14 @@ impl ChunkWalker { pub trait RopeExt { fn apply_edit(&mut self, edit: &TextEdit); - fn build_edit<'a>(&self, change: &'a lsp::TextDocumentContentChangeEvent) -> anyhow::Result>; - fn byte_to_lsp_position(&self, offset: usize) -> lsp::Position; + fn build_edit<'a>(&self, change: &'a lsp_types::TextDocumentContentChangeEvent) -> anyhow::Result>; + fn byte_to_lsp_position(&self, offset: usize) -> lsp_types::Position; fn byte_to_tree_sitter_point(&self, offset: usize) -> anyhow::Result; fn chunk_walker(self, byte_idx: usize) -> ChunkWalker; - fn lsp_position_to_core(&self, position: lsp::Position) -> anyhow::Result; - fn lsp_position_to_utf16_cu(&self, position: lsp::Position) -> anyhow::Result; - fn lsp_range_to_tree_sitter_range(&self, range: lsp::Range) -> anyhow::Result; - fn tree_sitter_range_to_lsp_range(&self, range: tree_sitter::Range) -> lsp::Range; + fn lsp_position_to_core(&self, position: lsp_types::Position) -> anyhow::Result; + fn lsp_position_to_utf16_cu(&self, position: lsp_types::Position) -> anyhow::Result; + fn lsp_range_to_tree_sitter_range(&self, range: lsp_types::Range) -> anyhow::Result; + fn tree_sitter_range_to_lsp_range(&self, range: tree_sitter::Range) -> lsp_types::Range; fn utf8_text_for_tree_sitter_node<'rope, 'tree>(&'rope self, node: &tree_sitter::Node<'tree>) -> Cow<'rope, str>; } @@ -95,7 +95,7 @@ impl RopeExt for Rope { } } - fn build_edit<'a>(&self, change: &'a lsp::TextDocumentContentChangeEvent) -> anyhow::Result> { + fn build_edit<'a>(&self, change: &'a lsp_types::TextDocumentContentChangeEvent) -> anyhow::Result> { let text = change.text.as_str(); let text_bytes = text.as_bytes(); let text_end_byte_idx = text_bytes.len(); @@ -105,7 +105,7 @@ impl RopeExt for Rope { } else { let start = self.byte_to_lsp_position(0); let end = self.byte_to_lsp_position(text_end_byte_idx); - lsp::Range { start, end } + lsp_types::Range { start, end } }; let start = self.lsp_position_to_core(range.start)?; @@ -149,7 +149,7 @@ impl RopeExt for Rope { }) } - fn byte_to_lsp_position(&self, byte_idx: usize) -> lsp::Position { + fn byte_to_lsp_position(&self, byte_idx: usize) -> lsp_types::Position { let line_idx = self.byte_to_line(byte_idx); let line_utf16_cu_idx = { @@ -165,7 +165,7 @@ impl RopeExt for Rope { let line = line_idx; let character = character_utf16_cu_idx - line_utf16_cu_idx; - lsp::Position::new(line as u32, character as u32) + lsp_types::Position::new(line as u32, character as u32) } fn byte_to_tree_sitter_point(&self, byte_idx: usize) -> anyhow::Result { @@ -191,7 +191,7 @@ impl RopeExt for Rope { } } - fn lsp_position_to_core(&self, position: lsp::Position) -> anyhow::Result { + fn lsp_position_to_core(&self, position: lsp_types::Position) -> anyhow::Result { let row_idx = position.line as usize; let col_code_idx = position.character as usize; @@ -218,7 +218,7 @@ impl RopeExt for Rope { }) } - fn lsp_position_to_utf16_cu(&self, position: lsp::Position) -> anyhow::Result { + fn lsp_position_to_utf16_cu(&self, position: lsp_types::Position) -> anyhow::Result { let line_idx = position.line as usize; let line_utf16_cu_idx = { let char_idx = self.line_to_char(line_idx); @@ -229,7 +229,7 @@ impl RopeExt for Rope { Ok(result) } - fn lsp_range_to_tree_sitter_range(&self, range: lsp::Range) -> anyhow::Result { + fn lsp_range_to_tree_sitter_range(&self, range: lsp_types::Range) -> anyhow::Result { let start = self.lsp_position_to_core(range.start)?; let end = self.lsp_position_to_core(range.end)?; let range = tree_sitter::Range { @@ -241,10 +241,10 @@ impl RopeExt for Rope { Ok(range) } - fn tree_sitter_range_to_lsp_range(&self, range: tree_sitter::Range) -> lsp::Range { + fn tree_sitter_range_to_lsp_range(&self, range: tree_sitter::Range) -> lsp_types::Range { let start = self.byte_to_lsp_position(range.start_byte as usize); let end = self.byte_to_lsp_position(range.end_byte as usize); - lsp::Range::new(start, end) + lsp_types::Range::new(start, end) } fn utf8_text_for_tree_sitter_node<'rope, 'tree>(&'rope self, node: &tree_sitter::Node<'tree>) -> Cow<'rope, str> { diff --git a/src/core/session.rs b/src/core/session.rs index 7d7bc4b5..c70726fb 100644 --- a/src/core/session.rs +++ b/src/core/session.rs @@ -1,18 +1,18 @@ -use crate::{core, providers, server}; +use crate::{core, providers}; use dashmap::{ mapref::one::{Ref, RefMut}, DashMap, }; use linked_list::LinkedList; use log::debug; -use lspower::lsp; +use providers::diagnostics; use serde::{Deserialize, Serialize}; use std::{ - env, fs::read_to_string, path::{Path, PathBuf}, }; use tokio::sync::{Mutex, RwLock}; +use tower_lsp::lsp_types; /// A tag representing of the kinds of session resource. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -25,17 +25,17 @@ pub enum SessionResourceKind { Tree, } -pub struct Session { - pub server_capabilities: RwLock, - pub client_capabilities: RwLock>, - client: Option, - documents: DashMap, - parsers: DashMap>, - pub forest: DashMap>, - pub root_journal_path: RwLock>, - pub bean_check_path: Option, - pub beancount_data: core::BeancountData, - pub diagnostic_data: providers::DiagnosticData, +pub(crate) struct Session { + //pub(crate) server_capabilities: RwLock, + pub(crate) client_capabilities: RwLock>, + pub(crate) client: tower_lsp::Client, + documents: DashMap, + parsers: DashMap>, + pub(crate) forest: DashMap>, + pub(crate) root_journal_path: RwLock>, + //pub(crate) bean_check_path: Option, + pub(crate) beancount_data: core::BeancountData, + pub(crate) diagnostic_data: diagnostics::DiagnosticData, } #[derive(Debug, Clone, Default, Deserialize, Serialize)] @@ -45,52 +45,45 @@ pub struct BeancountLspOptions { impl Session { /// Create a new [`Session`]. - pub fn new(client: Option) -> anyhow::Result { - let server_capabilities = RwLock::new(server::capabilities()); + pub fn new(client: tower_lsp::Client) -> Self { + //let server_capabilities = RwLock::new(server::capabilities()); let client_capabilities = RwLock::new(Default::default()); let documents = DashMap::new(); let parsers = DashMap::new(); let forest = DashMap::new(); let beancount_data = core::BeancountData::new(); - let diagnostic_data = providers::DiagnosticData::new(); + let diagnostic_data = diagnostics::DiagnosticData::new(); - let bean_check_path = env::var_os("PATH").and_then(|paths| { - env::split_paths(&paths).find_map(|p| { - let full_path = p.join("bean-check"); + //let bean_check_path = env::var_os("PATH").and_then(|paths| { + // env::split_paths(&paths).find_map(|p| { + // let full_path = p.join("bean-check"); - if full_path.is_file() { - Some(full_path) - } else { - None - } - }) - }); + // if full_path.is_file() { + // Some(full_path) + // } else { + // None + // } + // }) + //}); let root_journal_path = RwLock::new(None); - Ok(Session { - server_capabilities, + Self { + //server_capabilities, client_capabilities, client, documents, parsers, forest, root_journal_path, - bean_check_path, + //bean_check_path, beancount_data, diagnostic_data, - }) - } - - /// Retrieve the handle for the LSP client. - pub fn client(&self) -> anyhow::Result<&lspower::Client> { - self.client - .as_ref() - .ok_or_else(|| core::Error::ClientNotInitialized.into()) + } } /// Insert a [`core::Document`] into the [`Session`]. - pub fn insert_document(&self, uri: lsp::Url, document: core::Document) -> anyhow::Result<()> { + pub fn insert_document(&self, uri: lsp_types::Url, document: core::Document) -> anyhow::Result<()> { let result = self.documents.insert(uri, document); debug_assert!(result.is_none()); // let result = self.parsers.insert(uri.clone(), Mutex::new(document.parser)); @@ -101,7 +94,7 @@ impl Session { } /// Remove a [`core::Document`] from the [`Session`]. - pub fn remove_document(&self, uri: &lsp::Url) -> anyhow::Result<()> { + pub fn remove_document(&self, uri: &lsp_types::Url) -> anyhow::Result<()> { let result = self.documents.remove(uri); debug_assert!(result.is_some()); // let result = self.parsers.remove(uri); @@ -112,7 +105,7 @@ impl Session { } /// Get a reference to the [`core::Document`] in the [`Session`]. - pub async fn get_document(&self, uri: &lsp::Url) -> anyhow::Result> { + pub async fn get_document(&self, uri: &lsp_types::Url) -> anyhow::Result> { self.documents.get(uri).ok_or_else(|| { let kind = SessionResourceKind::Document; let uri = uri.clone(); @@ -121,7 +114,10 @@ impl Session { } /// Get a mutable reference to the [`core::Document`] in the [`Session`]. - pub async fn get_mut_document(&self, uri: &lsp::Url) -> anyhow::Result> { + pub async fn get_mut_document( + &self, + uri: &lsp_types::Url, + ) -> anyhow::Result> { self.documents.get_mut(uri).ok_or_else(|| { let kind = SessionResourceKind::Document; let uri = uri.clone(); @@ -131,8 +127,8 @@ impl Session { pub async fn get_mut_parser( &self, - uri: &lsp::Url, - ) -> anyhow::Result>> { + uri: &lsp_types::Url, + ) -> anyhow::Result>> { debug!("getting mutable parser {}", uri); debug!("parser contains key {}", self.parsers.contains_key(uri)); self.parsers.get_mut(uri).ok_or_else(|| { @@ -154,7 +150,10 @@ impl Session { /// Get a mutable reference to the [`tree_sitter::Tree`] for a [`core::Document`] in the /// [`Session`]. - pub async fn get_mut_tree(&self, uri: &lsp::Url) -> anyhow::Result>> { + pub async fn get_mut_tree( + &self, + uri: &lsp_types::Url, + ) -> anyhow::Result>> { self.forest.get_mut(uri).ok_or_else(|| { let kind = SessionResourceKind::Tree; let uri = uri.clone(); @@ -164,7 +163,7 @@ impl Session { // Issus to look at if running into issues with this // https://github.com/silvanshade/lspower/issues/8 - pub async fn parse_initial_forest(&self, root_url: lsp::Url) -> anyhow::Result { + pub async fn parse_initial_forest(&self, root_url: lsp_types::Url) -> anyhow::Result { let mut seen_files = LinkedList::new(); // let root_pathbuf: String = self.root_journal_path.into_inner().unwrap().as_ref().as_os_str(); // let temp = self.root_journal_path.read().await; @@ -224,7 +223,7 @@ impl Session { } else { path.to_path_buf() }; - let path_url = lsp::Url::from_file_path(path).unwrap(); + let path_url = lsp_types::Url::from_file_path(path).unwrap(); Some(path_url) }); diff --git a/src/handlers.rs b/src/handlers.rs index 6a4cc499..d13b788a 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -1,12 +1,18 @@ pub mod text_document { use crate::{core, core::RopeExt, providers}; use log::debug; - use lspower::lsp; + use providers::completion; + use providers::diagnostics; + use providers::formatting; use std::{path::PathBuf, sync::Arc}; use tokio::sync::Mutex; + use tower_lsp::lsp_types; /// handler for `textDocument/didOpen`. - pub async fn did_open(session: Arc, params: lsp::DidOpenTextDocumentParams) -> anyhow::Result<()> { + pub(crate) async fn did_open( + session: Arc, + params: lsp_types::DidOpenTextDocumentParams, + ) -> anyhow::Result<()> { debug!("handlers::did_open"); let uri = params.text_document.uri.clone(); @@ -18,9 +24,8 @@ pub mod text_document { if let Err(err) = check_beancont(&session).await { debug!("handlers::did_open -- Error finding diagnostics {}", err.to_string()); session - .as_ref() - .client()? - .log_message(lsp::MessageType::ERROR, err.to_string()) + .client + .log_message(lsp_types::MessageType::ERROR, err.to_string()) .await; } @@ -28,15 +33,17 @@ pub mod text_document { } /// handler for `textDocument/didSave`. - pub async fn did_save(session: Arc, _params: lsp::DidSaveTextDocumentParams) -> anyhow::Result<()> { + pub(crate) async fn did_save( + session: Arc, + _params: lsp_types::DidSaveTextDocumentParams, + ) -> anyhow::Result<()> { debug!("handlers::did_save"); if let Err(err) = check_beancont(&session).await { debug!("handlers::did_save -- Error finding diagnostics {}", err.to_string()); session - .as_ref() - .client()? - .log_message(lsp::MessageType::ERROR, err.to_string()) + .client + .log_message(lsp_types::MessageType::ERROR, err.to_string()) .await; } @@ -44,7 +51,10 @@ pub mod text_document { } // handler for `textDocument/didClose`. - pub async fn did_close(session: Arc, params: lsp::DidCloseTextDocumentParams) -> anyhow::Result<()> { + pub(crate) async fn did_close( + session: Arc, + params: lsp_types::DidCloseTextDocumentParams, + ) -> anyhow::Result<()> { debug!("handlers::did_close"); let uri = params.text_document.uri; session.remove_document(&uri)?; @@ -53,9 +63,9 @@ pub mod text_document { } // handler for `textDocument/didChange`. - pub async fn did_change( + pub(crate) async fn did_change( session: Arc, - params: lsp::DidChangeTextDocumentParams, + params: lsp_types::DidChangeTextDocumentParams, ) -> anyhow::Result<()> { debug!("handlers::did_change"); let uri = ¶ms.text_document.uri; @@ -105,18 +115,18 @@ pub mod text_document { Ok(()) } - pub async fn completion( + pub(crate) async fn completion( session: Arc, - params: lsp::CompletionParams, - ) -> anyhow::Result> { - providers::completion(session, params).await + params: lsp_types::CompletionParams, + ) -> anyhow::Result> { + completion::completion(session, params).await } - pub async fn formatting( + pub(crate) async fn formatting( session: Arc, - params: lsp::DocumentFormattingParams, - ) -> anyhow::Result>> { - providers::formatting(session, params).await + params: lsp_types::DocumentFormattingParams, + ) -> anyhow::Result>> { + formatting::formatting(session, params).await } async fn check_beancont(session: &Arc) -> anyhow::Result<()> { @@ -129,7 +139,7 @@ pub mod text_document { let temp = session.root_journal_path.read().await; let root_journal_path = temp.clone().unwrap(); - let diags = providers::diagnostics( + let diags = diagnostics::diagnostics( &session.diagnostic_data, &session.beancount_data, bean_check_cmd, @@ -138,7 +148,7 @@ pub mod text_document { .await; session.diagnostic_data.update(diags.clone()); for (key, value) in diags { - session.client()?.publish_diagnostics(key, value, None).await; + session.client.publish_diagnostics(key, value, None).await; } Ok(()) } diff --git a/src/main.rs b/src/main.rs index 3bafc835..75b5a3f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,15 @@ use clap::{Arg, Command}; -use lspower::{LspService, Server}; mod core; mod handlers; mod providers; mod server; use crate::core::logger::Logger; +use server::run_server; use std::path::PathBuf; #[tokio::main] -async fn main() -> anyhow::Result<()> { +async fn main() { let matches = Command::new("beancount-language-server") .arg(Arg::new("stdio").long("stdio").help("use std io for lang server")) //TODO let the user specify the file @@ -26,7 +26,5 @@ async fn main() -> anyhow::Result<()> { let stdin = tokio::io::stdin(); let stdout = tokio::io::stdout(); - let (service, messages) = LspService::new(|client| server::Server::new(client).unwrap()); - Server::new(stdin, stdout).interleave(messages).serve(service).await; - Ok(()) + run_server(stdin, stdout).await } diff --git a/src/providers.rs b/src/providers.rs index 95fa09e9..0561df08 100644 --- a/src/providers.rs +++ b/src/providers.rs @@ -1,7 +1,4 @@ +pub mod completion; /// Provider definitions for LSP `textDocument/publishDiagnostics`. pub mod diagnostics; -pub use diagnostics::*; -pub mod completion; -pub use completion::*; pub mod formatting; -pub use formatting::*; diff --git a/src/providers/completion.rs b/src/providers/completion.rs index acae4590..c6377ae2 100644 --- a/src/providers/completion.rs +++ b/src/providers/completion.rs @@ -1,14 +1,14 @@ use crate::{core, core::RopeExt}; use chrono::Datelike; use log::debug; -use lspower::lsp; use std::sync::Arc; +use tower_lsp::lsp_types; /// Provider function for LSP ``. -pub async fn completion( +pub(crate) async fn completion( session: Arc, - params: lsp::CompletionParams, -) -> anyhow::Result> { + params: lsp_types::CompletionParams, +) -> anyhow::Result> { debug!("providers::completion"); let uri = params.text_document_position.text_document.uri; @@ -117,7 +117,7 @@ pub async fn completion( } } -fn complete_date() -> anyhow::Result> { +fn complete_date() -> anyhow::Result> { debug!("providers::completion::date"); let today = chrono::offset::Local::now().naive_local().date(); let prev_month = sub_one_month(today).format("%Y-%m-").to_string(); @@ -128,11 +128,11 @@ fn complete_date() -> anyhow::Result> { debug!("providers::completion::date {}", next_month); let today = today.format("%Y-%m-%d").to_string(); debug!("providers::completion::date {}", today); - Ok(Some(lsp::CompletionResponse::Array(vec![ - lsp::CompletionItem::new_simple(today, "today".to_string()), - lsp::CompletionItem::new_simple(cur_month, "this month".to_string()), - lsp::CompletionItem::new_simple(prev_month, "prev month".to_string()), - lsp::CompletionItem::new_simple(next_month, "next month".to_string()), + Ok(Some(lsp_types::CompletionResponse::Array(vec![ + lsp_types::CompletionItem::new_simple(today, "today".to_string()), + lsp_types::CompletionItem::new_simple(cur_month, "this month".to_string()), + lsp_types::CompletionItem::new_simple(prev_month, "prev month".to_string()), + lsp_types::CompletionItem::new_simple(next_month, "next month".to_string()), ]))) } @@ -160,23 +160,23 @@ fn sub_one_month(date: chrono::NaiveDate) -> chrono::NaiveDate { chrono::NaiveDate::from_ymd(year, month, 1) } -fn complete_txn_string(data: &core::BeancountData) -> anyhow::Result> { +fn complete_txn_string(data: &core::BeancountData) -> anyhow::Result> { debug!("providers::completion::account"); let mut completions = Vec::new(); for txn_string in data.get_txn_strings() { - completions.push(lsp::CompletionItem::new_simple(txn_string, "".to_string())); + completions.push(lsp_types::CompletionItem::new_simple(txn_string, "".to_string())); } - Ok(Some(lsp::CompletionResponse::Array(completions))) + Ok(Some(lsp_types::CompletionResponse::Array(completions))) } -fn complete_account(data: &core::BeancountData) -> anyhow::Result> { +fn complete_account(data: &core::BeancountData) -> anyhow::Result> { debug!("providers::completion::account"); let mut completions = Vec::new(); for account in data.get_accounts() { - completions.push(lsp::CompletionItem::new_simple( + completions.push(lsp_types::CompletionItem::new_simple( account, "Beancount Account".to_string(), )); } - Ok(Some(lsp::CompletionResponse::Array(completions))) + Ok(Some(lsp_types::CompletionResponse::Array(completions))) } diff --git a/src/providers/diagnostics.rs b/src/providers/diagnostics.rs index bd2f6ccc..366c9242 100644 --- a/src/providers/diagnostics.rs +++ b/src/providers/diagnostics.rs @@ -1,12 +1,12 @@ use crate::core; use dashmap::DashMap; use log::debug; -use lspower::lsp; use std::path::Path; use tokio::process::Command; +use tower_lsp::lsp_types; pub struct DiagnosticData { - current_diagnostics: DashMap>, + current_diagnostics: DashMap>, } impl DiagnosticData { pub fn new() -> Self { @@ -15,7 +15,7 @@ impl DiagnosticData { } } - pub fn update(&self, data: DashMap>) { + pub fn update(&self, data: DashMap>) { self.current_diagnostics.clear(); for it in data.iter() { self.current_diagnostics.insert(it.key().clone(), it.value().clone()); @@ -29,7 +29,7 @@ pub async fn diagnostics( beancount_data: &core::BeancountData, bean_check_cmd: &Path, root_journal_file: &Path, -) -> DashMap> { +) -> DashMap> { let error_line_regexp = regex::Regex::new(r"^([^:]+):(\d+):\s*(.*)$").unwrap(); debug!("providers::diagnostics"); @@ -45,26 +45,26 @@ pub async fn diagnostics( debug!("bean-check generating diags"); let output = std::str::from_utf8(&output.stderr).map_err(core::Error::from); - let map: DashMap> = DashMap::new(); + let map: DashMap> = DashMap::new(); for line in output.unwrap().lines() { debug!("line: {}", line); if let Some(caps) = error_line_regexp.captures(line) { debug!("caps: {:?}", caps); - let position = lsp::Position { + let position = lsp_types::Position { line: caps[2].parse::().unwrap().saturating_sub(1), character: 0, }; - let file_url = lsp::Url::from_file_path(&caps[1]).unwrap(); - let diag = lsp::Diagnostic { - range: lsp::Range { + let file_url = lsp_types::Url::from_file_path(&caps[1]).unwrap(); + let diag = lsp_types::Diagnostic { + range: lsp_types::Range { start: position, end: position, }, message: caps[3].trim().to_string(), - severity: Some(lsp::DiagnosticSeverity::ERROR), - ..lsp::Diagnostic::default() + severity: Some(lsp_types::DiagnosticSeverity::ERROR), + ..lsp_types::Diagnostic::default() }; if map.contains_key(&file_url) { map.get_mut(&file_url).unwrap().push(diag); @@ -79,7 +79,7 @@ pub async fn diagnostics( DashMap::new() }; - let ret: DashMap> = DashMap::new(); + let ret: DashMap> = DashMap::new(); // Add previous urls to clear out if neccessary for it in previous_diagnostics.current_diagnostics.iter() { @@ -98,18 +98,18 @@ pub async fn diagnostics( // add flagged entries for uri in beancount_data.flagged_entries.iter() { for entry in uri.value().iter() { - let position = lsp::Position { + let position = lsp_types::Position { line: entry.line, character: 0, }; - let diag = lsp::Diagnostic { - range: lsp::Range { + let diag = lsp_types::Diagnostic { + range: lsp_types::Range { start: position, end: position, }, message: "Flagged".to_string(), - severity: Some(lsp::DiagnosticSeverity::WARNING), - ..lsp::Diagnostic::default() + severity: Some(lsp_types::DiagnosticSeverity::WARNING), + ..lsp_types::Diagnostic::default() }; if ret.contains_key(uri.key()) { ret.get_mut(uri.key()).unwrap().push(diag); diff --git a/src/providers/formatting.rs b/src/providers/formatting.rs index 0a86b8ca..4c614ede 100644 --- a/src/providers/formatting.rs +++ b/src/providers/formatting.rs @@ -1,8 +1,8 @@ use crate::core; use log::debug; -use lspower::lsp; use std::cmp::Ordering; use std::sync::Arc; +use tower_lsp::lsp_types; struct TSRange { pub start: tree_sitter::Point, @@ -62,10 +62,10 @@ impl<'a> tree_sitter::TextProvider<'a> for RopeProvider<'a> { } /// Provider function for LSP ``. -pub async fn formatting( +pub(crate) async fn formatting( session: Arc, - params: lsp::DocumentFormattingParams, -) -> anyhow::Result>> { + params: lsp_types::DocumentFormattingParams, +) -> anyhow::Result>> { debug!("providers::completion"); let uri = params.text_document.uri; @@ -136,7 +136,7 @@ pub async fn formatting( let num_col_pos = number.start.column; let new_num_pos = correct_number_placement + (max_number_width - num_len); - let insert_pos = lsp::Position { + let insert_pos = lsp_types::Position { line: prefix.end.row as u32, character: prefix.end.column as u32, }; @@ -144,8 +144,8 @@ pub async fn formatting( match new_num_pos.cmp(&num_col_pos) { Ordering::Greater => { // Insert Spaces - let edit = lsp::TextEdit { - range: lsp::Range { + let edit = lsp_types::TextEdit { + range: lsp_types::Range { start: insert_pos, end: insert_pos, }, @@ -156,12 +156,12 @@ pub async fn formatting( Ordering::Less => { // remove spaces // TODO conform text will not be deleted - let end_pos = lsp::Position { + let end_pos = lsp_types::Position { line: insert_pos.line, character: insert_pos.character + (num_col_pos - new_num_pos) as u32, }; - let edit = lsp::TextEdit { - range: lsp::Range { + let edit = lsp_types::TextEdit { + range: lsp_types::Range { start: insert_pos, end: end_pos, }, diff --git a/src/server.rs b/src/server.rs index 0bc85560..00f7b21d 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,35 +1,40 @@ use crate::{core, handlers}; -use lspower::{jsonrpc, lsp, LanguageServer}; use std::{path::PathBuf, sync::Arc}; - -pub struct Server { - pub client: lspower::Client, - pub session: Arc, +use tokio::io::{Stdin, Stdout}; +use tower_lsp::jsonrpc; +use tower_lsp::lsp_types; +use tower_lsp::{Client, LanguageServer, LspService, Server}; + +struct LspServer { + client: tower_lsp::Client, + session: Arc, } -impl Server { +impl LspServer { /// Create a new [`Server`] instance. - pub fn new(client: lspower::Client) -> anyhow::Result { - let session = Arc::new(core::Session::new(Some(client.clone()))?); - Ok(Server { client, session }) + fn new(client: Client) -> Self { + let session = Arc::new(core::Session::new(client.clone())); + Self { client, session } } } -pub fn capabilities() -> lsp::ServerCapabilities { +pub fn capabilities() -> lsp_types::ServerCapabilities { let text_document_sync = { - let options = lsp::TextDocumentSyncOptions { + let options = lsp_types::TextDocumentSyncOptions { open_close: Some(true), - change: Some(lsp::TextDocumentSyncKind::INCREMENTAL), + change: Some(lsp_types::TextDocumentSyncKind::INCREMENTAL), will_save: Some(true), will_save_wait_until: Some(false), - save: Some(lsp::TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions { - include_text: Some(true), - })), + save: Some(lsp_types::TextDocumentSyncSaveOptions::SaveOptions( + lsp_types::SaveOptions { + include_text: Some(true), + }, + )), }; - Some(lsp::TextDocumentSyncCapability::Options(options)) + Some(lsp_types::TextDocumentSyncCapability::Options(options)) }; let completion_provider = { - let options = lsp::CompletionOptions { + let options = lsp_types::CompletionOptions { resolve_provider: Some(false), trigger_characters: Some(vec![ "2".to_string(), @@ -42,9 +47,9 @@ pub fn capabilities() -> lsp::ServerCapabilities { Some(options) }; - let document_formatting_provider = { Some(lsp::OneOf::Left(true)) }; + let document_formatting_provider = { Some(lsp_types::OneOf::Left(true)) }; - lsp::ServerCapabilities { + lsp_types::ServerCapabilities { text_document_sync, completion_provider, document_formatting_provider, @@ -52,11 +57,11 @@ pub fn capabilities() -> lsp::ServerCapabilities { } } -#[lspower::async_trait] -impl LanguageServer for Server { - async fn initialize(&self, params: lsp::InitializeParams) -> jsonrpc::Result { +#[tower_lsp::async_trait] +impl LanguageServer for LspServer { + async fn initialize(&self, params: lsp_types::InitializeParams) -> jsonrpc::Result { self.client - .log_message(lsp::MessageType::ERROR, "Beancount Server initializing") + .log_message(lsp_types::MessageType::ERROR, "Beancount Server initializing") .await; *self.session.client_capabilities.write().await = Some(params.capabilities); @@ -73,55 +78,66 @@ impl LanguageServer for Server { *self.session.root_journal_path.write().await = Some(PathBuf::from(beancount_lsp_settings.journal_file.clone())); - let journal_file = lsp::Url::from_file_path(beancount_lsp_settings.journal_file).unwrap(); + let journal_file = lsp_types::Url::from_file_path(beancount_lsp_settings.journal_file).unwrap(); if (self.session.parse_initial_forest(journal_file).await).is_ok() {}; - Ok(lsp::InitializeResult { + Ok(lsp_types::InitializeResult { capabilities, - ..lsp::InitializeResult::default() + ..lsp_types::InitializeResult::default() }) } - async fn initialized(&self, _: lsp::InitializedParams) { - let typ = lsp::MessageType::INFO; - let message = "beancount language server initialized!"; - self.client.log_message(typ, message).await; + async fn initialized(&self, _: lsp_types::InitializedParams) { + //let typ = lsp_types::MessageType::INFO; + //let message = "beancount language server initialized!"; + //self.client.log_message(typ, message).await; } async fn shutdown(&self) -> jsonrpc::Result<()> { Ok(()) } - async fn did_open(&self, params: lsp::DidOpenTextDocumentParams) { + async fn did_open(&self, params: lsp_types::DidOpenTextDocumentParams) { let session = self.session.clone(); handlers::text_document::did_open(session, params).await.unwrap() } - async fn did_save(&self, params: lsp::DidSaveTextDocumentParams) { + async fn did_save(&self, params: lsp_types::DidSaveTextDocumentParams) { let session = self.session.clone(); handlers::text_document::did_save(session, params).await.unwrap() } - async fn did_change(&self, params: lsp::DidChangeTextDocumentParams) { + async fn did_change(&self, params: lsp_types::DidChangeTextDocumentParams) { let session = self.session.clone(); handlers::text_document::did_change(session, params).await.unwrap() } - async fn did_close(&self, params: lsp::DidCloseTextDocumentParams) { + async fn did_close(&self, params: lsp_types::DidCloseTextDocumentParams) { let session = self.session.clone(); handlers::text_document::did_close(session, params).await.unwrap() } - async fn completion(&self, params: lsp::CompletionParams) -> jsonrpc::Result> { + async fn completion( + &self, + params: lsp_types::CompletionParams, + ) -> jsonrpc::Result> { let session = self.session.clone(); let result = handlers::text_document::completion(session, params).await; Ok(result.map_err(core::IntoJsonRpcError)?) } - async fn formatting(&self, params: lsp::DocumentFormattingParams) -> jsonrpc::Result>> { + async fn formatting( + &self, + params: lsp_types::DocumentFormattingParams, + ) -> jsonrpc::Result>> { let session = self.session.clone(); let result = handlers::text_document::formatting(session, params).await; Ok(result.map_err(core::IntoJsonRpcError)?) } } + +pub async fn run_server(stdin: Stdin, stdout: Stdout) { + let (service, messages) = LspService::build(LspServer::new).finish(); + Server::new(stdin, stdout, messages).serve(service).await; +}