blues-lsp 0.1.0

LSP language server for the Bluespec SystemVerilog language
Documentation
use std::error::Error;

use tracing::{error, warn};

use crate::lsp::server::{Server, uri_to_pathbuf};

pub fn text_document_sync_capability() -> lsp_types::TextDocumentSyncCapability {
    lsp_types::TextDocumentSyncCapability::Options(lsp_types::TextDocumentSyncOptions {
        open_close: Some(true),
        change: Some(lsp_types::TextDocumentSyncKind::FULL),
        ..Default::default()
    })
}

pub fn did_open_text_document(
    server: &mut Server,
    params: lsp_types::DidOpenTextDocumentParams,
) -> Result<(), Box<dyn Error>> {
    if params.text_document.language_id != "bsv" {
        warn!(
            "Unuspported language_id '{}'",
            params.text_document.language_id
        );
        return Ok(());
    }

    let uri = params.text_document.uri;
    let file = match uri_to_pathbuf(&uri) {
        Some(path) => server.proj.lookup_file(&path),
        None => server.proj.make_dummy_file(),
    };

    if server.open_documents.insert(uri, file).is_some() {
        error!("Duplicate 'textDocument/didOpen' call");
    }

    server.proj.add_ovelay(file, params.text_document.text);

    Ok(())
}

pub fn did_change_text_document(
    server: &mut Server,
    params: lsp_types::DidChangeTextDocumentParams,
) -> Result<(), Box<dyn Error>> {
    let Some(file) = server.open_documents.get(&params.text_document.uri) else {
        error!("'textDocument/didOpen' on closed file");
        return Ok(());
    };

    server.proj.add_ovelay(
        *file,
        params.content_changes.into_iter().next().unwrap().text,
    );

    Ok(())
}

pub fn did_close_text_document(
    server: &mut Server,
    params: lsp_types::DidCloseTextDocumentParams,
) -> Result<(), Box<dyn Error>> {
    let Some(file) = server.open_documents.remove(&params.text_document.uri) else {
        error!("'textDocument/didClose' on already closed file");
        return Ok(());
    };

    server.proj.remove_overlay(file);

    Ok(())
}