Avoid maintaining indent size as state on buffers
Indent size is still hard-coded, but it's now controlled by the editor and not the buffer. Co-authored-by: Keith Simmons <keith@zed.dev>
This commit is contained in:
parent
e21f90fec5
commit
664f17f92b
4 changed files with 51 additions and 45 deletions
|
@ -63,6 +63,7 @@ const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||||
const MAX_LINE_LEN: usize = 1024;
|
const MAX_LINE_LEN: usize = 1024;
|
||||||
const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
|
const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
|
||||||
const MAX_SELECTION_HISTORY_LEN: usize = 1024;
|
const MAX_SELECTION_HISTORY_LEN: usize = 1024;
|
||||||
|
const INDENT_SIZE: u32 = 4;
|
||||||
|
|
||||||
action!(Cancel);
|
action!(Cancel);
|
||||||
action!(Backspace);
|
action!(Backspace);
|
||||||
|
@ -2946,7 +2947,7 @@ impl Editor {
|
||||||
{
|
{
|
||||||
let indent_column = buffer.indent_column_for_line(line_buffer_range.start.row);
|
let indent_column = buffer.indent_column_for_line(line_buffer_range.start.row);
|
||||||
if old_head.column <= indent_column && old_head.column > 0 {
|
if old_head.column <= indent_column && old_head.column > 0 {
|
||||||
let indent = buffer.indent_size();
|
let indent = INDENT_SIZE;
|
||||||
new_head = cmp::min(
|
new_head = cmp::min(
|
||||||
new_head,
|
new_head,
|
||||||
Point::new(old_head.row, ((old_head.column - 1) / indent) * indent),
|
Point::new(old_head.row, ((old_head.column - 1) / indent) * indent),
|
||||||
|
|
|
@ -287,6 +287,8 @@ impl MultiBuffer {
|
||||||
S: ToOffset,
|
S: ToOffset,
|
||||||
T: Into<String>,
|
T: Into<String>,
|
||||||
{
|
{
|
||||||
|
let indent_size = crate::INDENT_SIZE;
|
||||||
|
|
||||||
if self.buffers.borrow().is_empty() {
|
if self.buffers.borrow().is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +300,7 @@ impl MultiBuffer {
|
||||||
.map(|range| range.start.to_offset(&snapshot)..range.end.to_offset(&snapshot));
|
.map(|range| range.start.to_offset(&snapshot)..range.end.to_offset(&snapshot));
|
||||||
return buffer.update(cx, |buffer, cx| {
|
return buffer.update(cx, |buffer, cx| {
|
||||||
if autoindent {
|
if autoindent {
|
||||||
buffer.edit_with_autoindent(ranges, new_text, cx);
|
buffer.edit_with_autoindent(ranges, new_text, indent_size, cx);
|
||||||
} else {
|
} else {
|
||||||
buffer.edit(ranges, new_text, cx);
|
buffer.edit(ranges, new_text, cx);
|
||||||
}
|
}
|
||||||
|
@ -394,8 +396,8 @@ impl MultiBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if autoindent {
|
if autoindent {
|
||||||
buffer.edit_with_autoindent(deletions, "", cx);
|
buffer.edit_with_autoindent(deletions, "", indent_size, cx);
|
||||||
buffer.edit_with_autoindent(insertions, new_text.clone(), cx);
|
buffer.edit_with_autoindent(insertions, new_text.clone(), indent_size, cx);
|
||||||
} else {
|
} else {
|
||||||
buffer.edit(deletions, "", cx);
|
buffer.edit(deletions, "", cx);
|
||||||
buffer.edit(insertions, new_text.clone(), cx);
|
buffer.edit(insertions, new_text.clone(), cx);
|
||||||
|
|
|
@ -66,7 +66,6 @@ pub struct Buffer {
|
||||||
file_update_count: usize,
|
file_update_count: usize,
|
||||||
completion_triggers: Vec<String>,
|
completion_triggers: Vec<String>,
|
||||||
deferred_ops: OperationQueue<Operation>,
|
deferred_ops: OperationQueue<Operation>,
|
||||||
indent_size: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BufferSnapshot {
|
pub struct BufferSnapshot {
|
||||||
|
@ -80,7 +79,6 @@ pub struct BufferSnapshot {
|
||||||
selections_update_count: usize,
|
selections_update_count: usize,
|
||||||
language: Option<Arc<Language>>,
|
language: Option<Arc<Language>>,
|
||||||
parse_count: usize,
|
parse_count: usize,
|
||||||
indent_size: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -214,6 +212,7 @@ struct AutoindentRequest {
|
||||||
before_edit: BufferSnapshot,
|
before_edit: BufferSnapshot,
|
||||||
edited: Vec<Anchor>,
|
edited: Vec<Anchor>,
|
||||||
inserted: Option<Vec<Range<Anchor>>>,
|
inserted: Option<Vec<Range<Anchor>>>,
|
||||||
|
indent_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -427,8 +426,6 @@ impl Buffer {
|
||||||
file_update_count: 0,
|
file_update_count: 0,
|
||||||
completion_triggers: Default::default(),
|
completion_triggers: Default::default(),
|
||||||
deferred_ops: OperationQueue::new(),
|
deferred_ops: OperationQueue::new(),
|
||||||
// TODO: make this configurable
|
|
||||||
indent_size: 4,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +441,6 @@ impl Buffer {
|
||||||
language: self.language.clone(),
|
language: self.language.clone(),
|
||||||
parse_count: self.parse_count,
|
parse_count: self.parse_count,
|
||||||
selections_update_count: self.selections_update_count,
|
selections_update_count: self.selections_update_count,
|
||||||
indent_size: self.indent_size,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,7 +782,7 @@ impl Buffer {
|
||||||
.indent_column_for_line(suggestion.basis_row)
|
.indent_column_for_line(suggestion.basis_row)
|
||||||
});
|
});
|
||||||
let delta = if suggestion.indent {
|
let delta = if suggestion.indent {
|
||||||
snapshot.indent_size
|
request.indent_size
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -809,7 +805,7 @@ 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) {
|
||||||
let delta = if suggestion.indent {
|
let delta = if suggestion.indent {
|
||||||
snapshot.indent_size
|
request.indent_size
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -845,7 +841,7 @@ impl Buffer {
|
||||||
.flatten();
|
.flatten();
|
||||||
for (row, suggestion) in inserted_row_range.zip(suggestions) {
|
for (row, suggestion) in inserted_row_range.zip(suggestions) {
|
||||||
let delta = if suggestion.indent {
|
let delta = if suggestion.indent {
|
||||||
snapshot.indent_size
|
request.indent_size
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -1055,7 +1051,7 @@ impl Buffer {
|
||||||
where
|
where
|
||||||
T: Into<String>,
|
T: Into<String>,
|
||||||
{
|
{
|
||||||
self.edit_internal([0..self.len()], text, false, cx)
|
self.edit_internal([0..self.len()], text, None, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit<I, S, T>(
|
pub fn edit<I, S, T>(
|
||||||
|
@ -1069,13 +1065,14 @@ impl Buffer {
|
||||||
S: ToOffset,
|
S: ToOffset,
|
||||||
T: Into<String>,
|
T: Into<String>,
|
||||||
{
|
{
|
||||||
self.edit_internal(ranges_iter, new_text, false, cx)
|
self.edit_internal(ranges_iter, new_text, None, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_with_autoindent<I, S, T>(
|
pub fn edit_with_autoindent<I, S, T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ranges_iter: I,
|
ranges_iter: I,
|
||||||
new_text: T,
|
new_text: T,
|
||||||
|
indent_size: u32,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Option<clock::Local>
|
) -> Option<clock::Local>
|
||||||
where
|
where
|
||||||
|
@ -1083,14 +1080,14 @@ impl Buffer {
|
||||||
S: ToOffset,
|
S: ToOffset,
|
||||||
T: Into<String>,
|
T: Into<String>,
|
||||||
{
|
{
|
||||||
self.edit_internal(ranges_iter, new_text, true, cx)
|
self.edit_internal(ranges_iter, new_text, Some(indent_size), cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_internal<I, S, T>(
|
pub fn edit_internal<I, S, T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ranges_iter: I,
|
ranges_iter: I,
|
||||||
new_text: T,
|
new_text: T,
|
||||||
autoindent: bool,
|
autoindent_size: Option<u32>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Option<clock::Local>
|
) -> Option<clock::Local>
|
||||||
where
|
where
|
||||||
|
@ -1122,23 +1119,27 @@ impl Buffer {
|
||||||
|
|
||||||
self.start_transaction();
|
self.start_transaction();
|
||||||
self.pending_autoindent.take();
|
self.pending_autoindent.take();
|
||||||
let autoindent_request = if autoindent && self.language.is_some() {
|
let autoindent_request =
|
||||||
|
self.language
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|_| autoindent_size)
|
||||||
|
.map(|autoindent_size| {
|
||||||
let before_edit = self.snapshot();
|
let before_edit = self.snapshot();
|
||||||
let edited = ranges
|
let edited = ranges
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|range| {
|
.filter_map(|range| {
|
||||||
let start = range.start.to_point(self);
|
let start = range.start.to_point(self);
|
||||||
if new_text.starts_with('\n') && start.column == self.line_len(start.row) {
|
if new_text.starts_with('\n')
|
||||||
|
&& start.column == self.line_len(start.row)
|
||||||
|
{
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self.anchor_before(range.start))
|
Some(self.anchor_before(range.start))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Some((before_edit, edited))
|
(before_edit, edited, autoindent_size)
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let first_newline_ix = new_text.find('\n');
|
let first_newline_ix = new_text.find('\n');
|
||||||
let new_text_len = new_text.len();
|
let new_text_len = new_text.len();
|
||||||
|
@ -1146,7 +1147,7 @@ impl Buffer {
|
||||||
let edit = self.text.edit(ranges.iter().cloned(), new_text);
|
let edit = self.text.edit(ranges.iter().cloned(), new_text);
|
||||||
let edit_id = edit.local_timestamp();
|
let edit_id = edit.local_timestamp();
|
||||||
|
|
||||||
if let Some((before_edit, edited)) = autoindent_request {
|
if let Some((before_edit, edited, size)) = autoindent_request {
|
||||||
let mut inserted = None;
|
let mut inserted = None;
|
||||||
if let Some(first_newline_ix) = first_newline_ix {
|
if let Some(first_newline_ix) = first_newline_ix {
|
||||||
let mut delta = 0isize;
|
let mut delta = 0isize;
|
||||||
|
@ -1169,6 +1170,7 @@ impl Buffer {
|
||||||
before_edit,
|
before_edit,
|
||||||
edited,
|
edited,
|
||||||
inserted,
|
inserted,
|
||||||
|
indent_size: size,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1925,10 +1927,6 @@ impl BufferSnapshot {
|
||||||
pub fn file_update_count(&self) -> usize {
|
pub fn file_update_count(&self) -> usize {
|
||||||
self.file_update_count
|
self.file_update_count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn indent_size(&self) -> u32 {
|
|
||||||
self.indent_size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for BufferSnapshot {
|
impl Clone for BufferSnapshot {
|
||||||
|
@ -1944,7 +1942,6 @@ impl Clone for BufferSnapshot {
|
||||||
file_update_count: self.file_update_count,
|
file_update_count: self.file_update_count,
|
||||||
language: self.language.clone(),
|
language: self.language.clone(),
|
||||||
parse_count: self.parse_count,
|
parse_count: self.parse_count,
|
||||||
indent_size: self.indent_size,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -576,13 +576,13 @@ fn test_edit_with_autoindent(cx: &mut MutableAppContext) {
|
||||||
let text = "fn a() {}";
|
let text = "fn a() {}";
|
||||||
let mut buffer = Buffer::new(0, text, cx).with_language(Arc::new(rust_lang()), cx);
|
let mut buffer = Buffer::new(0, text, cx).with_language(Arc::new(rust_lang()), cx);
|
||||||
|
|
||||||
buffer.edit_with_autoindent([8..8], "\n\n", cx);
|
buffer.edit_with_autoindent([8..8], "\n\n", 4, cx);
|
||||||
assert_eq!(buffer.text(), "fn a() {\n \n}");
|
assert_eq!(buffer.text(), "fn a() {\n \n}");
|
||||||
|
|
||||||
buffer.edit_with_autoindent([Point::new(1, 4)..Point::new(1, 4)], "b()\n", cx);
|
buffer.edit_with_autoindent([Point::new(1, 4)..Point::new(1, 4)], "b()\n", 4, cx);
|
||||||
assert_eq!(buffer.text(), "fn a() {\n b()\n \n}");
|
assert_eq!(buffer.text(), "fn a() {\n b()\n \n}");
|
||||||
|
|
||||||
buffer.edit_with_autoindent([Point::new(2, 4)..Point::new(2, 4)], ".c", cx);
|
buffer.edit_with_autoindent([Point::new(2, 4)..Point::new(2, 4)], ".c", 4, cx);
|
||||||
assert_eq!(buffer.text(), "fn a() {\n b()\n .c\n}");
|
assert_eq!(buffer.text(), "fn a() {\n b()\n .c\n}");
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
|
@ -604,7 +604,12 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut Muta
|
||||||
|
|
||||||
// Lines 2 and 3 don't match the indentation suggestion. When editing these lines,
|
// Lines 2 and 3 don't match the indentation suggestion. When editing these lines,
|
||||||
// their indentation is not adjusted.
|
// their indentation is not adjusted.
|
||||||
buffer.edit_with_autoindent([empty(Point::new(1, 1)), empty(Point::new(2, 1))], "()", cx);
|
buffer.edit_with_autoindent(
|
||||||
|
[empty(Point::new(1, 1)), empty(Point::new(2, 1))],
|
||||||
|
"()",
|
||||||
|
4,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer.text(),
|
buffer.text(),
|
||||||
"
|
"
|
||||||
|
@ -621,6 +626,7 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut Muta
|
||||||
buffer.edit_with_autoindent(
|
buffer.edit_with_autoindent(
|
||||||
[empty(Point::new(1, 1)), empty(Point::new(2, 1))],
|
[empty(Point::new(1, 1)), empty(Point::new(2, 1))],
|
||||||
"\n.f\n.g",
|
"\n.f\n.g",
|
||||||
|
4,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -651,7 +657,7 @@ fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut MutableAppConte
|
||||||
|
|
||||||
let mut buffer = Buffer::new(0, text, cx).with_language(Arc::new(rust_lang()), cx);
|
let mut buffer = Buffer::new(0, text, cx).with_language(Arc::new(rust_lang()), cx);
|
||||||
|
|
||||||
buffer.edit_with_autoindent([5..5], "\nb", cx);
|
buffer.edit_with_autoindent([5..5], "\nb", 4, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer.text(),
|
buffer.text(),
|
||||||
"
|
"
|
||||||
|
@ -663,7 +669,7 @@ fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut MutableAppConte
|
||||||
|
|
||||||
// The indentation suggestion changed because `@end` node (a close paren)
|
// The indentation suggestion changed because `@end` node (a close paren)
|
||||||
// is now at the beginning of the line.
|
// is now at the beginning of the line.
|
||||||
buffer.edit_with_autoindent([Point::new(1, 4)..Point::new(1, 5)], "", cx);
|
buffer.edit_with_autoindent([Point::new(1, 4)..Point::new(1, 5)], "", 4, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer.text(),
|
buffer.text(),
|
||||||
"
|
"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue