Another batch of tests
This commit is contained in:
parent
4c4ec221af
commit
53f3f960d2
3 changed files with 1064 additions and 1072 deletions
|
@ -1026,337 +1026,337 @@ fn consolidate_wrap_edits(edits: &mut Vec<WrapEdit>) {
|
|||
}
|
||||
}
|
||||
|
||||
#[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::<String>();
|
||||
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::<String>();
|
||||
// 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::<String>();
|
||||
// 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::<String>();
|
||||
|
||||
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<f32>,
|
||||
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<f32>,
|
||||
// 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<Item = &str> {
|
||||
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<Item = &str> {
|
||||
// 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::<String>();
|
||||
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::<Vec<_>>()
|
||||
.join("\n");
|
||||
if end_row <= self.max_point().row() {
|
||||
expected_text.push('\n');
|
||||
}
|
||||
// let mut expected_text = self.text_chunks(start_row).collect::<String>();
|
||||
// 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::<Vec<_>>()
|
||||
// .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::<String>();
|
||||
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::<String>();
|
||||
// assert_eq!(
|
||||
// expected_text,
|
||||
// actual_text,
|
||||
// "chunks != highlighted_chunks for rows {:?}",
|
||||
// start_row..end_row
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -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::<Vec<_>>().join("")),
|
||||
"other.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|j| format!("let j = {j};\n")).collect::<Vec<_>>().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::<Vec<_>>().join("")),
|
||||
// "other.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|j| format!("let j = {j};\n")).collect::<Vec<_>>().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::<lsp::request::InlayHintRequest, _, _>(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::<lsp::request::InlayHintRequest, _, _>(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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue