refactor(vim): leverage scope in normal object

dino created

Update `vim::normal::Vim.normal_object` to always provide the scope to
the functions being called.

Change summary

crates/vim/src/command.rs                |  6 
crates/vim/src/helix/select.rs           |  9 +-
crates/vim/src/indent.rs                 | 11 ++
crates/vim/src/normal.rs                 | 38 ++++-----
crates/vim/src/normal/change.rs          |  7 -
crates/vim/src/normal/convert.rs         |  6 
crates/vim/src/normal/delete.rs          | 18 +++-
crates/vim/src/normal/paste.rs           |  6 
crates/vim/src/normal/toggle_comments.rs |  6 
crates/vim/src/normal/yank.rs            |  6 
crates/vim/src/object.rs                 | 95 ++++++++++++-------------
crates/vim/src/replace.rs                |  6 
crates/vim/src/rewrap.rs                 | 11 ++
crates/vim/src/state.rs                  | 36 +++++++++
crates/vim/src/surrounds.rs              | 19 +++-
crates/vim/src/vim.rs                    |  7 -
crates/vim/src/visual.rs                 | 21 +----
17 files changed, 172 insertions(+), 136 deletions(-)

Detailed changes

crates/vim/src/command.rs 🔗

@@ -47,7 +47,7 @@ use crate::{
         search::{FindCommand, ReplaceCommand, Replacement},
     },
     object::Object,
-    state::{Mark, Mode},
+    state::{Mark, Mode, ObjectScope},
     visual::VisualDeleteLine,
 };
 
