use std::path::PathBuf;
use cosh_sdk::lsp::ClientKey;
use super::{support::Deps, types::RestartInput, types::RestartOutput};
fn key_names(keys: &[cosh_sdk::lsp::ClientKey]) -> String {
keys.iter()
.map(|key| key.server.as_str())
.collect::<Vec<_>>()
.join(", ")
}
pub async fn run_restart(deps: &Deps<'_>, input: &RestartInput) -> Result<RestartOutput, String> {
let keys: Vec<ClientKey> = match &input.file_path {
Some(file_path) => {
let path: PathBuf = deps.manager.root().join(file_path);
deps.manager
.matches_for_file(&path)
.into_iter()
.map(|(key, _)| key)
.collect()
}
None => deps
.manager
.states()
.into_iter()
.map(|(key, _)| key)
.collect(),
};
if keys.is_empty() {
return Ok(RestartOutput {
restarted: Vec::new(),
});
}
let mut restarted = Vec::new();
for key in &keys {
deps.manager.stop_client(key).await;
restarted.push(key.server.clone());
}
if let Some(file_path) = &input.file_path {
let path: PathBuf = deps.manager.root().join(file_path);
if let Ok(handles) = deps.manager.ensure_for_file(&path).await {
for handle in &handles {
if let Err(err) = handle.touch_file(&path).await {
log::warn!(
"restart of `{}` could not reopen `{}`: {err}",
key_names(&keys),
path.display()
);
}
}
}
}
Ok(RestartOutput { restarted })
}