Skip to content

Commit

Permalink
add macro + react on notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidLee18 committed Oct 30, 2024
1 parent b35dd28 commit 3d2f2f9
Showing 1 changed file with 94 additions and 34 deletions.
128 changes: 94 additions & 34 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,93 @@
pub mod norminette_msg;
pub mod parser;

use lsp_server::{Connection, ExtractError, Message, Request, RequestId, Response};
use lsp_server::{Connection, ExtractError, Message, Notification, Request, RequestId, Response};
use lsp_types::notification::{DidChangeTextDocument, DidOpenTextDocument, DidSaveTextDocument};
use lsp_types::request::DocumentDiagnosticRequest;
use lsp_types::{
Diagnostic, DiagnosticOptions, DiagnosticServerCapabilities, InitializeParams,
LogMessageParams, MessageType, PublishDiagnosticsParams, ServerCapabilities,
Diagnostic, DiagnosticOptions, DiagnosticServerCapabilities,
InitializeParams, LogMessageParams, MessageType, PublishDiagnosticsParams, ServerCapabilities,
WorkDoneProgressOptions,
};
use parser::parse_norminette;
use std::error::Error;
use std::io;
use std::path::Path;

macro_rules! diag_on_event {
($conn: expr, $noti: expr, $t: ident) => {
match cast_noti::<$t>($noti) {
Ok(params) => {
eprintln!("got doc document open notification: {params:?}");
notify_diagnostics!($conn, params);
}
Err(_) => {}
}
};
}

macro_rules! notify_diagnostics {
($conn: expr, $params: expr) => {
match read_norminette(&Path::new($params.text_document.uri.path().as_str())) {
Ok(diags) => {
$conn.sender.send(Message::Notification(Notification {
method: String::from("textDocument/publishDiagnostics"),
params: serde_json::to_value(&PublishDiagnosticsParams {
uri: $params.text_document.uri,
diagnostics: diags,
version: None,
})?,
}))?;
}
Err(e) => {
$conn.sender.send(Message::Notification(Notification {
method: String::from("window/logMessage"),
params: serde_json::to_value(&LogMessageParams {
typ: MessageType::ERROR,
message: format!(
"norminette read of {} failed: {}",
$params.text_document.uri.path(),
e
),
})?,
}))?;
}
}
};
}

macro_rules! send_diagnostics {
($conn: expr, $id: expr, $params: expr) => {
match read_norminette(&Path::new($params.text_document.uri.path().as_str())) {
Ok(diags) => {
$conn.sender.send(Message::Response(Response {
id: $id,
result: Some(serde_json::to_value(&PublishDiagnosticsParams {
uri: $params.text_document.uri,
diagnostics: diags,
version: None,
})?),
error: None,
}))?;
}
Err(e) => {
$conn.sender.send(Message::Response(Response {
id: $id,
result: Some(serde_json::to_value(&LogMessageParams {
typ: MessageType::ERROR,
message: format!(
"norminette read of {} failed: {}",
$params.text_document.uri.path(),
e
),
})?),
error: None,
}))?;
}
}
};
}

fn read_norminette(path: &Path) -> io::Result<Vec<Diagnostic>> {
let output = std::process::Command::new("norminette")
.arg(path)
Expand Down Expand Up @@ -83,45 +158,22 @@ fn main_loop(
match cast::<DocumentDiagnosticRequest>(req) {
Ok((id, params)) => {
eprintln!("got doc diagnostic request #{id} params: {params:?}");
match read_norminette(&Path::new(params.text_document.uri.path().as_str()))
{
Ok(diags) => {
connection.sender.send(Message::Response(Response {
id,
result: Some(serde_json::to_value(
&PublishDiagnosticsParams {
uri: params.text_document.uri,
diagnostics: diags,
version: None,
},
)?),
error: None,
}))?;
}
Err(e) => {
connection.sender.send(Message::Response(Response {
id,
result: Some(serde_json::to_value(&LogMessageParams {
typ: MessageType::ERROR,
message: format!(
"norminette read of {} failed: {}",
params.text_document.uri.path(),
e
),
})?),
error: None,
}))?;
}
}
send_diagnostics!(connection, id, params);
}
Err(e) => {
eprintln!("got error: {e:?}");
continue;
}
Err(e) => return Err(Box::new(e)),
};
}
Message::Response(resp) => {
eprintln!("got response: {resp:?}");
}
Message::Notification(not) => {
eprintln!("got notification: {not:?}");
diag_on_event!(connection, not.clone(), DidOpenTextDocument);
diag_on_event!(connection, not.clone(), DidChangeTextDocument);
diag_on_event!(connection, not, DidSaveTextDocument);
}
}
}
Expand All @@ -135,3 +187,11 @@ where
{
req.extract(R::METHOD)
}

fn cast_noti<N>(noti: Notification) -> Result<N::Params, ExtractError<Notification>>
where
N: lsp_types::notification::Notification,
N::Params: serde::de::DeserializeOwned,
{
noti.extract(N::METHOD)
}

0 comments on commit 3d2f2f9

Please sign in to comment.