use emmylua_code_analysis::uri_to_file_path;
use lsp_types::{
DidChangeTextDocumentParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams,
DidSaveTextDocumentParams,
};
use std::time::Duration;
use crate::context::{ServerContextSnapshot, WorkspaceDiagnosticLevel};
pub async fn on_did_open_text_document(
context: ServerContextSnapshot,
params: DidOpenTextDocumentParams,
) -> Option<()> {
let uri = params.text_document.uri;
let text = params.text_document.text;
let should_process = {
let analysis = context.analysis().read().await;
let old_file_id = analysis.get_file_id(&uri);
if old_file_id.is_some() {
true
} else {
drop(analysis);
let workspace_manager = context.workspace_manager().read().await;
workspace_manager.is_workspace_file(&uri)
}
};
{
let mut workspace = context.workspace_manager().write().await;
workspace.sync_open_file(uri.clone(), text.clone());
}
if !should_process {
return None;
}
let (file_id, supports_pull, interval) = {
let mut analysis = context.analysis().write().await;
let file_id = analysis.update_file_by_uri(&uri, Some(text));
let emmyrc = analysis.get_emmyrc();
let interval = emmyrc.diagnostics.diagnostic_interval.unwrap_or(500);
let supports_pull = context.lsp_features().supports_pull_diagnostic();
(file_id, supports_pull, interval)
};
if !supports_pull {
if let Some(file_id) = file_id {
context
.file_diagnostic()
.add_diagnostic_task(file_id, interval)
.await;
}
}
Some(())
}
pub async fn on_did_save_text_document(
context: ServerContextSnapshot,
_: DidSaveTextDocumentParams,
) -> Option<()> {
let emmyrc = context.analysis().read().await.get_emmyrc();
if !emmyrc.workspace.enable_reindex {
if context.lsp_features().supports_workspace_diagnostic() {
context
.file_diagnostic()
.cancel_workspace_diagnostic()
.await;
let workspace_manager = context.workspace_manager().write().await;
workspace_manager.update_workspace_version(WorkspaceDiagnosticLevel::Slow, true);
workspace_manager.check_schema_update().await;
}
return Some(());
}
let mut duration = emmyrc.workspace.reindex_duration;
if duration < 1000 {
duration = 1000;
}
let workspace = context.workspace_manager().read().await;
workspace.reindex_workspace(Duration::from_millis(duration));
workspace.check_schema_update().await;
Some(())
}
pub async fn on_did_change_text_document(
context: ServerContextSnapshot,
params: DidChangeTextDocumentParams,
) -> Option<()> {
let uri = params.text_document.uri;
let text = params.content_changes.first()?.text.clone();
let should_process = {
let analysis = context.analysis().read().await;
let old_file_id = analysis.get_file_id(&uri);
if old_file_id.is_some() {
true
} else {
drop(analysis);
let workspace_manager = context.workspace_manager().read().await;
workspace_manager.is_workspace_file(&uri)
}
};
{
let mut workspace = context.workspace_manager().write().await;
workspace.sync_open_file(uri.clone(), text.clone());
}
if !should_process {
return None;
}
let (file_id, emmyrc, supports_pull) = {
let mut analysis = context.analysis().write().await;
let file_id = analysis.update_file_by_uri(&uri, Some(text));
let emmyrc = analysis.get_emmyrc();
let supports_pull = context.lsp_features().supports_pull_diagnostic();
(file_id, emmyrc, supports_pull)
};
let interval = emmyrc.diagnostics.diagnostic_interval.unwrap_or(500);
if emmyrc.workspace.enable_reindex {
let workspace = context.workspace_manager().read().await;
workspace.extend_reindex_delay();
}
if !supports_pull {
if let Some(file_id) = file_id {
context
.file_diagnostic()
.add_diagnostic_task(file_id, interval)
.await;
}
}
Some(())
}
pub async fn on_did_close_document(
context: ServerContextSnapshot,
params: DidCloseTextDocumentParams,
) -> Option<()> {
let uri = ¶ms.text_document.uri;
let mut workspace = context.workspace_manager().write().await;
workspace.close_open_file(¶ms.text_document.uri);
drop(workspace);
let lsp_features = context.lsp_features();
if let Some(file_path) = uri_to_file_path(uri)
&& !file_path.exists()
{
let mut mut_analysis = context.analysis().write().await;
mut_analysis.remove_file_by_uri(uri);
drop(mut_analysis);
if !lsp_features.supports_pull_diagnostic() {
context
.file_diagnostic()
.clear_push_file_diagnostics(uri.clone());
}
return Some(());
}
let analysis = context.analysis().read().await;
let file_id = analysis.get_file_id(uri)?;
let module_info = analysis
.compilation
.get_db()
.get_module_index()
.get_module(file_id);
if module_info.is_none() {
drop(analysis);
let mut mut_analysis = context.analysis().write().await;
mut_analysis.remove_file_by_uri(uri);
drop(mut_analysis);
if !lsp_features.supports_pull_diagnostic() {
context
.file_diagnostic()
.clear_push_file_diagnostics(uri.clone());
}
}
Some(())
}