use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Mutex;
use tower_lsp_server::{Client, LspService, Server};
use rowan::GreenNode;
mod config;
mod context;
mod conversions;
mod documents;
mod handlers;
mod helpers;
mod navigation;
mod server;
mod symbols;
#[derive(Clone)]
pub struct DocumentState {
pub path: Option<PathBuf>,
pub salsa_file: crate::salsa::FileText,
pub salsa_config: crate::salsa::FileConfig,
pub tree: GreenNode,
pub parsed_yaml_regions: Vec<crate::syntax::ParsedYamlRegionSnapshot>,
}
#[derive(Debug, Clone, Default)]
pub struct LspRuntimeSettings {
pub experimental_incremental_parsing: bool,
}
pub struct PanacheLsp {
client: Client,
document_map: Arc<Mutex<HashMap<String, DocumentState>>>,
workspace_root: Arc<Mutex<Option<PathBuf>>>,
salsa_db: Arc<Mutex<crate::salsa::SalsaDb>>,
runtime_settings: Arc<Mutex<LspRuntimeSettings>>,
}
impl PanacheLsp {
pub fn new(client: Client) -> Self {
Self {
client,
document_map: Arc::new(Mutex::new(HashMap::new())),
workspace_root: Arc::new(Mutex::new(None)),
salsa_db: Arc::new(Mutex::new(crate::salsa::SalsaDb::default())),
runtime_settings: Arc::new(Mutex::new(LspRuntimeSettings::default())),
}
}
#[doc(hidden)]
pub fn document_map(&self) -> Arc<Mutex<HashMap<String, DocumentState>>> {
Arc::clone(&self.document_map)
}
#[doc(hidden)]
pub fn workspace_root(&self) -> Arc<Mutex<Option<PathBuf>>> {
Arc::clone(&self.workspace_root)
}
#[doc(hidden)]
pub fn salsa_db(&self) -> Arc<Mutex<crate::salsa::SalsaDb>> {
Arc::clone(&self.salsa_db)
}
#[doc(hidden)]
pub fn runtime_settings(&self) -> Arc<Mutex<LspRuntimeSettings>> {
Arc::clone(&self.runtime_settings)
}
#[doc(hidden)]
pub async fn did_change_watched_files(
&self,
params: tower_lsp_server::ls_types::DidChangeWatchedFilesParams,
) {
crate::lsp::handlers::file_watcher::did_change_watched_files(
&self.client,
Arc::clone(&self.document_map),
Arc::clone(&self.salsa_db),
Arc::clone(&self.workspace_root),
params,
)
.await;
}
}
pub async fn run() -> std::io::Result<()> {
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();
let (service, socket) = LspService::new(PanacheLsp::new);
Server::new(stdin, stdout, socket).serve(service).await;
Ok(())
}