@@ -580,18 +580,18 @@
// "q": "vim::AnyQuotes",
"q": "vim::MiniQuotes",
"|": "vim::VerticalBars",
- "(": "vim::Parentheses",
+ "(": ["vim::Parentheses", { "opening": true }],
")": "vim::Parentheses",
"b": "vim::Parentheses",
// "b": "vim::AnyBrackets",
// "b": "vim::MiniBrackets",
- "[": "vim::SquareBrackets",
+ "[": ["vim::SquareBrackets", { "opening": true }],
"]": "vim::SquareBrackets",
"r": "vim::SquareBrackets",
- "{": "vim::CurlyBrackets",
+ "{": ["vim::CurlyBrackets", { "opening": true }],
"}": "vim::CurlyBrackets",
"shift-b": "vim::CurlyBrackets",
- "<": "vim::AngleBrackets",
+ "<": ["vim::AngleBrackets", { "opening": true }],
">": "vim::AngleBrackets",
"a": "vim::Argument",
"i": "vim::IndentObj",
@@ -85,6 +85,41 @@ pub struct CandidateWithRanges {
close_range: Range<usize>,
}
+/// Selects text at the same indentation level.
+#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
+#[action(namespace = vim)]
+#[serde(deny_unknown_fields)]
+struct Parentheses {
+ #[serde(default)]
+ opening: bool,
+}
+
+/// Selects text at the same indentation level.
+#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
+#[action(namespace = vim)]
+#[serde(deny_unknown_fields)]
+struct SquareBrackets {
+ #[serde(default)]
+ opening: bool,
+}
+
+/// Selects text at the same indentation level.
+#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
+#[action(namespace = vim)]
+#[serde(deny_unknown_fields)]
+struct AngleBrackets {
+ #[serde(default)]
+ opening: bool,
+}
+/// Selects text at the same indentation level.
+#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
+#[action(namespace = vim)]
+#[serde(deny_unknown_fields)]
+struct CurlyBrackets {
+ #[serde(default)]
+ opening: bool,
+}
+
fn cover_or_next<I: Iterator<Item = (Range<usize>, Range<usize>)>>(
candidates: Option<I>,
caret: DisplayPoint,
@@ -275,18 +310,10 @@ actions!(
DoubleQuotes,
/// Selects text within vertical bars (pipes).
VerticalBars,
- /// Selects text within parentheses.
- Parentheses,
/// Selects text within the nearest brackets.
MiniBrackets,
/// Selects text within any type of brackets.
AnyBrackets,
- /// Selects text within square brackets.
- SquareBrackets,
- /// Selects text within curly brackets.
- CurlyBrackets,
- /// Selects text within angle brackets.
- AngleBrackets,
/// Selects a function argument.
Argument,
/// Selects an HTML/XML tag.
@@ -350,17 +377,17 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
Vim::action(editor, cx, |vim, _: &DoubleQuotes, window, cx| {
vim.object(Object::DoubleQuotes, window, cx)
});
- Vim::action(editor, cx, |vim, _: &Parentheses, window, cx| {
- vim.object(Object::Parentheses, window, cx)
+ Vim::action(editor, cx, |vim, action: &Parentheses, window, cx| {
+ vim.object_impl(Object::Parentheses, action.is_opening, window, cx)
});
- Vim::action(editor, cx, |vim, _: &SquareBrackets, window, cx| {
- vim.object(Object::SquareBrackets, window, cx)
+ Vim::action(editor, cx, |vim, action: &SquareBrackets, window, cx| {
+ vim.object_impl(Object::SquareBrackets, action.is_opening, window, cx)
});
- Vim::action(editor, cx, |vim, _: &CurlyBrackets, window, cx| {
- vim.object(Object::CurlyBrackets, window, cx)
+ Vim::action(editor, cx, |vim, action: &CurlyBrackets, window, cx| {
+ vim.object_impl(Object::CurlyBrackets, action.is_opening, window, cx)
});
- Vim::action(editor, cx, |vim, _: &AngleBrackets, window, cx| {
- vim.object(Object::AngleBrackets, window, cx)
+ Vim::action(editor, cx, |vim, action: &AngleBrackets, window, cx| {
+ vim.object_impl(Object::AngleBrackets, action.is_opening, window, cx)
});
Vim::action(editor, cx, |vim, _: &VerticalBars, window, cx| {
vim.object(Object::VerticalBars, window, cx)
@@ -394,10 +421,22 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
impl Vim {
fn object(&mut self, object: Object, window: &mut Window, cx: &mut Context<Self>) {
+ self.object_impl(object, window, false, cx);
+ }
+
+ fn object_impl(
+ &mut self,
+ object: Object,
+ window: &mut Window,
+ is_opening: bool,
+ cx: &mut Context<Self>,
+ ) {
let count = Self::take_count(cx);
match self.mode {
- Mode::Normal | Mode::HelixNormal => self.normal_object(object, count, window, cx),
+ Mode::Normal | Mode::HelixNormal => {
+ self.normal_object(object, count, is_opening, window, cx)
+ }
Mode::Visual | Mode::VisualLine | Mode::VisualBlock | Mode::HelixSelect => {
self.visual_object(object, count, window, cx)
}