Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:36:31.301Z 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

base_keymap_picker.rs

235 lines · 6.5 KB · rust
1use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
2use gpui::{
3    App, Context, DismissEvent, Entity, EventEmitter, Focusable, Render, Task, WeakEntity, Window,
4    actions,
5};
6use picker::{Picker, PickerDelegate};
7use project::Fs;
8use settings::{BaseKeymap, Settings, update_settings_file};
9use std::sync::Arc;
10use ui::{ListItem, ListItemSpacing, prelude::*};
11use util::ResultExt;
12use workspace::{ModalView, Workspace, ui::HighlightedLabel};
13
14actions!(
15    omega,
16    [
17        /// Toggles the base keymap selector modal.
18        #[action(deprecated_aliases = ["zed::ToggleBaseKeymapSelector"])]
19        ToggleBaseKeymapSelector
20    ]
21);
22
23pub fn init(cx: &mut App) {
24    cx.observe_new(|workspace: &mut Workspace, _window, _cx| {
25        workspace.register_action(toggle);
26    })
27    .detach();
28}
29
30pub fn toggle(
31    workspace: &mut Workspace,
32    _: &ToggleBaseKeymapSelector,
33    window: &mut Window,
34    cx: &mut Context<Workspace>,
35) {
36    let fs = workspace.app_state().fs.clone();
37    workspace.toggle_modal(window, cx, |window, cx| {
38        BaseKeymapSelector::new(
39            BaseKeymapSelectorDelegate::new(cx.entity().downgrade(), fs, cx),
40            window,
41            cx,
42        )
43    });
44}
45
46pub struct BaseKeymapSelector {
47    picker: Entity<Picker<BaseKeymapSelectorDelegate>>,
48}
49
50impl Focusable for BaseKeymapSelector {
51    fn focus_handle(&self, cx: &App) -> gpui::FocusHandle {
52        self.picker.focus_handle(cx)
53    }
54}
55
56impl EventEmitter<DismissEvent> for BaseKeymapSelector {}
57impl ModalView for BaseKeymapSelector {}
58
59impl BaseKeymapSelector {
60    pub fn new(
61        delegate: BaseKeymapSelectorDelegate,
62        window: &mut Window,
63        cx: &mut Context<BaseKeymapSelector>,
64    ) -> Self {
65        let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
66        Self { picker }
67    }
68}
69
70impl Render for BaseKeymapSelector {
71    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
72        v_flex().child(self.picker.clone())
73    }
74}
75
76pub struct BaseKeymapSelectorDelegate {
77    selector: WeakEntity<BaseKeymapSelector>,
78    matches: Vec<StringMatch>,
79    selected_index: usize,
80    fs: Arc<dyn Fs>,
81}
82
83impl BaseKeymapSelectorDelegate {
84    fn new(
85        selector: WeakEntity<BaseKeymapSelector>,
86        fs: Arc<dyn Fs>,
87        cx: &mut Context<BaseKeymapSelector>,
88    ) -> Self {
89        let base = BaseKeymap::get(None, cx);
90        let selected_index = BaseKeymap::OPTIONS
91            .iter()
92            .position(|(_, value)| value == base)
93            .unwrap_or(0);
94        Self {
95            selector,
96            matches: Vec::new(),
97            selected_index,
98            fs,
99        }
100    }
101}
102
103impl PickerDelegate for BaseKeymapSelectorDelegate {
104    type ListItem = ui::ListItem;
105
106    fn name() -> &'static str {
107        "base keymap selector"
108    }
109
110    fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
111        "Select a base keymap...".into()
112    }
113
114    fn match_count(&self) -> usize {
115        self.matches.len()
116    }
117
118    fn selected_index(&self) -> usize {
119        self.selected_index
120    }
121
122    fn set_selected_index(
123        &mut self,
124        ix: usize,
125        _window: &mut Window,
126        _: &mut Context<Picker<BaseKeymapSelectorDelegate>>,
127    ) {
128        self.selected_index = ix;
129    }
130
131    fn update_matches(
132        &mut self,
133        query: String,
134        window: &mut Window,
135        cx: &mut Context<Picker<BaseKeymapSelectorDelegate>>,
136    ) -> Task<()> {
137        let background = cx.background_executor().clone();
138        let candidates = BaseKeymap::names()
139            .enumerate()
140            .map(|(id, name)| StringMatchCandidate::new(id, name))
141            .collect::<Vec<_>>();
142
143        cx.spawn_in(window, async move |this, cx| {
144            let matches = if query.is_empty() {
145                candidates
146                    .into_iter()
147                    .enumerate()
148                    .map(|(index, candidate)| StringMatch {
149                        candidate_id: index,
150                        string: candidate.string,
151                        positions: Vec::new(),
152                        score: 0.0,
153                    })
154                    .collect()
155            } else {
156                match_strings(
157                    &candidates,
158                    &query,
159                    false,
160                    true,
161                    100,
162                    &Default::default(),
163                    background,
164                )
165                .await
166            };
167
168            this.update(cx, |this, _| {
169                this.delegate.matches = matches;
170                this.delegate.selected_index = this
171                    .delegate
172                    .selected_index
173                    .min(this.delegate.matches.len().saturating_sub(1));
174            })
175            .log_err();
176        })
177    }
178
179    fn confirm(
180        &mut self,
181        _: bool,
182        _: &mut Window,
183        cx: &mut Context<Picker<BaseKeymapSelectorDelegate>>,
184    ) {
185        if let Some(selection) = self.matches.get(self.selected_index) {
186            let base_keymap = BaseKeymap::from_names(&selection.string);
187
188            telemetry::event!(
189                "Settings Changed",
190                setting = "keymap",
191                value = base_keymap.to_string()
192            );
193
194            update_settings_file(self.fs.clone(), cx, move |setting, _| {
195                setting.base_keymap = Some(base_keymap.into())
196            });
197        }
198
199        self.selector
200            .update(cx, |_, cx| {
201                cx.emit(DismissEvent);
202            })
203            .ok();
204    }
205
206    fn dismissed(&mut self, _: &mut Window, cx: &mut Context<Picker<BaseKeymapSelectorDelegate>>) {
207        self.selector
208            .update(cx, |_, cx| {
209                cx.emit(DismissEvent);
210            })
211            .log_err();
212    }
213
214    fn render_match(
215        &self,
216        ix: usize,
217        selected: bool,
218        _window: &mut Window,
219        _cx: &mut Context<Picker<Self>>,
220    ) -> Option<Self::ListItem> {
221        let keymap_match = &self.matches.get(ix)?;
222
223        Some(
224            ListItem::new(ix)
225                .inset(true)
226                .spacing(ListItemSpacing::Sparse)
227                .toggle_state(selected)
228                .child(HighlightedLabel::new(
229                    keymap_match.string.clone(),
230                    keymap_match.positions.clone(),
231                )),
232        )
233    }
234}
235
Served at tenant.openagents/omega Member data and write actions are omitted.