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