aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/ui/popup.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/ui/popup.rs')
-rw-r--r--helix-term/src/ui/popup.rs31
1 files changed, 24 insertions, 7 deletions
diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs
index 4d319423..45527482 100644
--- a/helix-term/src/ui/popup.rs
+++ b/helix-term/src/ui/popup.rs
@@ -1,5 +1,5 @@
use crate::{
- compositor::{Component, Compositor, Context, EventResult},
+ compositor::{Callback, Component, Context, EventResult},
ctrl, key,
};
use crossterm::event::Event;
@@ -18,6 +18,7 @@ pub struct Popup<T: Component> {
size: (u16, u16),
child_size: (u16, u16),
scroll: usize,
+ auto_close: bool,
id: &'static str,
}
@@ -33,6 +34,7 @@ impl<T: Component> Popup<T> {
size: (0, 0),
child_size: (0, 0),
scroll: 0,
+ auto_close: false,
id,
}
}
@@ -46,6 +48,11 @@ impl<T: Component> Popup<T> {
self
}
+ pub fn auto_close(mut self, auto_close: bool) -> Self {
+ self.auto_close = auto_close;
+ self
+ }
+
pub fn get_rel_position(&mut self, viewport: Rect, cx: &Context) -> (u16, u16) {
let position = self
.position
@@ -105,19 +112,19 @@ impl<T: Component> Component for Popup<T> {
Event::Key(event) => event,
Event::Resize(_, _) => {
// TODO: calculate inner area, call component's handle_event with that area
- return EventResult::Ignored;
+ return EventResult::Ignored(None);
}
- _ => return EventResult::Ignored,
+ _ => return EventResult::Ignored(None),
};
- let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| {
+ let close_fn: Callback = Box::new(|compositor, _| {
// remove the layer
compositor.pop();
- })));
+ });
match key.into() {
// esc or ctrl-c aborts the completion and closes the menu
- key!(Esc) | ctrl!('c') => close_fn,
+ key!(Esc) | ctrl!('c') => EventResult::Consumed(Some(close_fn)),
ctrl!('d') => {
self.scroll(self.size.1 as usize / 2, true);
EventResult::Consumed(None)
@@ -126,7 +133,17 @@ impl<T: Component> Component for Popup<T> {
self.scroll(self.size.1 as usize / 2, false);
EventResult::Consumed(None)
}
- _ => self.contents.handle_event(event, cx),
+ _ => {
+ let contents_event_result = self.contents.handle_event(event, cx);
+
+ if self.auto_close {
+ if let EventResult::Ignored(None) = contents_event_result {
+ return EventResult::Ignored(Some(close_fn));
+ }
+ }
+
+ contents_event_result
+ }
}
// for some events, we want to process them but send ignore, specifically all input except
// tab/enter/ctrl-k or whatever will confirm the selection/ ctrl-n/ctrl-p for scroll.