use lsp_types::{DidChangeWatchedFilesParams, FileChangeType};
use crate::context::{ServerContextSnapshot, UpdateEvent};
use crate::util::uri_to_file_path;
pub async fn on_did_change_watched_files(
context: ServerContextSnapshot,
params: DidChangeWatchedFilesParams,
) -> Option<()> {
context
.enqueue(UpdateEvent::WatchedFilesChanged(params))
.await;
Some(())
}
pub async fn process_did_change_watched_files(
context: ServerContextSnapshot,
params: DidChangeWatchedFilesParams,
) -> Option<()> {
let mut changes = Vec::new();
let mut deleted = Vec::new();
let mut configuration_files = Vec::new();
let mut reload_needed = false;
for change in params.changes {
let Some(path) = uri_to_file_path(&change.uri) else {
continue;
};
let open = {
let workspace_manager = context.workspace_manager().lock().await;
workspace_manager.is_open_file(&change.uri)
};
match change.typ {
FileChangeType::DELETED => {
deleted.push(change.uri.clone());
if !open {
changes.push(cpp_code_analysis::FileEvent::removed(path.clone()));
}
}
FileChangeType::CREATED | FileChangeType::CHANGED => {
if open {
continue;
}
changes.push(cpp_code_analysis::FileEvent::modified(path.clone()));
}
_ => continue,
}
let workspace_manager = context.workspace_manager().lock().await;
if workspace_manager.is_configuration_file(&path) {
configuration_files.push(path);
reload_needed = true;
}
}
if !changes.is_empty() {
let response = context
.analysis()
.update_session("a watched file changed", move |session| {
session.changed(changes)
})
.await;
let Some(response) = response else {
return Some(());
};
context.analysis().wake();
context
.diagnostics()
.schedule_open_files(context.clone())
.await;
if response.everything {
log::info!("the whole project has to be read again");
}
}
let _ = deleted;
if reload_needed {
for path in configuration_files {
context
.workspace_manager()
.lock()
.await
.add_update_config_task(context.clone(), path)
.await;
}
}
Some(())
}