crates/language_tools/src/lsp_log.rs 🔗
@@ -1145,19 +1145,28 @@ impl Render for LspLogToolbarItemView {
None
}
});
-
+ let available_language_servers: Vec<_> = menu_rows
+ .iter()
+ .map(|row| {
+ (
+ row.server_id,
+ row.server_name.clone(),
+ row.worktree_root_name.clone(),
+ row.selected_entry,
+ )
+ })
+ .collect();
let log_toolbar_view = cx.view().clone();
let lsp_menu = PopoverMenu::new("LspLogView")
.anchor(AnchorCorner::TopLeft)
.trigger(Button::new(
"language_server_menu_header",
current_server
+ .as_ref()
.map(|row| {
Cow::Owned(format!(
- "{} ({}) - {}",
- row.server_name.0,
- row.worktree_root_name,
- row.selected_entry.label()
+ "{} ({})",
+ row.server_name.0, row.worktree_root_name,
))
})
.unwrap_or_else(|| "No server selected".into()),
@@ -1165,36 +1174,71 @@ impl Render for LspLogToolbarItemView {
.menu({
let log_view = log_view.clone();
move |cx| {
- let menu_rows = menu_rows.clone();
let log_view = log_view.clone();
- let log_toolbar_view = log_toolbar_view.clone();
- ContextMenu::build(cx, move |mut menu, cx| {
- for (ix, row) in menu_rows.into_iter().enumerate() {
- let server_selected = Some(row.server_id) == current_server_id;
- menu = menu
- .header(format!(
- "{} ({})",
- row.server_name.0, row.worktree_root_name
- ))
- .entry(
- SERVER_LOGS,
- None,
- cx.handler_for(&log_view, move |view, cx| {
- view.show_logs_for_server(row.server_id, cx);
- }),
- );
- // We do not support tracing for remote language servers right now
- if row.server_kind.is_remote() {
- continue;
- }
+ ContextMenu::build(cx, |mut menu, cx| {
+ for (server_id, name, worktree_root, active_entry_kind) in
+ available_language_servers.iter()
+ {
+ let label = format!("{} ({})", name, worktree_root);
+ let server_id = *server_id;
+ let active_entry_kind = *active_entry_kind;
menu = menu.entry(
- SERVER_TRACE,
+ label,
None,
cx.handler_for(&log_view, move |view, cx| {
- view.show_trace_for_server(row.server_id, cx);
+ view.current_server_id = Some(server_id);
+ view.active_entry_kind = active_entry_kind;
+ match view.active_entry_kind {
+ LogKind::Rpc => {
+ view.toggle_rpc_trace_for_server(server_id, true, cx);
+ view.show_rpc_trace_for_server(server_id, cx);
+ }
+ LogKind::Trace => view.show_trace_for_server(server_id, cx),
+ LogKind::Logs => view.show_logs_for_server(server_id, cx),
+ LogKind::Capabilities => {
+ view.show_capabilities_for_server(server_id, cx)
+ }
+ }
+ cx.notify();
}),
);
- menu = menu.custom_entry(
+ }
+ menu
+ })
+ .into()
+ }
+ });
+ let view_selector = current_server.map(|server| {
+ let server_id = server.server_id;
+ let is_remote = server.server_kind.is_remote();
+ let rpc_trace_enabled = server.rpc_trace_enabled;
+ let log_view = log_view.clone();
+ PopoverMenu::new("LspViewSelector")
+ .anchor(AnchorCorner::TopLeft)
+ .trigger(Button::new(
+ "language_server_menu_header",
+ server.selected_entry.label(),
+ ))
+ .menu(move |cx| {
+ let log_toolbar_view = log_toolbar_view.clone();
+ let log_view = log_view.clone();
+ Some(ContextMenu::build(cx, move |this, cx| {
+ this.entry(
+ SERVER_LOGS,
+ None,
+ cx.handler_for(&log_view, move |view, cx| {
+ view.show_logs_for_server(server_id, cx);
+ }),
+ )
+ .when(!is_remote, |this| {
+ this.entry(
+ SERVER_TRACE,
+ None,
+ cx.handler_for(&log_view, move |view, cx| {
+ view.show_trace_for_server(server_id, cx);
+ }),
+ )
+ .custom_entry(
{
let log_toolbar_view = log_toolbar_view.clone();
move |cx| {
@@ -1205,8 +1249,8 @@ impl Render for LspLogToolbarItemView {
.child(
div().child(
Checkbox::new(
- ix,
- if row.rpc_trace_enabled {
+ "LspLogEnableRpcTrace",
+ if rpc_trace_enabled {
Selection::Selected
} else {
Selection::Unselected
@@ -1220,9 +1264,7 @@ impl Render for LspLogToolbarItemView {
Selection::Selected
);
view.toggle_rpc_logging_for_server(
- row.server_id,
- enabled,
- cx,
+ server_id, enabled, cx,
);
cx.stop_propagation();
},
@@ -1233,167 +1275,167 @@ impl Render for LspLogToolbarItemView {
}
},
cx.handler_for(&log_view, move |view, cx| {
- view.show_rpc_trace_for_server(row.server_id, cx);
- }),
- );
- if server_selected && row.selected_entry == LogKind::Rpc {
- let selected_ix = menu.select_last();
- // Each language server has:
- // 1. A title.
- // 2. Server logs.
- // 3. Server trace.
- // 4. RPC messages.
- // 5. Server capabilities
- // Thus, if nth server's RPC is selected, the index of selected entry should match this formula
- let _expected_index = ix * 5 + 3;
- debug_assert_eq!(
- Some(_expected_index),
- selected_ix,
- "Could not scroll to a just added LSP menu item"
- );
- }
- menu = menu.entry(
- SERVER_CAPABILITIES,
- None,
- cx.handler_for(&log_view, move |view, cx| {
- view.show_capabilities_for_server(row.server_id, cx);
+ view.show_rpc_trace_for_server(server_id, cx);
}),
- );
- }
- menu
- })
- .into()
- }
- });
-
+ )
+ })
+ .entry(
+ SERVER_CAPABILITIES,
+ None,
+ cx.handler_for(&log_view, move |view, cx| {
+ view.show_capabilities_for_server(server_id, cx);
+ }),
+ )
+ }))
+ })
+ });
h_flex()
.size_full()
- .child(lsp_menu)
+ .justify_between()
.child(
- div()
- .child(
- Button::new("clear_log_button", "Clear").on_click(cx.listener(
- |this, _, cx| {
- if let Some(log_view) = this.log_view.as_ref() {
- log_view.update(cx, |log_view, cx| {
- log_view.editor.update(cx, |editor, cx| {
- editor.set_read_only(false);
- editor.clear(cx);
- editor.set_read_only(true);
- });
- })
- }
- },
- )),
- )
- .ml_2(),
- )
- .child(log_view.update(cx, |this, _| match this.active_entry_kind {
- LogKind::Trace => {
- let log_view = log_view.clone();
- div().child(
- PopoverMenu::new("lsp-trace-level-menu")
- .anchor(AnchorCorner::TopLeft)
- .trigger(Button::new(
- "language_server_trace_level_selector",
- "Trace level",
- ))
- .menu({
- let log_view = log_view.clone();
-
- move |cx| {
- let id = log_view.read(cx).current_server_id?;
-
- let trace_level = log_view.update(cx, |this, cx| {
- this.log_store.update(cx, |this, _| {
- Some(this.get_language_server_state(id)?.trace_level)
- })
- })?;
-
- ContextMenu::build(cx, |mut menu, _| {
+ h_flex()
+ .child(lsp_menu)
+ .children(view_selector)
+ .child(log_view.update(cx, |this, _| match this.active_entry_kind {
+ LogKind::Trace => {
+ let log_view = log_view.clone();
+ div().child(
+ PopoverMenu::new("lsp-trace-level-menu")
+ .anchor(AnchorCorner::TopLeft)
+ .trigger(Button::new(
+ "language_server_trace_level_selector",
+ "Trace level",
+ ))
+ .menu({
let log_view = log_view.clone();
- for (option, label) in [
- (TraceValue::Off, "Off"),
- (TraceValue::Messages, "Messages"),
- (TraceValue::Verbose, "Verbose"),
- ] {
- menu = menu.entry(label, None, {
+ move |cx| {
+ let id = log_view.read(cx).current_server_id?;
+
+ let trace_level = log_view.update(cx, |this, cx| {
+ this.log_store.update(cx, |this, _| {
+ Some(
+ this.get_language_server_state(id)?
+ .trace_level,
+ )
+ })
+ })?;
+
+ ContextMenu::build(cx, |mut menu, _| {
let log_view = log_view.clone();
- move |cx| {
- log_view.update(cx, |this, cx| {
- if let Some(id) = this.current_server_id {
- this.update_trace_level(id, option, cx);
+
+ for (option, label) in [
+ (TraceValue::Off, "Off"),
+ (TraceValue::Messages, "Messages"),
+ (TraceValue::Verbose, "Verbose"),
+ ] {
+ menu = menu.entry(label, None, {
+ let log_view = log_view.clone();
+ move |cx| {
+ log_view.update(cx, |this, cx| {
+ if let Some(id) =
+ this.current_server_id
+ {
+ this.update_trace_level(
+ id, option, cx,
+ );
+ }
+ });
}
});
+ if option == trace_level {
+ menu.select_last();
+ }
}
- });
- if option == trace_level {
- menu.select_last();
- }
+
+ menu
+ })
+ .into()
}
+ }),
+ )
+ }
+ LogKind::Logs => {
+ let log_view = log_view.clone();
+ div().child(
+ PopoverMenu::new("lsp-log-level-menu")
+ .anchor(AnchorCorner::TopLeft)
+ .trigger(Button::new(
+ "language_server_log_level_selector",
+ "Log level",
+ ))
+ .menu({
+ let log_view = log_view.clone();
- menu
- })
- .into()
- }
- }),
- )
- }
- LogKind::Logs => {
- let log_view = log_view.clone();
- div().child(
- PopoverMenu::new("lsp-log-level-menu")
- .anchor(AnchorCorner::TopLeft)
- .trigger(Button::new(
- "language_server_log_level_selector",
- "Log level",
- ))
- .menu({
- let log_view = log_view.clone();
-
- move |cx| {
- let id = log_view.read(cx).current_server_id?;
-
- let log_level = log_view.update(cx, |this, cx| {
- this.log_store.update(cx, |this, _| {
- Some(this.get_language_server_state(id)?.log_level)
- })
- })?;
+ move |cx| {
+ let id = log_view.read(cx).current_server_id?;
- ContextMenu::build(cx, |mut menu, _| {
- let log_view = log_view.clone();
+ let log_level = log_view.update(cx, |this, cx| {
+ this.log_store.update(cx, |this, _| {
+ Some(
+ this.get_language_server_state(id)?
+ .log_level,
+ )
+ })
+ })?;
- for (option, label) in [
- (MessageType::LOG, "Log"),
- (MessageType::INFO, "Info"),
- (MessageType::WARNING, "Warning"),
- (MessageType::ERROR, "Error"),
- ] {
- menu = menu.entry(label, None, {
+ ContextMenu::build(cx, |mut menu, _| {
let log_view = log_view.clone();
- move |cx| {
- log_view.update(cx, |this, cx| {
- if let Some(id) = this.current_server_id {
- this.update_log_level(id, option, cx);
+
+ for (option, label) in [
+ (MessageType::LOG, "Log"),
+ (MessageType::INFO, "Info"),
+ (MessageType::WARNING, "Warning"),
+ (MessageType::ERROR, "Error"),
+ ] {
+ menu = menu.entry(label, None, {
+ let log_view = log_view.clone();
+ move |cx| {
+ log_view.update(cx, |this, cx| {
+ if let Some(id) =
+ this.current_server_id
+ {
+ this.update_log_level(
+ id, option, cx,
+ );
+ }
+ });
}
});
+ if option == log_level {
+ menu.select_last();
+ }
}
- });
- if option == log_level {
- menu.select_last();
- }
- }
- menu
+ menu
+ })
+ .into()
+ }
+ }),
+ )
+ }
+ _ => div(),
+ })),
+ )
+ .child(
+ div()
+ .child(
+ Button::new("clear_log_button", "Clear").on_click(cx.listener(
+ |this, _, cx| {
+ if let Some(log_view) = this.log_view.as_ref() {
+ log_view.update(cx, |log_view, cx| {
+ log_view.editor.update(cx, |editor, cx| {
+ editor.set_read_only(false);
+ editor.clear(cx);
+ editor.set_read_only(true);
+ });
})
- .into()
}
- }),
+ },
+ )),
)
- }
- _ => div(),
- }))
+ .ml_2(),
+ )
}
}