mod documentation;
mod iri;
use std::rc::Rc;
use futures::lock::Mutex;
use ll_sparql_parser::{TokenAtOffset, syntax_kind::SyntaxKind};
use tracing::instrument;
use crate::server::{
Server,
lsp::{
HoverRequest, HoverResponse,
errors::{ErrorCode, LSPError},
},
};
#[instrument(skip_all, fields(id = %request.get_id(), uri = %request.get_document_uri()))]
pub(super) async fn handle_hover_request(
server_rc: Rc<Mutex<Server>>,
request: HoverRequest,
) -> Result<(), LSPError> {
let (root, document_text) = {
let server = server_rc.lock().await;
let document = server.state.get_document(request.get_document_uri())?;
(
server
.state
.get_cached_parse_tree(request.get_document_uri())?
.tree,
document.text.clone(),
)
};
let mut hover_response = HoverResponse::new(request.get_id());
let offset = request
.get_position()
.byte_index(&document_text)
.ok_or_else(|| {
LSPError::new(
ErrorCode::InvalidParams,
"The hover position is not inside the text document",
)
})?;
if let TokenAtOffset::Single(token) = root.token_at_offset(offset)
&& let Some(content) = match token.kind() {
SyntaxKind::PNAME_LN | SyntaxKind::PNAME_NS | SyntaxKind::IRIREF => {
iri::hover(server_rc.clone(), root, token).await?
}
other => documentation::get_docstring_for_kind(other),
}
{
hover_response.set_markdown_content(content.to_string());
}
server_rc.lock().await.send_message(hover_response)
}