Remember default prettier and its plugin installation

This commit is contained in:
Kirill Bulatov 2023-10-30 22:07:40 +02:00
parent dc8a853842
commit 033d0ae610

View file

@ -162,6 +162,7 @@ pub struct Project {
copilot_log_subscription: Option<lsp::Subscription>,
current_lsp_settings: HashMap<Arc<str>, LspSettings>,
node: Option<Arc<dyn NodeRuntime>>,
default_prettier_plugins: Option<HashSet<&'static str>>,
prettier_instances: HashMap<
(Option<WorktreeId>, PathBuf),
Shared<Task<Result<Arc<Prettier>, Arc<anyhow::Error>>>>,
@ -677,6 +678,7 @@ impl Project {
copilot_log_subscription: None,
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
node: Some(node),
default_prettier_plugins: None,
prettier_instances: HashMap::default(),
}
})
@ -776,6 +778,7 @@ impl Project {
copilot_log_subscription: None,
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
node: None,
default_prettier_plugins: None,
prettier_instances: HashMap::default(),
};
for worktree in worktrees {
@ -8497,7 +8500,7 @@ impl Project {
#[cfg(any(test, feature = "test-support"))]
fn install_default_formatters(
&self,
&mut self,
_worktree: Option<WorktreeId>,
_new_language: &Language,
_language_settings: &LanguageSettings,
@ -8508,7 +8511,7 @@ impl Project {
#[cfg(not(any(test, feature = "test-support")))]
fn install_default_formatters(
&self,
&mut self,
worktree: Option<WorktreeId>,
new_language: &Language,
language_settings: &LanguageSettings,
@ -8537,6 +8540,30 @@ impl Project {
return Task::ready(Ok(()));
};
let mut plugins_to_install = prettier_plugins;
if let Some(already_installed) = &self.default_prettier_plugins {
plugins_to_install.retain(|plugin| !already_installed.contains(plugin));
}
if plugins_to_install.is_empty() && self.default_prettier_plugins.is_some() {
return Task::ready(Ok(()));
}
let previous_plugins = self.default_prettier_plugins.clone();
self.default_prettier_plugins
.get_or_insert_with(HashSet::default)
.extend(plugins_to_install.iter());
let (mut install_success_tx, mut install_success_rx) =
futures::channel::mpsc::channel::<()>(1);
cx.spawn(|this, mut cx| async move {
if install_success_rx.next().await.is_none() {
this.update(&mut cx, |this, _| {
log::warn!("Prettier plugin installation did not finish successfully, restoring previous installed plugins {previous_plugins:?}");
this.default_prettier_plugins = previous_plugins;
})
}
})
.detach();
let default_prettier_dir = util::paths::DEFAULT_PRETTIER_DIR.as_path();
let already_running_prettier = self
.prettier_instances
@ -8552,7 +8579,7 @@ impl Project {
.with_context(|| format!("writing {} file at {prettier_wrapper_path:?}", prettier::PRETTIER_SERVER_FILE))?;
let packages_to_versions = future::try_join_all(
prettier_plugins
plugins_to_install
.iter()
.chain(Some(&"prettier"))
.map(|package_name| async {
@ -8573,8 +8600,10 @@ impl Project {
(package.as_str(), version.as_str())
}).collect::<Vec<_>>();
node.npm_install_packages(default_prettier_dir, &borrowed_packages).await.context("fetching formatter packages")?;
let installed_packages = !plugins_to_install.is_empty();
install_success_tx.try_send(()).ok();
if !prettier_plugins.is_empty() {
if !installed_packages {
if let Some(prettier) = already_running_prettier {
prettier.await.map_err(|e| anyhow::anyhow!("Default prettier startup await failure: {e:#}"))?.clear_cache().await.context("clearing default prettier cache after plugins install")?;
}