diff --git a/crates/editor2/src/display_map/wrap_map.rs b/crates/editor2/src/display_map/wrap_map.rs index c8025c7da9..c2325fa96d 100644 --- a/crates/editor2/src/display_map/wrap_map.rs +++ b/crates/editor2/src/display_map/wrap_map.rs @@ -1026,337 +1026,337 @@ fn consolidate_wrap_edits(edits: &mut Vec) { } } -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap}, - MultiBuffer, - }; - use gpui::test::observe; - use rand::prelude::*; - use settings::SettingsStore; - use smol::stream::StreamExt; - use std::{cmp, env, num::NonZeroU32}; - use text::Rope; +// #[cfg(test)] +// mod tests { +// use super::*; +// use crate::{ +// display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap}, +// MultiBuffer, +// }; +// use gpui::test::observe; +// use rand::prelude::*; +// use settings::SettingsStore; +// use smol::stream::StreamExt; +// use std::{cmp, env, num::NonZeroU32}; +// use text::Rope; - #[gpui::test(iterations = 100)] - async fn test_random_wraps(cx: &mut gpui::TestAppContext, mut rng: StdRng) { - init_test(cx); +// #[gpui::test(iterations = 100)] +// async fn test_random_wraps(cx: &mut gpui::TestAppContext, mut rng: StdRng) { +// init_test(cx); - cx.background_executor.set_block_on_ticks(0..=50); - let operations = env::var("OPERATIONS") - .map(|i| i.parse().expect("invalid `OPERATIONS` variable")) - .unwrap_or(10); +// cx.background_executor.set_block_on_ticks(0..=50); +// let operations = env::var("OPERATIONS") +// .map(|i| i.parse().expect("invalid `OPERATIONS` variable")) +// .unwrap_or(10); - let font_cache = cx.read(|cx| cx.font_cache().clone()); - let font_system = cx.platform().fonts(); - let mut wrap_width = if rng.gen_bool(0.1) { - None - } else { - Some(rng.gen_range(0.0..=1000.0)) - }; - let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); - let family_id = font_cache - .load_family(&["Helvetica"], &Default::default()) - .unwrap(); - let font_id = font_cache - .select_font(family_id, &Default::default()) - .unwrap(); - let font_size = 14.0; +// let font_cache = cx.read(|cx| cx.font_cache().clone()); +// let font_system = cx.platform().fonts(); +// let mut wrap_width = if rng.gen_bool(0.1) { +// None +// } else { +// Some(rng.gen_range(0.0..=1000.0)) +// }; +// let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); +// let family_id = font_cache +// .load_family(&["Helvetica"], &Default::default()) +// .unwrap(); +// let font_id = font_cache +// .select_font(family_id, &Default::default()) +// .unwrap(); +// let font_size = 14.0; - log::info!("Tab size: {}", tab_size); - log::info!("Wrap width: {:?}", wrap_width); +// log::info!("Tab size: {}", tab_size); +// log::info!("Wrap width: {:?}", wrap_width); - let buffer = cx.update(|cx| { - if rng.gen() { - MultiBuffer::build_random(&mut rng, cx) - } else { - let len = rng.gen_range(0..10); - let text = util::RandomCharIter::new(&mut rng) - .take(len) - .collect::(); - MultiBuffer::build_simple(&text, cx) - } - }); - let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); - log::info!("Buffer text: {:?}", buffer_snapshot.text()); - let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone()); - log::info!("InlayMap text: {:?}", inlay_snapshot.text()); - let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone()); - log::info!("FoldMap text: {:?}", fold_snapshot.text()); - let (mut tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size); - let tabs_snapshot = tab_map.set_max_expansion_column(32); - log::info!("TabMap text: {:?}", tabs_snapshot.text()); +// let buffer = cx.update(|cx| { +// if rng.gen() { +// MultiBuffer::build_random(&mut rng, cx) +// } else { +// let len = rng.gen_range(0..10); +// let text = util::RandomCharIter::new(&mut rng) +// .take(len) +// .collect::(); +// MultiBuffer::build_simple(&text, cx) +// } +// }); +// let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); +// log::info!("Buffer text: {:?}", buffer_snapshot.text()); +// let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone()); +// log::info!("InlayMap text: {:?}", inlay_snapshot.text()); +// let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone()); +// log::info!("FoldMap text: {:?}", fold_snapshot.text()); +// let (mut tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size); +// let tabs_snapshot = tab_map.set_max_expansion_column(32); +// log::info!("TabMap text: {:?}", tabs_snapshot.text()); - let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system); - let unwrapped_text = tabs_snapshot.text(); - let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); +// let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system); +// let unwrapped_text = tabs_snapshot.text(); +// let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); - let (wrap_map, _) = - cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx)); - let mut notifications = observe(&wrap_map, cx); +// let (wrap_map, _) = +// cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx)); +// let mut notifications = observe(&wrap_map, cx); - if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { - notifications.next().await.unwrap(); - } +// if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { +// notifications.next().await.unwrap(); +// } - let (initial_snapshot, _) = wrap_map.update(cx, |map, cx| { - assert!(!map.is_rewrapping()); - map.sync(tabs_snapshot.clone(), Vec::new(), cx) - }); +// let (initial_snapshot, _) = wrap_map.update(cx, |map, cx| { +// assert!(!map.is_rewrapping()); +// map.sync(tabs_snapshot.clone(), Vec::new(), cx) +// }); - let actual_text = initial_snapshot.text(); - assert_eq!( - actual_text, expected_text, - "unwrapped text is: {:?}", - unwrapped_text - ); - log::info!("Wrapped text: {:?}", actual_text); +// let actual_text = initial_snapshot.text(); +// assert_eq!( +// actual_text, expected_text, +// "unwrapped text is: {:?}", +// unwrapped_text +// ); +// log::info!("Wrapped text: {:?}", actual_text); - let mut next_inlay_id = 0; - let mut edits = Vec::new(); - for _i in 0..operations { - log::info!("{} ==============================================", _i); +// let mut next_inlay_id = 0; +// let mut edits = Vec::new(); +// for _i in 0..operations { +// log::info!("{} ==============================================", _i); - let mut buffer_edits = Vec::new(); - match rng.gen_range(0..=100) { - 0..=19 => { - wrap_width = if rng.gen_bool(0.2) { - None - } else { - Some(rng.gen_range(0.0..=1000.0)) - }; - log::info!("Setting wrap width to {:?}", wrap_width); - wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx)); - } - 20..=39 => { - for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) { - let (tabs_snapshot, tab_edits) = - tab_map.sync(fold_snapshot, fold_edits, tab_size); - let (mut snapshot, wrap_edits) = - wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); - snapshot.check_invariants(); - snapshot.verify_chunks(&mut rng); - edits.push((snapshot, wrap_edits)); - } - } - 40..=59 => { - let (inlay_snapshot, inlay_edits) = - inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng); - let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits); - let (tabs_snapshot, tab_edits) = - tab_map.sync(fold_snapshot, fold_edits, tab_size); - let (mut snapshot, wrap_edits) = - wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); - snapshot.check_invariants(); - snapshot.verify_chunks(&mut rng); - edits.push((snapshot, wrap_edits)); - } - _ => { - buffer.update(cx, |buffer, cx| { - let subscription = buffer.subscribe(); - let edit_count = rng.gen_range(1..=5); - buffer.randomly_mutate(&mut rng, edit_count, cx); - buffer_snapshot = buffer.snapshot(cx); - buffer_edits.extend(subscription.consume()); - }); - } - } +// let mut buffer_edits = Vec::new(); +// match rng.gen_range(0..=100) { +// 0..=19 => { +// wrap_width = if rng.gen_bool(0.2) { +// None +// } else { +// Some(rng.gen_range(0.0..=1000.0)) +// }; +// log::info!("Setting wrap width to {:?}", wrap_width); +// wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx)); +// } +// 20..=39 => { +// for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) { +// let (tabs_snapshot, tab_edits) = +// tab_map.sync(fold_snapshot, fold_edits, tab_size); +// let (mut snapshot, wrap_edits) = +// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); +// snapshot.check_invariants(); +// snapshot.verify_chunks(&mut rng); +// edits.push((snapshot, wrap_edits)); +// } +// } +// 40..=59 => { +// let (inlay_snapshot, inlay_edits) = +// inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng); +// let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits); +// let (tabs_snapshot, tab_edits) = +// tab_map.sync(fold_snapshot, fold_edits, tab_size); +// let (mut snapshot, wrap_edits) = +// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); +// snapshot.check_invariants(); +// snapshot.verify_chunks(&mut rng); +// edits.push((snapshot, wrap_edits)); +// } +// _ => { +// buffer.update(cx, |buffer, cx| { +// let subscription = buffer.subscribe(); +// let edit_count = rng.gen_range(1..=5); +// buffer.randomly_mutate(&mut rng, edit_count, cx); +// buffer_snapshot = buffer.snapshot(cx); +// buffer_edits.extend(subscription.consume()); +// }); +// } +// } - log::info!("Buffer text: {:?}", buffer_snapshot.text()); - let (inlay_snapshot, inlay_edits) = - inlay_map.sync(buffer_snapshot.clone(), buffer_edits); - log::info!("InlayMap text: {:?}", inlay_snapshot.text()); - let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits); - log::info!("FoldMap text: {:?}", fold_snapshot.text()); - let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size); - log::info!("TabMap text: {:?}", tabs_snapshot.text()); +// log::info!("Buffer text: {:?}", buffer_snapshot.text()); +// let (inlay_snapshot, inlay_edits) = +// inlay_map.sync(buffer_snapshot.clone(), buffer_edits); +// log::info!("InlayMap text: {:?}", inlay_snapshot.text()); +// let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits); +// log::info!("FoldMap text: {:?}", fold_snapshot.text()); +// let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size); +// log::info!("TabMap text: {:?}", tabs_snapshot.text()); - let unwrapped_text = tabs_snapshot.text(); - let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); - let (mut snapshot, wrap_edits) = - wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), tab_edits, cx)); - snapshot.check_invariants(); - snapshot.verify_chunks(&mut rng); - edits.push((snapshot, wrap_edits)); +// let unwrapped_text = tabs_snapshot.text(); +// let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); +// let (mut snapshot, wrap_edits) = +// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), tab_edits, cx)); +// snapshot.check_invariants(); +// snapshot.verify_chunks(&mut rng); +// edits.push((snapshot, wrap_edits)); - if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) && rng.gen_bool(0.4) { - log::info!("Waiting for wrapping to finish"); - while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { - notifications.next().await.unwrap(); - } - wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty())); - } +// if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) && rng.gen_bool(0.4) { +// log::info!("Waiting for wrapping to finish"); +// while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { +// notifications.next().await.unwrap(); +// } +// wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty())); +// } - if !wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { - let (mut wrapped_snapshot, wrap_edits) = - wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx)); - let actual_text = wrapped_snapshot.text(); - let actual_longest_row = wrapped_snapshot.longest_row(); - log::info!("Wrapping finished: {:?}", actual_text); - wrapped_snapshot.check_invariants(); - wrapped_snapshot.verify_chunks(&mut rng); - edits.push((wrapped_snapshot.clone(), wrap_edits)); - assert_eq!( - actual_text, expected_text, - "unwrapped text is: {:?}", - unwrapped_text - ); +// if !wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { +// let (mut wrapped_snapshot, wrap_edits) = +// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx)); +// let actual_text = wrapped_snapshot.text(); +// let actual_longest_row = wrapped_snapshot.longest_row(); +// log::info!("Wrapping finished: {:?}", actual_text); +// wrapped_snapshot.check_invariants(); +// wrapped_snapshot.verify_chunks(&mut rng); +// edits.push((wrapped_snapshot.clone(), wrap_edits)); +// assert_eq!( +// actual_text, expected_text, +// "unwrapped text is: {:?}", +// unwrapped_text +// ); - let mut summary = TextSummary::default(); - for (ix, item) in wrapped_snapshot - .transforms - .items(&()) - .into_iter() - .enumerate() - { - summary += &item.summary.output; - log::info!("{} summary: {:?}", ix, item.summary.output,); - } +// let mut summary = TextSummary::default(); +// for (ix, item) in wrapped_snapshot +// .transforms +// .items(&()) +// .into_iter() +// .enumerate() +// { +// summary += &item.summary.output; +// log::info!("{} summary: {:?}", ix, item.summary.output,); +// } - if tab_size.get() == 1 - || !wrapped_snapshot - .tab_snapshot - .fold_snapshot - .text() - .contains('\t') - { - let mut expected_longest_rows = Vec::new(); - let mut longest_line_len = -1; - for (row, line) in expected_text.split('\n').enumerate() { - let line_char_count = line.chars().count() as isize; - if line_char_count > longest_line_len { - expected_longest_rows.clear(); - longest_line_len = line_char_count; - } - if line_char_count >= longest_line_len { - expected_longest_rows.push(row as u32); - } - } +// if tab_size.get() == 1 +// || !wrapped_snapshot +// .tab_snapshot +// .fold_snapshot +// .text() +// .contains('\t') +// { +// let mut expected_longest_rows = Vec::new(); +// let mut longest_line_len = -1; +// for (row, line) in expected_text.split('\n').enumerate() { +// let line_char_count = line.chars().count() as isize; +// if line_char_count > longest_line_len { +// expected_longest_rows.clear(); +// longest_line_len = line_char_count; +// } +// if line_char_count >= longest_line_len { +// expected_longest_rows.push(row as u32); +// } +// } - assert!( - expected_longest_rows.contains(&actual_longest_row), - "incorrect longest row {}. expected {:?} with length {}", - actual_longest_row, - expected_longest_rows, - longest_line_len, - ) - } - } - } +// assert!( +// expected_longest_rows.contains(&actual_longest_row), +// "incorrect longest row {}. expected {:?} with length {}", +// actual_longest_row, +// expected_longest_rows, +// longest_line_len, +// ) +// } +// } +// } - let mut initial_text = Rope::from(initial_snapshot.text().as_str()); - for (snapshot, patch) in edits { - let snapshot_text = Rope::from(snapshot.text().as_str()); - for edit in &patch { - let old_start = initial_text.point_to_offset(Point::new(edit.new.start, 0)); - let old_end = initial_text.point_to_offset(cmp::min( - Point::new(edit.new.start + edit.old.len() as u32, 0), - initial_text.max_point(), - )); - let new_start = snapshot_text.point_to_offset(Point::new(edit.new.start, 0)); - let new_end = snapshot_text.point_to_offset(cmp::min( - Point::new(edit.new.end, 0), - snapshot_text.max_point(), - )); - let new_text = snapshot_text - .chunks_in_range(new_start..new_end) - .collect::(); +// let mut initial_text = Rope::from(initial_snapshot.text().as_str()); +// for (snapshot, patch) in edits { +// let snapshot_text = Rope::from(snapshot.text().as_str()); +// for edit in &patch { +// let old_start = initial_text.point_to_offset(Point::new(edit.new.start, 0)); +// let old_end = initial_text.point_to_offset(cmp::min( +// Point::new(edit.new.start + edit.old.len() as u32, 0), +// initial_text.max_point(), +// )); +// let new_start = snapshot_text.point_to_offset(Point::new(edit.new.start, 0)); +// let new_end = snapshot_text.point_to_offset(cmp::min( +// Point::new(edit.new.end, 0), +// snapshot_text.max_point(), +// )); +// let new_text = snapshot_text +// .chunks_in_range(new_start..new_end) +// .collect::(); - initial_text.replace(old_start..old_end, &new_text); - } - assert_eq!(initial_text.to_string(), snapshot_text.to_string()); - } +// initial_text.replace(old_start..old_end, &new_text); +// } +// assert_eq!(initial_text.to_string(), snapshot_text.to_string()); +// } - if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { - log::info!("Waiting for wrapping to finish"); - while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { - notifications.next().await.unwrap(); - } - } - wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty())); - } +// if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { +// log::info!("Waiting for wrapping to finish"); +// while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { +// notifications.next().await.unwrap(); +// } +// } +// wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty())); +// } - fn init_test(cx: &mut gpui::TestAppContext) { - cx.foreground_executor().forbid_parking(); - cx.update(|cx| { - cx.set_global(SettingsStore::test(cx)); - theme::init((), cx); - }); - } +// fn init_test(cx: &mut gpui::TestAppContext) { +// cx.foreground_executor().forbid_parking(); +// cx.update(|cx| { +// cx.set_global(SettingsStore::test(cx)); +// theme::init((), cx); +// }); +// } - fn wrap_text( - unwrapped_text: &str, - wrap_width: Option, - line_wrapper: &mut LineWrapper, - ) -> String { - if let Some(wrap_width) = wrap_width { - let mut wrapped_text = String::new(); - for (row, line) in unwrapped_text.split('\n').enumerate() { - if row > 0 { - wrapped_text.push('\n') - } +// fn wrap_text( +// unwrapped_text: &str, +// wrap_width: Option, +// line_wrapper: &mut LineWrapper, +// ) -> String { +// if let Some(wrap_width) = wrap_width { +// let mut wrapped_text = String::new(); +// for (row, line) in unwrapped_text.split('\n').enumerate() { +// if row > 0 { +// wrapped_text.push('\n') +// } - let mut prev_ix = 0; - for boundary in line_wrapper.wrap_line(line, wrap_width) { - wrapped_text.push_str(&line[prev_ix..boundary.ix]); - wrapped_text.push('\n'); - wrapped_text.push_str(&" ".repeat(boundary.next_indent as usize)); - prev_ix = boundary.ix; - } - wrapped_text.push_str(&line[prev_ix..]); - } - wrapped_text - } else { - unwrapped_text.to_string() - } - } +// let mut prev_ix = 0; +// for boundary in line_wrapper.wrap_line(line, wrap_width) { +// wrapped_text.push_str(&line[prev_ix..boundary.ix]); +// wrapped_text.push('\n'); +// wrapped_text.push_str(&" ".repeat(boundary.next_indent as usize)); +// prev_ix = boundary.ix; +// } +// wrapped_text.push_str(&line[prev_ix..]); +// } +// wrapped_text +// } else { +// unwrapped_text.to_string() +// } +// } - impl WrapSnapshot { - pub fn text(&self) -> String { - self.text_chunks(0).collect() - } +// impl WrapSnapshot { +// pub fn text(&self) -> String { +// self.text_chunks(0).collect() +// } - pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator { - self.chunks( - wrap_row..self.max_point().row() + 1, - false, - Highlights::default(), - ) - .map(|h| h.text) - } +// pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator { +// self.chunks( +// wrap_row..self.max_point().row() + 1, +// false, +// Highlights::default(), +// ) +// .map(|h| h.text) +// } - fn verify_chunks(&mut self, rng: &mut impl Rng) { - for _ in 0..5 { - let mut end_row = rng.gen_range(0..=self.max_point().row()); - let start_row = rng.gen_range(0..=end_row); - end_row += 1; +// fn verify_chunks(&mut self, rng: &mut impl Rng) { +// for _ in 0..5 { +// let mut end_row = rng.gen_range(0..=self.max_point().row()); +// let start_row = rng.gen_range(0..=end_row); +// end_row += 1; - let mut expected_text = self.text_chunks(start_row).collect::(); - if expected_text.ends_with('\n') { - expected_text.push('\n'); - } - let mut expected_text = expected_text - .lines() - .take((end_row - start_row) as usize) - .collect::>() - .join("\n"); - if end_row <= self.max_point().row() { - expected_text.push('\n'); - } +// let mut expected_text = self.text_chunks(start_row).collect::(); +// if expected_text.ends_with('\n') { +// expected_text.push('\n'); +// } +// let mut expected_text = expected_text +// .lines() +// .take((end_row - start_row) as usize) +// .collect::>() +// .join("\n"); +// if end_row <= self.max_point().row() { +// expected_text.push('\n'); +// } - let actual_text = self - .chunks(start_row..end_row, true, Highlights::default()) - .map(|c| c.text) - .collect::(); - assert_eq!( - expected_text, - actual_text, - "chunks != highlighted_chunks for rows {:?}", - start_row..end_row - ); - } - } - } -} +// let actual_text = self +// .chunks(start_row..end_row, true, Highlights::default()) +// .map(|c| c.text) +// .collect::(); +// assert_eq!( +// expected_text, +// actual_text, +// "chunks != highlighted_chunks for rows {:?}", +// start_row..end_row +// ); +// } +// } +// } +// } diff --git a/crates/editor2/src/inlay_hint_cache.rs b/crates/editor2/src/inlay_hint_cache.rs index 1610c4826e..36b4e6af66 100644 --- a/crates/editor2/src/inlay_hint_cache.rs +++ b/crates/editor2/src/inlay_hint_cache.rs @@ -2401,346 +2401,346 @@ pub mod tests { }); } - #[gpui::test(iterations = 10)] - async fn test_multiple_excerpts_large_multibuffer(cx: &mut gpui::TestAppContext) { - init_test(cx, |settings| { - settings.defaults.inlay_hints = Some(InlayHintSettings { - enabled: true, - show_type_hints: true, - show_parameter_hints: true, - show_other_hints: true, - }) - }); + // #[gpui::test(iterations = 10)] + // async fn test_multiple_excerpts_large_multibuffer(cx: &mut gpui::TestAppContext) { + // init_test(cx, |settings| { + // settings.defaults.inlay_hints = Some(InlayHintSettings { + // enabled: true, + // show_type_hints: true, + // show_parameter_hints: true, + // show_other_hints: true, + // }) + // }); - let mut language = Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ); - let mut fake_servers = language - .set_fake_lsp_adapter(Arc::new(FakeLspAdapter { - capabilities: lsp::ServerCapabilities { - inlay_hint_provider: Some(lsp::OneOf::Left(true)), - ..Default::default() - }, - ..Default::default() - })) - .await; - let language = Arc::new(language); - let fs = FakeFs::new(cx.background_executor.clone()); - fs.insert_tree( - "/a", - json!({ - "main.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|i| format!("let i = {i};\n")).collect::>().join("")), - "other.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|j| format!("let j = {j};\n")).collect::>().join("")), - }), - ) - .await; - let project = Project::test(fs, ["/a".as_ref()], cx).await; - project.update(cx, |project, _| { - project.languages().add(Arc::clone(&language)) - }); - let worktree_id = project.update(cx, |project, cx| { - project.worktrees().next().unwrap().read(cx).id() - }); + // let mut language = Language::new( + // LanguageConfig { + // name: "Rust".into(), + // path_suffixes: vec!["rs".to_string()], + // ..Default::default() + // }, + // Some(tree_sitter_rust::language()), + // ); + // let mut fake_servers = language + // .set_fake_lsp_adapter(Arc::new(FakeLspAdapter { + // capabilities: lsp::ServerCapabilities { + // inlay_hint_provider: Some(lsp::OneOf::Left(true)), + // ..Default::default() + // }, + // ..Default::default() + // })) + // .await; + // let language = Arc::new(language); + // let fs = FakeFs::new(cx.background_executor.clone()); + // fs.insert_tree( + // "/a", + // json!({ + // "main.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|i| format!("let i = {i};\n")).collect::>().join("")), + // "other.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|j| format!("let j = {j};\n")).collect::>().join("")), + // }), + // ) + // .await; + // let project = Project::test(fs, ["/a".as_ref()], cx).await; + // project.update(cx, |project, _| { + // project.languages().add(Arc::clone(&language)) + // }); + // let worktree_id = project.update(cx, |project, cx| { + // project.worktrees().next().unwrap().read(cx).id() + // }); - let buffer_1 = project - .update(cx, |project, cx| { - project.open_buffer((worktree_id, "main.rs"), cx) - }) - .await - .unwrap(); - let buffer_2 = project - .update(cx, |project, cx| { - project.open_buffer((worktree_id, "other.rs"), cx) - }) - .await - .unwrap(); - let multibuffer = cx.build_model(|cx| { - let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpts( - buffer_1.clone(), - [ - ExcerptRange { - context: Point::new(0, 0)..Point::new(2, 0), - primary: None, - }, - ExcerptRange { - context: Point::new(4, 0)..Point::new(11, 0), - primary: None, - }, - ExcerptRange { - context: Point::new(22, 0)..Point::new(33, 0), - primary: None, - }, - ExcerptRange { - context: Point::new(44, 0)..Point::new(55, 0), - primary: None, - }, - ExcerptRange { - context: Point::new(56, 0)..Point::new(66, 0), - primary: None, - }, - ExcerptRange { - context: Point::new(67, 0)..Point::new(77, 0), - primary: None, - }, - ], - cx, - ); - multibuffer.push_excerpts( - buffer_2.clone(), - [ - ExcerptRange { - context: Point::new(0, 1)..Point::new(2, 1), - primary: None, - }, - ExcerptRange { - context: Point::new(4, 1)..Point::new(11, 1), - primary: None, - }, - ExcerptRange { - context: Point::new(22, 1)..Point::new(33, 1), - primary: None, - }, - ExcerptRange { - context: Point::new(44, 1)..Point::new(55, 1), - primary: None, - }, - ExcerptRange { - context: Point::new(56, 1)..Point::new(66, 1), - primary: None, - }, - ExcerptRange { - context: Point::new(67, 1)..Point::new(77, 1), - primary: None, - }, - ], - cx, - ); - multibuffer - }); + // let buffer_1 = project + // .update(cx, |project, cx| { + // project.open_buffer((worktree_id, "main.rs"), cx) + // }) + // .await + // .unwrap(); + // let buffer_2 = project + // .update(cx, |project, cx| { + // project.open_buffer((worktree_id, "other.rs"), cx) + // }) + // .await + // .unwrap(); + // let multibuffer = cx.build_model(|cx| { + // let mut multibuffer = MultiBuffer::new(0); + // multibuffer.push_excerpts( + // buffer_1.clone(), + // [ + // ExcerptRange { + // context: Point::new(0, 0)..Point::new(2, 0), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(4, 0)..Point::new(11, 0), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(22, 0)..Point::new(33, 0), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(44, 0)..Point::new(55, 0), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(56, 0)..Point::new(66, 0), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(67, 0)..Point::new(77, 0), + // primary: None, + // }, + // ], + // cx, + // ); + // multibuffer.push_excerpts( + // buffer_2.clone(), + // [ + // ExcerptRange { + // context: Point::new(0, 1)..Point::new(2, 1), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(4, 1)..Point::new(11, 1), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(22, 1)..Point::new(33, 1), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(44, 1)..Point::new(55, 1), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(56, 1)..Point::new(66, 1), + // primary: None, + // }, + // ExcerptRange { + // context: Point::new(67, 1)..Point::new(77, 1), + // primary: None, + // }, + // ], + // cx, + // ); + // multibuffer + // }); - cx.executor().run_until_parked(); - let editor = - cx.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)); - let editor_edited = Arc::new(AtomicBool::new(false)); - let fake_server = fake_servers.next().await.unwrap(); - let closure_editor_edited = Arc::clone(&editor_edited); - fake_server - .handle_request::(move |params, _| { - let task_editor_edited = Arc::clone(&closure_editor_edited); - async move { - let hint_text = if params.text_document.uri - == lsp::Url::from_file_path("/a/main.rs").unwrap() - { - "main hint" - } else if params.text_document.uri - == lsp::Url::from_file_path("/a/other.rs").unwrap() - { - "other hint" - } else { - panic!("unexpected uri: {:?}", params.text_document.uri); - }; + // cx.executor().run_until_parked(); + // let editor = + // cx.add_window(|cx| Editor::for_multibuffer(multibuffer, Some(project.clone()), cx)); + // let editor_edited = Arc::new(AtomicBool::new(false)); + // let fake_server = fake_servers.next().await.unwrap(); + // let closure_editor_edited = Arc::clone(&editor_edited); + // fake_server + // .handle_request::(move |params, _| { + // let task_editor_edited = Arc::clone(&closure_editor_edited); + // async move { + // let hint_text = if params.text_document.uri + // == lsp::Url::from_file_path("/a/main.rs").unwrap() + // { + // "main hint" + // } else if params.text_document.uri + // == lsp::Url::from_file_path("/a/other.rs").unwrap() + // { + // "other hint" + // } else { + // panic!("unexpected uri: {:?}", params.text_document.uri); + // }; - // one hint per excerpt - let positions = [ - lsp::Position::new(0, 2), - lsp::Position::new(4, 2), - lsp::Position::new(22, 2), - lsp::Position::new(44, 2), - lsp::Position::new(56, 2), - lsp::Position::new(67, 2), - ]; - let out_of_range_hint = lsp::InlayHint { - position: lsp::Position::new( - params.range.start.line + 99, - params.range.start.character + 99, - ), - label: lsp::InlayHintLabel::String( - "out of excerpt range, should be ignored".to_string(), - ), - kind: None, - text_edits: None, - tooltip: None, - padding_left: None, - padding_right: None, - data: None, - }; + // // one hint per excerpt + // let positions = [ + // lsp::Position::new(0, 2), + // lsp::Position::new(4, 2), + // lsp::Position::new(22, 2), + // lsp::Position::new(44, 2), + // lsp::Position::new(56, 2), + // lsp::Position::new(67, 2), + // ]; + // let out_of_range_hint = lsp::InlayHint { + // position: lsp::Position::new( + // params.range.start.line + 99, + // params.range.start.character + 99, + // ), + // label: lsp::InlayHintLabel::String( + // "out of excerpt range, should be ignored".to_string(), + // ), + // kind: None, + // text_edits: None, + // tooltip: None, + // padding_left: None, + // padding_right: None, + // data: None, + // }; - let edited = task_editor_edited.load(Ordering::Acquire); - Ok(Some( - std::iter::once(out_of_range_hint) - .chain(positions.into_iter().enumerate().map(|(i, position)| { - lsp::InlayHint { - position, - label: lsp::InlayHintLabel::String(format!( - "{hint_text}{} #{i}", - if edited { "(edited)" } else { "" }, - )), - kind: None, - text_edits: None, - tooltip: None, - padding_left: None, - padding_right: None, - data: None, - } - })) - .collect(), - )) - } - }) - .next() - .await; - cx.executor().run_until_parked(); + // let edited = task_editor_edited.load(Ordering::Acquire); + // Ok(Some( + // std::iter::once(out_of_range_hint) + // .chain(positions.into_iter().enumerate().map(|(i, position)| { + // lsp::InlayHint { + // position, + // label: lsp::InlayHintLabel::String(format!( + // "{hint_text}{} #{i}", + // if edited { "(edited)" } else { "" }, + // )), + // kind: None, + // text_edits: None, + // tooltip: None, + // padding_left: None, + // padding_right: None, + // data: None, + // } + // })) + // .collect(), + // )) + // } + // }) + // .next() + // .await; + // cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { - let expected_hints = vec![ - "main hint #0".to_string(), - "main hint #1".to_string(), - "main hint #2".to_string(), - "main hint #3".to_string(), - // todo!() there used to be no these hints, but new gpui2 presumably scrolls a bit farther - // (or renders less?) note that tests below pass - "main hint #4".to_string(), - "main hint #5".to_string(), - ]; - assert_eq!( - expected_hints, - cached_hint_labels(editor), - "When scroll is at the edge of a multibuffer, its visible excerpts only should be queried for inlay hints" - ); - assert_eq!(expected_hints, visible_hint_labels(editor, cx)); - assert_eq!(editor.inlay_hint_cache().version, expected_hints.len(), "Every visible excerpt hints should bump the verison"); - }); + // editor.update(cx, |editor, cx| { + // let expected_hints = vec![ + // "main hint #0".to_string(), + // "main hint #1".to_string(), + // "main hint #2".to_string(), + // "main hint #3".to_string(), + // // todo!() there used to be no these hints, but new gpui2 presumably scrolls a bit farther + // // (or renders less?) note that tests below pass + // "main hint #4".to_string(), + // "main hint #5".to_string(), + // ]; + // assert_eq!( + // expected_hints, + // cached_hint_labels(editor), + // "When scroll is at the edge of a multibuffer, its visible excerpts only should be queried for inlay hints" + // ); + // assert_eq!(expected_hints, visible_hint_labels(editor, cx)); + // assert_eq!(editor.inlay_hint_cache().version, expected_hints.len(), "Every visible excerpt hints should bump the verison"); + // }); - editor.update(cx, |editor, cx| { - editor.change_selections(Some(Autoscroll::Next), cx, |s| { - s.select_ranges([Point::new(4, 0)..Point::new(4, 0)]) - }); - editor.change_selections(Some(Autoscroll::Next), cx, |s| { - s.select_ranges([Point::new(22, 0)..Point::new(22, 0)]) - }); - editor.change_selections(Some(Autoscroll::Next), cx, |s| { - s.select_ranges([Point::new(50, 0)..Point::new(50, 0)]) - }); - }); - cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { - let expected_hints = vec![ - "main hint #0".to_string(), - "main hint #1".to_string(), - "main hint #2".to_string(), - "main hint #3".to_string(), - "main hint #4".to_string(), - "main hint #5".to_string(), - "other hint #0".to_string(), - "other hint #1".to_string(), - "other hint #2".to_string(), - ]; - assert_eq!(expected_hints, cached_hint_labels(editor), - "With more scrolls of the multibuffer, more hints should be added into the cache and nothing invalidated without edits"); - assert_eq!(expected_hints, visible_hint_labels(editor, cx)); - assert_eq!(editor.inlay_hint_cache().version, expected_hints.len(), - "Due to every excerpt having one hint, we update cache per new excerpt scrolled"); - }); + // editor.update(cx, |editor, cx| { + // editor.change_selections(Some(Autoscroll::Next), cx, |s| { + // s.select_ranges([Point::new(4, 0)..Point::new(4, 0)]) + // }); + // editor.change_selections(Some(Autoscroll::Next), cx, |s| { + // s.select_ranges([Point::new(22, 0)..Point::new(22, 0)]) + // }); + // editor.change_selections(Some(Autoscroll::Next), cx, |s| { + // s.select_ranges([Point::new(50, 0)..Point::new(50, 0)]) + // }); + // }); + // cx.executor().run_until_parked(); + // editor.update(cx, |editor, cx| { + // let expected_hints = vec![ + // "main hint #0".to_string(), + // "main hint #1".to_string(), + // "main hint #2".to_string(), + // "main hint #3".to_string(), + // "main hint #4".to_string(), + // "main hint #5".to_string(), + // "other hint #0".to_string(), + // "other hint #1".to_string(), + // "other hint #2".to_string(), + // ]; + // assert_eq!(expected_hints, cached_hint_labels(editor), + // "With more scrolls of the multibuffer, more hints should be added into the cache and nothing invalidated without edits"); + // assert_eq!(expected_hints, visible_hint_labels(editor, cx)); + // assert_eq!(editor.inlay_hint_cache().version, expected_hints.len(), + // "Due to every excerpt having one hint, we update cache per new excerpt scrolled"); + // }); - editor.update(cx, |editor, cx| { - editor.change_selections(Some(Autoscroll::Next), cx, |s| { - s.select_ranges([Point::new(100, 0)..Point::new(100, 0)]) - }); - }); - cx.executor().advance_clock(Duration::from_millis( - INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS + 100, - )); - cx.executor().run_until_parked(); - let last_scroll_update_version = editor.update(cx, |editor, cx| { - let expected_hints = vec![ - "main hint #0".to_string(), - "main hint #1".to_string(), - "main hint #2".to_string(), - "main hint #3".to_string(), - "main hint #4".to_string(), - "main hint #5".to_string(), - "other hint #0".to_string(), - "other hint #1".to_string(), - "other hint #2".to_string(), - "other hint #3".to_string(), - "other hint #4".to_string(), - "other hint #5".to_string(), - ]; - assert_eq!(expected_hints, cached_hint_labels(editor), - "After multibuffer was scrolled to the end, all hints for all excerpts should be fetched"); - assert_eq!(expected_hints, visible_hint_labels(editor, cx)); - assert_eq!(editor.inlay_hint_cache().version, expected_hints.len()); - expected_hints.len() - }).unwrap(); + // editor.update(cx, |editor, cx| { + // editor.change_selections(Some(Autoscroll::Next), cx, |s| { + // s.select_ranges([Point::new(100, 0)..Point::new(100, 0)]) + // }); + // }); + // cx.executor().advance_clock(Duration::from_millis( + // INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS + 100, + // )); + // cx.executor().run_until_parked(); + // let last_scroll_update_version = editor.update(cx, |editor, cx| { + // let expected_hints = vec![ + // "main hint #0".to_string(), + // "main hint #1".to_string(), + // "main hint #2".to_string(), + // "main hint #3".to_string(), + // "main hint #4".to_string(), + // "main hint #5".to_string(), + // "other hint #0".to_string(), + // "other hint #1".to_string(), + // "other hint #2".to_string(), + // "other hint #3".to_string(), + // "other hint #4".to_string(), + // "other hint #5".to_string(), + // ]; + // assert_eq!(expected_hints, cached_hint_labels(editor), + // "After multibuffer was scrolled to the end, all hints for all excerpts should be fetched"); + // assert_eq!(expected_hints, visible_hint_labels(editor, cx)); + // assert_eq!(editor.inlay_hint_cache().version, expected_hints.len()); + // expected_hints.len() + // }).unwrap(); - editor.update(cx, |editor, cx| { - editor.change_selections(Some(Autoscroll::Next), cx, |s| { - s.select_ranges([Point::new(4, 0)..Point::new(4, 0)]) - }); - }); - cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { - let expected_hints = vec![ - "main hint #0".to_string(), - "main hint #1".to_string(), - "main hint #2".to_string(), - "main hint #3".to_string(), - "main hint #4".to_string(), - "main hint #5".to_string(), - "other hint #0".to_string(), - "other hint #1".to_string(), - "other hint #2".to_string(), - "other hint #3".to_string(), - "other hint #4".to_string(), - "other hint #5".to_string(), - ]; - assert_eq!(expected_hints, cached_hint_labels(editor), - "After multibuffer was scrolled to the end, further scrolls up should not bring more hints"); - assert_eq!(expected_hints, visible_hint_labels(editor, cx)); - assert_eq!(editor.inlay_hint_cache().version, last_scroll_update_version, "No updates should happen during scrolling already scolled buffer"); - }); + // editor.update(cx, |editor, cx| { + // editor.change_selections(Some(Autoscroll::Next), cx, |s| { + // s.select_ranges([Point::new(4, 0)..Point::new(4, 0)]) + // }); + // }); + // cx.executor().run_until_parked(); + // editor.update(cx, |editor, cx| { + // let expected_hints = vec![ + // "main hint #0".to_string(), + // "main hint #1".to_string(), + // "main hint #2".to_string(), + // "main hint #3".to_string(), + // "main hint #4".to_string(), + // "main hint #5".to_string(), + // "other hint #0".to_string(), + // "other hint #1".to_string(), + // "other hint #2".to_string(), + // "other hint #3".to_string(), + // "other hint #4".to_string(), + // "other hint #5".to_string(), + // ]; + // assert_eq!(expected_hints, cached_hint_labels(editor), + // "After multibuffer was scrolled to the end, further scrolls up should not bring more hints"); + // assert_eq!(expected_hints, visible_hint_labels(editor, cx)); + // assert_eq!(editor.inlay_hint_cache().version, last_scroll_update_version, "No updates should happen during scrolling already scolled buffer"); + // }); - editor_edited.store(true, Ordering::Release); - editor.update(cx, |editor, cx| { - editor.change_selections(None, cx, |s| { - s.select_ranges([Point::new(56, 0)..Point::new(56, 0)]) - }); - editor.handle_input("++++more text++++", cx); - }); - cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { - let expected_hints = vec![ - "main hint(edited) #0".to_string(), - "main hint(edited) #1".to_string(), - "main hint(edited) #2".to_string(), - "main hint(edited) #3".to_string(), - "main hint(edited) #4".to_string(), - "main hint(edited) #5".to_string(), - "other hint(edited) #0".to_string(), - "other hint(edited) #1".to_string(), - ]; - assert_eq!( - expected_hints, - cached_hint_labels(editor), - "After multibuffer edit, editor gets scolled back to the last selection; \ -all hints should be invalidated and requeried for all of its visible excerpts" - ); - assert_eq!(expected_hints, visible_hint_labels(editor, cx)); + // editor_edited.store(true, Ordering::Release); + // editor.update(cx, |editor, cx| { + // editor.change_selections(None, cx, |s| { + // s.select_ranges([Point::new(56, 0)..Point::new(56, 0)]) + // }); + // editor.handle_input("++++more text++++", cx); + // }); + // cx.executor().run_until_parked(); + // editor.update(cx, |editor, cx| { + // let expected_hints = vec![ + // "main hint(edited) #0".to_string(), + // "main hint(edited) #1".to_string(), + // "main hint(edited) #2".to_string(), + // "main hint(edited) #3".to_string(), + // "main hint(edited) #4".to_string(), + // "main hint(edited) #5".to_string(), + // "other hint(edited) #0".to_string(), + // "other hint(edited) #1".to_string(), + // ]; + // assert_eq!( + // expected_hints, + // cached_hint_labels(editor), + // "After multibuffer edit, editor gets scolled back to the last selection; \ + // all hints should be invalidated and requeried for all of its visible excerpts" + // ); + // assert_eq!(expected_hints, visible_hint_labels(editor, cx)); - let current_cache_version = editor.inlay_hint_cache().version; - let minimum_expected_version = last_scroll_update_version + expected_hints.len(); - assert!( - current_cache_version == minimum_expected_version || current_cache_version == minimum_expected_version + 1, - "Due to every excerpt having one hint, cache should update per new excerpt received + 1 potential sporadic update" - ); - }); - } + // let current_cache_version = editor.inlay_hint_cache().version; + // let minimum_expected_version = last_scroll_update_version + expected_hints.len(); + // assert!( + // current_cache_version == minimum_expected_version || current_cache_version == minimum_expected_version + 1, + // "Due to every excerpt having one hint, cache should update per new excerpt received + 1 potential sporadic update" + // ); + // }); + // } #[gpui::test] async fn test_excerpts_removed(cx: &mut gpui::TestAppContext) { diff --git a/crates/editor2/src/movement.rs b/crates/editor2/src/movement.rs index 1414ae702d..ab25bb8499 100644 --- a/crates/editor2/src/movement.rs +++ b/crates/editor2/src/movement.rs @@ -452,483 +452,475 @@ pub fn split_display_range_by_lines( result } -// #[cfg(test)] -// mod tests { -// use super::*; -// use crate::{ -// display_map::Inlay, -// test::{}, -// Buffer, DisplayMap, ExcerptRange, InlayId, MultiBuffer, -// }; -// use project::Project; -// use settings::SettingsStore; -// use util::post_inc; +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + display_map::Inlay, + test::{editor_test_context::EditorTestContext, marked_display_snapshot}, + Buffer, DisplayMap, ExcerptRange, InlayId, MultiBuffer, + }; + use gpui::{font, Context as _}; + use project::Project; + use settings::SettingsStore; + use util::post_inc; -// #[gpui::test] -// fn test_previous_word_start(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_previous_word_start(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert(marked_text: &str, cx: &mut gpui::AppContext) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// previous_word_start(&snapshot, display_points[1]), -// display_points[0] -// ); -// } + fn assert(marked_text: &str, cx: &mut gpui::AppContext) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + previous_word_start(&snapshot, display_points[1]), + display_points[0] + ); + } -// assert("\nˇ ˇlorem", cx); -// assert("ˇ\nˇ lorem", cx); -// assert(" ˇloremˇ", cx); -// assert("ˇ ˇlorem", cx); -// assert(" ˇlorˇem", cx); -// assert("\nlorem\nˇ ˇipsum", cx); -// assert("\n\nˇ\nˇ", cx); -// assert(" ˇlorem ˇipsum", cx); -// assert("loremˇ-ˇipsum", cx); -// assert("loremˇ-#$@ˇipsum", cx); -// assert("ˇlorem_ˇipsum", cx); -// assert(" ˇdefγˇ", cx); -// assert(" ˇbcΔˇ", cx); -// assert(" abˇ——ˇcd", cx); -// } + assert("\nˇ ˇlorem", cx); + assert("ˇ\nˇ lorem", cx); + assert(" ˇloremˇ", cx); + assert("ˇ ˇlorem", cx); + assert(" ˇlorˇem", cx); + assert("\nlorem\nˇ ˇipsum", cx); + assert("\n\nˇ\nˇ", cx); + assert(" ˇlorem ˇipsum", cx); + assert("loremˇ-ˇipsum", cx); + assert("loremˇ-#$@ˇipsum", cx); + assert("ˇlorem_ˇipsum", cx); + assert(" ˇdefγˇ", cx); + assert(" ˇbcΔˇ", cx); + assert(" abˇ——ˇcd", cx); + } -// #[gpui::test] -// fn test_previous_subword_start(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_previous_subword_start(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert(marked_text: &str, cx: &mut gpui::AppContext) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// previous_subword_start(&snapshot, display_points[1]), -// display_points[0] -// ); -// } + fn assert(marked_text: &str, cx: &mut gpui::AppContext) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + previous_subword_start(&snapshot, display_points[1]), + display_points[0] + ); + } -// // Subword boundaries are respected -// assert("lorem_ˇipˇsum", cx); -// assert("lorem_ˇipsumˇ", cx); -// assert("ˇlorem_ˇipsum", cx); -// assert("lorem_ˇipsum_ˇdolor", cx); -// assert("loremˇIpˇsum", cx); -// assert("loremˇIpsumˇ", cx); + // Subword boundaries are respected + assert("lorem_ˇipˇsum", cx); + assert("lorem_ˇipsumˇ", cx); + assert("ˇlorem_ˇipsum", cx); + assert("lorem_ˇipsum_ˇdolor", cx); + assert("loremˇIpˇsum", cx); + assert("loremˇIpsumˇ", cx); -// // Word boundaries are still respected -// assert("\nˇ ˇlorem", cx); -// assert(" ˇloremˇ", cx); -// assert(" ˇlorˇem", cx); -// assert("\nlorem\nˇ ˇipsum", cx); -// assert("\n\nˇ\nˇ", cx); -// assert(" ˇlorem ˇipsum", cx); -// assert("loremˇ-ˇipsum", cx); -// assert("loremˇ-#$@ˇipsum", cx); -// assert(" ˇdefγˇ", cx); -// assert(" bcˇΔˇ", cx); -// assert(" ˇbcδˇ", cx); -// assert(" abˇ——ˇcd", cx); -// } + // Word boundaries are still respected + assert("\nˇ ˇlorem", cx); + assert(" ˇloremˇ", cx); + assert(" ˇlorˇem", cx); + assert("\nlorem\nˇ ˇipsum", cx); + assert("\n\nˇ\nˇ", cx); + assert(" ˇlorem ˇipsum", cx); + assert("loremˇ-ˇipsum", cx); + assert("loremˇ-#$@ˇipsum", cx); + assert(" ˇdefγˇ", cx); + assert(" bcˇΔˇ", cx); + assert(" ˇbcδˇ", cx); + assert(" abˇ——ˇcd", cx); + } -// #[gpui::test] -// fn test_find_preceding_boundary(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_find_preceding_boundary(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert( -// marked_text: &str, -// cx: &mut gpui::AppContext, -// is_boundary: impl FnMut(char, char) -> bool, -// ) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// find_preceding_boundary( -// &snapshot, -// display_points[1], -// FindRange::MultiLine, -// is_boundary -// ), -// display_points[0] -// ); -// } + fn assert( + marked_text: &str, + cx: &mut gpui::AppContext, + is_boundary: impl FnMut(char, char) -> bool, + ) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + find_preceding_boundary( + &snapshot, + display_points[1], + FindRange::MultiLine, + is_boundary + ), + display_points[0] + ); + } -// assert("abcˇdef\ngh\nijˇk", cx, |left, right| { -// left == 'c' && right == 'd' -// }); -// assert("abcdef\nˇgh\nijˇk", cx, |left, right| { -// left == '\n' && right == 'g' -// }); -// let mut line_count = 0; -// assert("abcdef\nˇgh\nijˇk", cx, |left, _| { -// if left == '\n' { -// line_count += 1; -// line_count == 2 -// } else { -// false -// } -// }); -// } + assert("abcˇdef\ngh\nijˇk", cx, |left, right| { + left == 'c' && right == 'd' + }); + assert("abcdef\nˇgh\nijˇk", cx, |left, right| { + left == '\n' && right == 'g' + }); + let mut line_count = 0; + assert("abcdef\nˇgh\nijˇk", cx, |left, _| { + if left == '\n' { + line_count += 1; + line_count == 2 + } else { + false + } + }); + } -// #[gpui::test] -// fn test_find_preceding_boundary_with_inlays(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_find_preceding_boundary_with_inlays(cx: &mut gpui::AppContext) { + init_test(cx); -// let input_text = "abcdefghijklmnopqrstuvwxys"; -// let family_id = cx -// .font_cache() -// .load_family(&["Helvetica"], &Default::default()) -// .unwrap(); -// let font_id = cx -// .font_cache() -// .select_font(family_id, &Default::default()) -// .unwrap(); -// let font_size = 14.0; -// let buffer = MultiBuffer::build_simple(input_text, cx); -// let buffer_snapshot = buffer.read(cx).snapshot(cx); -// let display_map = -// cx.add_model(|cx| DisplayMap::new(buffer, font_id, font_size, None, 1, 1, cx)); + let input_text = "abcdefghijklmnopqrstuvwxys"; + let font = font("Helvetica"); + let font_size = px(14.0); + let buffer = MultiBuffer::build_simple(input_text, cx); + let buffer_snapshot = buffer.read(cx).snapshot(cx); + let display_map = + cx.build_model(|cx| DisplayMap::new(buffer, font, font_size, None, 1, 1, cx)); -// // add all kinds of inlays between two word boundaries: we should be able to cross them all, when looking for another boundary -// let mut id = 0; -// let inlays = (0..buffer_snapshot.len()) -// .map(|offset| { -// [ -// Inlay { -// id: InlayId::Suggestion(post_inc(&mut id)), -// position: buffer_snapshot.anchor_at(offset, Bias::Left), -// text: format!("test").into(), -// }, -// Inlay { -// id: InlayId::Suggestion(post_inc(&mut id)), -// position: buffer_snapshot.anchor_at(offset, Bias::Right), -// text: format!("test").into(), -// }, -// Inlay { -// id: InlayId::Hint(post_inc(&mut id)), -// position: buffer_snapshot.anchor_at(offset, Bias::Left), -// text: format!("test").into(), -// }, -// Inlay { -// id: InlayId::Hint(post_inc(&mut id)), -// position: buffer_snapshot.anchor_at(offset, Bias::Right), -// text: format!("test").into(), -// }, -// ] -// }) -// .flatten() -// .collect(); -// let snapshot = display_map.update(cx, |map, cx| { -// map.splice_inlays(Vec::new(), inlays, cx); -// map.snapshot(cx) -// }); + // add all kinds of inlays between two word boundaries: we should be able to cross them all, when looking for another boundary + let mut id = 0; + let inlays = (0..buffer_snapshot.len()) + .map(|offset| { + [ + Inlay { + id: InlayId::Suggestion(post_inc(&mut id)), + position: buffer_snapshot.anchor_at(offset, Bias::Left), + text: format!("test").into(), + }, + Inlay { + id: InlayId::Suggestion(post_inc(&mut id)), + position: buffer_snapshot.anchor_at(offset, Bias::Right), + text: format!("test").into(), + }, + Inlay { + id: InlayId::Hint(post_inc(&mut id)), + position: buffer_snapshot.anchor_at(offset, Bias::Left), + text: format!("test").into(), + }, + Inlay { + id: InlayId::Hint(post_inc(&mut id)), + position: buffer_snapshot.anchor_at(offset, Bias::Right), + text: format!("test").into(), + }, + ] + }) + .flatten() + .collect(); + let snapshot = display_map.update(cx, |map, cx| { + map.splice_inlays(Vec::new(), inlays, cx); + map.snapshot(cx) + }); -// assert_eq!( -// find_preceding_boundary( -// &snapshot, -// buffer_snapshot.len().to_display_point(&snapshot), -// FindRange::MultiLine, -// |left, _| left == 'e', -// ), -// snapshot -// .buffer_snapshot -// .offset_to_point(5) -// .to_display_point(&snapshot), -// "Should not stop at inlays when looking for boundaries" -// ); -// } + assert_eq!( + find_preceding_boundary( + &snapshot, + buffer_snapshot.len().to_display_point(&snapshot), + FindRange::MultiLine, + |left, _| left == 'e', + ), + snapshot + .buffer_snapshot + .offset_to_point(5) + .to_display_point(&snapshot), + "Should not stop at inlays when looking for boundaries" + ); + } -// #[gpui::test] -// fn test_next_word_end(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_next_word_end(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert(marked_text: &str, cx: &mut gpui::AppContext) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// next_word_end(&snapshot, display_points[0]), -// display_points[1] -// ); -// } + fn assert(marked_text: &str, cx: &mut gpui::AppContext) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + next_word_end(&snapshot, display_points[0]), + display_points[1] + ); + } -// assert("\nˇ loremˇ", cx); -// assert(" ˇloremˇ", cx); -// assert(" lorˇemˇ", cx); -// assert(" loremˇ ˇ\nipsum\n", cx); -// assert("\nˇ\nˇ\n\n", cx); -// assert("loremˇ ipsumˇ ", cx); -// assert("loremˇ-ˇipsum", cx); -// assert("loremˇ#$@-ˇipsum", cx); -// assert("loremˇ_ipsumˇ", cx); -// assert(" ˇbcΔˇ", cx); -// assert(" abˇ——ˇcd", cx); -// } + assert("\nˇ loremˇ", cx); + assert(" ˇloremˇ", cx); + assert(" lorˇemˇ", cx); + assert(" loremˇ ˇ\nipsum\n", cx); + assert("\nˇ\nˇ\n\n", cx); + assert("loremˇ ipsumˇ ", cx); + assert("loremˇ-ˇipsum", cx); + assert("loremˇ#$@-ˇipsum", cx); + assert("loremˇ_ipsumˇ", cx); + assert(" ˇbcΔˇ", cx); + assert(" abˇ——ˇcd", cx); + } -// #[gpui::test] -// fn test_next_subword_end(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_next_subword_end(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert(marked_text: &str, cx: &mut gpui::AppContext) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// next_subword_end(&snapshot, display_points[0]), -// display_points[1] -// ); -// } + fn assert(marked_text: &str, cx: &mut gpui::AppContext) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + next_subword_end(&snapshot, display_points[0]), + display_points[1] + ); + } -// // Subword boundaries are respected -// assert("loˇremˇ_ipsum", cx); -// assert("ˇloremˇ_ipsum", cx); -// assert("loremˇ_ipsumˇ", cx); -// assert("loremˇ_ipsumˇ_dolor", cx); -// assert("loˇremˇIpsum", cx); -// assert("loremˇIpsumˇDolor", cx); + // Subword boundaries are respected + assert("loˇremˇ_ipsum", cx); + assert("ˇloremˇ_ipsum", cx); + assert("loremˇ_ipsumˇ", cx); + assert("loremˇ_ipsumˇ_dolor", cx); + assert("loˇremˇIpsum", cx); + assert("loremˇIpsumˇDolor", cx); -// // Word boundaries are still respected -// assert("\nˇ loremˇ", cx); -// assert(" ˇloremˇ", cx); -// assert(" lorˇemˇ", cx); -// assert(" loremˇ ˇ\nipsum\n", cx); -// assert("\nˇ\nˇ\n\n", cx); -// assert("loremˇ ipsumˇ ", cx); -// assert("loremˇ-ˇipsum", cx); -// assert("loremˇ#$@-ˇipsum", cx); -// assert("loremˇ_ipsumˇ", cx); -// assert(" ˇbcˇΔ", cx); -// assert(" abˇ——ˇcd", cx); -// } + // Word boundaries are still respected + assert("\nˇ loremˇ", cx); + assert(" ˇloremˇ", cx); + assert(" lorˇemˇ", cx); + assert(" loremˇ ˇ\nipsum\n", cx); + assert("\nˇ\nˇ\n\n", cx); + assert("loremˇ ipsumˇ ", cx); + assert("loremˇ-ˇipsum", cx); + assert("loremˇ#$@-ˇipsum", cx); + assert("loremˇ_ipsumˇ", cx); + assert(" ˇbcˇΔ", cx); + assert(" abˇ——ˇcd", cx); + } -// #[gpui::test] -// fn test_find_boundary(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_find_boundary(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert( -// marked_text: &str, -// cx: &mut gpui::AppContext, -// is_boundary: impl FnMut(char, char) -> bool, -// ) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// find_boundary( -// &snapshot, -// display_points[0], -// FindRange::MultiLine, -// is_boundary -// ), -// display_points[1] -// ); -// } + fn assert( + marked_text: &str, + cx: &mut gpui::AppContext, + is_boundary: impl FnMut(char, char) -> bool, + ) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + find_boundary( + &snapshot, + display_points[0], + FindRange::MultiLine, + is_boundary + ), + display_points[1] + ); + } -// assert("abcˇdef\ngh\nijˇk", cx, |left, right| { -// left == 'j' && right == 'k' -// }); -// assert("abˇcdef\ngh\nˇijk", cx, |left, right| { -// left == '\n' && right == 'i' -// }); -// let mut line_count = 0; -// assert("abcˇdef\ngh\nˇijk", cx, |left, _| { -// if left == '\n' { -// line_count += 1; -// line_count == 2 -// } else { -// false -// } -// }); -// } + assert("abcˇdef\ngh\nijˇk", cx, |left, right| { + left == 'j' && right == 'k' + }); + assert("abˇcdef\ngh\nˇijk", cx, |left, right| { + left == '\n' && right == 'i' + }); + let mut line_count = 0; + assert("abcˇdef\ngh\nˇijk", cx, |left, _| { + if left == '\n' { + line_count += 1; + line_count == 2 + } else { + false + } + }); + } -// #[gpui::test] -// fn test_surrounding_word(cx: &mut gpui::AppContext) { -// init_test(cx); + #[gpui::test] + fn test_surrounding_word(cx: &mut gpui::AppContext) { + init_test(cx); -// fn assert(marked_text: &str, cx: &mut gpui::AppContext) { -// let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); -// assert_eq!( -// surrounding_word(&snapshot, display_points[1]), -// display_points[0]..display_points[2], -// "{}", -// marked_text.to_string() -// ); -// } + fn assert(marked_text: &str, cx: &mut gpui::AppContext) { + let (snapshot, display_points) = marked_display_snapshot(marked_text, cx); + assert_eq!( + surrounding_word(&snapshot, display_points[1]), + display_points[0]..display_points[2], + "{}", + marked_text.to_string() + ); + } -// assert("ˇˇloremˇ ipsum", cx); -// assert("ˇloˇremˇ ipsum", cx); -// assert("ˇloremˇˇ ipsum", cx); -// assert("loremˇ ˇ ˇipsum", cx); -// assert("lorem\nˇˇˇ\nipsum", cx); -// assert("lorem\nˇˇipsumˇ", cx); -// assert("loremˇ,ˇˇ ipsum", cx); -// assert("ˇloremˇˇ, ipsum", cx); -// } + assert("ˇˇloremˇ ipsum", cx); + assert("ˇloˇremˇ ipsum", cx); + assert("ˇloremˇˇ ipsum", cx); + assert("loremˇ ˇ ˇipsum", cx); + assert("lorem\nˇˇˇ\nipsum", cx); + assert("lorem\nˇˇipsumˇ", cx); + assert("loremˇ,ˇˇ ipsum", cx); + assert("ˇloremˇˇ, ipsum", cx); + } -// #[gpui::test] -// async fn test_move_up_and_down_with_excerpts(cx: &mut gpui::TestAppContext) { -// cx.update(|cx| { -// init_test(cx); -// }); + #[gpui::test] + async fn test_move_up_and_down_with_excerpts(cx: &mut gpui::TestAppContext) { + cx.update(|cx| { + init_test(cx); + }); -// let mut cx = EditorTestContext::new(cx).await; -// let editor = cx.editor.clone(); -// let window = cx.window.clone(); -// cx.update_window(window, |cx| { -// let text_layout_details = -// editor.read_with(cx, |editor, cx| editor.text_layout_details(cx)); + let mut cx = EditorTestContext::new(cx).await; + let editor = cx.editor.clone(); + let window = cx.window.clone(); + cx.update_window(window, |_, cx| { + let text_layout_details = + editor.update(cx, |editor, cx| editor.text_layout_details(cx)); -// let family_id = cx -// .font_cache() -// .load_family(&["Helvetica"], &Default::default()) -// .unwrap(); -// let font_id = cx -// .font_cache() -// .select_font(family_id, &Default::default()) -// .unwrap(); + let font = font("Helvetica"); -// let buffer = -// cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, "abc\ndefg\nhijkl\nmn")); -// let multibuffer = cx.add_model(|cx| { -// let mut multibuffer = MultiBuffer::new(0); -// multibuffer.push_excerpts( -// buffer.clone(), -// [ -// ExcerptRange { -// context: Point::new(0, 0)..Point::new(1, 4), -// primary: None, -// }, -// ExcerptRange { -// context: Point::new(2, 0)..Point::new(3, 2), -// primary: None, -// }, -// ], -// cx, -// ); -// multibuffer -// }); -// let display_map = -// cx.add_model(|cx| DisplayMap::new(multibuffer, font_id, 14.0, None, 2, 2, cx)); -// let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx)); + let buffer = cx + .build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abc\ndefg\nhijkl\nmn")); + let multibuffer = cx.build_model(|cx| { + let mut multibuffer = MultiBuffer::new(0); + multibuffer.push_excerpts( + buffer.clone(), + [ + ExcerptRange { + context: Point::new(0, 0)..Point::new(1, 4), + primary: None, + }, + ExcerptRange { + context: Point::new(2, 0)..Point::new(3, 2), + primary: None, + }, + ], + cx, + ); + multibuffer + }); + let display_map = + cx.build_model(|cx| DisplayMap::new(multibuffer, font, px(14.0), None, 2, 2, cx)); + let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx)); -// assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\nhijkl\nmn"); + assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\nhijkl\nmn"); -// let col_2_x = snapshot.x_for_point(DisplayPoint::new(2, 2), &text_layout_details); + let col_2_x = + snapshot.x_for_display_point(DisplayPoint::new(2, 2), &text_layout_details); -// // Can't move up into the first excerpt's header -// assert_eq!( -// up( -// &snapshot, -// DisplayPoint::new(2, 2), -// SelectionGoal::HorizontalPosition(col_2_x), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(2, 0), -// SelectionGoal::HorizontalPosition(0.0) -// ), -// ); -// assert_eq!( -// up( -// &snapshot, -// DisplayPoint::new(2, 0), -// SelectionGoal::None, -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(2, 0), -// SelectionGoal::HorizontalPosition(0.0) -// ), -// ); + // Can't move up into the first excerpt's header + assert_eq!( + up( + &snapshot, + DisplayPoint::new(2, 2), + SelectionGoal::HorizontalPosition(col_2_x.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(2, 0), + SelectionGoal::HorizontalPosition(0.0) + ), + ); + assert_eq!( + up( + &snapshot, + DisplayPoint::new(2, 0), + SelectionGoal::None, + false, + &text_layout_details + ), + ( + DisplayPoint::new(2, 0), + SelectionGoal::HorizontalPosition(0.0) + ), + ); -// let col_4_x = snapshot.x_for_point(DisplayPoint::new(3, 4), &text_layout_details); + let col_4_x = + snapshot.x_for_display_point(DisplayPoint::new(3, 4), &text_layout_details); -// // Move up and down within first excerpt -// assert_eq!( -// up( -// &snapshot, -// DisplayPoint::new(3, 4), -// SelectionGoal::HorizontalPosition(col_4_x), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(2, 3), -// SelectionGoal::HorizontalPosition(col_4_x) -// ), -// ); -// assert_eq!( -// down( -// &snapshot, -// DisplayPoint::new(2, 3), -// SelectionGoal::HorizontalPosition(col_4_x), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(3, 4), -// SelectionGoal::HorizontalPosition(col_4_x) -// ), -// ); + // Move up and down within first excerpt + assert_eq!( + up( + &snapshot, + DisplayPoint::new(3, 4), + SelectionGoal::HorizontalPosition(col_4_x.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(2, 3), + SelectionGoal::HorizontalPosition(col_4_x.0) + ), + ); + assert_eq!( + down( + &snapshot, + DisplayPoint::new(2, 3), + SelectionGoal::HorizontalPosition(col_4_x.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(3, 4), + SelectionGoal::HorizontalPosition(col_4_x.0) + ), + ); -// let col_5_x = snapshot.x_for_point(DisplayPoint::new(6, 5), &text_layout_details); + let col_5_x = + snapshot.x_for_display_point(DisplayPoint::new(6, 5), &text_layout_details); -// // Move up and down across second excerpt's header -// assert_eq!( -// up( -// &snapshot, -// DisplayPoint::new(6, 5), -// SelectionGoal::HorizontalPosition(col_5_x), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(3, 4), -// SelectionGoal::HorizontalPosition(col_5_x) -// ), -// ); -// assert_eq!( -// down( -// &snapshot, -// DisplayPoint::new(3, 4), -// SelectionGoal::HorizontalPosition(col_5_x), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(6, 5), -// SelectionGoal::HorizontalPosition(col_5_x) -// ), -// ); + // Move up and down across second excerpt's header + assert_eq!( + up( + &snapshot, + DisplayPoint::new(6, 5), + SelectionGoal::HorizontalPosition(col_5_x.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(3, 4), + SelectionGoal::HorizontalPosition(col_5_x.0) + ), + ); + assert_eq!( + down( + &snapshot, + DisplayPoint::new(3, 4), + SelectionGoal::HorizontalPosition(col_5_x.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(6, 5), + SelectionGoal::HorizontalPosition(col_5_x.0) + ), + ); -// let max_point_x = snapshot.x_for_point(DisplayPoint::new(7, 2), &text_layout_details); + let max_point_x = + snapshot.x_for_display_point(DisplayPoint::new(7, 2), &text_layout_details); -// // Can't move down off the end -// assert_eq!( -// down( -// &snapshot, -// DisplayPoint::new(7, 0), -// SelectionGoal::HorizontalPosition(0.0), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(7, 2), -// SelectionGoal::HorizontalPosition(max_point_x) -// ), -// ); -// assert_eq!( -// down( -// &snapshot, -// DisplayPoint::new(7, 2), -// SelectionGoal::HorizontalPosition(max_point_x), -// false, -// &text_layout_details -// ), -// ( -// DisplayPoint::new(7, 2), -// SelectionGoal::HorizontalPosition(max_point_x) -// ), -// ); -// }); -// } + // Can't move down off the end + assert_eq!( + down( + &snapshot, + DisplayPoint::new(7, 0), + SelectionGoal::HorizontalPosition(0.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(7, 2), + SelectionGoal::HorizontalPosition(max_point_x.0) + ), + ); + assert_eq!( + down( + &snapshot, + DisplayPoint::new(7, 2), + SelectionGoal::HorizontalPosition(max_point_x.0), + false, + &text_layout_details + ), + ( + DisplayPoint::new(7, 2), + SelectionGoal::HorizontalPosition(max_point_x.0) + ), + ); + }); + } -// fn init_test(cx: &mut gpui::AppContext) { -// cx.set_global(SettingsStore::test(cx)); -// theme::init(cx); -// language::init(cx); -// crate::init(cx); -// Project::init_settings(cx); -// } -// } + fn init_test(cx: &mut gpui::AppContext) { + let settings_store = SettingsStore::test(cx); + cx.set_global(settings_store); + theme::init(theme::LoadThemes::JustBase, cx); + language::init(cx); + crate::init(cx); + Project::init_settings(cx); + } +}