diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 4910790a..1f7a2275 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5130,8 +5130,12 @@ fn hover(cx: &mut Context) { // skip if contents empty let contents = ui::Markdown::new(contents, editor.syn_loader.clone()); - let popup = Popup::new(contents); - compositor.push(Box::new(popup)); + let popup = Popup::new("documentation", contents); + if let Some(doc_popup) = compositor.find_id("documentation") { + *doc_popup = popup; + } else { + compositor.push(Box::new(popup)); + } } }, ); diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 3a644750..37e67973 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -64,6 +64,10 @@ pub trait Component: Any + AnyComponent { fn type_name(&self) -> &'static str { std::any::type_name::() } + + fn id(&self) -> Option<&'static str> { + None + } } use anyhow::Error; @@ -184,6 +188,14 @@ impl Compositor { .find(|component| component.type_name() == type_name) .and_then(|component| component.as_any_mut().downcast_mut()) } + + pub fn find_id(&mut self, id: &'static str) -> Option<&mut T> { + let type_name = std::any::type_name::(); + self.layers + .iter_mut() + .find(|component| component.type_name() == type_name && component.id() == Some(id)) + .and_then(|component| component.as_any_mut().downcast_mut()) + } } // View casting, taken straight from Cursive diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index dd782d29..fcd63199 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -168,7 +168,7 @@ impl Completion { } }; }); - let popup = Popup::new(menu); + let popup = Popup::new("completion", menu); let mut completion = Self { popup, start_offset, diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs index 8f7921a1..a5310b23 100644 --- a/helix-term/src/ui/popup.rs +++ b/helix-term/src/ui/popup.rs @@ -16,15 +16,17 @@ pub struct Popup { position: Option, size: (u16, u16), scroll: usize, + id: &'static str, } impl Popup { - pub fn new(contents: T) -> Self { + pub fn new(id: &'static str, contents: T) -> Self { Self { contents, position: None, size: (0, 0), scroll: 0, + id, } } @@ -143,4 +145,8 @@ impl Component for Popup { self.contents.render(area, surface, cx); } + + fn id(&self) -> Option<&'static str> { + Some(self.id) + } }