indent.rs

 1use crate::{motion::Motion, object::Object, Vim};
 2use collections::HashMap;
 3use editor::{display_map::ToDisplayPoint, Bias};
 4use language::SelectionGoal;
 5use ui::ViewContext;
 6
 7#[derive(PartialEq, Eq)]
 8pub(crate) enum IndentDirection {
 9    In,
10    Out,
11}
12
13impl Vim {
14    pub(crate) fn indent_motion(
15        &mut self,
16        motion: Motion,
17        times: Option<usize>,
18        dir: IndentDirection,
19        cx: &mut ViewContext<Self>,
20    ) {
21        self.stop_recording(cx);
22        self.update_editor(cx, |_, editor, cx| {
23            let text_layout_details = editor.text_layout_details(cx);
24            editor.transact(cx, |editor, cx| {
25                let mut selection_starts: HashMap<_, _> = Default::default();
26                editor.change_selections(None, cx, |s| {
27                    s.move_with(|map, selection| {
28                        let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
29                        selection_starts.insert(selection.id, anchor);
30                        motion.expand_selection(map, selection, times, false, &text_layout_details);
31                    });
32                });
33                if dir == IndentDirection::In {
34                    editor.indent(&Default::default(), cx);
35                } else {
36                    editor.outdent(&Default::default(), cx);
37                }
38                editor.change_selections(None, cx, |s| {
39                    s.move_with(|map, selection| {
40                        let anchor = selection_starts.remove(&selection.id).unwrap();
41                        selection.collapse_to(anchor.to_display_point(map), SelectionGoal::None);
42                    });
43                });
44            });
45        });
46    }
47
48    pub(crate) fn indent_object(
49        &mut self,
50        object: Object,
51        around: bool,
52        dir: IndentDirection,
53        cx: &mut ViewContext<Self>,
54    ) {
55        self.stop_recording(cx);
56        self.update_editor(cx, |_, editor, cx| {
57            editor.transact(cx, |editor, cx| {
58                let mut original_positions: HashMap<_, _> = Default::default();
59                editor.change_selections(None, cx, |s| {
60                    s.move_with(|map, selection| {
61                        let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
62                        original_positions.insert(selection.id, anchor);
63                        object.expand_selection(map, selection, around);
64                    });
65                });
66                if dir == IndentDirection::In {
67                    editor.indent(&Default::default(), cx);
68                } else {
69                    editor.outdent(&Default::default(), cx);
70                }
71                editor.change_selections(None, cx, |s| {
72                    s.move_with(|map, selection| {
73                        let anchor = original_positions.remove(&selection.id).unwrap();
74                        selection.collapse_to(anchor.to_display_point(map), SelectionGoal::None);
75                    });
76                });
77            });
78        });
79    }
80}