1use text::SelectionGoal;
2use ui::{Context, Window};
3
4use crate::{Vim, helix::object::cursor_range, object::Object, state::ObjectScope};
5
6impl Vim {
7 /// Selects the object each cursor is over.
8 /// Follows helix convention.
9 pub fn select_current_object(
10 &mut self,
11 object: Object,
12 scope: ObjectScope,
13 window: &mut Window,
14 cx: &mut Context<Self>,
15 ) {
16 self.stop_recording(cx);
17 self.update_editor(cx, |_, editor, cx| {
18 editor.change_selections(Default::default(), window, cx, |s| {
19 s.move_with(|map, selection| {
20 let Some(range) = object
21 .helix_range(map, selection.clone(), &scope)
22 .unwrap_or({
23 let vim_range = object.range(map, selection.clone(), &scope, None);
24 vim_range.filter(|r| r.start <= cursor_range(selection, map).start)
25 })
26 else {
27 return;
28 };
29
30 selection.set_head_tail(range.end, range.start, SelectionGoal::None);
31 });
32 });
33 });
34 }
35
36 /// Selects the next object from each cursor which the cursor is not over.
37 /// Follows helix convention.
38 pub fn select_next_object(
39 &mut self,
40 object: Object,
41 around: bool,
42 window: &mut Window,
43 cx: &mut Context<Self>,
44 ) {
45 self.stop_recording(cx);
46 self.update_editor(cx, |_, editor, cx| {
47 editor.change_selections(Default::default(), window, cx, |s| {
48 s.move_with(|map, selection| {
49 let Ok(Some(range)) = object.helix_next_range(map, selection.clone(), around)
50 else {
51 return;
52 };
53
54 selection.set_head_tail(range.end, range.start, SelectionGoal::None);
55 });
56 });
57 });
58 }
59
60 /// Selects the previous object from each cursor which the cursor is not over.
61 /// Follows helix convention.
62 pub fn select_previous_object(
63 &mut self,
64 object: Object,
65 around: bool,
66 window: &mut Window,
67 cx: &mut Context<Self>,
68 ) {
69 self.stop_recording(cx);
70 self.update_editor(cx, |_, editor, cx| {
71 editor.change_selections(Default::default(), window, cx, |s| {
72 s.move_with(|map, selection| {
73 let Ok(Some(range)) =
74 object.helix_previous_range(map, selection.clone(), around)
75 else {
76 return;
77 };
78
79 selection.set_head_tail(range.start, range.end, SelectionGoal::None);
80 });
81 });
82 });
83 }
84}