Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:00:17.794Z 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

inspector.rs

187 lines · 6.5 KB · rust
1use anyhow::{Context as _, anyhow};
2use gpui::{App, DivInspectorState, Inspector, InspectorElementId, IntoElement, TaskExt, Window};
3use std::{cell::OnceCell, path::Path, sync::Arc};
4use ui::{Label, Tooltip, prelude::*, utils::platform_title_bar_height};
5use util::{ResultExt as _, command::new_command};
6use workspace::AppState;
7
8use crate::div_inspector::DivInspector;
9
10pub fn init(app_state: Arc<AppState>, cx: &mut App) {
11    cx.on_action(|_: &zed_actions::dev::ToggleInspector, cx| {
12        let Some(active_window) = cx
13            .active_window()
14            .context("no active window to toggle inspector")
15            .log_err()
16        else {
17            return;
18        };
19        // This is deferred to avoid double lease due to window already being updated.
20        cx.defer(move |cx| {
21            active_window
22                .update(cx, |_, window, cx| window.toggle_inspector(cx))
23                .log_err();
24        });
25    });
26
27    // Project used for editor buffers with LSP support
28    let project = project::Project::local(
29        app_state.client.clone(),
30        app_state.node_runtime.clone(),
31        app_state.user_store.clone(),
32        app_state.languages.clone(),
33        app_state.fs.clone(),
34        None,
35        project::LocalProjectFlags {
36            init_worktree_trust: false,
37            ..Default::default()
38        },
39        cx,
40    );
41
42    let div_inspector = OnceCell::new();
43    cx.register_inspector_element(move |id, state: &DivInspectorState, window, cx| {
44        let div_inspector = div_inspector
45            .get_or_init(|| cx.new(|cx| DivInspector::new(project.clone(), window, cx)));
46        div_inspector.update(cx, |div_inspector, cx| {
47            div_inspector.update_inspected_element(&id, state.clone(), window, cx);
48            div_inspector.render(window, cx).into_any_element()
49        })
50    });
51
52    cx.set_inspector_renderer(Box::new(render_inspector));
53}
54
55fn render_inspector(
56    inspector: &mut Inspector,
57    window: &mut Window,
58    cx: &mut Context<Inspector>,
59) -> AnyElement {
60    let ui_font = theme_settings::setup_ui_font(window, cx);
61    let colors = cx.theme().colors();
62    let inspector_id = inspector.active_element_id();
63    let toolbar_height = platform_title_bar_height(window);
64
65    v_flex()
66        .size_full()
67        .bg(colors.panel_background)
68        .text_color(colors.text)
69        .font(ui_font)
70        .border_l_1()
71        .border_color(colors.border)
72        .child(
73            h_flex()
74                .justify_between()
75                .pr_2()
76                .pl_1()
77                .mt_px()
78                .h(toolbar_height)
79                .border_b_1()
80                .border_color(colors.border_variant)
81                .child(
82                    IconButton::new("pick-mode", IconName::MagnifyingGlass)
83                        .tooltip(Tooltip::text("Start inspector pick mode"))
84                        .selected_icon_color(Color::Selected)
85                        .toggle_state(inspector.is_picking())
86                        .on_click(cx.listener(|inspector, _, window, _cx| {
87                            inspector.start_picking();
88                            window.refresh();
89                        })),
90                )
91                .child(h_flex().justify_end().child(Label::new("GPUI Inspector"))),
92        )
93        .child(
94            v_flex()
95                .id("gpui-inspector-content")
96                .overflow_y_scroll()
97                .px_2()
98                .py_0p5()
99                .gap_2()
100                .when_some(inspector_id, |this, inspector_id| {
101                    this.child(render_inspector_id(inspector_id, cx))
102                })
103                .children(inspector.render_inspector_states(window, cx)),
104        )
105        .into_any_element()
106}
107
108fn render_inspector_id(inspector_id: &InspectorElementId, cx: &App) -> Div {
109    let source_location = inspector_id.path.source_location;
110    // For unknown reasons, for some elements the path is absolute.
111    let source_location_string = source_location.to_string();
112    let source_location_string = source_location_string
113        .strip_prefix(env!("ZED_REPO_DIR"))
114        .and_then(|s| s.strip_prefix("/"))
115        .map(|s| s.to_string())
116        .unwrap_or(source_location_string);
117
118    v_flex()
119        .child(
120            h_flex()
121                .justify_between()
122                .child(Label::new("Element ID").size(LabelSize::Large))
123                .child(
124                    div()
125                        .id("instance-id")
126                        .text_ui(cx)
127                        .tooltip(Tooltip::text(
128                            "Disambiguates elements from the same source location",
129                        ))
130                        .child(format!("Instance {}", inspector_id.instance_id)),
131                ),
132        )
133        .child(
134            div()
135                .id("source-location")
136                .text_ui(cx)
137                .bg(cx.theme().colors().editor_foreground.opacity(0.025))
138                .underline()
139                .font_buffer(cx)
140                .text_xs()
141                .child(source_location_string)
142                .tooltip(Tooltip::text("Click to open by running Omega CLI"))
143                .on_click(move |_, _window, cx| {
144                    cx.background_spawn(open_zed_source_location(source_location))
145                        .detach_and_log_err(cx);
146                }),
147        )
148        .child(
149            div()
150                .id("global-id")
151                .text_ui(cx)
152                .min_h_20()
153                .tooltip(Tooltip::text(
154                    "GlobalElementId of the nearest ancestor with an ID",
155                ))
156                .child(inspector_id.path.global_id.to_string()),
157        )
158}
159
160async fn open_zed_source_location(
161    location: &'static std::panic::Location<'static>,
162) -> anyhow::Result<()> {
163    let mut path = Path::new(env!("ZED_REPO_DIR")).to_path_buf();
164    path.push(Path::new(location.file()));
165    let path_arg = format!(
166        "{}:{}:{}",
167        path.display(),
168        location.line(),
169        location.column()
170    );
171
172    let output = new_command("zed")
173        .arg(&path_arg)
174        .output()
175        .await
176        .with_context(|| format!("running omega to open {path_arg} failed"))?;
177
178    if !output.status.success() {
179        Err(anyhow!(
180            "running omega to open {path_arg} failed with stderr: {}",
181            String::from_utf8_lossy(&output.stderr)
182        ))
183    } else {
184        Ok(())
185    }
186}
187
Served at tenant.openagents/omega Member data and write actions are omitted.