From bbf803d7dc0868b5944f6d72d7511025c1a15824 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 29 Jun 2021 20:07:37 -0600 Subject: [PATCH] Store a reference to the LangageRegistry on the Worktree --- zed/src/editor.rs | 2 +- zed/src/editor/buffer.rs | 25 +++++---------- zed/src/file_finder.rs | 14 +++------ zed/src/language.rs | 6 ++++ zed/src/lib.rs | 2 +- zed/src/main.rs | 8 ++--- zed/src/rpc.rs | 6 ++-- zed/src/test.rs | 6 ++-- zed/src/workspace.rs | 53 +++++++++++-------------------- zed/src/worktree.rs | 68 ++++++++++++++++++++-------------------- 10 files changed, 84 insertions(+), 106 deletions(-) diff --git a/zed/src/editor.rs b/zed/src/editor.rs index 3dea5ec4ac97516540f078466a66499d74218758..107098ecb278eccf7d9f075d9f458448fb4bea95 100644 --- a/zed/src/editor.rs +++ b/zed/src/editor.rs @@ -4003,7 +4003,7 @@ mod tests { #[gpui::test] async fn test_select_larger_smaller_syntax_node(mut cx: gpui::TestAppContext) { let app_state = cx.read(build_app_state); - let lang = app_state.language_registry.select_language("z.rs"); + let lang = app_state.languages.select_language("z.rs"); let text = r#" use mod1::mod2::{mod3, mod4}; diff --git a/zed/src/editor/buffer.rs b/zed/src/editor/buffer.rs index 4634870620b8b278492a1014d16048f1c4065bca..be4d8c011052a4f4b0f752f3d5d3ae7fb9d239e9 100644 --- a/zed/src/editor/buffer.rs +++ b/zed/src/editor/buffer.rs @@ -2671,7 +2671,6 @@ impl ToPoint for usize { mod tests { use super::*; use crate::{ - language::LanguageRegistry, test::{build_app_state, temp_tree}, util::RandomCharIter, worktree::{Worktree, WorktreeHandle}, @@ -3144,22 +3143,18 @@ mod tests { #[gpui::test] async fn test_is_dirty(mut cx: gpui::TestAppContext) { - let language_registry = Arc::new(LanguageRegistry::new()); - let dir = temp_tree(json!({ "file1": "abc", "file2": "def", "file3": "ghi", })); - let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx)); + let tree = cx.add_model(|cx| Worktree::local(dir.path(), Default::default(), cx)); tree.flush_fs_events(&cx).await; cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; let buffer1 = tree - .update(&mut cx, |tree, cx| { - tree.open_buffer("file1", language_registry.clone(), cx) - }) + .update(&mut cx, |tree, cx| tree.open_buffer("file1", cx)) .await .unwrap(); let events = Rc::new(RefCell::new(Vec::new())); @@ -3218,9 +3213,7 @@ mod tests { // When a file is deleted, the buffer is considered dirty. let events = Rc::new(RefCell::new(Vec::new())); let buffer2 = tree - .update(&mut cx, |tree, cx| { - tree.open_buffer("file2", language_registry.clone(), cx) - }) + .update(&mut cx, |tree, cx| tree.open_buffer("file2", cx)) .await .unwrap(); buffer2.update(&mut cx, |_, cx| { @@ -3240,9 +3233,7 @@ mod tests { // When a file is already dirty when deleted, we don't emit a Dirtied event. let events = Rc::new(RefCell::new(Vec::new())); let buffer3 = tree - .update(&mut cx, |tree, cx| { - tree.open_buffer("file3", language_registry.clone(), cx) - }) + .update(&mut cx, |tree, cx| tree.open_buffer("file3", cx)) .await .unwrap(); buffer3.update(&mut cx, |_, cx| { @@ -3269,14 +3260,14 @@ mod tests { async fn test_file_changes_on_disk(mut cx: gpui::TestAppContext) { let initial_contents = "aaa\nbbbbb\nc\n"; let dir = temp_tree(json!({ "the-file": initial_contents })); - let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx)); + let tree = cx.add_model(|cx| Worktree::local(dir.path(), Default::default(), cx)); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; let abs_path = dir.path().join("the-file"); let buffer = tree .update(&mut cx, |tree, cx| { - tree.open_buffer(Path::new("the-file"), Arc::new(LanguageRegistry::new()), cx) + tree.open_buffer(Path::new("the-file"), cx) }) .await .unwrap(); @@ -3620,7 +3611,7 @@ mod tests { #[gpui::test] async fn test_reparse(mut cx: gpui::TestAppContext) { let app_state = cx.read(build_app_state); - let rust_lang = app_state.language_registry.select_language("test.rs"); + let rust_lang = app_state.languages.select_language("test.rs"); assert!(rust_lang.is_some()); let buffer = cx.add_model(|cx| { @@ -3761,7 +3752,7 @@ mod tests { use unindent::Unindent as _; let app_state = cx.read(build_app_state); - let rust_lang = app_state.language_registry.select_language("test.rs"); + let rust_lang = app_state.languages.select_language("test.rs"); assert!(rust_lang.is_some()); let buffer = cx.add_model(|cx| { diff --git a/zed/src/file_finder.rs b/zed/src/file_finder.rs index 66d99fc542c5e33da758a2acf94893d177923475..ee63f57faf11ff09494aa06b6175d94a26e73295 100644 --- a/zed/src/file_finder.rs +++ b/zed/src/file_finder.rs @@ -479,12 +479,8 @@ mod tests { let app_state = cx.read(build_app_state); let (window_id, workspace) = cx.add_window(|cx| { - let mut workspace = Workspace::new( - app_state.settings, - app_state.language_registry, - app_state.rpc, - cx, - ); + let mut workspace = + Workspace::new(app_state.settings, app_state.languages, app_state.rpc, cx); workspace.add_worktree(tmp_dir.path(), cx); workspace }); @@ -553,7 +549,7 @@ mod tests { let (_, workspace) = cx.add_window(|cx| { let mut workspace = Workspace::new( app_state.settings.clone(), - app_state.language_registry.clone(), + app_state.languages.clone(), app_state.rpc.clone(), cx, ); @@ -616,7 +612,7 @@ mod tests { let (_, workspace) = cx.add_window(|cx| { let mut workspace = Workspace::new( app_state.settings.clone(), - app_state.language_registry.clone(), + app_state.languages.clone(), app_state.rpc.clone(), cx, ); @@ -667,7 +663,7 @@ mod tests { let (_, workspace) = cx.add_window(|cx| { Workspace::new( app_state.settings.clone(), - app_state.language_registry.clone(), + app_state.languages.clone(), app_state.rpc.clone(), cx, ) diff --git a/zed/src/language.rs b/zed/src/language.rs index 9f977bf408fc4e402d884a58c3da47e10c8e5fb8..7d286dfbe3e9ae3fbf2df2fd671550885e517455 100644 --- a/zed/src/language.rs +++ b/zed/src/language.rs @@ -90,6 +90,12 @@ impl LanguageRegistry { } } +impl Default for LanguageRegistry { + fn default() -> Self { + Self::new() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/zed/src/lib.rs b/zed/src/lib.rs index 4567a9d5dba62893c456a0e80b8f9a50c21a0ead..925c798d4ccff2e83c35a1cdaff286b45e5a1ab0 100644 --- a/zed/src/lib.rs +++ b/zed/src/lib.rs @@ -17,7 +17,7 @@ pub mod worktree; #[derive(Clone)] pub struct AppState { pub settings: postage::watch::Receiver, - pub language_registry: std::sync::Arc, + pub languages: std::sync::Arc, pub rpc: rpc::Client, } diff --git a/zed/src/main.rs b/zed/src/main.rs index 54a55ce86115c857241934ff59b1fe61536b8702..d5edf9ba7b5319305982eafef86ec3c29f001915 100644 --- a/zed/src/main.rs +++ b/zed/src/main.rs @@ -17,13 +17,13 @@ fn main() { let app = gpui::App::new(assets::Assets).unwrap(); let (_, settings) = settings::channel(&app.font_cache()).unwrap(); - let language_registry = Arc::new(language::LanguageRegistry::new()); - language_registry.set_theme(&settings.borrow().theme); + let languages = Arc::new(language::LanguageRegistry::new()); + languages.set_theme(&settings.borrow().theme); let app_state = AppState { - language_registry: language_registry.clone(), + languages: languages.clone(), settings, - rpc: rpc::Client::new(language_registry), + rpc: rpc::Client::new(languages), }; app.run(move |cx| { diff --git a/zed/src/rpc.rs b/zed/src/rpc.rs index e50d334b03e5e45a1f57c76de99d83b2d9752054..a0aa38846672990629859150fc51b5890634a8fe 100644 --- a/zed/src/rpc.rs +++ b/zed/src/rpc.rs @@ -31,7 +31,7 @@ pub struct ClientState { connection_id: Option, pub remote_worktrees: HashMap>, pub shared_buffers: HashMap>>, - pub language_registry: Arc, + pub languages: Arc, } impl ClientState { @@ -54,14 +54,14 @@ impl ClientState { } impl Client { - pub fn new(language_registry: Arc) -> Self { + pub fn new(languages: Arc) -> Self { Self { peer: Peer::new(), state: Arc::new(Mutex::new(ClientState { connection_id: None, remote_worktrees: Default::default(), shared_buffers: Default::default(), - language_registry, + languages, })), } } diff --git a/zed/src/test.rs b/zed/src/test.rs index edf49ab545fd221263f2c605ac35259aaf0552a8..55504d678f9ebd6d190b690c56a1b31890ffad27 100644 --- a/zed/src/test.rs +++ b/zed/src/test.rs @@ -142,10 +142,10 @@ fn write_tree(path: &Path, tree: serde_json::Value) { pub fn build_app_state(cx: &AppContext) -> AppState { let settings = settings::channel(&cx.font_cache()).unwrap().1; - let language_registry = Arc::new(LanguageRegistry::new()); + let languages = Arc::new(LanguageRegistry::new()); AppState { settings, - language_registry: language_registry.clone(), - rpc: rpc::Client::new(language_registry), + languages: languages.clone(), + rpc: rpc::Client::new(languages), } } diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index 70b84cca3878f51051cd6fee98c3779225fb433a..52788c25212233469e733351ac37ce2aab270027 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -91,7 +91,7 @@ fn open_paths(params: &OpenParams, cx: &mut MutableAppContext) { cx.add_window(|cx| { let mut view = Workspace::new( params.app_state.settings.clone(), - params.app_state.language_registry.clone(), + params.app_state.languages.clone(), params.app_state.rpc.clone(), cx, ); @@ -105,7 +105,7 @@ fn open_new(app_state: &AppState, cx: &mut MutableAppContext) { cx.add_window(|cx| { let mut view = Workspace::new( app_state.settings.clone(), - app_state.language_registry.clone(), + app_state.languages.clone(), app_state.rpc.clone(), cx, ); @@ -312,7 +312,7 @@ pub struct State { pub struct Workspace { pub settings: watch::Receiver, - language_registry: Arc, + languages: Arc, rpc: rpc::Client, modal: Option, center: PaneGroup, @@ -329,7 +329,7 @@ pub struct Workspace { impl Workspace { pub fn new( settings: watch::Receiver, - language_registry: Arc, + languages: Arc, rpc: rpc::Client, cx: &mut ViewContext, ) -> Self { @@ -346,7 +346,7 @@ impl Workspace { panes: vec![pane.clone()], active_pane: pane.clone(), settings, - language_registry, + languages: languages, rpc, worktrees: Default::default(), items: Default::default(), @@ -462,7 +462,7 @@ impl Workspace { path: &Path, cx: &mut ViewContext, ) -> ModelHandle { - let worktree = cx.add_model(|cx| Worktree::local(path, cx)); + let worktree = cx.add_model(|cx| Worktree::local(path, self.languages.clone(), cx)); cx.observe_model(&worktree, |_, _, cx| cx.notify()); self.worktrees.insert(worktree.clone()); cx.notify(); @@ -558,13 +558,12 @@ impl Workspace { if let Entry::Vacant(entry) = self.loading_items.entry(entry.clone()) { let (mut tx, rx) = postage::watch::channel(); entry.insert(rx); - let language_registry = self.language_registry.clone(); cx.as_mut() .spawn(|mut cx| async move { let buffer = worktree .update(&mut cx, |worktree, cx| { - worktree.open_buffer(path.as_ref(), language_registry, cx) + worktree.open_buffer(path.as_ref(), cx) }) .await; *tx.borrow_mut() = Some( @@ -714,6 +713,7 @@ impl Workspace { fn join_worktree(&mut self, _: &(), cx: &mut ViewContext) { let rpc = self.rpc.clone(); + let languages = self.languages.clone(); let task = cx.spawn(|this, mut cx| async move { rpc.log_in_and_connect(&cx).await?; @@ -727,7 +727,8 @@ impl Workspace { log::info!("read worktree url from clipboard: {}", worktree_url.text()); let worktree = - Worktree::remote(rpc.clone(), worktree_id, access_token, &mut cx).await?; + Worktree::remote(rpc.clone(), worktree_id, access_token, languages, &mut cx) + .await?; this.update(&mut cx, |workspace, cx| { cx.observe_model(&worktree, |_, _, cx| cx.notify()); workspace.worktrees.insert(worktree); @@ -961,12 +962,8 @@ mod tests { let app_state = cx.read(build_app_state); let (_, workspace) = cx.add_window(|cx| { - let mut workspace = Workspace::new( - app_state.settings, - app_state.language_registry, - app_state.rpc, - cx, - ); + let mut workspace = + Workspace::new(app_state.settings, app_state.languages, app_state.rpc, cx); workspace.add_worktree(dir.path(), cx); workspace }); @@ -1069,12 +1066,8 @@ mod tests { let app_state = cx.read(build_app_state); let (_, workspace) = cx.add_window(|cx| { - let mut workspace = Workspace::new( - app_state.settings, - app_state.language_registry, - app_state.rpc, - cx, - ); + let mut workspace = + Workspace::new(app_state.settings, app_state.languages, app_state.rpc, cx); workspace.add_worktree(dir1.path(), cx); workspace }); @@ -1142,12 +1135,8 @@ mod tests { let app_state = cx.read(build_app_state); let (window_id, workspace) = cx.add_window(|cx| { - let mut workspace = Workspace::new( - app_state.settings, - app_state.language_registry, - app_state.rpc, - cx, - ); + let mut workspace = + Workspace::new(app_state.settings, app_state.languages, app_state.rpc, cx); workspace.add_worktree(dir.path(), cx); workspace }); @@ -1192,7 +1181,7 @@ mod tests { let (_, workspace) = cx.add_window(|cx| { let mut workspace = Workspace::new( app_state.settings.clone(), - app_state.language_registry.clone(), + app_state.languages.clone(), app_state.rpc.clone(), cx, ); @@ -1315,12 +1304,8 @@ mod tests { let app_state = cx.read(build_app_state); let (window_id, workspace) = cx.add_window(|cx| { - let mut workspace = Workspace::new( - app_state.settings, - app_state.language_registry, - app_state.rpc, - cx, - ); + let mut workspace = + Workspace::new(app_state.settings, app_state.languages, app_state.rpc, cx); workspace.add_worktree(dir.path(), cx); workspace }); diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index 14330e9c96b86f58bd22f1d562a049836b9d423d..b69ae9277f4eeb269b57b2c09494dc749f5ee974 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -74,14 +74,19 @@ impl Entity for Worktree { } impl Worktree { - pub fn local(path: impl Into>, cx: &mut ModelContext) -> Self { - Worktree::Local(LocalWorktree::new(path, cx)) + pub fn local( + path: impl Into>, + languages: Arc, + cx: &mut ModelContext, + ) -> Self { + Worktree::Local(LocalWorktree::new(path, languages, cx)) } pub async fn remote( rpc: rpc::Client, id: u64, access_token: String, + languages: Arc, cx: &mut AsyncAppContext, ) -> Result> { let open_worktree_response = rpc @@ -103,6 +108,7 @@ impl Worktree { worktree_message, rpc.clone(), replica_id as ReplicaId, + languages, cx, )) }) @@ -149,14 +155,11 @@ impl Worktree { pub fn open_buffer( &mut self, path: impl AsRef, - language_registry: Arc, cx: &mut ModelContext, ) -> Task>> { match self { - Worktree::Local(worktree) => worktree.open_buffer(path.as_ref(), language_registry, cx), - Worktree::Remote(worktree) => { - worktree.open_buffer(path.as_ref(), language_registry, cx) - } + Worktree::Local(worktree) => worktree.open_buffer(path.as_ref(), cx), + Worktree::Remote(worktree) => worktree.open_buffer(path.as_ref(), cx), } } @@ -241,10 +244,15 @@ pub struct LocalWorktree { poll_scheduled: bool, rpc: Option<(rpc::Client, u64)>, open_buffers: HashMap>, + languages: Arc, } impl LocalWorktree { - fn new(path: impl Into>, cx: &mut ModelContext) -> Self { + fn new( + path: impl Into>, + languages: Arc, + cx: &mut ModelContext, + ) -> Self { let abs_path = path.into(); let (scan_state_tx, scan_state_rx) = smol::channel::unbounded(); let id = cx.model_id(); @@ -268,11 +276,12 @@ impl LocalWorktree { let tree = Self { snapshot, background_snapshot: background_snapshot.clone(), - open_buffers: Default::default(), scan_state: watch::channel_with(ScanState::Scanning), _event_stream_handle: event_stream_handle, poll_scheduled: false, + open_buffers: Default::default(), rpc: None, + languages, }; std::thread::spawn(move || { @@ -313,7 +322,6 @@ impl LocalWorktree { pub fn open_buffer( &mut self, path: &Path, - language_registry: Arc, cx: &mut ModelContext, ) -> Task>> { let handle = cx.handle(); @@ -333,6 +341,7 @@ impl LocalWorktree { } }); + let languages = self.languages.clone(); let path = Arc::from(path); cx.spawn(|this, mut cx| async move { if let Some(existing_buffer) = existing_buffer { @@ -341,7 +350,7 @@ impl LocalWorktree { let (file, contents) = this .update(&mut cx, |this, cx| this.as_local().unwrap().load(&path, cx)) .await?; - let language = language_registry.select_language(&path).cloned(); + let language = languages.select_language(&path).cloned(); let buffer = cx.add_model(|cx| { Buffer::from_history(0, History::new(contents.into()), Some(file), language, cx) }); @@ -638,6 +647,7 @@ pub struct RemoteWorktree { rpc: rpc::Client, replica_id: ReplicaId, open_buffers: HashMap>, + languages: Arc, } impl RemoteWorktree { @@ -646,6 +656,7 @@ impl RemoteWorktree { worktree: proto::Worktree, rpc: rpc::Client, replica_id: ReplicaId, + languages: Arc, cx: &mut ModelContext, ) -> Self { let root_char_bag: CharBag = worktree @@ -700,13 +711,13 @@ impl RemoteWorktree { rpc, replica_id, open_buffers: Default::default(), + languages, } } pub fn open_buffer( &mut self, path: &Path, - language_registry: Arc, cx: &mut ModelContext, ) -> Task>> { let handle = cx.handle(); @@ -725,6 +736,7 @@ impl RemoteWorktree { }); let rpc = self.rpc.clone(); + let languages = self.languages.clone(); let replica_id = self.replica_id; let remote_worktree_id = self.remote_id; let path = path.to_string_lossy().to_string(); @@ -736,7 +748,7 @@ impl RemoteWorktree { .read_with(&cx, |tree, _| tree.entry_for_path(&path).cloned()) .ok_or_else(|| anyhow!("file does not exist"))?; let file = File::new(entry.id, handle, entry.path, entry.mtime); - let language = language_registry.select_language(&path).cloned(); + let language = languages.select_language(&path).cloned(); let response = rpc .request(proto::OpenBuffer { worktree_id: remote_worktree_id as u64, @@ -1880,11 +1892,7 @@ mod remote { let buffer = worktree .update(cx, |worktree, cx| { - worktree.open_buffer( - Path::new(&message.path), - state.language_registry.clone(), - cx, - ) + worktree.open_buffer(Path::new(&message.path), cx) }) .await?; state @@ -2026,7 +2034,7 @@ mod tests { ) .unwrap(); - let tree = cx.add_model(|cx| Worktree::local(root_link_path, cx)); + let tree = cx.add_model(|cx| Worktree::local(root_link_path, Default::default(), cx)); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; @@ -2068,11 +2076,9 @@ mod tests { let dir = temp_tree(json!({ "file1": "the old contents", })); - let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx)); + let tree = cx.add_model(|cx| Worktree::local(dir.path(), app_state.languages, cx)); let buffer = tree - .update(&mut cx, |tree, cx| { - tree.open_buffer("file1", app_state.language_registry, cx) - }) + .update(&mut cx, |tree, cx| tree.open_buffer("file1", cx)) .await .unwrap(); let save = buffer.update(&mut cx, |buffer, cx| { @@ -2093,15 +2099,13 @@ mod tests { })); let file_path = dir.path().join("file1"); - let tree = cx.add_model(|cx| Worktree::local(file_path.clone(), cx)); + let tree = cx.add_model(|cx| Worktree::local(file_path.clone(), app_state.languages, cx)); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; cx.read(|cx| assert_eq!(tree.read(cx).file_count(), 1)); let buffer = tree - .update(&mut cx, |tree, cx| { - tree.open_buffer("", app_state.language_registry, cx) - }) + .update(&mut cx, |tree, cx| tree.open_buffer("", cx)) .await .unwrap(); let save = buffer.update(&mut cx, |buffer, cx| { @@ -2130,14 +2134,10 @@ mod tests { } })); - let language_registry = Arc::new(LanguageRegistry::new()); - - let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx)); + let tree = cx.add_model(|cx| Worktree::local(dir.path(), Default::default(), cx)); let buffer_for_path = |path: &'static str, cx: &mut gpui::TestAppContext| { - let buffer = tree.update(cx, |tree, cx| { - tree.open_buffer(path, language_registry.clone(), cx) - }); + let buffer = tree.update(cx, |tree, cx| tree.open_buffer(path, cx)); async move { buffer.await.unwrap() } }; let id_for_path = |path: &'static str, cx: &gpui::TestAppContext| { @@ -2233,7 +2233,7 @@ mod tests { } })); - let tree = cx.add_model(|cx| Worktree::local(dir.path(), cx)); + let tree = cx.add_model(|cx| Worktree::local(dir.path(), Default::default(), cx)); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; tree.flush_fs_events(&cx).await;