select.rs

 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}