Create a special worktree for settings files

To avoid LSP server restarts/leaks when those are being opened

co-authored-by: Piotr <piotr@zed.dev>
This commit is contained in:
Kirill Bulatov 2024-01-23 13:10:30 +02:00
parent ab8585ee7e
commit 5e0cabc394
4 changed files with 34 additions and 14 deletions

View File

@ -70,10 +70,6 @@ impl TextSystem {
/// Get a list of all available font names from the operating system. /// Get a list of all available font names from the operating system.
pub fn all_font_names(&self) -> Vec<String> { pub fn all_font_names(&self) -> Vec<String> {
eprintln!(
"~~~~~~~~~~~~~ all_font_names called {}",
std::backtrace::Backtrace::capture()
);
let mut names: BTreeSet<_> = self let mut names: BTreeSet<_> = self
.platform_text_system .platform_text_system
.all_font_names() .all_font_names()

View File

@ -973,7 +973,7 @@ impl Project {
} }
// Start all the newly-enabled language servers. // Start all the newly-enabled language servers.
for (worktree, language) in dbg!(language_servers_to_start) { for (worktree, language) in language_servers_to_start {
let worktree_path = worktree.read(cx).abs_path(); let worktree_path = worktree.read(cx).abs_path();
self.start_language_servers(&worktree, worktree_path, language, cx); self.start_language_servers(&worktree, worktree_path, language, cx);
} }

View File

@ -1355,7 +1355,7 @@ impl Workspace {
Some(visible) => match this Some(visible) => match this
.update(&mut cx, |this, cx| { .update(&mut cx, |this, cx| {
Workspace::project_path_for_path( Workspace::project_path_for_path(
dbg!(this.project.clone()), this.project.clone(),
abs_path, abs_path,
visible, visible,
cx, cx,
@ -1368,7 +1368,6 @@ impl Workspace {
}, },
None => None, None => None,
}; };
dbg!(&project_path);
let this = this.clone(); let this = this.clone();
let abs_path = abs_path.clone(); let abs_path = abs_path.clone();

View File

@ -20,9 +20,10 @@ use assets::Assets;
use futures::{channel::mpsc, select_biased, StreamExt}; use futures::{channel::mpsc, select_biased, StreamExt};
use project_panel::ProjectPanel; use project_panel::ProjectPanel;
use quick_action_bar::QuickActionBar; use quick_action_bar::QuickActionBar;
use rope::Rope;
use search::project_search::ProjectSearchBar; use search::project_search::ProjectSearchBar;
use settings::{initial_local_settings_content, KeymapFile, Settings, SettingsStore}; use settings::{initial_local_settings_content, KeymapFile, Settings, SettingsStore};
use std::{borrow::Cow, ops::Deref, sync::Arc}; use std::{borrow::Cow, ops::Deref, path::Path, sync::Arc};
use terminal_view::terminal_panel::{self, TerminalPanel}; use terminal_view::terminal_panel::{self, TerminalPanel};
use util::{ use util::{
asset_str, asset_str,
@ -256,16 +257,16 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
) )
.register_action( .register_action(
move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| { move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
create_and_open_local_file(&paths::KEYMAP, cx, Default::default) open_settings_file(&paths::KEYMAP, Rope::default, cx);
.detach_and_log_err(cx);
}, },
) )
.register_action( .register_action(
move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| { move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
create_and_open_local_file(&paths::SETTINGS, cx, || { open_settings_file(
settings::initial_user_settings_content().as_ref().into() &paths::SETTINGS,
}) || settings::initial_user_settings_content().as_ref().into(),
.detach_and_log_err(cx); cx,
);
}, },
) )
.register_action(open_local_settings_file) .register_action(open_local_settings_file)
@ -723,6 +724,30 @@ fn open_bundled_file(
.detach_and_log_err(cx); .detach_and_log_err(cx);
} }
fn open_settings_file(
abs_path: &'static Path,
default_content: impl FnOnce() -> Rope + Send + 'static,
cx: &mut ViewContext<Workspace>,
) {
cx.spawn(|workspace, mut cx| async move {
let (worktree_creation_task, settings_open_task) =
workspace.update(&mut cx, |workspace, cx| {
let worktree_creation_task = workspace.project().update(cx, |project, cx| {
// Set up a dedicated worktree for settings, since otherwise we're dropping and re-starting LSP servers for each file inside on every settings file close/open
// TODO: Do note that all other external files (e.g. drag and drop from OS) still have their worktrees released on file close, causing LSP servers' restarts.
project.find_or_create_local_worktree(paths::CONFIG_DIR.as_path(), false, cx)
});
let settings_open_task = create_and_open_local_file(&abs_path, cx, default_content);
(worktree_creation_task, settings_open_task)
})?;
let _ = worktree_creation_task.await?;
let _ = settings_open_task.await?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;