mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 02:46:43 +00:00
Add insert line above and below
This commit is contained in:
parent
833a7b6e76
commit
b2138f5935
3 changed files with 72 additions and 23 deletions
|
@ -66,7 +66,9 @@
|
||||||
"shift-A": "vim::InsertEndOfLine",
|
"shift-A": "vim::InsertEndOfLine",
|
||||||
"x": "vim::DeleteRight",
|
"x": "vim::DeleteRight",
|
||||||
"shift-X": "vim::DeleteLeft",
|
"shift-X": "vim::DeleteLeft",
|
||||||
"shift-^": "vim::FirstNonWhitespace"
|
"shift-^": "vim::FirstNonWhitespace",
|
||||||
|
"o": "vim::InsertLineBelow",
|
||||||
|
"shift-O": "vim::InsertLineAbove"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1334,6 +1334,19 @@ impl Editor {
|
||||||
self.update_selections(vec![selection], None, cx);
|
self.update_selections(vec![selection], None, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn display_selections(
|
||||||
|
&mut self,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> (DisplaySnapshot, Vec<Selection<DisplayPoint>>) {
|
||||||
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
|
let selections = self
|
||||||
|
.local_selections::<Point>(cx)
|
||||||
|
.into_iter()
|
||||||
|
.map(|selection| selection.map(|point| point.to_display_point(&display_map)))
|
||||||
|
.collect();
|
||||||
|
(display_map, selections)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_selections(
|
pub fn move_selections(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
|
@ -1382,6 +1395,25 @@ impl Editor {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn edit<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = (Range<S>, T)>,
|
||||||
|
S: ToOffset,
|
||||||
|
T: Into<Arc<str>>,
|
||||||
|
{
|
||||||
|
self.buffer.update(cx, |buffer, cx| buffer.edit(edits, cx));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn edit_with_autoindent<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = (Range<S>, T)>,
|
||||||
|
S: ToOffset,
|
||||||
|
T: Into<Arc<str>>,
|
||||||
|
{
|
||||||
|
self.buffer
|
||||||
|
.update(cx, |buffer, cx| buffer.edit_with_autoindent(edits, cx));
|
||||||
|
}
|
||||||
|
|
||||||
fn select(&mut self, Select(phase): &Select, cx: &mut ViewContext<Self>) {
|
fn select(&mut self, Select(phase): &Select, cx: &mut ViewContext<Self>) {
|
||||||
self.hide_context_menu(cx);
|
self.hide_context_menu(cx);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ use crate::{
|
||||||
Vim,
|
Vim,
|
||||||
};
|
};
|
||||||
use change::init as change_init;
|
use change::init as change_init;
|
||||||
|
use collections::HashSet;
|
||||||
|
use editor::{Bias, DisplayPoint};
|
||||||
use gpui::{actions, MutableAppContext, ViewContext};
|
use gpui::{actions, MutableAppContext, ViewContext};
|
||||||
use language::SelectionGoal;
|
use language::SelectionGoal;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
@ -120,41 +122,54 @@ fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContex
|
||||||
vim.switch_mode(Mode::Insert, cx);
|
vim.switch_mode(Mode::Insert, cx);
|
||||||
vim.update_active_editor(cx, |editor, cx| {
|
vim.update_active_editor(cx, |editor, cx| {
|
||||||
editor.transact(cx, |editor, cx| {
|
editor.transact(cx, |editor, cx| {
|
||||||
editor.move_cursors(cx, |map, cursor, goal| {
|
let (map, old_selections) = editor.display_selections(cx);
|
||||||
let (indent, _) = map.line_indent(cursor.row());
|
let selection_start_rows: HashSet<u32> = old_selections
|
||||||
let (cursor, _) = Motion::EndOfLine.move_point(map, cursor, goal);
|
.into_iter()
|
||||||
(cursor, SelectionGoal::Column(indent))
|
.map(|selection| selection.start.row())
|
||||||
|
.collect();
|
||||||
|
let edits = selection_start_rows.into_iter().map(|row| {
|
||||||
|
let (indent, _) = map.line_indent(row);
|
||||||
|
let start_of_line = map
|
||||||
|
.clip_point(DisplayPoint::new(row, 0), Bias::Left)
|
||||||
|
.to_point(&map);
|
||||||
|
let mut new_text = " ".repeat(indent as usize);
|
||||||
|
new_text.push('\n');
|
||||||
|
(start_of_line..start_of_line, new_text)
|
||||||
});
|
});
|
||||||
editor.insert("\n", cx);
|
editor.edit(edits, cx);
|
||||||
editor.move_cursors(cx, |_, mut cursor, goal| {
|
editor.move_cursors(cx, |map, mut cursor, _| {
|
||||||
if let SelectionGoal::Column(column) = goal {
|
*cursor.row_mut() -= 1;
|
||||||
*cursor.column_mut() = column;
|
*cursor.column_mut() = map.line_len(cursor.row());
|
||||||
}
|
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
||||||
(cursor, SelectionGoal::None)
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_line_below(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContext<Workspace>) {
|
fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContext<Workspace>) {
|
||||||
Vim::update(cx, |vim, cx| {
|
Vim::update(cx, |vim, cx| {
|
||||||
vim.switch_mode(Mode::Insert, cx);
|
vim.switch_mode(Mode::Insert, cx);
|
||||||
vim.update_active_editor(cx, |editor, cx| {
|
vim.update_active_editor(cx, |editor, cx| {
|
||||||
editor.transact(cx, |editor, cx| {
|
editor.transact(cx, |editor, cx| {
|
||||||
|
let (map, old_selections) = editor.display_selections(cx);
|
||||||
|
let selection_end_rows: HashSet<u32> = old_selections
|
||||||
|
.into_iter()
|
||||||
|
.map(|selection| selection.end.row())
|
||||||
|
.collect();
|
||||||
|
let edits = selection_end_rows.into_iter().map(|row| {
|
||||||
|
let (indent, _) = map.line_indent(row);
|
||||||
|
let end_of_line = map
|
||||||
|
.clip_point(DisplayPoint::new(row, map.line_len(row)), Bias::Left)
|
||||||
|
.to_point(&map);
|
||||||
|
let mut new_text = "\n".to_string();
|
||||||
|
new_text.push_str(&" ".repeat(indent as usize));
|
||||||
|
(end_of_line..end_of_line, new_text)
|
||||||
|
});
|
||||||
editor.move_cursors(cx, |map, cursor, goal| {
|
editor.move_cursors(cx, |map, cursor, goal| {
|
||||||
let (indent, _) = map.line_indent(cursor.row());
|
Motion::EndOfLine.move_point(map, cursor, goal)
|
||||||
let (cursor, _) = Motion::StartOfLine.move_point(map, cursor, goal);
|
|
||||||
(cursor, SelectionGoal::Column(indent))
|
|
||||||
});
|
|
||||||
editor.insert("\n", cx);
|
|
||||||
editor.move_cursors(cx, |_, mut cursor, goal| {
|
|
||||||
*cursor.row_mut() -= 1;
|
|
||||||
if let SelectionGoal::Column(column) = goal {
|
|
||||||
*cursor.column_mut() = column;
|
|
||||||
}
|
|
||||||
(cursor, SelectionGoal::None)
|
|
||||||
});
|
});
|
||||||
|
editor.edit(edits, cx);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue