cargo-lsp 0.0.4

LSP for Cargo.toml files
mod toml;

mod doc;
use doc::Doc;

use std::collections::HashMap;

use mylsp::prelude::*;

#[derive(Default, Clone, Debug)]
struct Functions {
    documents: HashMap<String, Doc>,
}

impl BasicFunctions for Functions {
    #[allow(clippy::field_reassign_with_default)]
    fn initialize(
        &mut self,
        _: Request,
        _: InitializeParams,
    ) -> Result<InitializedResult, Response> {
        let mut caps = ServerCapabilities::default();
        caps.position_encoding = Some("utf-8".to_string());
        caps.text_document_sync = Some(TextDocumentSyncOptions {
            open_close: Some(true),
            change: Some(TextDocumentSyncKind::Full),
        });
        caps.completion_provider = Some(CompletionOptions {
            trigger_characters: None,
            all_commit_characters: None,
            resolve_provider: None,
            completion_item: None,
        });
        Ok(InitializedResult {
            capabilities: caps,
            server_info: None,
        })
    }
}

impl TextDocumentFunctions for Functions {
    fn did_open(
        &mut self,
        ctx: &mut dyn LspContext,
        _: Notification,
        params: DidOpenTextDocumentParams,
    ) {
        let uri = params.text_document.uri;
        let doc = Doc::new(&uri, params.text_document.text);
        ctx.send_notification((&doc).into());
        self.documents.insert(uri, doc);
    }

    fn did_change(
        &mut self,
        ctx: &mut dyn LspContext,
        _: Notification,
        params: DidChangeTextDocumentParams,
    ) {
        let Some(change) = params.content_changes.first().cloned() else {
            return;
        };
        let uri = params.text_document.uri;
        let doc = Doc::new(&uri, change.text);
        ctx.send_notification((&doc).into());
        self.documents.insert(uri, doc);
    }

    fn did_close(
        &mut self,
        ctx: &mut dyn LspContext,
        _: Notification,
        params: DidCloseTextDocumentParams,
    ) {
        let uri = params.text_document.uri;
        ctx.send_notification(
            (
                "textDocument/publishDiagnostics",
                PublishDiagnosticsParams {
                    uri: uri.clone(),
                    version: None,
                    diagnostics: vec![],
                },
            )
                .into(),
        );
        self.documents.remove(&uri);
    }

    fn completion(
        &mut self,
        _: &mut dyn LspContext,
        _: Request,
        params: CompletionParams,
    ) -> Result<CompletionList, Response> {
        let uri = params.text_document.uri;
        let Some(doc) = self.documents.get(&uri) else {
            return Ok(CompletionList {
                is_incomplete: false,
                items: vec![],
            });
        };
        Ok(doc.completions_at(&params.position))
    }

    fn diagnostic(
        &mut self,
        _: &mut dyn LspContext,
        _: Request,
        params: DocumentDiagnosticParams,
    ) -> Result<DocumentDiagnosticReport, Response> {
        let docuri = params.text_document.uri;
        let Some(doc) = self.documents.get(&docuri) else {
            return Ok(DocumentDiagnosticReport::default());
        };
        Ok(doc.into())
    }
}

fn main() {
    mylsp::run_std(&mut Functions::default());
}