on master help sign in
Filter the initial completion
commit66f26e82ceaf4b81dfeb429dcb840a3242e8f254 authorBlaž Hrastnik <blaz@mxxn.io> dateFri 27 Aug 2021, 10:44 (5 years ago) parent40abec8
5 files changed+57−17
helix-term/src/application.rs+6−5 helix-term/src/commands.rs+12−5 helix-term/src/ui/completion.rs+19−6 helix-term/src/ui/editor.rs+4−1 helix-view/src/macros.rs+16
helix-term/src/application.rs+6−5
@@ -234,9 +234,8 @@ impl Application {
234234 }
235235
236236 pub fn handle_idle_timeout(&mut self) {
237+ use crate::commands::{completion, Context};
237238 use helix_view::document::Mode;
238− use crate::commands::{Context, completion};
239−
240239
241240 if doc_mut!(self.editor).mode != Mode::Insert {
242241 return;
@@ -254,6 +253,8 @@ impl Application {
254253 return;
255254 }
256255
256+ // TODO: if completion window was closed with enter (and no selection) we shouldn't retrigger
257+
257258 let mut cx = Context {
258259 selected_register: helix_view::RegisterSelection::default(),
259260 editor: &mut self.editor,
@@ -262,9 +263,9 @@ impl Application {
262263 callback: None,
263264 on_next_key_callback: None,
264265 };
265− completion(&mut cx);
266− // TODO: scan backwards for trigger and filter the box
267− self.render();
266+ completion(&mut cx);
267+ // TODO: scan backwards for trigger and filter the box
268+ self.render();
268269 }
269270
270271 pub fn handle_terminal_events(&mut self, event: Option<Result<Event, crossterm::ErrorKind>>) {
helix-term/src/commands.rs+12−5
@@ -4090,10 +4090,8 @@ pub fn completion(cx: &mut Context) {
40904090 };
40914091
40924092 let offset_encoding = language_server.offset_encoding();
4093− let cursor = doc
4094− .selection(view.id)
4095− .primary()
4096− .cursor(doc.text().slice(..));
4093+ let text = doc.text().slice(..);
4094+ let cursor = doc.selection(view.id).primary().cursor(text);
40974095
40984096 let pos = pos_to_lsp_pos(doc.text(), cursor, offset_encoding);
40994097
@@ -4101,6 +4099,15 @@ pub fn completion(cx: &mut Context) {
41014099
41024100 let trigger_offset = cursor;
41034101
4102+ // TODO: trigger_offset should be the cursor offset but we also need a starting offset from where we want to apply
4103+ // completion filtering. For example logger.te| should filter the initial suggestion list with "te".
4104+
4105+ use helix_core::chars;
4106+ let mut iter = text.chars_at(cursor);
4107+ iter.reverse();
4108+ let offset = iter.take_while(|ch| chars::char_is_word(*ch)).count();
4109+ let start_offset = cursor.saturating_sub(offset);
4110+
41044111 cx.callback(
41054112 future,
41064113 move |editor: &mut Editor,
@@ -4131,7 +4138,7 @@ pub fn completion(cx: &mut Context) {
41314138 .find(std::any::type_name::<ui::EditorView>())
41324139 .unwrap();
41334140 if let Some(ui) = ui.as_any_mut().downcast_mut::<ui::EditorView>() {
4134− ui.set_completion(items, offset_encoding, trigger_offset, size);
4141+ ui.set_completion(editor, items, offset_encoding, start_offset, trigger_offset, size);
41354142 };
41364143 },
41374144 );
helix-term/src/ui/completion.rs+19−6
@@ -69,14 +69,17 @@ impl menu::Item for CompletionItem {
6969/// Wraps a Menu.
7070pub struct Completion {
7171 popup: Popup<Menu<CompletionItem>>,
72+ start_offset: usize,
7273 trigger_offset: usize,
7374 // TODO: maintain a completioncontext with trigger kind & trigger char
7475}
7576
7677impl Completion {
7778 pub fn new(
79+ editor: &Editor,
7880 items: Vec<CompletionItem>,
7981 offset_encoding: helix_lsp::OffsetEncoding,
82+ start_offset: usize,
8083 trigger_offset: usize,
8184 ) -> Self {
8285 // let items: Vec<CompletionItem> = Vec::new();
@@ -175,16 +178,22 @@ impl Completion {
175178 };
176179 });
177180 let popup = Popup::new(menu);
178− Self {
181+ let mut completion = Self {
179182 popup,
183+ start_offset,
180184 trigger_offset,
181− }
185+ };
186+
187+ // need to recompute immediately in case start_offset != trigger_offset
188+ completion.recompute_filter(editor);
189+
190+ completion
182191 }
183192
184− pub fn update(&mut self, cx: &mut commands::Context) {
193+ pub fn recompute_filter(&mut self, editor: &Editor) {
185194 // recompute menu based on matches
186195 let menu = self.popup.contents_mut();
187− let (view, doc) = current!(cx.editor);
196+ let (view, doc) = current_ref!(editor);
188197
189198 // cx.hooks()
190199 // cx.add_hook(enum type, ||)
@@ -200,14 +209,18 @@ impl Completion {
200209 .selection(view.id)
201210 .primary()
202211 .cursor(doc.text().slice(..));
203− if self.trigger_offset <= cursor {
204− let fragment = doc.text().slice(self.trigger_offset..cursor);
212+ if self.start_offset <= cursor {
213+ let fragment = doc.text().slice(self.start_offset..cursor);
205214 let text = Cow::from(fragment);
206215 // TODO: logic is same as ui/picker
207216 menu.score(&text);
208217 }
209218 }
210219
220+ pub fn update(&mut self, cx: &mut commands::Context) {
221+ self.recompute_filter(cx.editor)
222+ }
223+
211224 pub fn is_empty(&self) -> bool {
212225 self.popup.contents().is_empty()
213226 }
helix-term/src/ui/editor.rs+4−1
@@ -721,12 +721,15 @@ impl EditorView {
721721
722722 pub fn set_completion(
723723 &mut self,
724+ editor: &Editor,
724725 items: Vec<helix_lsp::lsp::CompletionItem>,
725726 offset_encoding: helix_lsp::OffsetEncoding,
727+ start_offset: usize,
726728 trigger_offset: usize,
727729 size: Rect,
728730 ) {
729− let mut completion = Completion::new(items, offset_encoding, trigger_offset);
731+ let mut completion =
732+ Completion::new(editor, items, offset_encoding, start_offset, trigger_offset);
730733 // TODO : propagate required size on resize to completion too
731734 completion.required_size((size.width, size.height));
732735 self.completion = Some(completion);
helix-view/src/macros.rs+16
@@ -44,3 +44,19 @@ macro_rules! view {
4444 $( $editor ).+ .tree.get($( $editor ).+ .tree.focus)
4545 }};
4646}
47+
48+#[macro_export]
49+macro_rules! doc {
50+ ( $( $editor:ident ).+ ) => {{
51+ $crate::current_ref!( $( $editor ).+ ).1
52+ }};
53+}
54+
55+#[macro_export]
56+macro_rules! current_ref {
57+ ( $( $editor:ident ).+ ) => {{
58+ let view = $( $editor ).+ .tree.get($( $editor ).+ .tree.focus);
59+ let doc = &$( $editor ).+ .documents[view.doc];
60+ (view, doc)
61+ }};
62+}