mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 19:10:24 +00:00
Implement selective auto-indent by comparing old and new suggestions
Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
54932a8050
commit
2f295382c4
1 changed files with 50 additions and 8 deletions
|
@ -1023,7 +1023,8 @@ impl Buffer {
|
|||
self.autoindent_requests = autoindent_requests;
|
||||
|
||||
let mut row_range = None;
|
||||
let mut cursor = QueryCursorHandle::new();
|
||||
let mut cursor1 = QueryCursorHandle::new();
|
||||
let mut cursor2 = QueryCursorHandle::new();
|
||||
self.start_transaction(None).unwrap();
|
||||
for row in autoindent_requests_by_row.keys().copied() {
|
||||
match &mut row_range {
|
||||
|
@ -1038,7 +1039,8 @@ impl Buffer {
|
|||
&new_tree,
|
||||
&autoindent_requests_by_row,
|
||||
language.as_ref(),
|
||||
&mut cursor,
|
||||
&mut cursor1,
|
||||
&mut cursor2,
|
||||
cx,
|
||||
);
|
||||
row_range.take();
|
||||
|
@ -1053,7 +1055,8 @@ impl Buffer {
|
|||
&new_tree,
|
||||
&autoindent_requests_by_row,
|
||||
language.as_ref(),
|
||||
&mut cursor,
|
||||
&mut cursor1,
|
||||
&mut cursor2,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
@ -1067,9 +1070,48 @@ impl Buffer {
|
|||
new_tree: &Tree,
|
||||
autoindent_requests: &BTreeMap<u32, AutoindentRequest>,
|
||||
language: &Language,
|
||||
cursor: &mut QueryCursor,
|
||||
cursor1: &mut QueryCursor,
|
||||
cursor2: &mut QueryCursor,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let new_suggestions = self.suggest_autoindents(
|
||||
autoindent_requests,
|
||||
row_range.clone(),
|
||||
new_tree,
|
||||
language,
|
||||
cursor1,
|
||||
);
|
||||
|
||||
if let Some(old_tree) = old_tree {
|
||||
let old_suggestions = self.suggest_autoindents(
|
||||
autoindent_requests,
|
||||
row_range.clone(),
|
||||
old_tree,
|
||||
language,
|
||||
cursor2,
|
||||
);
|
||||
let suggestions = old_suggestions.zip(new_suggestions).collect::<Vec<_>>();
|
||||
let requests = autoindent_requests.range(row_range);
|
||||
for ((row, request), (old_suggestion, new_suggestion)) in requests.zip(suggestions) {
|
||||
if request.force || new_suggestion != old_suggestion {
|
||||
self.set_indent_column_for_line(*row, new_suggestion, cx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (row, new_suggestion) in row_range.zip(new_suggestions.collect::<Vec<_>>()) {
|
||||
self.set_indent_column_for_line(row, new_suggestion, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_autoindents<'a>(
|
||||
&'a self,
|
||||
autoindent_requests: &'a BTreeMap<u32, AutoindentRequest>,
|
||||
row_range: Range<u32>,
|
||||
tree: &Tree,
|
||||
language: &Language,
|
||||
cursor: &mut QueryCursor,
|
||||
) -> impl Iterator<Item = u32> + 'a {
|
||||
let prev_non_blank_row = self.prev_non_blank_row(row_range.start);
|
||||
|
||||
// Get the "indentation ranges" that intersect this row range.
|
||||
|
@ -1082,7 +1124,7 @@ impl Buffer {
|
|||
let mut indentation_ranges = Vec::<(Range<Point>, &'static str)>::new();
|
||||
for mat in cursor.matches(
|
||||
&language.indents_query,
|
||||
new_tree.root_node(),
|
||||
tree.root_node(),
|
||||
TextProvider(&self.visible_text),
|
||||
) {
|
||||
let mut node_kind = "";
|
||||
|
@ -1117,7 +1159,7 @@ impl Buffer {
|
|||
let mut prev_row = prev_non_blank_row.unwrap_or(0);
|
||||
let mut prev_indent_column =
|
||||
prev_non_blank_row.map_or(0, |prev_row| self.indent_column_for_line(prev_row));
|
||||
for row in row_range {
|
||||
row_range.map(move |row| {
|
||||
let request = autoindent_requests.get(&row).unwrap();
|
||||
let row_start = Point::new(row, self.indent_column_for_line(row));
|
||||
|
||||
|
@ -1150,10 +1192,10 @@ impl Buffer {
|
|||
indent_column = self.indent_column_for_line(dedent_to_row);
|
||||
}
|
||||
|
||||
self.set_indent_column_for_line(row, indent_column, cx);
|
||||
prev_indent_column = indent_column;
|
||||
prev_row = row;
|
||||
}
|
||||
indent_column
|
||||
})
|
||||
}
|
||||
|
||||
fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
|
||||
|
|
Loading…
Reference in a new issue