This commit is contained in:
Nathan Sobo 2023-11-02 21:28:56 -06:00
parent dfc7c81500
commit a731f8fb1e
4 changed files with 155 additions and 127 deletions

View file

@ -4,13 +4,14 @@ use super::{
Highlights,
};
use crate::MultiBufferSnapshot;
use gpui::{AppContext, FontId, LineWrapper, Model, ModelContext, Pixels, Task};
use gpui::{AppContext, Context, Font, LineWrapper, Model, ModelContext, Pixels, Task};
use language::{Chunk, Point};
use lazy_static::lazy_static;
use smol::future::yield_now;
use std::{cmp, collections::VecDeque, mem, ops::Range, time::Duration};
use sum_tree::{Bias, Cursor, SumTree};
use text::Patch;
use util::ResultExt;
pub use super::tab_map::TextSummary;
pub type WrapEdit = text::Edit<u32>;
@ -22,7 +23,7 @@ pub struct WrapMap {
edits_since_sync: Patch<u32>,
wrap_width: Option<Pixels>,
background_task: Option<Task<()>>,
font: (FontId, Pixels),
font: (Font, Pixels),
}
#[derive(Clone)]
@ -68,14 +69,14 @@ pub struct WrapBufferRows<'a> {
impl WrapMap {
pub fn new(
tab_snapshot: TabSnapshot,
font_id: FontId,
font_size: f32,
wrap_width: Option<f32>,
font: Font,
font_size: Pixels,
wrap_width: Option<Pixels>,
cx: &mut AppContext,
) -> (Model<Self>, WrapSnapshot) {
let handle = cx.build_model(|cx| {
let mut this = Self {
font: (font_id, font_size),
font: (font, font_size),
wrap_width: None,
pending_edits: Default::default(),
interpolated_edits: Default::default(),
@ -115,14 +116,9 @@ impl WrapMap {
(self.snapshot.clone(), mem::take(&mut self.edits_since_sync))
}
pub fn set_font(
&mut self,
font_id: FontId,
font_size: f32,
cx: &mut ModelContext<Self>,
) -> bool {
if (font_id, font_size) != self.font {
self.font = (font_id, font_size);
pub fn set_font(&mut self, font: Font, font_size: Pixels, cx: &mut ModelContext<Self>) -> bool {
if (font, font_size) != self.font {
self.font = (font, font_size);
self.rewrap(cx);
true
} else {
@ -151,28 +147,32 @@ impl WrapMap {
if let Some(wrap_width) = self.wrap_width {
let mut new_snapshot = self.snapshot.clone();
let font_cache = cx.font_cache().clone();
let mut edits = Patch::default();
let text_system = cx.text_system().clone();
let (font_id, font_size) = self.font;
let task = cx.background().spawn(async move {
let mut line_wrapper = font_cache.line_wrapper(font_id, font_size);
let tab_snapshot = new_snapshot.tab_snapshot.clone();
let range = TabPoint::zero()..tab_snapshot.max_point();
let edits = new_snapshot
.update(
tab_snapshot,
&[TabEdit {
old: range.clone(),
new: range.clone(),
}],
wrap_width,
&mut line_wrapper,
)
.await;
let task = cx.background_executor().spawn(async move {
if let Some(mut line_wrapper) =
text_system.line_wrapper(font_id, font_size).log_err()
{
let tab_snapshot = new_snapshot.tab_snapshot.clone();
let range = TabPoint::zero()..tab_snapshot.max_point();
let edits = new_snapshot
.update(
tab_snapshot,
&[TabEdit {
old: range.clone(),
new: range.clone(),
}],
wrap_width,
&mut line_wrapper,
)
.await;
}
(new_snapshot, edits)
});
match cx
.background()
.background_executor()
.block_with_timeout(Duration::from_millis(5), task)
{
Ok((snapshot, edits)) => {
@ -235,23 +235,25 @@ impl WrapMap {
if self.background_task.is_none() {
let pending_edits = self.pending_edits.clone();
let mut snapshot = self.snapshot.clone();
let font_cache = cx.font_cache().clone();
let text_system = cx.text_system().clone();
let (font_id, font_size) = self.font;
let update_task = cx.background().spawn(async move {
let mut line_wrapper = font_cache.line_wrapper(font_id, font_size);
let update_task = cx.background_executor().spawn(async move {
let mut edits = Patch::default();
for (tab_snapshot, tab_edits) in pending_edits {
let wrap_edits = snapshot
.update(tab_snapshot, &tab_edits, wrap_width, &mut line_wrapper)
.await;
edits = edits.compose(&wrap_edits);
if let Some(mut line_wrapper) =
text_system.line_wrapper(font_id, font_size).log_err()
{
for (tab_snapshot, tab_edits) in pending_edits {
let wrap_edits = snapshot
.update(tab_snapshot, &tab_edits, wrap_width, &mut line_wrapper)
.await;
edits = edits.compose(&wrap_edits);
}
}
(snapshot, edits)
});
match cx
.background()
.background_executor()
.block_with_timeout(Duration::from_millis(1), update_task)
{
Ok((snapshot, output_edits)) => {
@ -733,48 +735,49 @@ impl WrapSnapshot {
}
fn check_invariants(&self) {
#[cfg(test)]
{
assert_eq!(
TabPoint::from(self.transforms.summary().input.lines),
self.tab_snapshot.max_point()
);
// todo!()
// #[cfg(test)]
// {
// assert_eq!(
// TabPoint::from(self.transforms.summary().input.lines),
// self.tab_snapshot.max_point()
// );
{
let mut transforms = self.transforms.cursor::<()>().peekable();
while let Some(transform) = transforms.next() {
if let Some(next_transform) = transforms.peek() {
assert!(transform.is_isomorphic() != next_transform.is_isomorphic());
}
}
}
// {
// let mut transforms = self.transforms.cursor::<()>().peekable();
// while let Some(transform) = transforms.next() {
// if let Some(next_transform) = transforms.peek() {
// assert!(transform.is_isomorphic() != next_transform.is_isomorphic());
// }
// }
// }
let text = language::Rope::from(self.text().as_str());
let mut input_buffer_rows = self.tab_snapshot.buffer_rows(0);
let mut expected_buffer_rows = Vec::new();
let mut prev_tab_row = 0;
for display_row in 0..=self.max_point().row() {
let tab_point = self.to_tab_point(WrapPoint::new(display_row, 0));
if tab_point.row() == prev_tab_row && display_row != 0 {
expected_buffer_rows.push(None);
} else {
expected_buffer_rows.push(input_buffer_rows.next().unwrap());
}
// let text = language::Rope::from(self.text().as_str());
// let mut input_buffer_rows = self.tab_snapshot.buffer_rows(0);
// let mut expected_buffer_rows = Vec::new();
// let mut prev_tab_row = 0;
// for display_row in 0..=self.max_point().row() {
// let tab_point = self.to_tab_point(WrapPoint::new(display_row, 0));
// if tab_point.row() == prev_tab_row && display_row != 0 {
// expected_buffer_rows.push(None);
// } else {
// expected_buffer_rows.push(input_buffer_rows.next().unwrap());
// }
prev_tab_row = tab_point.row();
assert_eq!(self.line_len(display_row), text.line_len(display_row));
}
// prev_tab_row = tab_point.row();
// assert_eq!(self.line_len(display_row), text.line_len(display_row));
// }
for start_display_row in 0..expected_buffer_rows.len() {
assert_eq!(
self.buffer_rows(start_display_row as u32)
.collect::<Vec<_>>(),
&expected_buffer_rows[start_display_row..],
"invalid buffer_rows({}..)",
start_display_row
);
}
}
// for start_display_row in 0..expected_buffer_rows.len() {
// assert_eq!(
// self.buffer_rows(start_display_row as u32)
// .collect::<Vec<_>>(),
// &expected_buffer_rows[start_display_row..],
// "invalid buffer_rows({}..)",
// start_display_row
// );
// }
// }
}
}