1use dashmap::DashMap;
11use tower_lsp::lsp_types::*;
12use tower_lsp::{Client, LanguageServer, LspService, Server};
13
14pub struct GlyphLanguageServer {
15 client: Client,
16 documents: DashMap<Url, String>,
17}
18
19#[tower_lsp::async_trait]
20impl LanguageServer for GlyphLanguageServer {
21 async fn initialize(
22 &self,
23 _: InitializeParams,
24 ) -> tower_lsp::jsonrpc::Result<InitializeResult> {
25 Ok(InitializeResult {
26 server_info: Some(ServerInfo {
27 name: "glyph-lsp".to_string(),
28 version: Some(env!("CARGO_PKG_VERSION").to_string()),
29 }),
30 capabilities: ServerCapabilities {
31 text_document_sync: Some(TextDocumentSyncCapability::Kind(
32 TextDocumentSyncKind::FULL,
33 )),
34 completion_provider: Some(CompletionOptions {
35 resolve_provider: Some(false),
36 trigger_characters: Some(vec![".".to_string()]),
37 ..Default::default()
38 }),
39 hover_provider: Some(HoverProviderCapability::Simple(true)),
40 ..Default::default()
41 }
42 })
43 }
44
45 async fn initialized(&self, _: InitializedParams) {
46 self.client
47 .log_message(MessageType::INFO, "Glyph language server initialized")
48 .await;
49 }
50
51 async fn shutdown(&self) -> tower_lsp::jsonrpc::Result<()> {
52 Ok(())
53 }
54
55 async fn did_open(&self, params: DidOpenTextDocumentParams) {
56 self.documents
57 .insert(params.text_document.uri.clone(), params.text_document.text);
58 }
59
60 async fn did_change(&self, params: DidChangeTextDocumentParams) {
61 if let Some(mut doc) = self.documents.get_mut(¶ms.text_document.uri) {
62 *doc = params.content_changes[0].text.clone();
63 }
64 }
65
66 async fn did_close(&self, params: DidCloseTextDocumentParams) {
67 self.documents.remove(¶ms.text_document.uri);
68 }
69}
70
71impl GlyphLanguageServer {
72 pub fn new(client: Client) -> Self {
73 Self {
74 client,
75 documents: DashMap::new(),
76 }
77 }
78}
79
80pub async fn run_lsp_server() -> anyhow::Result<()> {
81 let stdin = tokio::io::stdin();
82 let stdout = tokio::io::stdout();
83
84 let (service, socket) = LspService::new(GlyphLanguageServer::new);
85 Server::new(stdin, stdout, socket).serve(service).await;
86
87 Ok(())
88}