@@ -2043,7 +2043,7 @@ impl Vim {
     pub fn shell_command_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         window: &mut Window,
         cx: &mut Context<Vim>,
     ) {
@@ -2057,7 +2057,7 @@ impl Vim {
                 .selections
                 .newest_display(&editor.display_snapshot(cx));
             let range = object
-                .range(&snapshot, start.clone(), around, true, None)
+                .range(&snapshot, start.clone(), &scope, None)
                 .unwrap_or(start.range());
             if range.start != start.start {
                 editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {

crates/vim/src/helix/select.rs 🔗

@@ -1,7 +1,7 @@
 use text::SelectionGoal;
 use ui::{Context, Window};
 
-use crate::{Vim, helix::object::cursor_range, object::Object};
+use crate::{Vim, helix::object::cursor_range, object::Object, state::ObjectScope};
 
 impl Vim {
     /// Selects the object each cursor is over.
@@ -9,7 +9,7 @@ impl Vim {
     pub fn select_current_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         window: &mut Window,
         cx: &mut Context<Self>,
     ) {
@@ -18,10 +18,9 @@ impl Vim {
             editor.change_selections(Default::default(), window, cx, |s| {
                 s.move_with(|map, selection| {
                     let Some(range) = object
-                        .helix_range(map, selection.clone(), around)
+                        .helix_range(map, selection.clone(), scope.around())
                         .unwrap_or({
-                            let vim_range =
-                                object.range(map, selection.clone(), around, true, None);
+                            let vim_range = object.range(map, selection.clone(), &scope, None);
                             vim_range.filter(|r| r.start <= cursor_range(selection, map).start)
                         })
                     else {

crates/vim/src/indent.rs 🔗

@@ -1,4 +1,9 @@
-use crate::{Vim, motion::Motion, object::Object, state::Mode};
+use crate::{
+    Vim,
+    motion::Motion,
+    object::Object,
+    state::{Mode, ObjectScope},
+};
 use collections::HashMap;
 use editor::SelectionEffects;
 use editor::{Bias, Editor, display_map::ToDisplayPoint};
@@ -136,7 +141,7 @@ impl Vim {
     pub(crate) fn indent_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         dir: IndentDirection,
         times: Option<usize>,
         window: &mut Window,
@@ -150,7 +155,7 @@ impl Vim {
                     s.move_with(|map, selection| {
                         let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
                         original_positions.insert(selection.id, anchor);
-                        object.expand_selection(map, selection, around, true, times);
+                        object.expand_selection(map, selection, &scope, times);
                     });
                 });
                 match dir {

crates/vim/src/normal.rs 🔗

@@ -455,34 +455,32 @@ impl Vim {
         let mut waiting_operator: Option<Operator> = None;
         match self.maybe_pop_operator() {
             Some(Operator::Object { scope }) => {
-                let (around, whitespace) = match scope {
+                let (around, _whitespace) = match scope {
                     ObjectScope::Inside => (false, false),
                     ObjectScope::Around => (true, true),
                     ObjectScope::AroundTrimmed => (true, false),
                 };
 
                 match self.maybe_pop_operator() {
-                    Some(Operator::Change) => self.change_object(object, around, times, window, cx),
-                    Some(Operator::Delete) => {
-                        self.delete_object(object, around, whitespace, times, window, cx)
-                    }
-                    Some(Operator::Yank) => self.yank_object(object, around, times, window, cx),
+                    Some(Operator::Change) => self.change_object(object, scope, times, window, cx),
+                    Some(Operator::Delete) => self.delete_object(object, scope, times, window, cx),
+                    Some(Operator::Yank) => self.yank_object(object, scope, times, window, cx),
                     Some(Operator::Indent) => {
-                        self.indent_object(object, around, IndentDirection::In, times, window, cx)
+                        self.indent_object(object, scope, IndentDirection::In, times, window, cx)
                     }
                     Some(Operator::Outdent) => {
-                        self.indent_object(object, around, IndentDirection::Out, times, window, cx)
+                        self.indent_object(object, scope, IndentDirection::Out, times, window, cx)
                     }
                     Some(Operator::AutoIndent) => {
-                        self.indent_object(object, around, IndentDirection::Auto, times, window, cx)
+                        self.indent_object(object, scope, IndentDirection::Auto, times, window, cx)
                     }
                     Some(Operator::ShellCommand) => {
-                        self.shell_command_object(object, around, window, cx);
+                        self.shell_command_object(object, scope, window, cx);
                     }
-                    Some(Operator::Rewrap) => self.rewrap_object(object, around, times, window, cx),
+                    Some(Operator::Rewrap) => self.rewrap_object(object, scope, times, window, cx),
                     Some(Operator::Lowercase) => self.convert_object(
                         object,
-                        around,
+                        scope,
                         ConvertTarget::LowerCase,
                         times,
                         window,
@@ -490,7 +488,7 @@ impl Vim {
                     ),
                     Some(Operator::Uppercase) => self.convert_object(
                         object,
-                        around,
+                        scope,
                         ConvertTarget::UpperCase,
                         times,
                         window,
@@ -498,17 +496,17 @@ impl Vim {
                     ),
                     Some(Operator::OppositeCase) => self.convert_object(
                         object,
-                        around,
+                        scope,
                         ConvertTarget::OppositeCase,
                         times,
                         window,
                         cx,
                     ),
                     Some(Operator::Rot13) => {
-                        self.convert_object(object, around, ConvertTarget::Rot13, times, window, cx)
+                        self.convert_object(object, scope, ConvertTarget::Rot13, times, window, cx)
                     }
                     Some(Operator::Rot47) => {
-                        self.convert_object(object, around, ConvertTarget::Rot47, times, window, cx)
+                        self.convert_object(object, scope, ConvertTarget::Rot47, times, window, cx)
                     }
                     Some(Operator::AddSurrounds { target: None }) => {
                         waiting_operator = Some(Operator::AddSurrounds {
@@ -516,14 +514,14 @@ impl Vim {
                         });
                     }
                     Some(Operator::ToggleComments) => {
-                        self.toggle_comments_object(object, around, times, window, cx)
+                        self.toggle_comments_object(object, scope, times, window, cx)
                     }
                     Some(Operator::ReplaceWithRegister) => {
-                        self.replace_with_register_object(object, around, window, cx)
+                        self.replace_with_register_object(object, scope, window, cx)
                     }
-                    Some(Operator::Exchange) => self.exchange_object(object, around, window, cx),
+                    Some(Operator::Exchange) => self.exchange_object(object, scope, window, cx),
                     Some(Operator::HelixMatch) => {
-                        self.select_current_object(object, around, window, cx)
+                        self.select_current_object(object, scope, window, cx)
                     }
                     _ => {
                         // Can't do anything for namespace operators. Ignoring

crates/vim/src/normal/change.rs 🔗

@@ -2,7 +2,7 @@ use crate::{
     Vim,
     motion::{self, Motion, MotionKind},
     object::Object,
-    state::Mode,
+    state::{Mode, ObjectScope},
 };
 use editor::{
     Bias, DisplayPoint,
@@ -105,7 +105,7 @@ impl Vim {
     pub fn change_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         times: Option<usize>,
         window: &mut Window,
         cx: &mut Context<Self>,
@@ -117,8 +117,7 @@ impl Vim {
             editor.transact(window, cx, |editor, window, cx| {
                 editor.change_selections(Default::default(), window, cx, |s| {
                     s.move_with(|map, selection| {
-                        objects_found |=
-                            object.expand_selection(map, selection, around, true, times);
+                        objects_found |= object.expand_selection(map, selection, &scope, times);
                     });
                 });
                 if objects_found {

crates/vim/src/normal/convert.rs 🔗

@@ -9,7 +9,7 @@ use crate::{
     motion::Motion,
     normal::{ChangeCase, ConvertToLowerCase, ConvertToRot13, ConvertToRot47, ConvertToUpperCase},
     object::Object,
-    state::Mode,
+    state::{Mode, ObjectScope},
 };
 
 pub enum ConvertTarget {
@@ -80,7 +80,7 @@ impl Vim {
     pub fn convert_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         mode: ConvertTarget,
         times: Option<usize>,
         window: &mut Window,
@@ -93,7 +93,7 @@ impl Vim {
                 let mut original_positions: HashMap<_, _> = Default::default();
                 editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
                     s.move_with(|map, selection| {
-                        object.expand_selection(map, selection, around, true, times);
+                        object.expand_selection(map, selection, &scope, times);
                         original_positions.insert(
                             selection.id,
                             map.display_point_to_anchor(selection.start, Bias::Left),

crates/vim/src/normal/delete.rs 🔗

@@ -1,5 +1,5 @@
 use crate::{
-    Vim,
+    ObjectScope, Vim,
     motion::{Motion, MotionKind},
     object::Object,
     state::Mode,
@@ -92,8 +92,7 @@ impl Vim {
     pub fn delete_object(
         &mut self,
         object: Object,
-        around: bool,
-        whitespace: bool,
+        scope: ObjectScope,
         times: Option<usize>,
         window: &mut Window,
         cx: &mut Context<Self>,
@@ -110,7 +109,7 @@ impl Vim {
                 // to the same column it was before deletion if the line is not empty or only
                 // contains whitespace
                 let mut column_before_move: HashMap<_, _> = Default::default();
-                let target_mode = object.target_visual_mode(vim.mode, around);
+                let target_mode = object.target_visual_mode(vim.mode, &scope);
 
                 editor.change_selections(Default::default(), window, cx, |s| {
                     s.move_with(|map, selection| {
@@ -119,7 +118,7 @@ impl Vim {
                             column_before_move.insert(selection.id, cursor_point.column);
                         }
 
-                        object.expand_selection(map, selection, around, whitespace, times);
+                        object.expand_selection(map, selection, &scope, times);
                         let offset_range = selection.map(|p| p.to_offset(map, Bias::Left)).range();
                         let mut move_selection_start_to_previous_line =
                             |map: &DisplaySnapshot, selection: &mut Selection<DisplayPoint>| {
@@ -146,7 +145,10 @@ impl Vim {
                         // If expanded range contains only newlines and
                         // the object is around or sentence, expand to include a newline
                         // at the end or start
-                        if (around || object == Object::Sentence) && contains_only_newlines {
+                        if (matches!(scope, ObjectScope::AroundTrimmed | ObjectScope::Around)
+                            || object == Object::Sentence)
+                            && contains_only_newlines
+                        {
                             if end_at_newline {
                                 move_selection_end_to_next_line(map, selection);
                             } else {
@@ -156,7 +158,9 @@ impl Vim {
 
                         // Does post-processing for the trailing newline and EOF
                         // when not cancelled.
-                        let cancelled = around && selection.start == selection.end;
+                        let cancelled =
+                            matches!(scope, ObjectScope::AroundTrimmed | ObjectScope::Around)
+                                && selection.start == selection.end;
                         if object == Object::Paragraph && !cancelled {
                             // EOF check should be done before including a trailing newline.
                             if ends_at_eof(map, selection) {

crates/vim/src/normal/paste.rs 🔗

@@ -11,7 +11,7 @@ use crate::{
     Vim,
     motion::{Motion, MotionKind},
     object::Object,
-    state::{Mode, Register},
+    state::{Mode, ObjectScope, Register},
 };
 
 /// Pastes text from the specified register at the cursor position.
@@ -233,7 +233,7 @@ impl Vim {
     pub fn replace_with_register_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         window: &mut Window,
         cx: &mut Context<Self>,
     ) {
@@ -244,7 +244,7 @@ impl Vim {
                 editor.set_clip_at_line_ends(false, cx);
                 editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
                     s.move_with(|map, selection| {
-                        object.expand_selection(map, selection, around, true, None);
+                        object.expand_selection(map, selection, &scope, None);
                     });
                 });
 

crates/vim/src/normal/toggle_comments.rs 🔗

@@ -1,4 +1,4 @@
-use crate::{Vim, motion::Motion, object::Object};
+use crate::{ObjectScope, Vim, motion::Motion, object::Object};
 use collections::HashMap;
 use editor::{Bias, SelectionEffects, display_map::ToDisplayPoint};
 use gpui::{Context, Window};
@@ -45,7 +45,7 @@ impl Vim {
     pub fn toggle_comments_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         times: Option<usize>,
         window: &mut Window,
         cx: &mut Context<Self>,
@@ -58,7 +58,7 @@ impl Vim {
                     s.move_with(|map, selection| {
                         let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
                         original_positions.insert(selection.id, anchor);
-                        object.expand_selection(map, selection, around, true, times);
+                        object.expand_selection(map, selection, &scope, times);
                     });
                 });
                 editor.toggle_comments(&Default::default(), window, cx);

crates/vim/src/normal/yank.rs 🔗

@@ -4,7 +4,7 @@ use crate::{
     Vim, VimSettings,
     motion::{Motion, MotionKind},
     object::Object,
-    state::{Mode, Register},
+    state::{Mode, ObjectScope, Register},
 };
 use collections::HashMap;
 use editor::{ClipboardSelection, Editor, SelectionEffects};
@@ -65,7 +65,7 @@ impl Vim {
     pub fn yank_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         times: Option<usize>,
         window: &mut Window,
         cx: &mut Context<Self>,
@@ -76,7 +76,7 @@ impl Vim {
                 let mut start_positions: HashMap<_, _> = Default::default();
                 editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
                     s.move_with(|map, selection| {
-                        object.expand_selection(map, selection, around, true, times);
+                        object.expand_selection(map, selection, &scope, times);
                         let start_position = (selection.start, selection.goal);
                         start_positions.insert(selection.id, start_position);
                     });

crates/vim/src/object.rs 🔗

@@ -510,7 +510,7 @@ impl Object {
         }
     }
 
-    pub fn target_visual_mode(self, current_mode: Mode, around: bool) -> Mode {
+    pub fn target_visual_mode(self, current_mode: Mode, scope: &ObjectScope) -> Mode {
         match self {
             Object::Word { .. }
             | Object::Subword { .. }
@@ -537,13 +537,10 @@ impl Object {
             | Object::Comment
             | Object::Argument
             | Object::IndentObj { .. } => Mode::Visual,
-            Object::Method | Object::Class => {
-                if around {
-                    Mode::VisualLine
-                } else {
-                    Mode::Visual
-                }
-            }
+            Object::Method | Object::Class => match scope {
+                ObjectScope::Around | ObjectScope::AroundTrimmed => Mode::VisualLine,
+                ObjectScope::Inside => Mode::Visual,
+            },
             Object::Paragraph | Object::EntireFile => Mode::VisualLine,
         }
     }
@@ -552,34 +549,33 @@ impl Object {
         self,
         map: &DisplaySnapshot,
         selection: Selection<DisplayPoint>,
-        around: bool,
-        whitespace: bool,
+        scope: &ObjectScope,
         times: Option<usize>,
     ) -> Option<Range<DisplayPoint>> {
         let relative_to = selection.head();
         match self {
             Object::Word { ignore_punctuation } => {
-                if around {
+                if scope.around() {
                     around_word(map, relative_to, ignore_punctuation)
                 } else {
                     in_word(map, relative_to, ignore_punctuation)
                 }
             }
             Object::Subword { ignore_punctuation } => {
-                if around {
+                if scope.around() {
                     around_subword(map, relative_to, ignore_punctuation)
                 } else {
                     in_subword(map, relative_to, ignore_punctuation)
                 }
             }
-            Object::Sentence => sentence(map, relative_to, around),
+            Object::Sentence => sentence(map, relative_to, scope.around()),
             //change others later
-            Object::Paragraph => paragraph(map, relative_to, around, times.unwrap_or(1)),
+            Object::Paragraph => paragraph(map, relative_to, scope.around(), times.unwrap_or(1)),
             Object::Quotes => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '\'',
                 '\'',
@@ -587,8 +583,8 @@ impl Object {
             Object::BackQuotes => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '`',
                 '`',
@@ -606,8 +602,8 @@ impl Object {
                     if let Some(range) = surrounding_markers(
                         map,
                         relative_to,
-                        around,
-                        whitespace,
+                        scope.around(),
+                        scope.whitespace(),
                         self.is_multiline(),
                         quote,
                         quote,
@@ -636,8 +632,8 @@ impl Object {
                         surrounding_markers(
                             map,
                             relative_to,
-                            around,
-                            whitespace,
+                            scope.around(),
+                            scope.whitespace(),
                             self.is_multiline(),
                             quote,
                             quote,
@@ -655,12 +651,12 @@ impl Object {
                         }
                     })
             }
-            Object::MiniQuotes => find_mini_quotes(map, relative_to, around),
+            Object::MiniQuotes => find_mini_quotes(map, relative_to, scope.around()),
             Object::DoubleQuotes => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '"',
                 '"',
@@ -668,8 +664,8 @@ impl Object {
             Object::VerticalBars => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '|',
                 '|',
@@ -677,8 +673,8 @@ impl Object {
             Object::Parentheses => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '(',
                 ')',
@@ -686,7 +682,7 @@ impl Object {
             Object::Tag => {
                 let head = selection.head();
                 let range = selection.range();
-                surrounding_html_tag(map, head, range, around)
+                surrounding_html_tag(map, head, range, scope.around())
             }
             Object::AnyBrackets => {
                 let bracket_pairs = [('(', ')'), ('[', ']'), ('{', '}'), ('<', '>')];
@@ -700,8 +696,8 @@ impl Object {
                     if let Some(range) = surrounding_markers(
                         map,
                         relative_to,
-                        around,
-                        whitespace,
+                        scope.around(),
+                        scope.whitespace(),
                         self.is_multiline(),
                         open,
                         close,
@@ -730,8 +726,8 @@ impl Object {
                         surrounding_markers(
                             map,
                             relative_to,
-                            around,
-                            whitespace,
+                            scope.around(),
+                            scope.whitespace(),
                             self.is_multiline(),
                             open,
                             close,
@@ -749,12 +745,12 @@ impl Object {
                         }
                     })
             }
-            Object::MiniBrackets => find_mini_brackets(map, relative_to, around),
+            Object::MiniBrackets => find_mini_brackets(map, relative_to, scope.around()),
             Object::SquareBrackets => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '[',
                 ']',
@@ -762,8 +758,8 @@ impl Object {
             Object::CurlyBrackets => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '{',
                 '}',
@@ -771,8 +767,8 @@ impl Object {
             Object::AngleBrackets => surrounding_markers(
                 map,
                 relative_to,
-                around,
-                whitespace,
+                scope.around(),
+                scope.whitespace(),
                 self.is_multiline(),
                 '<',
                 '>',
@@ -780,7 +776,7 @@ impl Object {
             Object::Method => text_object(
                 map,
                 relative_to,
-                if around {
+                if scope.around() {
                     TextObject::AroundFunction
                 } else {
                     TextObject::InsideFunction
@@ -789,7 +785,7 @@ impl Object {
             Object::Comment => text_object(
                 map,
                 relative_to,
-                if around {
+                if scope.around() {
                     TextObject::AroundComment
                 } else {
                     TextObject::InsideComment
@@ -798,14 +794,16 @@ impl Object {
             Object::Class => text_object(
                 map,
                 relative_to,
-                if around {
+                if scope.around() {
                     TextObject::AroundClass
                 } else {
                     TextObject::InsideClass
                 },
             ),
-            Object::Argument => argument(map, relative_to, around),
-            Object::IndentObj { include_below } => indent(map, relative_to, around, include_below),
+            Object::Argument => argument(map, relative_to, scope.around()),
+            Object::IndentObj { include_below } => {
+                indent(map, relative_to, scope.around(), include_below)
+            }
             Object::EntireFile => entire_file(map),
         }
     }
@@ -814,11 +812,10 @@ impl Object {
         self,
         map: &DisplaySnapshot,
         selection: &mut Selection<DisplayPoint>,
-        around: bool,
-        whitespace: bool,
+        scope: &ObjectScope,
         times: Option<usize>,
     ) -> bool {
-        if let Some(range) = self.range(map, selection.clone(), around, whitespace, times) {
+        if let Some(range) = self.range(map, selection.clone(), scope, times) {
             selection.start = range.start;
             selection.end = range.end;
             true

crates/vim/src/replace.rs 🔗

@@ -2,7 +2,7 @@ use crate::{
     Vim,
     motion::{self, Motion},
     object::Object,
-    state::Mode,
+    state::{Mode, ObjectScope},
 };
 use editor::{
     Anchor, Bias, Editor, EditorSnapshot, SelectionEffects, ToOffset, ToPoint,
@@ -143,7 +143,7 @@ impl Vim {
     pub fn exchange_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         window: &mut Window,
         cx: &mut Context<Self>,
     ) {
@@ -154,7 +154,7 @@ impl Vim {
                 .selections
                 .newest_display(&editor.display_snapshot(cx));
             let snapshot = editor.snapshot(window, cx);
-            object.expand_selection(&snapshot, &mut selection, around, true, None);
+            object.expand_selection(&snapshot, &mut selection, &scope, None);
             let start = snapshot
                 .buffer_snapshot()
                 .anchor_before(selection.start.to_point(&snapshot));

crates/vim/src/rewrap.rs 🔗

@@ -1,4 +1,9 @@
-use crate::{Vim, motion::Motion, object::Object, state::Mode};
+use crate::{
+    Vim,
+    motion::Motion,
+    object::Object,
+    state::{Mode, ObjectScope},
+};
 use collections::HashMap;
 use editor::{Bias, Editor, RewrapOptions, SelectionEffects, display_map::ToDisplayPoint};
 use gpui::{Context, Window, actions};
@@ -94,7 +99,7 @@ impl Vim {
     pub(crate) fn rewrap_object(
         &mut self,
         object: Object,
-        around: bool,
+        scope: ObjectScope,
         times: Option<usize>,
         window: &mut Window,
         cx: &mut Context<Self>,
@@ -107,7 +112,7 @@ impl Vim {
                     s.move_with(|map, selection| {
                         let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
                         original_positions.insert(selection.id, anchor);
-                        object.expand_selection(map, selection, around, true, times);
+                        object.expand_selection(map, selection, &scope, times);
                     });
                 });
                 editor.rewrap_impl(

crates/vim/src/state.rs 🔗

@@ -2,7 +2,10 @@ use crate::command::command_interceptor;
 use crate::motion::MotionKind;
 use crate::normal::repeat::Replayer;
 use crate::surrounds::SurroundsType;
-use crate::{ToggleMarksView, ToggleRegistersView, UseSystemClipboard, Vim, VimAddon, VimSettings};
+use crate::{
+    PushObject, ToggleMarksView, ToggleRegistersView, UseSystemClipboard, Vim, VimAddon,
+    VimSettings,
+};
 use crate::{motion::Motion, object::Object};
 use anyhow::Result;
 use collections::HashMap;
@@ -171,6 +174,37 @@ pub(crate) enum ObjectScope {
     AroundTrimmed,
 }
 
+impl ObjectScope {
+    // TODO!: This is meant to be removed after everything has been migrated to
+    // work with `ObjectScope` directly.
+    pub(crate) fn around(&self) -> bool {
+        match self {
+            ObjectScope::Inside => false,
+            ObjectScope::Around => true,
+            ObjectScope::AroundTrimmed => true,
+        }
+    }
+
+    // TODO!: This is meant to be removed after everything has been migrated to
+    // work with `ObjectScope` directly.
+    pub(crate) fn whitespace(&self) -> bool {
+        match self {
+            ObjectScope::Inside | ObjectScope::AroundTrimmed => false,
+            ObjectScope::Around => true,
+        }
+    }
+
+    /// Create the `ObjectScope` from a `PushObject` action, taking into account
+    /// its `around` and `whitespace` values.
+    pub(crate) fn from_action(action: &PushObject) -> Self {
+        match (action.around, action.whitespace) {
+            (false, _) => ObjectScope::Inside,
+            (true, true) => ObjectScope::Around,
+            (true, false) => ObjectScope::AroundTrimmed,
+        }
+    }
+}
+
 #[derive(Default, Clone, Debug)]
 pub enum RecordedSelection {
     #[default]

crates/vim/src/surrounds.rs 🔗

@@ -2,7 +2,7 @@ use crate::{
     Vim,
     motion::{self, Motion},
     object::{Object, surrounding_markers},
-    state::Mode,
+    state::{Mode, ObjectScope},
 };
 use editor::{Bias, movement};
 use gpui::{Context, Window};
@@ -53,7 +53,13 @@ impl Vim {
                 for selection in &display_selections {
                     let range = match &target {
                         SurroundsType::Object(object, around) => {
-                            object.range(&display_map, selection.clone(), *around, true, None)
+                            // TODO!: Should `SurroundsType::Object` be updated to also leverage `ObjectScope`?
+                            let scope = match around {
+                                true => ObjectScope::Around,
+                                false => ObjectScope::Inside,
+                            };
+
+                            object.range(&display_map, selection.clone(), &scope, None)
                         }
                         SurroundsType::Motion(motion) => {
                             motion
@@ -152,8 +158,9 @@ impl Vim {
 
                 for selection in &display_selections {
                     let start = selection.start.to_offset(&display_map, Bias::Left);
+                    let scope = ObjectScope::Around;
                     if let Some(range) =
-                        pair_object.range(&display_map, selection.clone(), true, true, None)
+                        pair_object.range(&display_map, selection.clone(), &scope, None)
                     {
                         // If the current parenthesis object is single-line,
                         // then we need to filter whether it is the current line or not
@@ -265,8 +272,9 @@ impl Vim {
 
                     for selection in &selections {
                         let start = selection.start.to_offset(&display_map, Bias::Left);
+                        let scope = ObjectScope::Around;
                         if let Some(range) =
-                            target.range(&display_map, selection.clone(), true, true, None)
+                            target.range(&display_map, selection.clone(), &scope, None)
                         {
                             if !target.is_multiline() {
                                 let is_same_row = selection.start.row() == range.start.row()
@@ -391,8 +399,9 @@ impl Vim {
 
                     for selection in &selections {
                         let start = selection.start.to_offset(&display_map, Bias::Left);
+                        let scope = ObjectScope::Around;
                         if let Some(range) =
-                            object.range(&display_map, selection.clone(), true, true, None)
+                            object.range(&display_map, selection.clone(), &scope, None)
                         {
                             // If the current parenthesis object is single-line,
                             // then we need to filter whether it is the current line or not

crates/vim/src/vim.rs 🔗

@@ -662,12 +662,7 @@ impl Vim {
                 Vim::globals(cx).forced_motion = true;
             });
             Vim::action(editor, cx, |vim, action: &PushObject, window, cx| {
-                let scope = match (action.around, action.whitespace) {
-                    (false, _) => ObjectScope::Inside,
-                    (true, true) => ObjectScope::Around,
-                    (true, false) => ObjectScope::AroundTrimmed,
-                };
-
+                let scope = ObjectScope::from_action(action);
                 vim.push_operator(Operator::Object { scope }, window, cx)
             });
 

crates/vim/src/visual.rs 🔗

@@ -17,7 +17,7 @@ use crate::{
     Vim,
     motion::{Motion, MotionKind, first_non_whitespace, next_line_end, start_of_line},
     object::Object,
-    state::{Mark, Mode, ObjectScope, Operator},
+    state::{Mark, Mode, Operator},
 };
 
 actions!(
@@ -427,14 +427,9 @@ impl Vim {
         cx: &mut Context<Vim>,
     ) {
         if let Some(Operator::Object { scope }) = self.active_operator() {
-            let around = match scope {
-                ObjectScope::Around | ObjectScope::AroundTrimmed => true,
-                ObjectScope::Inside => false,
-            };
-
             self.pop_operator(window, cx);
             let current_mode = self.mode;
-            let target_mode = object.target_visual_mode(current_mode, around);
+            let target_mode = object.target_visual_mode(current_mode, &scope);
             if target_mode != current_mode {
                 self.switch_mode(target_mode, true, window, cx);
             }
@@ -458,7 +453,7 @@ impl Vim {
 
                         let original_point = selection.tail().to_point(map);
 
-                        if let Some(range) = object.range(map, mut_selection, around, true, count) {
+                        if let Some(range) = object.range(map, mut_selection, &scope, count) {
                             if !range.is_empty() {
                                 let expand_both_ways = object.always_expands_both_ways()
                                     || selection.is_empty()
@@ -469,13 +464,9 @@ impl Vim {
                                         && selection.end == range.end
                                         && object.always_expands_both_ways()
                                     {
-                                        if let Some(range) = object.range(
-                                            map,
-                                            selection.clone(),
-                                            around,
-                                            true,
-                                            count,
-                                        ) {
+                                        if let Some(range) =
+                                            object.range(map, selection.clone(), &scope, count)
+                                        {
                                             selection.start = range.start;
                                             selection.end = range.end;
                                         }