diff --git a/gpui/Cargo.toml b/gpui/Cargo.toml index 7cc202e0b6..be86a788d8 100644 --- a/gpui/Cargo.toml +++ b/gpui/Cargo.toml @@ -4,6 +4,9 @@ edition = "2018" name = "gpui" version = "0.1.0" +[features] +test-support = [] + [dependencies] arrayvec = "0.7.1" async-task = "4.0.3" diff --git a/gpui/src/elements/svg.rs b/gpui/src/elements/svg.rs index 55e11a9253..3e93d3adae 100644 --- a/gpui/src/elements/svg.rs +++ b/gpui/src/elements/svg.rs @@ -47,8 +47,9 @@ impl Element for Svg { ); (size, Some(tree)) } - Err(error) => { - log::error!("{}", error); + Err(_error) => { + #[cfg(not(any(test, feature = "test-support")))] + log::error!("{}", _error); (constraint.min, None) } } diff --git a/zed/Cargo.toml b/zed/Cargo.toml index 8d27fcd4c5..17d42a04c9 100644 --- a/zed/Cargo.toml +++ b/zed/Cargo.toml @@ -14,7 +14,7 @@ name = "Zed" path = "src/main.rs" [features] -test-support = ["tempdir", "zrpc/test-support"] +test-support = ["tempdir", "zrpc/test-support", "gpui/test-support"] [dependencies] anyhow = "1.0.38" @@ -69,6 +69,7 @@ serde_json = { version = "1.0.64", features = ["preserve_order"] } tempdir = { version = "0.3.7" } unindent = "0.1.7" zrpc = { path = "../zrpc", features = ["test-support"] } +gpui = { path = "../gpui", features = ["test-support"] } [package.metadata.bundle] icon = ["app-icon@2x.png", "app-icon.png"] diff --git a/zed/src/editor.rs b/zed/src/editor.rs index 98f0b4a023..25403d3aae 100644 --- a/zed/src/editor.rs +++ b/zed/src/editor.rs @@ -4,6 +4,7 @@ mod element; pub mod movement; use crate::{ + language::Language, settings::Settings, theme::Theme, time::ReplicaId, @@ -449,6 +450,10 @@ impl Editor { } } + pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc> { + self.buffer.read(cx).language() + } + pub fn set_placeholder_text( &mut self, placeholder_text: impl Into>, diff --git a/zed/src/editor/buffer.rs b/zed/src/editor/buffer.rs index 97e0202cec..82aa10d438 100644 --- a/zed/src/editor/buffer.rs +++ b/zed/src/editor/buffer.rs @@ -714,9 +714,16 @@ impl Buffer { path: impl Into>, cx: &mut ModelContext, ) -> Task> { + let path = path.into(); let handle = cx.handle(); let text = self.visible_text.clone(); let version = self.version.clone(); + + if let Some(language) = worktree.read(cx).languages().select_language(&path).cloned() { + self.language = Some(language); + self.reparse(cx); + } + let save_as = worktree.update(cx, |worktree, cx| { worktree .as_local_mut() @@ -794,6 +801,10 @@ impl Buffer { cx.emit(Event::FileHandleChanged); } + pub fn language(&self) -> Option<&Arc> { + self.language.as_ref() + } + pub fn parse_count(&self) -> usize { self.parse_count } @@ -871,7 +882,11 @@ impl Buffer { cx.spawn(move |this, mut cx| async move { let new_tree = parse_task.await; this.update(&mut cx, move |this, cx| { - let parse_again = this.version > parsed_version; + let language_changed = + this.language.as_ref().map_or(true, |curr_language| { + !Arc::ptr_eq(curr_language, &language) + }); + let parse_again = this.version > parsed_version || language_changed; *this.syntax_tree.lock() = Some(SyntaxTree { tree: new_tree, dirty: false, diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index ff3666e0de..1a83c35876 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -1476,7 +1476,7 @@ mod tests { }); cx.simulate_new_path_selection(|parent_dir| { assert_eq!(parent_dir, dir.path()); - Some(parent_dir.join("the-new-name")) + Some(parent_dir.join("the-new-name.rs")) }); cx.read(|cx| { assert!(editor.is_dirty(cx)); @@ -1489,8 +1489,10 @@ mod tests { .await; cx.read(|cx| { assert!(!editor.is_dirty(cx)); - assert_eq!(editor.title(cx), "the-new-name"); + assert_eq!(editor.title(cx), "the-new-name.rs"); }); + // The language is assigned based on the path + editor.read_with(&cx, |editor, cx| assert!(editor.language(cx).is_some())); // Edit the file and save it again. This time, there is no filename prompt. editor.update(&mut cx, |editor, cx| { @@ -1504,7 +1506,7 @@ mod tests { editor .condition(&cx, |editor, cx| !editor.is_dirty(cx)) .await; - cx.read(|cx| assert_eq!(editor.title(cx), "the-new-name")); + cx.read(|cx| assert_eq!(editor.title(cx), "the-new-name.rs")); // Open the same newly-created file in another pane item. The new editor should reuse // the same buffer. @@ -1512,7 +1514,7 @@ mod tests { workspace.open_new_file(&OpenNew(app_state.clone()), cx); workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx); assert!(workspace - .open_entry((tree.id(), Path::new("the-new-name").into()), cx) + .open_entry((tree.id(), Path::new("the-new-name.rs").into()), cx) .is_none()); }); let editor2 = workspace.update(&mut cx, |workspace, cx| { diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index 7b2fea9175..f952bef22f 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -268,6 +268,13 @@ impl Worktree { } } + pub fn languages(&self) -> &Arc { + match self { + Worktree::Local(worktree) => &worktree.languages, + Worktree::Remote(worktree) => &worktree.languages, + } + } + pub fn snapshot(&self) -> Snapshot { match self { Worktree::Local(worktree) => worktree.snapshot(),