use std::path::PathBuf;
use lsp_types::{
DidChangeTextDocumentParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams,
DidSaveTextDocumentParams,
};
use crate::context::{AnalysisState, ServerContextSnapshot, UpdateEvent};
use crate::util::uri_to_file_path;
pub async fn on_did_open_text_document(
context: ServerContextSnapshot,
params: DidOpenTextDocumentParams,
) -> Option<()> {
context.enqueue(UpdateEvent::Opened(params)).await;
Some(())
}
pub async fn process_did_open_text_document(
context: ServerContextSnapshot,
params: DidOpenTextDocumentParams,
) -> Option<()> {
let uri = params.text_document.uri;
let text = params.text_document.text;
let path = uri_to_file_path(&uri)?;
{
let mut workspace_manager = context.workspace_manager().lock().await;
workspace_manager.sync_open_file(uri.clone(), text.clone());
}
apply_buffer(&context, path, text).await;
Some(())
}
pub async fn on_did_change_text_document(
context: ServerContextSnapshot,
params: DidChangeTextDocumentParams,
) -> Option<()> {
context.enqueue(UpdateEvent::Changed(params)).await;
Some(())
}
pub async fn process_did_change_text_document(
context: ServerContextSnapshot,
params: DidChangeTextDocumentParams,
) -> Option<()> {
let uri = params.text_document.uri;
let text = params.content_changes.last()?.text.clone();
let path = uri_to_file_path(&uri)?;
{
let mut workspace_manager = context.workspace_manager().lock().await;
workspace_manager.sync_open_file(uri.clone(), text.clone());
}
apply_buffer(&context, path, text).await;
Some(())
}
pub async fn on_did_save_text_document(
context: ServerContextSnapshot,
params: DidSaveTextDocumentParams,
) -> Option<()> {
context.enqueue(UpdateEvent::Saved(params)).await;
Some(())
}
pub async fn process_did_save_text_document(
context: ServerContextSnapshot,
params: DidSaveTextDocumentParams,
) -> Option<()> {
let text = params.text?;
let uri = params.text_document.uri;
let path = uri_to_file_path(&uri)?;
{
let mut workspace_manager = context.workspace_manager().lock().await;
workspace_manager.sync_open_file(uri, text.clone());
}
apply_buffer(&context, path, text).await;
Some(())
}
pub async fn on_did_close_document(
context: ServerContextSnapshot,
params: DidCloseTextDocumentParams,
) -> Option<()> {
context.enqueue(UpdateEvent::Closed(params)).await;
Some(())
}
pub async fn process_did_close_document(
context: ServerContextSnapshot,
params: DidCloseTextDocumentParams,
) -> Option<()> {
let uri = params.text_document.uri;
{
let mut workspace_manager = context.workspace_manager().lock().await;
workspace_manager.close_open_file(&uri);
}
let Some(path) = uri_to_file_path(&uri) else {
return Some(());
};
context
.analysis()
.update_session("didClose", |session| session.did_close(&path))
.await;
context.analysis().wake();
Some(())
}
async fn apply_buffer(context: &ServerContextSnapshot, path: PathBuf, text: String) {
let analysis: &AnalysisState = context.analysis();
let for_session = path.clone();
let applied = analysis
.update_session("didOpen", move |session| {
session.did_open(&for_session, &text);
session.advance(1);
})
.await;
if applied.is_none() {
log::debug!("no analysis yet: the buffer is held until a workspace root is named");
return;
}
analysis.wake();
}