feat: add API to register additional hooks with Pickrs

pull/12902/head
Nikita Revenco 2025-02-17 20:53:14 +00:00
parent 1b89f998e8
commit 87b5bd58bc
1 changed files with 25 additions and 2 deletions

View File

@ -47,6 +47,7 @@ use helix_core::{
use helix_view::{ use helix_view::{
editor::Action, editor::Action,
graphics::{CursorKind, Margin, Modifier, Rect}, graphics::{CursorKind, Margin, Modifier, Rect},
input::KeyEvent,
theme::Style, theme::Style,
view::ViewPosition, view::ViewPosition,
Document, DocumentId, Editor, Document, DocumentId, Editor,
@ -258,6 +259,7 @@ pub struct Picker<T: 'static + Send + Sync, D: 'static> {
widths: Vec<Constraint>, widths: Vec<Constraint>,
callback_fn: PickerCallback<T>, callback_fn: PickerCallback<T>,
custom_key_handlers: PickerKeyHandler,
pub truncate_start: bool, pub truncate_start: bool,
/// Caches paths to documents /// Caches paths to documents
@ -385,6 +387,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
completion_height: 0, completion_height: 0,
widths, widths,
preview_cache: HashMap::new(), preview_cache: HashMap::new(),
custom_key_handlers: HashMap::new(),
read_buffer: Vec::with_capacity(1024), read_buffer: Vec::with_capacity(1024),
file_fn: None, file_fn: None,
preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(), preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(),
@ -392,6 +395,11 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
} }
} }
pub fn with_key_handler(mut self, handlers: PickerKeyHandler) -> Self {
self.custom_key_handlers = handlers;
self
}
pub fn injector(&self) -> Injector<T, D> { pub fn injector(&self) -> Injector<T, D> {
Injector { Injector {
dst: self.matcher.injector(), dst: self.matcher.injector(),
@ -509,6 +517,15 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
self.show_preview = !self.show_preview; self.show_preview = !self.show_preview;
} }
fn custom_event_handler(&mut self, event: &KeyEvent, cx: &mut Context) -> EventResult {
if let Some(callback) = self.custom_key_handlers.get(event) {
callback(cx);
EventResult::Consumed(None)
} else {
EventResult::Ignored(None)
}
}
fn prompt_handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult { fn prompt_handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {
if let EventResult::Consumed(_) = self.prompt.handle_event(event, cx) { if let EventResult::Consumed(_) = self.prompt.handle_event(event, cx) {
self.handle_prompt_change(matches!(event, Event::Paste(_))); self.handle_prompt_change(matches!(event, Event::Paste(_)));
@ -1113,8 +1130,13 @@ impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I,
ctrl!('t') => { ctrl!('t') => {
self.toggle_preview(); self.toggle_preview();
} }
_ => { key_event => {
self.prompt_handle_event(event, ctx); if !matches!(
self.custom_event_handler(&key_event, ctx),
EventResult::Consumed(_)
) {
self.prompt_handle_event(event, ctx);
};
} }
} }
@ -1157,3 +1179,4 @@ impl<T: 'static + Send + Sync, D> Drop for Picker<T, D> {
} }
type PickerCallback<T> = Box<dyn Fn(&mut Context, &T, Action)>; type PickerCallback<T> = Box<dyn Fn(&mut Context, &T, Action)>;
type PickerKeyHandler = HashMap<KeyEvent, Box<dyn Fn(&mut Context)>>;