select.rs

 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}