mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 19:10:24 +00:00
Introduce a Tab
action to indent line or insert soft tabs
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
d36805c464
commit
2018537bb8
2 changed files with 61 additions and 7 deletions
|
@ -1086,12 +1086,15 @@ 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, cx));
|
||||
prev_non_blank_row.map_or(0, |prev_row| self.indent_column_for_line(prev_row));
|
||||
for row in row_range {
|
||||
let request = autoindent_requests.get(&row).unwrap();
|
||||
let row_start = Point::new(row, self.indent_column_for_line(row, cx));
|
||||
let row_start = Point::new(row, self.indent_column_for_line(row));
|
||||
|
||||
eprintln!("autoindent row: {:?}", row);
|
||||
eprintln!(
|
||||
"autoindent row: {:?}, prev_indent_column: {:?}",
|
||||
row, prev_indent_column
|
||||
);
|
||||
|
||||
let mut increase_from_prev_row = false;
|
||||
let mut dedent_to_row = u32::MAX;
|
||||
|
@ -1114,7 +1117,7 @@ impl Buffer {
|
|||
if increase_from_prev_row {
|
||||
indent_column += request.indent_size as u32;
|
||||
} else if dedent_to_row < row {
|
||||
indent_column = self.indent_column_for_line(dedent_to_row, cx);
|
||||
indent_column = self.indent_column_for_line(dedent_to_row);
|
||||
}
|
||||
|
||||
self.set_indent_column_for_line(row, indent_column, cx);
|
||||
|
@ -1133,7 +1136,7 @@ impl Buffer {
|
|||
None
|
||||
}
|
||||
|
||||
fn indent_column_for_line(&mut self, row: u32, cx: &mut ModelContext<Self>) -> u32 {
|
||||
pub fn indent_column_for_line(&self, row: u32) -> u32 {
|
||||
let mut result = 0;
|
||||
for c in self.chars_at(Point::new(row, 0)) {
|
||||
if c == ' ' {
|
||||
|
@ -1146,7 +1149,7 @@ impl Buffer {
|
|||
}
|
||||
|
||||
fn set_indent_column_for_line(&mut self, row: u32, column: u32, cx: &mut ModelContext<Self>) {
|
||||
let current_column = self.indent_column_for_line(row, cx);
|
||||
let current_column = self.indent_column_for_line(row);
|
||||
if column > current_column {
|
||||
let offset = self.visible_text.to_offset(Point::new(row, 0));
|
||||
|
||||
|
@ -1346,6 +1349,10 @@ impl Buffer {
|
|||
self.visible_text.chars_at(offset)
|
||||
}
|
||||
|
||||
pub fn chars_for_range<T: ToOffset>(&self, range: Range<T>) -> impl Iterator<Item = char> + '_ {
|
||||
self.text_for_range(range).flat_map(str::chars)
|
||||
}
|
||||
|
||||
pub fn bytes_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = u8> + '_ {
|
||||
let offset = position.to_offset(self);
|
||||
self.visible_text.bytes_at(offset)
|
||||
|
|
|
@ -38,6 +38,7 @@ action!(Cancel);
|
|||
action!(Backspace);
|
||||
action!(Delete);
|
||||
action!(Input, String);
|
||||
action!(Tab);
|
||||
action!(DeleteLine);
|
||||
action!(DeleteToPreviousWordBoundary);
|
||||
action!(DeleteToNextWordBoundary);
|
||||
|
@ -101,7 +102,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
Input("\n".into()),
|
||||
Some("Editor && mode == auto_height"),
|
||||
),
|
||||
Binding::new("tab", Input("\t".into()), Some("Editor")),
|
||||
Binding::new("tab", Tab, Some("Editor")),
|
||||
Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
|
||||
Binding::new(
|
||||
"alt-backspace",
|
||||
|
@ -195,6 +196,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
cx.add_action(Editor::handle_input);
|
||||
cx.add_action(Editor::backspace);
|
||||
cx.add_action(Editor::delete);
|
||||
cx.add_action(Editor::tab);
|
||||
cx.add_action(Editor::delete_line);
|
||||
cx.add_action(Editor::delete_to_previous_word_boundary);
|
||||
cx.add_action(Editor::delete_to_next_word_boundary);
|
||||
|
@ -962,6 +964,51 @@ impl Editor {
|
|||
self.end_transaction(cx);
|
||||
}
|
||||
|
||||
pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
|
||||
self.start_transaction(cx);
|
||||
let tab_size = self.build_settings.borrow()(cx).tab_size;
|
||||
let mut selections = self.selections(cx).to_vec();
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
let mut last_indented_row = None;
|
||||
for selection in &mut selections {
|
||||
let mut range = selection.point_range(buffer);
|
||||
if range.is_empty() {
|
||||
let char_column = buffer
|
||||
.chars_for_range(Point::new(range.start.row, 0)..range.start)
|
||||
.count();
|
||||
let chars_to_next_tab_stop = tab_size - (char_column % tab_size);
|
||||
buffer.edit(
|
||||
[range.start..range.start],
|
||||
" ".repeat(chars_to_next_tab_stop),
|
||||
cx,
|
||||
);
|
||||
range.start.column += chars_to_next_tab_stop as u32;
|
||||
|
||||
let head = buffer.anchor_before(range.start);
|
||||
selection.start = head.clone();
|
||||
selection.end = head;
|
||||
} else {
|
||||
for row in range.start.row..=range.end.row {
|
||||
if last_indented_row != Some(row) {
|
||||
let char_column = buffer.indent_column_for_line(row) as usize;
|
||||
let chars_to_next_tab_stop = tab_size - (char_column % tab_size);
|
||||
let row_start = Point::new(row, 0);
|
||||
buffer.edit(
|
||||
[row_start..row_start],
|
||||
" ".repeat(chars_to_next_tab_stop),
|
||||
cx,
|
||||
);
|
||||
last_indented_row = Some(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.update_selections(selections, true, cx);
|
||||
self.end_transaction(cx);
|
||||
}
|
||||
|
||||
pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext<Self>) {
|
||||
self.start_transaction(cx);
|
||||
|
||||
|
|
Loading…
Reference in a new issue