diff options
Diffstat (limited to 'helix-term/src/ui/completion.rs')
-rw-r--r-- | helix-term/src/ui/completion.rs | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 53241c57..637fc5f4 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -12,6 +12,7 @@ use std::borrow::Cow; use helix_core::{Position, Transaction}; use helix_view::Editor; +use crate::commands; use crate::ui::{Menu, Popup, PromptEvent}; use helix_lsp::lsp; @@ -112,44 +113,50 @@ impl Completion { trigger_offset, } } + + pub fn update(&mut self, cx: &mut commands::Context) { + // recompute menu based on matches + let menu = self.popup.contents_mut(); + let (view, doc) = cx.editor.current(); + + // cx.hooks() + // cx.add_hook(enum type, ||) + // cx.trigger_hook(enum type, &str, ...) <-- there has to be enough to identify doc/view + // callback with editor & compositor + // + // trigger_hook sends event into channel, that's consumed in the global loop and + // triggers all registered callbacks + // TODO: hooks should get processed immediately so maybe do it after select!(), before + // looping? + + let cursor = doc.selection(view.id).cursor(); + if self.trigger_offset <= cursor { + let fragment = doc.text().slice(self.trigger_offset..=cursor); + let text = Cow::from(fragment); + // TODO: logic is same as ui/picker + menu.score(&text); + } + } + + pub fn is_empty(&self) -> bool { + self.popup.contents().is_empty() + } } +// need to: +// - trigger on the right trigger char +// - detect previous open instance and recycle +// - update after input, but AFTER the document has changed +// - if no more matches, need to auto close +// +// missing bits: +// - a more robust hook system: emit to a channel, process in main loop +// - a way to find specific layers in compositor +// - components register for hooks, then unregister when terminated +// ... since completion is a special case, maybe just build it into doc/render? + impl Component for Completion { fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult { - // input - if let Event::Key(KeyEvent { - code: KeyCode::Char(ch), - .. - }) = event - { - // recompute menu based on matches - let menu = self.popup.contents(); - let (view, doc) = cx.editor.current(); - - // cx.hooks() - // cx.add_hook(enum type, ||) - // cx.trigger_hook(enum type, &str, ...) <-- there has to be enough to identify doc/view - // callback with editor & compositor - // - // trigger_hook sends event into channel, that's consumed in the global loop and - // triggers all registered callbacks - // TODO: hooks should get processed immediately so maybe do it after select!(), before - // looping? - - let cursor = doc.selection(view.id).cursor(); - if self.trigger_offset <= cursor { - let fragment = doc.text().slice(self.trigger_offset..cursor); - // ^ problem seems to be that we handle events here before the editor layer, so the - // keypress isn't included in the editor layer yet... - // so we can't use ..= for now. - let text = Cow::from(fragment); - // TODO: logic is same as ui/picker - menu.score(&text); - - // TODO: if after scoring the selection is 0 items, remove popup - } - } - self.popup.handle_event(event, cx) } |