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
|
@ -9,9 +9,10 @@ use ui::ViewContext;
|
|||
pub(crate) enum IndentDirection {
|
||||
In,
|
||||
Out,
|
||||
Auto,
|
||||
}
|
||||
|
||||
actions!(vim, [Indent, Outdent,]);
|
||||
actions!(vim, [Indent, Outdent, AutoIndent]);
|
||||
|
||||
pub(crate) fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
||||
Vim::action(editor, cx, |vim, _: &Indent, cx| {
|
||||
|
@ -49,6 +50,24 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
vim.switch_mode(Mode::Normal, true, cx)
|
||||
}
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &AutoIndent, cx| {
|
||||
vim.record_current_action(cx);
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
vim.store_visual_marks(cx);
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(cx, |editor, cx| {
|
||||
let original_positions = vim.save_selection_starts(editor, cx);
|
||||
for _ in 0..count {
|
||||
editor.autoindent(&Default::default(), cx);
|
||||
}
|
||||
vim.restore_selection_cursors(editor, cx, original_positions);
|
||||
});
|
||||
});
|
||||
if vim.mode.is_visual() {
|
||||
vim.switch_mode(Mode::Normal, true, cx)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
impl Vim {
|
||||
|
@ -71,10 +90,10 @@ impl Vim {
|
|||
motion.expand_selection(map, selection, times, false, &text_layout_details);
|
||||
});
|
||||
});
|
||||
if dir == IndentDirection::In {
|
||||
editor.indent(&Default::default(), cx);
|
||||
} else {
|
||||
editor.outdent(&Default::default(), cx);
|
||||
match dir {
|
||||
IndentDirection::In => editor.indent(&Default::default(), cx),
|
||||
IndentDirection::Out => editor.outdent(&Default::default(), cx),
|
||||
IndentDirection::Auto => editor.autoindent(&Default::default(), cx),
|
||||
}
|
||||
editor.change_selections(None, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
|
@ -104,10 +123,10 @@ impl Vim {
|
|||
object.expand_selection(map, selection, around);
|
||||
});
|
||||
});
|
||||
if dir == IndentDirection::In {
|
||||
editor.indent(&Default::default(), cx);
|
||||
} else {
|
||||
editor.outdent(&Default::default(), cx);
|
||||
match dir {
|
||||
IndentDirection::In => editor.indent(&Default::default(), cx),
|
||||
IndentDirection::Out => editor.outdent(&Default::default(), cx),
|
||||
IndentDirection::Auto => editor.autoindent(&Default::default(), cx),
|
||||
}
|
||||
editor.change_selections(None, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
|
@ -122,7 +141,11 @@ impl Vim {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::test::NeovimBackedTestContext;
|
||||
use crate::{
|
||||
state::Mode,
|
||||
test::{NeovimBackedTestContext, VimTestContext},
|
||||
};
|
||||
use indoc::indoc;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_indent_gv(cx: &mut gpui::TestAppContext) {
|
||||
|
@ -135,4 +158,46 @@ mod test {
|
|||
.await
|
||||
.assert_eq("« hello\n ˇ» world\n");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_autoindent_op(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
cx.set_state(
|
||||
indoc!(
|
||||
"
|
||||
fn a() {
|
||||
b();
|
||||
c();
|
||||
|
||||
d();
|
||||
ˇe();
|
||||
f();
|
||||
|
||||
g();
|
||||
}
|
||||
"
|
||||
),
|
||||
Mode::Normal,
|
||||
);
|
||||
|
||||
cx.simulate_keystrokes("= a p");
|
||||
cx.assert_state(
|
||||
indoc!(
|
||||
"
|
||||
fn a() {
|
||||
b();
|
||||
c();
|
||||
|
||||
d();
|
||||
ˇe();
|
||||
f();
|
||||
|
||||
g();
|
||||
}
|
||||
"
|
||||
),
|
||||
Mode::Normal,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,6 +170,9 @@ impl Vim {
|
|||
Some(Operator::Indent) => self.indent_motion(motion, times, IndentDirection::In, cx),
|
||||
Some(Operator::Rewrap) => self.rewrap_motion(motion, times, cx),
|
||||
Some(Operator::Outdent) => self.indent_motion(motion, times, IndentDirection::Out, cx),
|
||||
Some(Operator::AutoIndent) => {
|
||||
self.indent_motion(motion, times, IndentDirection::Auto, cx)
|
||||
}
|
||||
Some(Operator::Lowercase) => {
|
||||
self.change_case_motion(motion, times, CaseTarget::Lowercase, cx)
|
||||
}
|
||||
|
@ -202,6 +205,9 @@ impl Vim {
|
|||
Some(Operator::Outdent) => {
|
||||
self.indent_object(object, around, IndentDirection::Out, cx)
|
||||
}
|
||||
Some(Operator::AutoIndent) => {
|
||||
self.indent_object(object, around, IndentDirection::Auto, cx)
|
||||
}
|
||||
Some(Operator::Rewrap) => self.rewrap_object(object, around, cx),
|
||||
Some(Operator::Lowercase) => {
|
||||
self.change_case_object(object, around, CaseTarget::Lowercase, cx)
|
||||
|
|
|
@ -72,6 +72,7 @@ pub enum Operator {
|
|||
Jump { line: bool },
|
||||
Indent,
|
||||
Outdent,
|
||||
AutoIndent,
|
||||
Rewrap,
|
||||
Lowercase,
|
||||
Uppercase,
|
||||
|
@ -465,6 +466,7 @@ impl Operator {
|
|||
Operator::Jump { line: true } => "'",
|
||||
Operator::Jump { line: false } => "`",
|
||||
Operator::Indent => ">",
|
||||
Operator::AutoIndent => "eq",
|
||||
Operator::Rewrap => "gq",
|
||||
Operator::Outdent => "<",
|
||||
Operator::Uppercase => "gU",
|
||||
|
@ -510,6 +512,7 @@ impl Operator {
|
|||
| Operator::Rewrap
|
||||
| Operator::Indent
|
||||
| Operator::Outdent
|
||||
| Operator::AutoIndent
|
||||
| Operator::Lowercase
|
||||
| Operator::Uppercase
|
||||
| Operator::Object { .. }
|
||||
|
|
|
@ -470,6 +470,7 @@ impl Vim {
|
|||
| Operator::Replace
|
||||
| Operator::Indent
|
||||
| Operator::Outdent
|
||||
| Operator::AutoIndent
|
||||
| Operator::Lowercase
|
||||
| Operator::Uppercase
|
||||
| Operator::OppositeCase
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue