Skip to repository content235 lines · 6.5 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T03:36:31.301Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
base_keymap_picker.rs
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