diff options
author | Bram | 2022-02-23 03:46:12 +0000 |
---|---|---|
committer | GitHub | 2022-02-23 03:46:12 +0000 |
commit | 40eb1268c72b60f1249389c58892e7c45d268cff (patch) | |
tree | 84f741c7067547b4af3e6b0a867c10639d00ede8 /helix-term/src/ui | |
parent | e1a92fd3998aca2a313d4cbf0aca3157eca0b53f (diff) |
Close some popups automatically (#1285)
* Add Event::Used to use event callback without consuming
* Close popup if contents ignored event
* collect event results before executing callbacks
* don't add new result variant, use Ignored(..) instead
* break in match cases
* Make auto_close configurable
* fix merge
* auto close hover popups
* fix formatting
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r-- | helix-term/src/ui/completion.rs | 2 | ||||
-rw-r--r-- | helix-term/src/ui/editor.rs | 24 | ||||
-rw-r--r-- | helix-term/src/ui/menu.rs | 4 | ||||
-rw-r--r-- | helix-term/src/ui/picker.rs | 2 | ||||
-rw-r--r-- | helix-term/src/ui/popup.rs | 31 | ||||
-rw-r--r-- | helix-term/src/ui/prompt.rs | 2 |
6 files changed, 40 insertions, 25 deletions
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index d3b618a9..adaac1a7 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -276,7 +276,7 @@ impl Component for Completion { code: KeyCode::Esc, .. }) = event { - return EventResult::Ignored; + return EventResult::Ignored(None); } self.popup.handle_event(event, cx) } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fc749ebb..29552b67 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -872,9 +872,7 @@ impl EditorView { let path = match doc.path() { Some(path) => path.clone(), - None => { - return EventResult::Ignored; - } + None => return EventResult::Ignored(None), }; let line = coords.row + view.offset.row; @@ -884,7 +882,7 @@ impl EditorView { } } - EventResult::Ignored + EventResult::Ignored(None) } MouseEvent { @@ -897,7 +895,7 @@ impl EditorView { let pos = match view.pos_at_screen_coords(doc, row, column) { Some(pos) => pos, - None => return EventResult::Ignored, + None => return EventResult::Ignored(None), }; let mut selection = doc.selection(view.id).clone(); @@ -928,7 +926,7 @@ impl EditorView { match result { Some(view_id) => cxt.editor.tree.focus = view_id, - None => return EventResult::Ignored, + None => return EventResult::Ignored(None), } let offset = cxt.editor.config.scroll_lines.abs() as usize; @@ -944,14 +942,14 @@ impl EditorView { .. } => { if !cxt.editor.config.middle_click_paste { - return EventResult::Ignored; + return EventResult::Ignored(None); } let (view, doc) = current!(cxt.editor); let range = doc.selection(view.id).primary(); if range.to() - range.from() <= 1 { - return EventResult::Ignored; + return EventResult::Ignored(None); } commands::MappableCommand::yank_main_selection_to_primary_clipboard.execute(cxt); @@ -988,7 +986,7 @@ impl EditorView { return EventResult::Consumed(None); } } - EventResult::Ignored + EventResult::Ignored(None) } MouseEvent { @@ -1000,7 +998,7 @@ impl EditorView { } => { let editor = &mut cxt.editor; if !editor.config.middle_click_paste { - return EventResult::Ignored; + return EventResult::Ignored(None); } if modifiers == crossterm::event::KeyModifiers::ALT { @@ -1023,10 +1021,10 @@ impl EditorView { return EventResult::Consumed(None); } - EventResult::Ignored + EventResult::Ignored(None) } - _ => EventResult::Ignored, + _ => EventResult::Ignored(None), } } } @@ -1117,7 +1115,7 @@ impl Component for EditorView { // if the command consumed the last view, skip the render. // on the next loop cycle the Application will then terminate. if cx.editor.should_close() { - return EventResult::Ignored; + return EventResult::Ignored(None); } let (view, doc) = current!(cx.editor); diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index f9a0438c..1839da47 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -202,7 +202,7 @@ impl<T: Item + 'static> Component for Menu<T> { fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult { let event = match event { Event::Key(event) => event, - _ => return EventResult::Ignored, + _ => return EventResult::Ignored(None), }; let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { @@ -252,7 +252,7 @@ impl<T: Item + 'static> Component for Menu<T> { // 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. // EventResult::Consumed(None) - EventResult::Ignored + EventResult::Ignored(None) } fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> { diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 9e236510..34709e8b 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -419,7 +419,7 @@ impl<T: 'static> Component for Picker<T> { let key_event = match event { Event::Key(event) => event, Event::Resize(..) => return EventResult::Consumed(None), - _ => return EventResult::Ignored, + _ => return EventResult::Ignored(None), }; let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { 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. diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index cd8e14ee..c3402f02 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -438,7 +438,7 @@ impl Component for Prompt { let event = match event { Event::Key(event) => event, Event::Resize(..) => return EventResult::Consumed(None), - _ => return EventResult::Ignored, + _ => return EventResult::Ignored(None), }; let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { |