Another lsp tool UI migration (#34009)

https://github.com/user-attachments/assets/54182f0d-43e9-4482-89b9-94db5ddaabf8

Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov 2025-07-07 17:28:18 +03:00 committed by GitHub
parent 955580dae6
commit 82aee6bcf7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 485 additions and 535 deletions

1
Cargo.lock generated
View file

@ -9023,7 +9023,6 @@ dependencies = [
"itertools 0.14.0",
"language",
"lsp",
"picker",
"project",
"release_channel",
"serde_json",

View file

@ -426,6 +426,7 @@ impl ContextPicker {
this.add_recent_file(project_path.clone(), window, cx);
})
},
None,
)
}
RecentEntry::Thread(thread) => {
@ -443,6 +444,7 @@ impl ContextPicker {
.detach_and_log_err(cx);
})
},
None,
)
}
}

View file

@ -835,10 +835,6 @@ impl InlineCompletionButton {
cx.notify();
}
pub fn toggle_menu(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.popover_menu_handle.toggle(window, cx);
}
}
impl StatusItemView for InlineCompletionButton {

View file

@ -24,7 +24,6 @@ gpui.workspace = true
itertools.workspace = true
language.workspace = true
lsp.workspace = true
picker.workspace = true
project.workspace = true
serde_json.workspace = true
settings.workspace = true

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@ pub enum ContextMenuItem {
entry_render: Box<dyn Fn(&mut Window, &mut App) -> AnyElement>,
handler: Rc<dyn Fn(Option<&FocusHandle>, &mut Window, &mut App)>,
selectable: bool,
documentation_aside: Option<DocumentationAside>,
},
}
@ -31,11 +32,13 @@ impl ContextMenuItem {
pub fn custom_entry(
entry_render: impl Fn(&mut Window, &mut App) -> AnyElement + 'static,
handler: impl Fn(&mut Window, &mut App) + 'static,
documentation_aside: Option<DocumentationAside>,
) -> Self {
Self::CustomEntry {
entry_render: Box::new(entry_render),
handler: Rc::new(move |_, window, cx| handler(window, cx)),
selectable: true,
documentation_aside,
}
}
}
@ -170,6 +173,12 @@ pub struct DocumentationAside {
render: Rc<dyn Fn(&mut App) -> AnyElement>,
}
impl DocumentationAside {
pub fn new(side: DocumentationSide, render: Rc<dyn Fn(&mut App) -> AnyElement>) -> Self {
Self { side, render }
}
}
impl Focusable for ContextMenu {
fn focus_handle(&self, _cx: &App) -> FocusHandle {
self.focus_handle.clone()
@ -456,6 +465,7 @@ impl ContextMenu {
entry_render: Box::new(entry_render),
handler: Rc::new(|_, _, _| {}),
selectable: false,
documentation_aside: None,
});
self
}
@ -469,6 +479,7 @@ impl ContextMenu {
entry_render: Box::new(entry_render),
handler: Rc::new(move |_, window, cx| handler(window, cx)),
selectable: true,
documentation_aside: None,
});
self
}
@ -705,10 +716,19 @@ impl ContextMenu {
let item = self.items.get(ix)?;
if item.is_selectable() {
self.selected_index = Some(ix);
if let ContextMenuItem::Entry(entry) = item {
if let Some(callback) = &entry.documentation_aside {
match item {
ContextMenuItem::Entry(entry) => {
if let Some(callback) = &entry.documentation_aside {
self.documentation_aside = Some((ix, callback.clone()));
}
}
ContextMenuItem::CustomEntry {
documentation_aside: Some(callback),
..
} => {
self.documentation_aside = Some((ix, callback.clone()));
}
_ => (),
}
}
Some(ix)
@ -806,6 +826,7 @@ impl ContextMenu {
entry_render,
handler,
selectable,
..
} => {
let handler = handler.clone();
let menu = cx.entity().downgrade();

View file

@ -105,6 +105,24 @@ impl<M: ManagedView> PopoverMenuHandle<M> {
.map_or(false, |model| model.focus_handle(cx).is_focused(window))
})
}
pub fn refresh_menu(
&self,
window: &mut Window,
cx: &mut App,
new_menu_builder: Rc<dyn Fn(&mut Window, &mut App) -> Option<Entity<M>>>,
) {
let show_menu = if let Some(state) = self.0.borrow_mut().as_mut() {
state.menu_builder = new_menu_builder;
state.menu.borrow().is_some()
} else {
false
};
if show_menu {
self.show(window, cx);
}
}
}
pub struct PopoverMenu<M: ManagedView> {