From 49447128a9e0b2943890e5cf8cc5cac6ff19e709 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 29 Mar 2023 21:40:37 +0200 Subject: [PATCH] Make edits smaller when tab expansion changes on a line --- crates/editor/src/display_map/tab_map.rs | 64 +++++++++++++++--------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 7dd4d763e19afb3aa0c4ac3536531a6d3d0cfcf1..3b24579ae6bf7593b3f6e98134fdac848c539704 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -52,45 +52,59 @@ impl TabMap { if old_snapshot.tab_size == new_snapshot.tab_size { for suggestion_edit in &mut suggestion_edits { - let old_end = old_snapshot + let mut old_column = old_snapshot .suggestion_snapshot - .to_point(suggestion_edit.old.end); - let old_end_row_len = old_snapshot.suggestion_snapshot.line_len(old_end.row()); - let old_end_row_exceeds_max_expansion = - old_end_row_len > old_snapshot.max_expansion_column; - let new_end = new_snapshot + .to_point(suggestion_edit.old.end) + .column(); + let mut new_column = new_snapshot .suggestion_snapshot - .to_point(suggestion_edit.new.end); - let new_end_row_len = new_snapshot.suggestion_snapshot.line_len(new_end.row()); - let new_end_row_exceeds_max_expansion = - new_end_row_len > new_snapshot.max_expansion_column; - if old_end_row_exceeds_max_expansion || new_end_row_exceeds_max_expansion { - suggestion_edit.old.end = old_snapshot - .suggestion_snapshot - .to_offset(SuggestionPoint::new(old_end.row(), old_end_row_len)); - suggestion_edit.new.end = new_snapshot - .suggestion_snapshot - .to_offset(SuggestionPoint::new(new_end.row(), new_end_row_len)); - continue; - } + .to_point(suggestion_edit.new.end) + .column(); let mut delta = 0; - for chunk in old_snapshot.suggestion_snapshot.chunks( + let mut first_tab_ix = None; + let mut last_tab_ix_with_changed_expansion = None; + 'outer: for chunk in old_snapshot.suggestion_snapshot.chunks( suggestion_edit.old.end..old_max_offset, false, None, ) { let patterns: &[_] = &['\t', '\n']; - if let Some(ix) = chunk.text.find(patterns) { - if &chunk.text[ix..ix + 1] == "\t" { - suggestion_edit.old.end.0 += delta + ix + 1; - suggestion_edit.new.end.0 += delta + ix + 1; + for (ix, mat) in chunk.text.match_indices(patterns) { + match mat { + "\t" => { + if first_tab_ix.is_none() { + first_tab_ix = Some(delta + ix); + } + + let old_column = old_column + ix as u32; + let new_column = new_column + ix as u32; + let was_expanded = old_column < old_snapshot.max_expansion_column; + let is_expanded = new_column < new_snapshot.max_expansion_column; + if was_expanded != is_expanded { + last_tab_ix_with_changed_expansion = Some(delta + ix); + } else if !was_expanded && !is_expanded { + break 'outer; + } + } + "\n" => break 'outer, + _ => unreachable!(), } + } + delta += chunk.text.len(); + old_column += chunk.text.len() as u32; + new_column += chunk.text.len() as u32; + if old_column >= old_snapshot.max_expansion_column + && new_column >= new_snapshot.max_expansion_column + { break; } + } - delta += chunk.text.len(); + if let Some(tab_ix) = last_tab_ix_with_changed_expansion.or(first_tab_ix) { + suggestion_edit.old.end.0 += tab_ix + 1; + suggestion_edit.new.end.0 += tab_ix + 1; } }