Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:30:46.550Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

rewrap.rs

151 lines · 5.9 KB · rust
1use crate::{Vim, motion::Motion, object::Object, state::Mode};
2use collections::HashMap;
3use editor::{Bias, Editor, RewrapOptions, SelectionEffects, display_map::ToDisplayPoint};
4use gpui::{Action, Context, Window};
5use language::SelectionGoal;
6use schemars::JsonSchema;
7use serde::Deserialize;
8
9/// Rewraps the selected text to fit within the line width.
10#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
11#[action(namespace = vim)]
12pub(crate) struct Rewrap {
13    pub line_length: Option<usize>,
14}
15
16pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
17    Vim::action(editor, cx, |vim, action: &Rewrap, window, cx| {
18        vim.record_current_action(cx);
19        Vim::take_count(cx);
20        Vim::take_forced_motion(cx);
21        vim.store_visual_marks(window, cx);
22        vim.update_editor(cx, |vim, editor, cx| {
23            editor.transact(window, cx, |editor, window, cx| {
24                let mut positions = vim.save_selection_starts(editor, cx);
25                editor.rewrap(
26                    RewrapOptions {
27                        override_language_settings: true,
28                        line_length: action.line_length,
29                        ..Default::default()
30                    },
31                    cx,
32                );
33                editor.change_selections(Default::default(), window, cx, |s| {
34                    s.move_with(&mut |map, selection| {
35                        if let Some(anchor) = positions.remove(&selection.id) {
36                            let mut point = anchor.to_display_point(map);
37                            *point.column_mut() = 0;
38                            selection.collapse_to(point, SelectionGoal::None);
39                        }
40                    });
41                });
42            });
43        });
44        if vim.mode.is_visual() {
45            vim.switch_mode(Mode::Normal, true, window, cx)
46        }
47    });
48}
49
50impl Vim {
51    pub(crate) fn rewrap_motion(
52        &mut self,
53        motion: Motion,
54        times: Option<usize>,
55        forced_motion: bool,
56        window: &mut Window,
57        cx: &mut Context<Self>,
58    ) {
59        self.stop_recording(cx);
60        self.update_editor(cx, |_, editor, cx| {
61            let text_layout_details = editor.text_layout_details(window, cx);
62            editor.transact(window, cx, |editor, window, cx| {
63                let mut selection_starts: HashMap<_, _> = Default::default();
64                editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
65                    s.move_with(&mut |map, selection| {
66                        let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
67                        selection_starts.insert(selection.id, anchor);
68                        motion.expand_selection(
69                            map,
70                            selection,
71                            times,
72                            &text_layout_details,
73                            forced_motion,
74                        );
75                    });
76                });
77                editor.rewrap(
78                    RewrapOptions {
79                        override_language_settings: true,
80                        ..Default::default()
81                    },
82                    cx,
83                );
84                editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
85                    s.move_with(&mut |map, selection| {
86                        let anchor = selection_starts.remove(&selection.id).unwrap();
87                        let mut point = anchor.to_display_point(map);
88                        *point.column_mut() = 0;
89                        selection.collapse_to(point, SelectionGoal::None);
90                    });
91                });
92            });
93        });
94    }
95
96    pub(crate) fn rewrap_object(
97        &mut self,
98        object: Object,
99        around: bool,
100        times: Option<usize>,
101        window: &mut Window,
102        cx: &mut Context<Self>,
103    ) {
104        self.stop_recording(cx);
105        self.update_editor(cx, |_, editor, cx| {
106            editor.transact(window, cx, |editor, window, cx| {
107                let mut original_positions: HashMap<_, _> = Default::default();
108                editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
109                    s.move_with(&mut |map, selection| {
110                        let anchor = map.display_point_to_anchor(selection.head(), Bias::Right);
111                        original_positions.insert(selection.id, anchor);
112                        object.expand_selection(map, selection, around, times);
113                    });
114                });
115                editor.rewrap(
116                    RewrapOptions {
117                        override_language_settings: true,
118                        ..Default::default()
119                    },
120                    cx,
121                );
122                editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
123                    s.move_with(&mut |map, selection| {
124                        let anchor = original_positions.remove(&selection.id).unwrap();
125                        let mut point = anchor.to_display_point(map);
126                        *point.column_mut() = 0;
127                        selection.collapse_to(point, SelectionGoal::None);
128                    });
129                });
130            });
131        });
132    }
133}
134
135#[cfg(test)]
136mod test {
137    use crate::test::NeovimBackedTestContext;
138
139    #[gpui::test]
140    async fn test_indent_gv(cx: &mut gpui::TestAppContext) {
141        let mut cx = NeovimBackedTestContext::new(cx).await;
142        cx.set_neovim_option("shiftwidth=4").await;
143
144        cx.set_shared_state("ˇhello\nworld\n").await;
145        cx.simulate_shared_keystrokes("v j > g v").await;
146        cx.shared_state()
147            .await
148            .assert_eq("«    hello\n ˇ»   world\n");
149    }
150}
151
Served at tenant.openagents/omega Member data and write actions are omitted.