From ef6e694e39cc7235bf9e6260047aa001518ca605 Mon Sep 17 00:00:00 2001 From: supersurviveur Date: Sun, 28 Jul 2024 19:51:59 +0200 Subject: [PATCH] Add mouse scroll for completions --- helix-term/src/ui/editor.rs | 19 ++++++++++++++++++- helix-term/src/ui/menu.rs | 28 +++++++++++++++++++++++++++- helix-term/src/ui/popup.rs | 24 ++++++++---------------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index f7541fe25..3e1daafaa 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1455,7 +1455,24 @@ impl Component for EditorView { EventResult::Consumed(callback) } - Event::Mouse(event) => self.handle_mouse_event(event, &mut cx), + Event::Mouse(mouse_event) => { + // let completion swallow the event if necessary + if let Some(completion) = &mut self.completion { + // use a fake context here + let mut cx = Context { + editor: cx.editor, + jobs: cx.jobs, + scroll: None, + }; + + if let EventResult::Consumed(callback) = completion.handle_event(event, &mut cx) + { + return EventResult::Consumed(callback); + } + } + + self.handle_mouse_event(mouse_event, &mut cx) + } Event::IdleTimeout => self.handle_idle_timeout(&mut cx), Event::FocusGained => { self.terminal_focused = true; diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index c120d0b25..40a728c3f 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -11,7 +11,12 @@ use tui::{buffer::Buffer as Surface, widgets::Table}; pub use tui::widgets::{Cell, Row}; -use helix_view::{editor::SmartTabConfig, graphics::Rect, Editor}; +use helix_view::{ + editor::SmartTabConfig, + graphics::Rect, + input::{MouseEvent, MouseEventKind}, + Editor, +}; use tui::layout::Constraint; pub trait Item: Sync + Send + 'static { @@ -225,6 +230,26 @@ impl Menu { pub fn len(&self) -> usize { self.matches.len() } + + fn handle_mouse_event( + &mut self, + &MouseEvent { kind, .. }: &MouseEvent, + cx: &mut Context, + ) -> EventResult { + match kind { + MouseEventKind::ScrollDown => { + self.move_down(); + (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update); + EventResult::Consumed(None) + } + MouseEventKind::ScrollUp => { + self.move_up(); + (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update); + EventResult::Consumed(None) + } + _ => EventResult::Ignored(None), + } + } } impl Menu { @@ -244,6 +269,7 @@ impl Component for Menu { fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult { let event = match event { Event::Key(event) => *event, + Event::Mouse(event) => return self.handle_mouse_event(event, cx), _ => return EventResult::Ignored(None), }; diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs index 2cefaf61b..1bfd7a8e3 100644 --- a/helix-term/src/ui/popup.rs +++ b/helix-term/src/ui/popup.rs @@ -217,25 +217,17 @@ impl Popup { } } - fn handle_mouse_event( - &mut self, - &MouseEvent { - kind, - column: x, - row: y, - .. - }: &MouseEvent, - ) -> EventResult { - let mouse_is_within_popup = x >= self.area.left() - && x < self.area.right() - && y >= self.area.top() - && y < self.area.bottom(); + fn handle_mouse_event(&mut self, event: &MouseEvent, cx: &mut Context) -> EventResult { + let mouse_is_within_popup = event.column >= self.area.left() + && event.column < self.area.right() + && event.row >= self.area.top() + && event.row < self.area.bottom(); if !mouse_is_within_popup { return EventResult::Ignored(None); } - match kind { + match event.kind { MouseEventKind::ScrollDown if self.has_scrollbar => { self.scroll_half_page_down(); EventResult::Consumed(None) @@ -244,7 +236,7 @@ impl Popup { self.scroll_half_page_up(); EventResult::Consumed(None) } - _ => EventResult::Ignored(None), + _ => self.contents.handle_event(&Event::Mouse(*event), cx), } } } @@ -253,7 +245,7 @@ impl Component for Popup { fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult { let key = match event { Event::Key(event) => *event, - Event::Mouse(event) => return self.handle_mouse_event(event), + Event::Mouse(mouse_event) => return self.handle_mouse_event(mouse_event, cx), Event::Resize(_, _) => { // TODO: calculate inner area, call component's handle_event with that area return EventResult::Ignored(None);