diff --git a/crates/gpui/src/app/test_context.rs b/crates/gpui/src/app/test_context.rs index 032d0a7963bc8d6bd2e78a156e97b792cac39b8c..ddf88537579809f9c5c2d22995d8b1379812c789 100644 --- a/crates/gpui/src/app/test_context.rs +++ b/crates/gpui/src/app/test_context.rs @@ -25,6 +25,7 @@ pub struct TestAppContext { pub dispatcher: TestDispatcher, test_platform: Rc, text_system: Arc, + fn_name: Option<&'static str>, } impl Context for TestAppContext { @@ -85,7 +86,7 @@ impl Context for TestAppContext { impl TestAppContext { /// Creates a new `TestAppContext`. Usually you can rely on `#[gpui::test]` to do this for you. - pub fn new(dispatcher: TestDispatcher) -> Self { + pub fn new(dispatcher: TestDispatcher, fn_name: Option<&'static str>) -> Self { let arc_dispatcher = Arc::new(dispatcher.clone()); let background_executor = BackgroundExecutor::new(arc_dispatcher.clone()); let foreground_executor = ForegroundExecutor::new(arc_dispatcher); @@ -101,12 +102,18 @@ impl TestAppContext { dispatcher: dispatcher.clone(), test_platform: platform, text_system, + fn_name, } } + /// The name of the test function that created this `TestAppContext` + pub fn test_function_name(&self) -> Option<&'static str> { + self.fn_name + } + /// returns a new `TestAppContext` re-using the same executors to interleave tasks. pub fn new_app(&self) -> TestAppContext { - Self::new(self.dispatcher.clone()) + Self::new(self.dispatcher.clone(), self.fn_name) } /// Simulates quitting the app. diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index 45097411d13875c7b1a8fecc4888711dbc0d9dd3..627a2ac339d631c666926d4fc8e1354396cb36f7 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -1003,7 +1003,7 @@ impl Interactivity { if let Some(text) = cx .text_system() .shape_text( - &element_id, + element_id.into(), FONT_SIZE, &[cx.text_style().to_run(str_len)], None, @@ -1055,22 +1055,11 @@ impl Interactivity { }; eprintln!( - "This element is created at:\n{}:{}:{}", - location.file(), + "This element was created at:\n{}:{}:{}", + dir.join(location.file()).to_string_lossy(), location.line(), location.column() ); - - std::process::Command::new("zed") - .arg(format!( - "{}/{}:{}:{}", - dir.to_string_lossy(), - location.file(), - location.line(), - location.column() - )) - .spawn() - .ok(); } } }); diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 29c93fd19e91518a96a5f663352b92519264aca9..4e5c6721472398233a457573a56d27d43881c071 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -202,7 +202,10 @@ impl TextState { let Some(lines) = cx .text_system() .shape_text( - &text, font_size, &runs, wrap_width, // Wrap if we know the width. + text.clone(), + font_size, + &runs, + wrap_width, // Wrap if we know the width. ) .log_err() else { diff --git a/crates/gpui/src/style.rs b/crates/gpui/src/style.rs index 244ccebf2498fb9ff275d0818215a9ba658ffc02..a21957611d09feb25f59d4a842ab9b998e83b4d4 100644 --- a/crates/gpui/src/style.rs +++ b/crates/gpui/src/style.rs @@ -165,7 +165,8 @@ impl Default for TextStyle { fn default() -> Self { TextStyle { color: black(), - font_family: "Helvetica".into(), // todo!("Get a font we know exists on the system") + // Helvetica is a web safe font, so it should be available + font_family: "Helvetica".into(), font_features: FontFeatures::default(), font_size: rems(1.).into(), line_height: phi(), diff --git a/crates/gpui/src/test.rs b/crates/gpui/src/test.rs index 1771f29c67b13639fbb7b87029840c435b6a681d..f53d19fdc8b1028bdddba0957719e05b3af4d69d 100644 --- a/crates/gpui/src/test.rs +++ b/crates/gpui/src/test.rs @@ -39,7 +39,6 @@ pub fn run_test( max_retries: usize, test_fn: &mut (dyn RefUnwindSafe + Fn(TestDispatcher, u64)), on_fail_fn: Option, - _fn_name: String, // todo!("re-enable fn_name") ) { let starting_seed = env::var("SEED") .map(|seed| seed.parse().expect("invalid SEED variable")) diff --git a/crates/gpui/src/text_system.rs b/crates/gpui/src/text_system.rs index 0969560e95d62e6d74dc82e88eb4b13958a77480..47073bcde0ef77b7b6674d0c0a24b7dfa107e948 100644 --- a/crates/gpui/src/text_system.rs +++ b/crates/gpui/src/text_system.rs @@ -258,7 +258,7 @@ impl TextSystem { pub fn shape_text( &self, - text: &str, // todo!("pass a SharedString and preserve it when passed a single line?") + text: SharedString, font_size: Pixels, runs: &[TextRun], wrap_width: Option, @@ -268,8 +268,8 @@ impl TextSystem { let mut lines = SmallVec::new(); let mut line_start = 0; - for line_text in text.split('\n') { - let line_text = SharedString::from(line_text.to_string()); + + let mut process_line = |line_text: SharedString| { let line_end = line_start + line_text.len(); let mut last_font: Option = None; @@ -335,6 +335,24 @@ impl TextSystem { } font_runs.clear(); + }; + + let mut split_lines = text.split('\n'); + let mut processed = false; + + if let Some(first_line) = split_lines.next() { + if let Some(second_line) = split_lines.next() { + processed = true; + process_line(first_line.to_string().into()); + process_line(second_line.to_string().into()); + for line_text in split_lines { + process_line(line_text.to_string().into()); + } + } + } + + if !processed { + process_line(text); } self.font_runs_pool.lock().push(font_runs); diff --git a/crates/gpui/src/text_system/line_wrapper.rs b/crates/gpui/src/text_system/line_wrapper.rs index e2f0a8a5fdbce9c0e3f81c9fb018bdf517b1db7c..79013adbb2c83cd0e8e816ca5ef7bb88618b5ae8 100644 --- a/crates/gpui/src/text_system/line_wrapper.rs +++ b/crates/gpui/src/text_system/line_wrapper.rs @@ -143,7 +143,7 @@ mod tests { #[test] fn test_wrap_line() { let dispatcher = TestDispatcher::new(StdRng::seed_from_u64(0)); - let cx = TestAppContext::new(dispatcher); + let cx = TestAppContext::new(dispatcher, None); cx.update(|cx| { let text_system = cx.text_system().clone(); diff --git a/crates/gpui_macros/src/test.rs b/crates/gpui_macros/src/test.rs index 70c6da22d5a7ab888f586d87f2d8ad261089d1bf..ee3f8f713701cfc334a1343902edf29fddd781d2 100644 --- a/crates/gpui_macros/src/test.rs +++ b/crates/gpui_macros/src/test.rs @@ -106,7 +106,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { let cx_varname = format_ident!("cx_{}", ix); cx_vars.extend(quote!( let mut #cx_varname = gpui::TestAppContext::new( - dispatcher.clone() + dispatcher.clone(), + Some(stringify!(#outer_fn_name)), ); )); cx_teardowns.extend(quote!( @@ -140,8 +141,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { executor.block_test(#inner_fn_name(#inner_fn_args)); #cx_teardowns }, - #on_failure_fn_name, - stringify!(#outer_fn_name).to_string(), + #on_failure_fn_name ); } } @@ -169,7 +169,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { let cx_varname_lock = format_ident!("cx_{}_lock", ix); cx_vars.extend(quote!( let mut #cx_varname = gpui::TestAppContext::new( - dispatcher.clone() + dispatcher.clone(), + Some(stringify!(#outer_fn_name)) ); let mut #cx_varname_lock = #cx_varname.app.borrow_mut(); )); @@ -186,7 +187,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { let cx_varname = format_ident!("cx_{}", ix); cx_vars.extend(quote!( let mut #cx_varname = gpui::TestAppContext::new( - dispatcher.clone() + dispatcher.clone(), + Some(stringify!(#outer_fn_name)) ); )); cx_teardowns.extend(quote!( @@ -222,7 +224,6 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { #cx_teardowns }, #on_failure_fn_name, - stringify!(#outer_fn_name).to_string(), ); } }