beancount_language_server/
lib.rs1mod beancount_data;
2mod capabilities;
3mod config;
4mod dispatcher;
5pub mod document;
6pub mod forest;
8pub mod handlers;
9pub mod progress;
10pub mod providers;
11pub mod server;
12mod treesitter_utils;
14mod utils;
15
16use crate::config::Config;
17use crate::server::LspServerState;
18use anyhow::Result;
19use lsp_server::Connection;
20use lsp_types::InitializeParams;
21use serde::{de::DeserializeOwned, Serialize};
22use utils::ToFilePath;
23
24pub fn run_server() -> Result<()> {
25 tracing::info!("beancount-language-server started");
26
27 let (connection, io_threads) = lsp_server::Connection::stdio();
29
30 let (request_id, initialize_params) = connection.initialize_start()?;
32 tracing::info!("initialize params: {}", initialize_params);
33
34 let initialize_params = serde_json::from_value::<InitializeParams>(initialize_params)?;
35
36 let server_capabilities = capabilities::server_capabilities();
37
38 let initialize_result = lsp_types::InitializeResult {
39 capabilities: server_capabilities,
40 server_info: Some(lsp_types::ServerInfo {
41 name: String::from("beancount-language-server"),
42 version: Some(String::from(env!("CARGO_PKG_VERSION"))),
43 }),
44 };
45
46 let initialize_result = serde_json::to_value(initialize_result).unwrap();
47
48 connection.initialize_finish(request_id, initialize_result)?;
49
50 if let Some(client_info) = initialize_params.client_info {
51 tracing::info!(
52 "client '{}' {}",
53 client_info.name,
54 client_info.version.unwrap_or_default()
55 );
56 }
57
58 let config = {
59 let root_file = match initialize_params
60 .root_uri
61 .and_then(|it| it.to_file_path().ok())
62 {
63 Some(it) => it,
64 None => std::env::current_dir()?,
65 };
66 let mut config = Config::new(root_file);
67 if let Some(json) = initialize_params.initialization_options {
68 config.update(json).unwrap();
69 }
70 config
71 };
72
73 main_loop(connection, config)?;
74
75 io_threads.join()?;
76
77 Ok(())
78}
79
80pub fn main_loop(connection: Connection, config: Config) -> Result<()> {
81 tracing::info!("initial config: {:#?}", config);
82 LspServerState::new(connection.sender, config).run(connection.receiver)
83}
84
85pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> {
86 T::deserialize(&json)
87 .map_err(|e| anyhow::anyhow!("could not deserialize {}: {} - {}", what, e, json))
88}
89
90pub fn to_json<T: Serialize>(value: T) -> Result<serde_json::Value> {
91 serde_json::to_value(value).map_err(|e| anyhow::anyhow!("could not serialize to json {}", e))
92}