beancount_language_server/
lib.rs

1mod beancount_data;
2mod capabilities;
3mod config;
4mod dispatcher;
5pub mod document;
6//pub mod error;
7pub mod forest;
8pub mod handlers;
9pub mod progress;
10pub mod providers;
11pub mod server;
12//pub mod session;
13mod 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    //Setup IO connections
28    let (connection, io_threads) = lsp_server::Connection::stdio();
29
30    //wait for client to connection
31    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}