🎨 compute_autoindents

This commit is contained in:
Max Brunsfeld 2022-07-26 08:56:22 -07:00
parent 09ed149184
commit 537530bf76

View file

@ -19,7 +19,7 @@ use smol::future::yield_now;
use std::{ use std::{
any::Any, any::Any,
cmp::{self, Ordering}, cmp::{self, Ordering},
collections::{BTreeMap, HashMap}, collections::BTreeMap,
ffi::OsStr, ffi::OsStr,
future::Future, future::Future,
iter::{self, Iterator, Peekable}, iter::{self, Iterator, Peekable},
@ -808,7 +808,7 @@ impl Buffer {
) )
.collect::<BTreeMap<u32, u32>>(); .collect::<BTreeMap<u32, u32>>();
let mut old_suggestions = HashMap::<u32, IndentSize>::default(); let mut old_suggestions = BTreeMap::<u32, IndentSize>::default();
let old_edited_ranges = let old_edited_ranges =
contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields); contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
for old_edited_range in old_edited_ranges { for old_edited_range in old_edited_ranges {
@ -819,19 +819,15 @@ impl Buffer {
.flatten(); .flatten();
for (old_row, suggestion) in old_edited_range.zip(suggestions) { for (old_row, suggestion) in old_edited_range.zip(suggestions) {
if let Some(suggestion) = suggestion { if let Some(suggestion) = suggestion {
let mut suggested_indent = old_to_new_rows let suggested_indent = old_to_new_rows
.get(&suggestion.basis_row) .get(&suggestion.basis_row)
.and_then(|from_row| old_suggestions.get(from_row).copied()) .and_then(|from_row| old_suggestions.get(from_row).copied())
.unwrap_or_else(|| { .unwrap_or_else(|| {
request request
.before_edit .before_edit
.indent_size_for_line(suggestion.basis_row) .indent_size_for_line(suggestion.basis_row)
}); })
if suggestion.delta.is_gt() { .with_delta(suggestion.delta, request.indent_size);
suggested_indent += request.indent_size;
} else if suggestion.delta.is_lt() {
suggested_indent -= request.indent_size;
}
old_suggestions old_suggestions
.insert(*old_to_new_rows.get(&old_row).unwrap(), suggested_indent); .insert(*old_to_new_rows.get(&old_row).unwrap(), suggested_indent);
} }
@ -850,17 +846,13 @@ impl Buffer {
.flatten(); .flatten();
for (new_row, suggestion) in new_edited_row_range.zip(suggestions) { for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
if let Some(suggestion) = suggestion { if let Some(suggestion) = suggestion {
let mut suggested_indent = indent_sizes let suggested_indent = indent_sizes
.get(&suggestion.basis_row) .get(&suggestion.basis_row)
.copied() .copied()
.unwrap_or_else(|| { .unwrap_or_else(|| {
snapshot.indent_size_for_line(suggestion.basis_row) snapshot.indent_size_for_line(suggestion.basis_row)
}); })
if suggestion.delta.is_gt() { .with_delta(suggestion.delta, request.indent_size);
suggested_indent += request.indent_size;
} else if suggestion.delta.is_lt() {
suggested_indent -= request.indent_size;
}
if old_suggestions if old_suggestions
.get(&new_row) .get(&new_row)
.map_or(true, |old_indentation| { .map_or(true, |old_indentation| {
@ -874,38 +866,32 @@ impl Buffer {
yield_now().await; yield_now().await;
} }
if !request.inserted.is_empty() { let inserted_row_ranges = contiguous_ranges(
let inserted_row_ranges = contiguous_ranges( request
request .inserted
.inserted .iter()
.iter() .map(|range| range.to_point(&snapshot))
.map(|range| range.to_point(&snapshot)) .flat_map(|range| range.start.row..range.end.row + 1),
.flat_map(|range| range.start.row..range.end.row + 1), max_rows_between_yields,
max_rows_between_yields, );
); for inserted_row_range in inserted_row_ranges {
for inserted_row_range in inserted_row_ranges { let suggestions = snapshot
let suggestions = snapshot .suggest_autoindents(inserted_row_range.clone())
.suggest_autoindents(inserted_row_range.clone()) .into_iter()
.into_iter() .flatten();
.flatten(); for (row, suggestion) in inserted_row_range.zip(suggestions) {
for (row, suggestion) in inserted_row_range.zip(suggestions) { if let Some(suggestion) = suggestion {
if let Some(suggestion) = suggestion { let suggested_indent = indent_sizes
let mut suggested_indent = indent_sizes .get(&suggestion.basis_row)
.get(&suggestion.basis_row) .copied()
.copied() .unwrap_or_else(|| {
.unwrap_or_else(|| { snapshot.indent_size_for_line(suggestion.basis_row)
snapshot.indent_size_for_line(suggestion.basis_row) })
}); .with_delta(suggestion.delta, request.indent_size);
if suggestion.delta.is_gt() { indent_sizes.insert(row, suggested_indent);
suggested_indent += request.indent_size;
} else if suggestion.delta.is_lt() {
suggested_indent -= request.indent_size;
}
indent_sizes.insert(row, suggested_indent);
}
} }
yield_now().await;
} }
yield_now().await;
} }
} }
@ -2513,23 +2499,24 @@ impl IndentSize {
IndentKind::Tab => '\t', IndentKind::Tab => '\t',
} }
} }
}
impl std::ops::AddAssign for IndentSize { pub fn with_delta(mut self, direction: Ordering, size: IndentSize) -> Self {
fn add_assign(&mut self, other: IndentSize) { match direction {
if self.len == 0 { Ordering::Less => {
*self = other; if self.kind == size.kind && self.len >= size.len {
} else if self.kind == other.kind { self.len -= size.len;
self.len += other.len; }
} }
} Ordering::Equal => {}
} Ordering::Greater => {
if self.len == 0 {
impl std::ops::SubAssign for IndentSize { self = size;
fn sub_assign(&mut self, other: IndentSize) { } else if self.kind == size.kind {
if self.kind == other.kind && self.len >= other.len { self.len += size.len;
self.len -= other.len; }
}
} }
self
} }
} }