Add | as a bracket and a motion

Although vim/nvim doesn't have | as brackets, it's common in langauges like Rust
and Ruby, and I expect it to work.
This commit is contained in:
Conrad Irwin 2023-10-22 22:04:55 -06:00
parent 9589f5573d
commit 3cf98c4fae
4 changed files with 119 additions and 181 deletions

View file

@ -39,6 +39,7 @@
"w": "vim::NextWordStart",
"{": "vim::StartOfParagraph",
"}": "vim::EndOfParagraph",
"|": "vim::GoToColumn",
"shift-w": [
"vim::NextWordStart",
{
@ -97,14 +98,8 @@
"ctrl-o": "pane::GoBack",
"ctrl-i": "pane::GoForward",
"ctrl-]": "editor::GoToDefinition",
"escape": [
"vim::SwitchMode",
"Normal"
],
"ctrl+[": [
"vim::SwitchMode",
"Normal"
],
"escape": ["vim::SwitchMode", "Normal"],
"ctrl+[": ["vim::SwitchMode", "Normal"],
"v": "vim::ToggleVisual",
"shift-v": "vim::ToggleVisualLine",
"ctrl-v": "vim::ToggleVisualBlock",
@ -233,123 +228,36 @@
}
],
// Count support
"1": [
"vim::Number",
1
],
"2": [
"vim::Number",
2
],
"3": [
"vim::Number",
3
],
"4": [
"vim::Number",
4
],
"5": [
"vim::Number",
5
],
"6": [
"vim::Number",
6
],
"7": [
"vim::Number",
7
],
"8": [
"vim::Number",
8
],
"9": [
"vim::Number",
9
],
"1": ["vim::Number", 1],
"2": ["vim::Number", 2],
"3": ["vim::Number", 3],
"4": ["vim::Number", 4],
"5": ["vim::Number", 5],
"6": ["vim::Number", 6],
"7": ["vim::Number", 7],
"8": ["vim::Number", 8],
"9": ["vim::Number", 9],
// window related commands (ctrl-w X)
"ctrl-w left": [
"workspace::ActivatePaneInDirection",
"Left"
],
"ctrl-w right": [
"workspace::ActivatePaneInDirection",
"Right"
],
"ctrl-w up": [
"workspace::ActivatePaneInDirection",
"Up"
],
"ctrl-w down": [
"workspace::ActivatePaneInDirection",
"Down"
],
"ctrl-w h": [
"workspace::ActivatePaneInDirection",
"Left"
],
"ctrl-w l": [
"workspace::ActivatePaneInDirection",
"Right"
],
"ctrl-w k": [
"workspace::ActivatePaneInDirection",
"Up"
],
"ctrl-w j": [
"workspace::ActivatePaneInDirection",
"Down"
],
"ctrl-w ctrl-h": [
"workspace::ActivatePaneInDirection",
"Left"
],
"ctrl-w ctrl-l": [
"workspace::ActivatePaneInDirection",
"Right"
],
"ctrl-w ctrl-k": [
"workspace::ActivatePaneInDirection",
"Up"
],
"ctrl-w ctrl-j": [
"workspace::ActivatePaneInDirection",
"Down"
],
"ctrl-w shift-left": [
"workspace::SwapPaneInDirection",
"Left"
],
"ctrl-w shift-right": [
"workspace::SwapPaneInDirection",
"Right"
],
"ctrl-w shift-up": [
"workspace::SwapPaneInDirection",
"Up"
],
"ctrl-w shift-down": [
"workspace::SwapPaneInDirection",
"Down"
],
"ctrl-w shift-h": [
"workspace::SwapPaneInDirection",
"Left"
],
"ctrl-w shift-l": [
"workspace::SwapPaneInDirection",
"Right"
],
"ctrl-w shift-k": [
"workspace::SwapPaneInDirection",
"Up"
],
"ctrl-w shift-j": [
"workspace::SwapPaneInDirection",
"Down"
],
"ctrl-w left": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-w right": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-w up": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-w down": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-w h": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-w l": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-w k": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-w j": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-w ctrl-h": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-w ctrl-l": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-w ctrl-k": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-w ctrl-j": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-w shift-left": ["workspace::SwapPaneInDirection", "Left"],
"ctrl-w shift-right": ["workspace::SwapPaneInDirection", "Right"],
"ctrl-w shift-up": ["workspace::SwapPaneInDirection", "Up"],
"ctrl-w shift-down": ["workspace::SwapPaneInDirection", "Down"],
"ctrl-w shift-h": ["workspace::SwapPaneInDirection", "Left"],
"ctrl-w shift-l": ["workspace::SwapPaneInDirection", "Right"],
"ctrl-w shift-k": ["workspace::SwapPaneInDirection", "Up"],
"ctrl-w shift-j": ["workspace::SwapPaneInDirection", "Down"],
"ctrl-w g t": "pane::ActivateNextItem",
"ctrl-w ctrl-g t": "pane::ActivateNextItem",
"ctrl-w g shift-t": "pane::ActivatePrevItem",
@ -371,14 +279,8 @@
"ctrl-w ctrl-q": "pane::CloseAllItems",
"ctrl-w o": "workspace::CloseInactiveTabsAndPanes",
"ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes",
"ctrl-w n": [
"workspace::NewFileInDirection",
"Up"
],
"ctrl-w ctrl-n": [
"workspace::NewFileInDirection",
"Up"
]
"ctrl-w n": ["workspace::NewFileInDirection", "Up"],
"ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"]
}
},
{
@ -393,21 +295,12 @@
"context": "Editor && vim_mode == normal && vim_operator == none && !VimWaiting",
"bindings": {
".": "vim::Repeat",
"c": [
"vim::PushOperator",
"Change"
],
"c": ["vim::PushOperator", "Change"],
"shift-c": "vim::ChangeToEndOfLine",
"d": [
"vim::PushOperator",
"Delete"
],
"d": ["vim::PushOperator", "Delete"],
"shift-d": "vim::DeleteToEndOfLine",
"shift-j": "vim::JoinLines",
"y": [
"vim::PushOperator",
"Yank"
],
"y": ["vim::PushOperator", "Yank"],
"shift-y": "vim::YankLine",
"i": "vim::InsertBefore",
"shift-i": "vim::InsertFirstNonWhitespace",
@ -443,10 +336,7 @@
"backwards": true
}
],
"r": [
"vim::PushOperator",
"Replace"
],
"r": ["vim::PushOperator", "Replace"],
"s": "vim::Substitute",
"shift-s": "vim::SubstituteLine",
"> >": "editor::Indent",
@ -458,10 +348,7 @@
{
"context": "Editor && VimCount",
"bindings": {
"0": [
"vim::Number",
0
]
"0": ["vim::Number", 0]
}
},
{
@ -497,12 +384,15 @@
"'": "vim::Quotes",
"`": "vim::BackQuotes",
"\"": "vim::DoubleQuotes",
"|": "vim::VerticalBars",
"(": "vim::Parentheses",
")": "vim::Parentheses",
"b": "vim::Parentheses",
"[": "vim::SquareBrackets",
"]": "vim::SquareBrackets",
"{": "vim::CurlyBrackets",
"}": "vim::CurlyBrackets",
"shift-b": "vim::CurlyBrackets",
"<": "vim::AngleBrackets",
">": "vim::AngleBrackets"
}
@ -548,22 +438,10 @@
"shift-i": "vim::InsertBefore",
"shift-a": "vim::InsertAfter",
"shift-j": "vim::JoinLines",
"r": [
"vim::PushOperator",
"Replace"
],
"ctrl-c": [
"vim::SwitchMode",
"Normal"
],
"escape": [
"vim::SwitchMode",
"Normal"
],
"ctrl+[": [
"vim::SwitchMode",
"Normal"
],
"r": ["vim::PushOperator", "Replace"],
"ctrl-c": ["vim::SwitchMode", "Normal"],
"escape": ["vim::SwitchMode", "Normal"],
"ctrl+[": ["vim::SwitchMode", "Normal"],
">": "editor::Indent",
"<": "editor::Outdent",
"i": [
@ -602,14 +480,8 @@
"bindings": {
"tab": "vim::Tab",
"enter": "vim::Enter",
"escape": [
"vim::SwitchMode",
"Normal"
],
"ctrl+[": [
"vim::SwitchMode",
"Normal"
]
"escape": ["vim::SwitchMode", "Normal"],
"ctrl+[": ["vim::SwitchMode", "Normal"]
}
},
{

View file

@ -40,6 +40,7 @@ pub enum Motion {
NextLineStart,
StartOfLineDownward,
EndOfLineDownward,
GoToColumn,
}
#[derive(Clone, Deserialize, PartialEq)]
@ -119,6 +120,7 @@ actions!(
NextLineStart,
StartOfLineDownward,
EndOfLineDownward,
GoToColumn,
]
);
impl_actions!(
@ -215,6 +217,7 @@ pub fn init(cx: &mut AppContext) {
cx.add_action(|_: &mut Workspace, &EndOfLineDownward, cx: _| {
motion(Motion::EndOfLineDownward, cx)
});
cx.add_action(|_: &mut Workspace, &GoToColumn, cx: _| motion(Motion::GoToColumn, cx));
cx.add_action(|_: &mut Workspace, action: &RepeatFind, cx: _| {
repeat_motion(action.backwards, cx)
})
@ -292,6 +295,7 @@ impl Motion {
| Right
| StartOfLine { .. }
| EndOfLineDownward
| GoToColumn
| NextWordStart { .. }
| PreviousWordStart { .. }
| FirstNonWhitespace { .. }
@ -317,6 +321,7 @@ impl Motion {
| EndOfParagraph
| StartOfLineDownward
| EndOfLineDownward
| GoToColumn
| NextWordStart { .. }
| PreviousWordStart { .. }
| FirstNonWhitespace { .. }
@ -346,6 +351,7 @@ impl Motion {
| StartOfLineDownward
| StartOfParagraph
| EndOfParagraph
| GoToColumn
| NextWordStart { .. }
| PreviousWordStart { .. }
| FirstNonWhitespace { .. }
@ -429,6 +435,7 @@ impl Motion {
NextLineStart => (next_line_start(map, point, times), SelectionGoal::None),
StartOfLineDownward => (next_line_start(map, point, times - 1), SelectionGoal::None),
EndOfLineDownward => (next_line_end(map, point, times), SelectionGoal::None),
GoToColumn => (go_to_column(map, point, times), SelectionGoal::None),
};
(new_point != point || infallible).then_some((new_point, goal))
@ -919,6 +926,11 @@ fn next_line_start(map: &DisplaySnapshot, point: DisplayPoint, times: usize) ->
first_non_whitespace(map, false, correct_line)
}
fn go_to_column(map: &DisplaySnapshot, point: DisplayPoint, times: usize) -> DisplayPoint {
let correct_line = start_of_relative_buffer_row(map, point, 0);
right(map, correct_line, times.saturating_sub(1))
}
pub(crate) fn next_line_end(
map: &DisplaySnapshot,
mut point: DisplayPoint,

View file

@ -20,6 +20,7 @@ pub enum Object {
Quotes,
BackQuotes,
DoubleQuotes,
VerticalBars,
Parentheses,
SquareBrackets,
CurlyBrackets,
@ -40,6 +41,7 @@ actions!(
Quotes,
BackQuotes,
DoubleQuotes,
VerticalBars,
Parentheses,
SquareBrackets,
CurlyBrackets,
@ -64,6 +66,7 @@ pub fn init(cx: &mut AppContext) {
});
cx.add_action(|_: &mut Workspace, _: &CurlyBrackets, cx: _| object(Object::CurlyBrackets, cx));
cx.add_action(|_: &mut Workspace, _: &AngleBrackets, cx: _| object(Object::AngleBrackets, cx));
cx.add_action(|_: &mut Workspace, _: &VerticalBars, cx: _| object(Object::VerticalBars, cx));
}
fn object(object: Object, cx: &mut WindowContext) {
@ -79,9 +82,11 @@ fn object(object: Object, cx: &mut WindowContext) {
impl Object {
pub fn is_multiline(self) -> bool {
match self {
Object::Word { .. } | Object::Quotes | Object::BackQuotes | Object::DoubleQuotes => {
false
}
Object::Word { .. }
| Object::Quotes
| Object::BackQuotes
| Object::VerticalBars
| Object::DoubleQuotes => false,
Object::Sentence
| Object::Parentheses
| Object::AngleBrackets
@ -96,6 +101,7 @@ impl Object {
Object::Quotes
| Object::BackQuotes
| Object::DoubleQuotes
| Object::VerticalBars
| Object::Parentheses
| Object::SquareBrackets
| Object::CurlyBrackets
@ -111,6 +117,7 @@ impl Object {
| Object::Quotes
| Object::BackQuotes
| Object::DoubleQuotes
| Object::VerticalBars
| Object::Parentheses
| Object::SquareBrackets
| Object::CurlyBrackets
@ -142,6 +149,9 @@ impl Object {
Object::DoubleQuotes => {
surrounding_markers(map, relative_to, around, self.is_multiline(), '"', '"')
}
Object::VerticalBars => {
surrounding_markers(map, relative_to, around, self.is_multiline(), '|', '|')
}
Object::Parentheses => {
surrounding_markers(map, relative_to, around, self.is_multiline(), '(', ')')
}
@ -568,7 +578,10 @@ fn surrounding_markers(
mod test {
use indoc::indoc;
use crate::test::{ExemptionFeatures, NeovimBackedTestContext};
use crate::{
state::Mode,
test::{ExemptionFeatures, NeovimBackedTestContext, VimTestContext},
};
const WORD_LOCATIONS: &'static str = indoc! {"
The quick ˇbrowˇnˇ
@ -940,6 +953,47 @@ mod test {
.await;
}
#[gpui::test]
async fn test_vertical_bars(cx: &mut gpui::TestAppContext) {
let mut cx = VimTestContext::new(cx, true).await;
cx.set_state(
indoc! {"
fn boop() {
baz(ˇ|a, b| { bar(|j, k| { })})
}"
},
Mode::Normal,
);
cx.simulate_keystrokes(["c", "i", "|"]);
cx.assert_state(
indoc! {"
fn boop() {
baz(|ˇ| { bar(|j, k| { })})
}"
},
Mode::Insert,
);
cx.simulate_keystrokes(["escape", "1", "8", "|"]);
cx.assert_state(
indoc! {"
fn boop() {
baz(|| { bar(ˇ|j, k| { })})
}"
},
Mode::Normal,
);
cx.simulate_keystrokes(["v", "a", "|"]);
cx.assert_state(
indoc! {"
fn boop() {
baz(|| { bar(«|j, k| ˇ»{ })})
}"
},
Mode::Visual,
);
}
#[gpui::test]
async fn test_delete_surrounding_character_objects(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;

View file

@ -8,7 +8,7 @@
{"Key":"i"}
{"Key":"{"}
{"Get":{"state":"func empty(a string) bool {\n if a == \"\" {\n« return true\nˇ» }\n return false\n}","mode":"Visual"}}
{"Put":{"state":"func empty(a string) bool {\n if a == \"\" {\n ˇreturn true\n }\n return false\n}"}}
{"Put":{"state":"func empty(a string) bool {\n if a == \"\" ˇ{\n return true\n }\n return false\n}"}}
{"Key":"v"}
{"Key":"i"}
{"Key":"{"}