WIP
This commit is contained in:
@@ -784,6 +784,9 @@ impl BufferView {
|
||||
|
||||
let mut edits = Vec::new();
|
||||
let mut new_selection_ranges = Vec::new();
|
||||
let mut old_folds = Vec::new();
|
||||
let mut new_folds = Vec::new();
|
||||
|
||||
let mut selections = self.selections(app).iter().peekable();
|
||||
let mut contiguous_selections = Vec::new();
|
||||
while let Some(selection) = selections.next() {
|
||||
@@ -830,25 +833,42 @@ impl BufferView {
|
||||
edits.push((prev_row_start..prev_row_start, text));
|
||||
edits.push((selection_row_start - 1..selection_row_end, String::new()));
|
||||
|
||||
// Move selections up.
|
||||
let row_delta = buffer_rows.start
|
||||
- prev_row_display_start
|
||||
.to_buffer_point(map, Bias::Left, app)
|
||||
.unwrap()
|
||||
.row;
|
||||
|
||||
// Move selections up.
|
||||
for range in &mut contiguous_selections {
|
||||
range.start.row -= row_delta;
|
||||
range.end.row -= row_delta;
|
||||
}
|
||||
|
||||
// Move folds up.
|
||||
old_folds.push(selection_row_start..selection_row_end);
|
||||
for fold in map
|
||||
.folds_in_range(selection_row_start..selection_row_end, app)
|
||||
.unwrap()
|
||||
{
|
||||
let mut start = fold.start.to_point(buffer).unwrap();
|
||||
let mut end = fold.end.to_point(buffer).unwrap();
|
||||
start.row -= row_delta;
|
||||
end.row -= row_delta;
|
||||
new_folds.push(start..end);
|
||||
}
|
||||
}
|
||||
|
||||
new_selection_ranges.extend(contiguous_selections.drain(..));
|
||||
}
|
||||
|
||||
self.unfold_ranges(old_folds, ctx);
|
||||
self.buffer.update(ctx, |buffer, ctx| {
|
||||
for (range, text) in edits.into_iter().rev() {
|
||||
buffer.edit(Some(range), text, Some(ctx)).unwrap();
|
||||
}
|
||||
});
|
||||
self.fold_ranges(new_folds, ctx);
|
||||
self.select_ranges(new_selection_ranges, true, ctx);
|
||||
|
||||
self.end_transaction(ctx);
|
||||
@@ -863,6 +883,9 @@ impl BufferView {
|
||||
|
||||
let mut edits = Vec::new();
|
||||
let mut new_selection_ranges = Vec::new();
|
||||
let mut old_folds = Vec::new();
|
||||
let mut new_folds = Vec::new();
|
||||
|
||||
let mut selections = self.selections(app).iter().peekable();
|
||||
let mut contiguous_selections = Vec::new();
|
||||
while let Some(selection) = selections.next() {
|
||||
@@ -912,26 +935,43 @@ impl BufferView {
|
||||
edits.push((selection_row_start..selection_row_end + 1, String::new()));
|
||||
edits.push((next_row_end..next_row_end, text));
|
||||
|
||||
// Move selections down.
|
||||
let row_delta = next_row_display_end
|
||||
.to_buffer_point(map, Bias::Right, app)
|
||||
.unwrap()
|
||||
.row
|
||||
- buffer_rows.end
|
||||
+ 1;
|
||||
|
||||
// Move selections down.
|
||||
for range in &mut contiguous_selections {
|
||||
range.start.row += row_delta;
|
||||
range.end.row += row_delta;
|
||||
}
|
||||
|
||||
// Move folds down.
|
||||
old_folds.push(selection_row_start..selection_row_end);
|
||||
for fold in map
|
||||
.folds_in_range(selection_row_start..selection_row_end, app)
|
||||
.unwrap()
|
||||
{
|
||||
let mut start = fold.start.to_point(buffer).unwrap();
|
||||
let mut end = fold.end.to_point(buffer).unwrap();
|
||||
start.row += row_delta;
|
||||
end.row += row_delta;
|
||||
new_folds.push(start..end);
|
||||
}
|
||||
}
|
||||
|
||||
new_selection_ranges.extend(contiguous_selections.drain(..));
|
||||
}
|
||||
|
||||
self.unfold_ranges(old_folds, ctx);
|
||||
self.buffer.update(ctx, |buffer, ctx| {
|
||||
for (range, text) in edits.into_iter().rev() {
|
||||
buffer.edit(Some(range), text, Some(ctx)).unwrap();
|
||||
}
|
||||
});
|
||||
self.fold_ranges(new_folds, ctx);
|
||||
self.select_ranges(new_selection_ranges, true, ctx);
|
||||
|
||||
self.end_transaction(ctx);
|
||||
@@ -1533,12 +1573,7 @@ impl BufferView {
|
||||
}
|
||||
}
|
||||
|
||||
if !fold_ranges.is_empty() {
|
||||
self.display_map.update(ctx, |map, ctx| {
|
||||
map.fold(fold_ranges, ctx).unwrap();
|
||||
});
|
||||
*self.autoscroll_requested.lock() = true;
|
||||
}
|
||||
self.fold_ranges(fold_ranges, ctx);
|
||||
}
|
||||
|
||||
pub fn unfold(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
|
||||
@@ -1559,11 +1594,7 @@ impl BufferView {
|
||||
start..end
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.display_map.update(ctx, |map, ctx| {
|
||||
map.unfold(ranges, ctx).unwrap();
|
||||
});
|
||||
*self.autoscroll_requested.lock() = true;
|
||||
self.unfold_ranges(ranges, ctx);
|
||||
}
|
||||
|
||||
fn is_line_foldable(&self, display_row: u32, app: &AppContext) -> bool {
|
||||
@@ -1621,6 +1652,24 @@ impl BufferView {
|
||||
});
|
||||
}
|
||||
|
||||
fn fold_ranges<T: ToOffset>(&mut self, ranges: Vec<Range<T>>, ctx: &mut ViewContext<Self>) {
|
||||
if !ranges.is_empty() {
|
||||
self.display_map.update(ctx, |map, ctx| {
|
||||
map.fold(ranges, ctx).unwrap();
|
||||
});
|
||||
*self.autoscroll_requested.lock() = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn unfold_ranges<T: ToOffset>(&mut self, ranges: Vec<Range<T>>, ctx: &mut ViewContext<Self>) {
|
||||
if !ranges.is_empty() {
|
||||
self.display_map.update(ctx, |map, ctx| {
|
||||
map.unfold(ranges, ctx).unwrap();
|
||||
});
|
||||
*self.autoscroll_requested.lock() = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn line(&self, display_row: u32, app: &AppContext) -> Result<String> {
|
||||
self.display_map.read(app).line(display_row, app)
|
||||
}
|
||||
|
||||
@@ -89,6 +89,33 @@ impl FoldMap {
|
||||
DisplayPoint(self.transforms.summary().display.rightmost_point)
|
||||
}
|
||||
|
||||
pub fn folds_in_range<T>(&self, range: Range<T>, app: &AppContext) -> Result<&[Range<Anchor>]>
|
||||
where
|
||||
T: ToOffset,
|
||||
{
|
||||
let buffer = self.buffer.read(app);
|
||||
let range = buffer.anchor_before(range.start)?..buffer.anchor_before(range.end)?;
|
||||
let mut start_ix = find_insertion_index(&self.folds, |probe| probe.cmp(&range, buffer))?;
|
||||
let mut end_ix = start_ix;
|
||||
|
||||
for fold in self.folds[..start_ix].iter().rev() {
|
||||
if fold.end.cmp(&range.start, buffer)? == Ordering::Greater {
|
||||
start_ix -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for fold in &self.folds[end_ix..] {
|
||||
if range.end.cmp(&fold.start, buffer)? == Ordering::Greater {
|
||||
end_ix += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(&self.folds[start_ix..end_ix])
|
||||
}
|
||||
|
||||
pub fn fold<T: ToOffset>(
|
||||
&mut self,
|
||||
ranges: impl IntoIterator<Item = Range<T>>,
|
||||
@@ -422,7 +449,7 @@ impl<'a> Iterator for Chars<'a> {
|
||||
return Some(c);
|
||||
}
|
||||
|
||||
if self.offset == self.cursor.end().display.chars {
|
||||
while self.offset == self.cursor.end().display.chars && self.cursor.item().is_some() {
|
||||
self.cursor.next();
|
||||
}
|
||||
|
||||
@@ -584,6 +611,9 @@ mod tests {
|
||||
let iterations = env::var("ITERATIONS")
|
||||
.map(|i| i.parse().expect("invalid `ITERATIONS` variable"))
|
||||
.unwrap_or(100);
|
||||
let operations = env::var("OPERATIONS")
|
||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||
.unwrap_or(10);
|
||||
let seed_range = if let Ok(seed) = env::var("SEED") {
|
||||
let seed = seed.parse().expect("invalid `SEED` variable");
|
||||
seed..seed + 1
|
||||
@@ -591,6 +621,8 @@ mod tests {
|
||||
0..iterations
|
||||
};
|
||||
|
||||
let operations = 2;
|
||||
let seed_range = 133..=133;
|
||||
for seed in seed_range {
|
||||
println!("{:?}", seed);
|
||||
let mut rng = StdRng::seed_from_u64(seed);
|
||||
@@ -603,66 +635,78 @@ mod tests {
|
||||
});
|
||||
let mut map = FoldMap::new(buffer.clone(), app.as_ref());
|
||||
|
||||
{
|
||||
let buffer = buffer.read(app);
|
||||
for op_ix in 0..operations {
|
||||
dbg!(op_ix);
|
||||
|
||||
let fold_count = rng.gen_range(0..10);
|
||||
let mut fold_ranges: Vec<Range<usize>> = Vec::new();
|
||||
for _ in 0..fold_count {
|
||||
let end = rng.gen_range(0..buffer.len() + 1);
|
||||
let start = rng.gen_range(0..end + 1);
|
||||
fold_ranges.push(start..end);
|
||||
log::info!("Text: {:?}", buffer.read(app).text());
|
||||
{
|
||||
let buffer = buffer.read(app);
|
||||
|
||||
let fold_count = rng.gen_range(0..=2);
|
||||
let mut fold_ranges: Vec<Range<usize>> = Vec::new();
|
||||
for _ in 0..fold_count {
|
||||
let end = rng.gen_range(0..buffer.len() + 1);
|
||||
let start = rng.gen_range(0..end + 1);
|
||||
fold_ranges.push(start..end);
|
||||
}
|
||||
log::info!("Folding {:?}", fold_ranges);
|
||||
if op_ix == 1 {
|
||||
dbg!("stopping");
|
||||
}
|
||||
map.fold(fold_ranges.clone(), app.as_ref()).unwrap();
|
||||
assert_eq!(map.transforms.summary().buffer.chars, buffer.len());
|
||||
|
||||
let mut expected_text = buffer.text();
|
||||
for fold_range in map.merged_fold_ranges(app.as_ref()).into_iter().rev() {
|
||||
expected_text.replace_range(fold_range.start..fold_range.end, "…");
|
||||
}
|
||||
assert_eq!(map.text(app.as_ref()), expected_text);
|
||||
|
||||
for fold_range in map.merged_fold_ranges(app.as_ref()) {
|
||||
let display_point =
|
||||
map.to_display_point(fold_range.start.to_point(buffer).unwrap());
|
||||
assert!(map.is_line_folded(display_point.row()));
|
||||
}
|
||||
}
|
||||
|
||||
map.fold(fold_ranges, app.as_ref()).unwrap();
|
||||
let edits = buffer.update(app, |buffer, ctx| {
|
||||
let start_version = buffer.version.clone();
|
||||
let edit_count = rng.gen_range(0..=2);
|
||||
buffer.randomly_edit(&mut rng, edit_count, Some(ctx));
|
||||
buffer.edits_since(start_version).collect::<Vec<_>>()
|
||||
});
|
||||
log::info!("Editing {:?}", edits);
|
||||
map.apply_edits(&edits, app.as_ref()).unwrap();
|
||||
assert_eq!(
|
||||
map.transforms.summary().buffer.chars,
|
||||
buffer.read(app).len()
|
||||
);
|
||||
|
||||
let buffer = map.buffer.read(app);
|
||||
let mut expected_text = buffer.text();
|
||||
let mut expected_buffer_rows = Vec::new();
|
||||
let mut next_row = buffer.max_point().row;
|
||||
for fold_range in map.merged_fold_ranges(app.as_ref()).into_iter().rev() {
|
||||
let fold_start = buffer.point_for_offset(fold_range.start).unwrap();
|
||||
let fold_end = buffer.point_for_offset(fold_range.end).unwrap();
|
||||
expected_buffer_rows.extend((fold_end.row + 1..=next_row).rev());
|
||||
next_row = fold_start.row;
|
||||
|
||||
expected_text.replace_range(fold_range.start..fold_range.end, "…");
|
||||
}
|
||||
expected_buffer_rows.extend((0..=next_row).rev());
|
||||
expected_buffer_rows.reverse();
|
||||
|
||||
assert_eq!(map.text(app.as_ref()), expected_text);
|
||||
|
||||
for fold_range in map.merged_fold_ranges(app.as_ref()) {
|
||||
let display_point =
|
||||
map.to_display_point(fold_range.start.to_point(buffer).unwrap());
|
||||
assert!(map.is_line_folded(display_point.row()));
|
||||
for (idx, buffer_row) in expected_buffer_rows.iter().enumerate() {
|
||||
let display_row = map.to_display_point(Point::new(*buffer_row, 0)).row();
|
||||
assert_eq!(
|
||||
map.buffer_rows(display_row).unwrap().collect::<Vec<_>>(),
|
||||
expected_buffer_rows[idx..],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let edits = buffer.update(app, |buffer, ctx| {
|
||||
let start_version = buffer.version.clone();
|
||||
let edit_count = rng.gen_range(1..10);
|
||||
buffer.randomly_edit(&mut rng, edit_count, Some(ctx));
|
||||
buffer.edits_since(start_version).collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
map.apply_edits(&edits, app.as_ref()).unwrap();
|
||||
|
||||
let buffer = map.buffer.read(app);
|
||||
let mut expected_text = buffer.text();
|
||||
let mut expected_buffer_rows = Vec::new();
|
||||
let mut next_row = buffer.max_point().row;
|
||||
for fold_range in map.merged_fold_ranges(app.as_ref()).into_iter().rev() {
|
||||
let fold_start = buffer.point_for_offset(fold_range.start).unwrap();
|
||||
let fold_end = buffer.point_for_offset(fold_range.end).unwrap();
|
||||
expected_buffer_rows.extend((fold_end.row + 1..=next_row).rev());
|
||||
next_row = fold_start.row;
|
||||
|
||||
expected_text.replace_range(fold_range.start..fold_range.end, "…");
|
||||
}
|
||||
expected_buffer_rows.extend((0..=next_row).rev());
|
||||
expected_buffer_rows.reverse();
|
||||
|
||||
assert_eq!(map.text(app.as_ref()), expected_text);
|
||||
|
||||
for (idx, buffer_row) in expected_buffer_rows.iter().enumerate() {
|
||||
let display_row = map.to_display_point(Point::new(*buffer_row, 0)).row();
|
||||
assert_eq!(
|
||||
map.buffer_rows(display_row).unwrap().collect::<Vec<_>>(),
|
||||
expected_buffer_rows[idx..],
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,13 @@ impl DisplayMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn folds_in_range<T>(&self, range: Range<T>, app: &AppContext) -> Result<&[Range<Anchor>]>
|
||||
where
|
||||
T: ToOffset,
|
||||
{
|
||||
self.fold_map.folds_in_range(range, app)
|
||||
}
|
||||
|
||||
pub fn fold<T: ToOffset>(
|
||||
&mut self,
|
||||
ranges: impl IntoIterator<Item = Range<T>>,
|
||||
|
||||
Reference in New Issue
Block a user