use std::sync::Arc;
use std::sync::RwLock;
use anyhow::Result;
use tower_lsp::LanguageServer;
pub async fn kcl_lsp_server(execute: bool) -> Result<crate::lsp::kcl::Backend> {
let kcl_std = crate::docs::kcl_doc::walk_prelude();
let stdlib_completions = crate::lsp::kcl::get_completions_from_stdlib(&kcl_std)?;
let sketch_block_stdlib_completions = crate::lsp::kcl::get_completions_from_stdlib_for_sketch_block(&kcl_std)?;
let stdlib_signatures = crate::lsp::kcl::get_signatures_from_stdlib(&kcl_std);
let sketch_block_stdlib_signatures = crate::lsp::kcl::get_signatures_from_stdlib_for_sketch_block(&kcl_std);
let stdlib_args = crate::lsp::kcl::get_arg_maps_from_stdlib(&kcl_std);
let sketch_block_stdlib_args = crate::lsp::kcl::get_arg_maps_from_stdlib_for_sketch_block(&kcl_std);
let kcl_keywords = crate::lsp::kcl::get_keywords();
let zoo_client = crate::engine::new_zoo_client(if execute { None } else { Some("bad_token".to_string()) }, None)?;
let executor_ctx = if execute {
Some(crate::execution::ExecutorContext::new(&zoo_client, Default::default()).await?)
} else {
None
};
let can_execute = executor_ctx.is_some();
assert!(!execute || can_execute);
let (service, _) = tower_lsp::LspService::build(|client| crate::lsp::kcl::Backend {
client,
fs: Arc::new(crate::fs::FileManager::new()),
workspace_folders: Default::default(),
stdlib_completions,
sketch_block_stdlib_completions,
stdlib_signatures,
sketch_block_stdlib_signatures,
stdlib_args,
sketch_block_stdlib_args,
token_map: Default::default(),
ast_map: Default::default(),
code_map: Default::default(),
diagnostics_map: Default::default(),
symbols_map: Default::default(),
semantic_tokens_map: Default::default(),
zoo_client,
executor_ctx: Arc::new(tokio::sync::RwLock::new(executor_ctx)),
can_execute: Arc::new(tokio::sync::RwLock::new(can_execute)),
is_initialized: Default::default(),
kcl_keywords,
})
.custom_method("kcl/updateCanExecute", crate::lsp::kcl::Backend::update_can_execute)
.finish();
let server = service.inner();
server
.initialize(tower_lsp::lsp_types::InitializeParams::default())
.await?;
server.initialized(tower_lsp::lsp_types::InitializedParams {}).await;
Ok(server.clone())
}
pub async fn copilot_lsp_server() -> Result<crate::lsp::copilot::Backend> {
let zoo_client = kittycad::Client::new_from_env();
let (service, _) = tower_lsp::LspService::new(|client| crate::lsp::copilot::Backend {
client,
fs: Arc::new(crate::fs::FileManager::new()),
workspace_folders: Default::default(),
code_map: Default::default(),
zoo_client,
editor_info: Arc::new(RwLock::new(crate::lsp::copilot::types::CopilotEditorInfo::default())),
cache: Arc::new(crate::lsp::copilot::cache::CopilotCache::new()),
telemetry: Default::default(),
is_initialized: Default::default(),
diagnostics_map: Default::default(),
dev_mode: Default::default(),
});
let server = service.inner();
server
.initialize(tower_lsp::lsp_types::InitializeParams::default())
.await?;
server.initialized(tower_lsp::lsp_types::InitializedParams {}).await;
Ok(server.clone())
}