Add AutoIndent action and '=' vim operator (#21427)
Release Notes: - vim: Added the `=` operator, for auto-indent Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
f3140f54d8
commit
7c994cd4a5
13 changed files with 481 additions and 186 deletions
|
@ -467,6 +467,7 @@ struct AutoindentRequest {
|
|||
before_edit: BufferSnapshot,
|
||||
entries: Vec<AutoindentRequestEntry>,
|
||||
is_block_mode: bool,
|
||||
ignore_empty_lines: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -1381,7 +1382,7 @@ impl Buffer {
|
|||
|
||||
let autoindent_requests = self.autoindent_requests.clone();
|
||||
Some(async move {
|
||||
let mut indent_sizes = BTreeMap::new();
|
||||
let mut indent_sizes = BTreeMap::<u32, (IndentSize, bool)>::new();
|
||||
for request in autoindent_requests {
|
||||
// Resolve each edited range to its row in the current buffer and in the
|
||||
// buffer before this batch of edits.
|
||||
|
@ -1475,10 +1476,12 @@ impl Buffer {
|
|||
let suggested_indent = indent_sizes
|
||||
.get(&suggestion.basis_row)
|
||||
.copied()
|
||||
.map(|e| e.0)
|
||||
.unwrap_or_else(|| {
|
||||
snapshot.indent_size_for_line(suggestion.basis_row)
|
||||
})
|
||||
.with_delta(suggestion.delta, language_indent_size);
|
||||
|
||||
if old_suggestions.get(&new_row).map_or(
|
||||
true,
|
||||
|(old_indentation, was_within_error)| {
|
||||
|
@ -1486,7 +1489,10 @@ impl Buffer {
|
|||
&& (!suggestion.within_error || *was_within_error)
|
||||
},
|
||||
) {
|
||||
indent_sizes.insert(new_row, suggested_indent);
|
||||
indent_sizes.insert(
|
||||
new_row,
|
||||
(suggested_indent, request.ignore_empty_lines),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1494,10 +1500,12 @@ impl Buffer {
|
|||
if let (true, Some(original_indent_column)) =
|
||||
(request.is_block_mode, original_indent_column)
|
||||
{
|
||||
let new_indent = indent_sizes
|
||||
.get(&row_range.start)
|
||||
.copied()
|
||||
.unwrap_or_else(|| snapshot.indent_size_for_line(row_range.start));
|
||||
let new_indent =
|
||||
if let Some((indent, _)) = indent_sizes.get(&row_range.start) {
|
||||
*indent
|
||||
} else {
|
||||
snapshot.indent_size_for_line(row_range.start)
|
||||
};
|
||||
let delta = new_indent.len as i64 - original_indent_column as i64;
|
||||
if delta != 0 {
|
||||
for row in row_range.skip(1) {
|
||||
|
@ -1512,7 +1520,7 @@ impl Buffer {
|
|||
Ordering::Equal => {}
|
||||
}
|
||||
}
|
||||
size
|
||||
(size, request.ignore_empty_lines)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1523,6 +1531,15 @@ impl Buffer {
|
|||
}
|
||||
|
||||
indent_sizes
|
||||
.into_iter()
|
||||
.filter_map(|(row, (indent, ignore_empty_lines))| {
|
||||
if ignore_empty_lines && snapshot.line_len(row) == 0 {
|
||||
None
|
||||
} else {
|
||||
Some((row, indent))
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2067,6 +2084,7 @@ impl Buffer {
|
|||
before_edit,
|
||||
entries,
|
||||
is_block_mode: matches!(mode, AutoindentMode::Block { .. }),
|
||||
ignore_empty_lines: false,
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -2094,6 +2112,30 @@ impl Buffer {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn autoindent_ranges<I, T>(&mut self, ranges: I, cx: &mut ModelContext<Self>)
|
||||
where
|
||||
I: IntoIterator<Item = Range<T>>,
|
||||
T: ToOffset + Copy,
|
||||
{
|
||||
let before_edit = self.snapshot();
|
||||
let entries = ranges
|
||||
.into_iter()
|
||||
.map(|range| AutoindentRequestEntry {
|
||||
range: before_edit.anchor_before(range.start)..before_edit.anchor_after(range.end),
|
||||
first_line_is_new: true,
|
||||
indent_size: before_edit.language_indent_size_at(range.start, cx),
|
||||
original_indent_column: None,
|
||||
})
|
||||
.collect();
|
||||
self.autoindent_requests.push(Arc::new(AutoindentRequest {
|
||||
before_edit,
|
||||
entries,
|
||||
is_block_mode: false,
|
||||
ignore_empty_lines: true,
|
||||
}));
|
||||
self.request_autoindent(cx);
|
||||
}
|
||||
|
||||
// Inserts newlines at the given position to create an empty line, returning the start of the new line.
|
||||
// You can also request the insertion of empty lines above and below the line starting at the returned point.
|
||||
pub fn insert_empty_line(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue