From f99bea404f43ea0e373fd9fe54616d3282e8364b Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Sun, 22 Aug 2021 15:28:45 +0900 Subject: idle timer wip --- helix-term/src/application.rs | 5 +++++ helix-term/src/ui/editor.rs | 1 + 2 files changed, 6 insertions(+) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 6206e6f2..dbd8755d 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -199,6 +199,11 @@ impl Application { self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback); self.render(); } + _ = &mut self.editor.idle_timer => { + self.editor.clear_idle_timer(); + println!("idle!") + // idle timeout + } } } } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 0605e2c7..aa2d6636 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -901,6 +901,7 @@ impl Component for EditorView { EventResult::Consumed(None) } Event::Key(key) => { + cxt.editor.reset_idle_timer(); let mut key = KeyEvent::from(key); canonicalize_key(&mut key); // clear status -- cgit v1.2.3-70-g09d2 From 40abec80e1062503d70055ed9e968cd4b31411a7 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 26 Aug 2021 11:14:46 +0900 Subject: Experiment with autocompletion on idle --- helix-term/src/application.rs | 38 ++++++++++++++++++++++++++++++++++++-- helix-term/src/commands.rs | 2 +- helix-term/src/ui/editor.rs | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index dbd8755d..ab268041 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -200,9 +200,9 @@ impl Application { self.render(); } _ = &mut self.editor.idle_timer => { + // idle timeout self.editor.clear_idle_timer(); - println!("idle!") - // idle timeout + self.handle_idle_timeout(); } } } @@ -233,6 +233,40 @@ impl Application { } } + pub fn handle_idle_timeout(&mut self) { + use helix_view::document::Mode; + use crate::commands::{Context, completion}; + + + if doc_mut!(self.editor).mode != Mode::Insert { + return; + } + let editor_view = self + .compositor + .find(std::any::type_name::()) + .expect("expected at least one EditorView"); + let editor_view = editor_view + .as_any_mut() + .downcast_mut::() + .unwrap(); + + if editor_view.completion.is_some() { + return; + } + + let mut cx = Context { + selected_register: helix_view::RegisterSelection::default(), + editor: &mut self.editor, + jobs: &mut self.jobs, + count: None, + callback: None, + on_next_key_callback: None, + }; + completion(&mut cx); + // TODO: scan backwards for trigger and filter the box + self.render(); + } + pub fn handle_terminal_events(&mut self, event: Option>) { let mut cx = crate::compositor::Context { editor: &mut self.editor, diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ec76c81d..1dbb5616 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -4045,7 +4045,7 @@ fn remove_primary_selection(cx: &mut Context) { doc.set_selection(view.id, selection); } -fn completion(cx: &mut Context) { +pub fn completion(cx: &mut Context) { // trigger on trigger char, or if user calls it // (or on word char typing??) // after it's triggered, if response marked is_incomplete, update on every subsequent keypress diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index aa2d6636..ee3b3c65 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -33,7 +33,7 @@ pub struct EditorView { keymaps: Keymaps, on_next_key: Option>, last_insert: (commands::Command, Vec), - completion: Option, + pub(crate) completion: Option, spinners: ProgressSpinners, autoinfo: Option, } -- cgit v1.2.3-70-g09d2 From 66f26e82ceaf4b81dfeb429dcb840a3242e8f254 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Fri, 27 Aug 2021 10:44:12 +0900 Subject: Filter the initial completion --- helix-term/src/application.rs | 11 ++++++----- helix-term/src/commands.rs | 17 ++++++++++++----- helix-term/src/ui/completion.rs | 25 +++++++++++++++++++------ helix-term/src/ui/editor.rs | 5 ++++- helix-view/src/macros.rs | 16 ++++++++++++++++ 5 files changed, 57 insertions(+), 17 deletions(-) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index ab268041..79921268 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -234,9 +234,8 @@ impl Application { } pub fn handle_idle_timeout(&mut self) { + use crate::commands::{completion, Context}; use helix_view::document::Mode; - use crate::commands::{Context, completion}; - if doc_mut!(self.editor).mode != Mode::Insert { return; @@ -254,6 +253,8 @@ impl Application { return; } + // TODO: if completion window was closed with enter (and no selection) we shouldn't retrigger + let mut cx = Context { selected_register: helix_view::RegisterSelection::default(), editor: &mut self.editor, @@ -262,9 +263,9 @@ impl Application { callback: None, on_next_key_callback: None, }; - completion(&mut cx); - // TODO: scan backwards for trigger and filter the box - self.render(); + completion(&mut cx); + // TODO: scan backwards for trigger and filter the box + self.render(); } pub fn handle_terminal_events(&mut self, event: Option>) { diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 1dbb5616..3798c99a 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -4090,10 +4090,8 @@ pub fn completion(cx: &mut Context) { }; let offset_encoding = language_server.offset_encoding(); - let cursor = doc - .selection(view.id) - .primary() - .cursor(doc.text().slice(..)); + let text = doc.text().slice(..); + let cursor = doc.selection(view.id).primary().cursor(text); let pos = pos_to_lsp_pos(doc.text(), cursor, offset_encoding); @@ -4101,6 +4099,15 @@ pub fn completion(cx: &mut Context) { let trigger_offset = cursor; + // TODO: trigger_offset should be the cursor offset but we also need a starting offset from where we want to apply + // completion filtering. For example logger.te| should filter the initial suggestion list with "te". + + use helix_core::chars; + let mut iter = text.chars_at(cursor); + iter.reverse(); + let offset = iter.take_while(|ch| chars::char_is_word(*ch)).count(); + let start_offset = cursor.saturating_sub(offset); + cx.callback( future, move |editor: &mut Editor, @@ -4131,7 +4138,7 @@ pub fn completion(cx: &mut Context) { .find(std::any::type_name::()) .unwrap(); if let Some(ui) = ui.as_any_mut().downcast_mut::() { - ui.set_completion(items, offset_encoding, trigger_offset, size); + ui.set_completion(editor, items, offset_encoding, start_offset, trigger_offset, size); }; }, ); diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 6c9e3a80..72b03274 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -69,14 +69,17 @@ impl menu::Item for CompletionItem { /// Wraps a Menu. pub struct Completion { popup: Popup>, + start_offset: usize, trigger_offset: usize, // TODO: maintain a completioncontext with trigger kind & trigger char } impl Completion { pub fn new( + editor: &Editor, items: Vec, offset_encoding: helix_lsp::OffsetEncoding, + start_offset: usize, trigger_offset: usize, ) -> Self { // let items: Vec = Vec::new(); @@ -175,16 +178,22 @@ impl Completion { }; }); let popup = Popup::new(menu); - Self { + let mut completion = Self { popup, + start_offset, trigger_offset, - } + }; + + // need to recompute immediately in case start_offset != trigger_offset + completion.recompute_filter(editor); + + completion } - pub fn update(&mut self, cx: &mut commands::Context) { + pub fn recompute_filter(&mut self, editor: &Editor) { // recompute menu based on matches let menu = self.popup.contents_mut(); - let (view, doc) = current!(cx.editor); + let (view, doc) = current_ref!(editor); // cx.hooks() // cx.add_hook(enum type, ||) @@ -200,14 +209,18 @@ impl Completion { .selection(view.id) .primary() .cursor(doc.text().slice(..)); - if self.trigger_offset <= cursor { - let fragment = doc.text().slice(self.trigger_offset..cursor); + if self.start_offset <= cursor { + let fragment = doc.text().slice(self.start_offset..cursor); let text = Cow::from(fragment); // TODO: logic is same as ui/picker menu.score(&text); } } + pub fn update(&mut self, cx: &mut commands::Context) { + self.recompute_filter(cx.editor) + } + pub fn is_empty(&self) -> bool { self.popup.contents().is_empty() } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index ee3b3c65..fda6a6d3 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -721,12 +721,15 @@ impl EditorView { pub fn set_completion( &mut self, + editor: &Editor, items: Vec, offset_encoding: helix_lsp::OffsetEncoding, + start_offset: usize, trigger_offset: usize, size: Rect, ) { - let mut completion = Completion::new(items, offset_encoding, trigger_offset); + let mut completion = + Completion::new(editor, items, offset_encoding, start_offset, trigger_offset); // TODO : propagate required size on resize to completion too completion.required_size((size.width, size.height)); self.completion = Some(completion); diff --git a/helix-view/src/macros.rs b/helix-view/src/macros.rs index c9a04270..0bebd02f 100644 --- a/helix-view/src/macros.rs +++ b/helix-view/src/macros.rs @@ -44,3 +44,19 @@ macro_rules! view { $( $editor ).+ .tree.get($( $editor ).+ .tree.focus) }}; } + +#[macro_export] +macro_rules! doc { + ( $( $editor:ident ).+ ) => {{ + $crate::current_ref!( $( $editor ).+ ).1 + }}; +} + +#[macro_export] +macro_rules! current_ref { + ( $( $editor:ident ).+ ) => {{ + let view = $( $editor ).+ .tree.get($( $editor ).+ .tree.focus); + let doc = &$( $editor ).+ .documents[view.doc]; + (view, doc) + }}; +} -- cgit v1.2.3-70-g09d2 From 8ca91891d1f8f6df8073a4cc4af4132f8c6695ce Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Tue, 5 Oct 2021 22:35:38 +0900 Subject: fix compilation --- helix-term/src/application.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 79921268..8019b839 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -256,7 +256,7 @@ impl Application { // TODO: if completion window was closed with enter (and no selection) we shouldn't retrigger let mut cx = Context { - selected_register: helix_view::RegisterSelection::default(), + register: None, editor: &mut self.editor, jobs: &mut self.jobs, count: None, -- cgit v1.2.3-70-g09d2 From f692ede2b7af9ee3c0a83642c0e169ac2db90ca5 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 7 Oct 2021 10:37:35 +0900 Subject: fix: Don't crash on empty completion, don't retrigger on close --- helix-term/src/ui/editor.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'helix-term/src') diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fda6a6d3..9234bb96 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -730,6 +730,12 @@ impl EditorView { ) { let mut completion = Completion::new(editor, items, offset_encoding, start_offset, trigger_offset); + + if completion.is_empty() { + // skip if we got no completion results + return; + } + // TODO : propagate required size on resize to completion too completion.required_size((size.width, size.height)); self.completion = Some(completion); @@ -939,6 +945,7 @@ impl Component for EditorView { if callback.is_some() { // assume close_fn self.completion = None; + cxt.editor.clear_idle_timer(); // don't retrigger } } } @@ -952,6 +959,7 @@ impl Component for EditorView { completion.update(&mut cxt); if completion.is_empty() { self.completion = None; + cxt.editor.clear_idle_timer(); // don't retrigger } } } -- cgit v1.2.3-70-g09d2 From 9f27be429d0b4848a01876cd0eb192f2db8a830b Mon Sep 17 00:00:00 2001 From: Ethan Frei Date: Thu, 7 Oct 2021 21:08:10 -0500 Subject: relative paths showing active file in global search (#803) --- helix-term/src/commands.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'helix-term/src') diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ec76c81d..c1fd7bfe 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1291,7 +1291,8 @@ fn global_search(cx: &mut Context) { cx.push_layer(Box::new(prompt)); - let root = find_root(None).unwrap_or_else(|| PathBuf::from("./")); + let current_path = doc_mut!(cx.editor).path().cloned(); + let show_picker = async move { let all_matches: Vec<(usize, PathBuf)> = UnboundedReceiverStream::new(all_matches_rx).collect().await; @@ -1301,14 +1302,19 @@ fn global_search(cx: &mut Context) { editor.set_status("No matches found".to_string()); return; } + let picker = FilePicker::new( all_matches, move |(_line_num, path)| { - path.strip_prefix(&root) - .unwrap_or(path) + let relative_path = helix_core::path::get_relative_path(path) .to_str() .unwrap() - .into() + .to_owned(); + if current_path.as_ref().map(|p| p == path).unwrap_or(false) { + format!("{} (*)", relative_path).into() + } else { + relative_path.into() + } }, move |editor: &mut Editor, (line_num, path), action| { match editor.open(path.into(), action) { -- cgit v1.2.3-70-g09d2 From a6852fb88f72ea6bb41b19e65b531c17662ba57d Mon Sep 17 00:00:00 2001 From: Leoi Hung Kin Date: Sat, 9 Oct 2021 19:34:10 +0800 Subject: Picker: Don't panick at move_up/move_down when matches is empty (#818) --- helix-term/src/ui/picker.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'helix-term/src') diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index c5b90a9c..9be2a73e 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -270,12 +270,18 @@ impl Picker { } pub fn move_up(&mut self) { + if self.matches.is_empty() { + return; + } let len = self.matches.len(); let pos = ((self.cursor + len.saturating_sub(1)) % len) % len; self.cursor = pos; } pub fn move_down(&mut self) { + if self.matches.is_empty() { + return; + } let len = self.matches.len(); let pos = (self.cursor + 1) % len; self.cursor = pos; -- cgit v1.2.3-70-g09d2 From c7f3a971c0e42d1ecb8b91f075b2300040b656fa Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Sun, 10 Oct 2021 12:22:11 +0900 Subject: Remove resolved TODOs --- helix-term/src/application.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 8019b839..c39a9173 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -253,8 +253,6 @@ impl Application { return; } - // TODO: if completion window was closed with enter (and no selection) we shouldn't retrigger - let mut cx = Context { register: None, editor: &mut self.editor, @@ -264,7 +262,6 @@ impl Application { on_next_key_callback: None, }; completion(&mut cx); - // TODO: scan backwards for trigger and filter the box self.render(); } -- cgit v1.2.3-70-g09d2 From 633b981db22bb30c601b838eaaeb814a64156125 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Sun, 10 Oct 2021 12:32:06 +0900 Subject: Make idle-timeout configurable --- book/src/configuration.md | 1 + helix-term/src/commands.rs | 11 +++++++++-- helix-view/src/editor.rs | 12 ++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'helix-term/src') diff --git a/book/src/configuration.md b/book/src/configuration.md index 60b12bfd..f30146dd 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -19,6 +19,7 @@ To override global configuration parameters, create a `config.toml` file located | `line-number` | Line number display (`absolute`, `relative`) | `absolute` | | `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` | | `auto-pairs` | Enable automatic insertion of pairs to parenthese, brackets, etc. | `true` | +| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` | ## LSP diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3798c99a..f005e376 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -4130,7 +4130,7 @@ pub fn completion(cx: &mut Context) { }; if items.is_empty() { - editor.set_error("No completion available".to_string()); + // editor.set_error("No completion available".to_string()); return; } let size = compositor.size(); @@ -4138,7 +4138,14 @@ pub fn completion(cx: &mut Context) { .find(std::any::type_name::()) .unwrap(); if let Some(ui) = ui.as_any_mut().downcast_mut::() { - ui.set_completion(editor, items, offset_encoding, start_offset, trigger_offset, size); + ui.set_completion( + editor, + items, + offset_encoding, + start_offset, + trigger_offset, + size, + ); }; }, ); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 5362acc8..5af6dbf3 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -26,6 +26,14 @@ use helix_core::Position; use serde::Deserialize; +fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let millis = u64::deserialize(deserializer)?; + Ok(Duration::from_millis(millis)) +} + #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(rename_all = "kebab-case", default)] pub struct Config { @@ -45,6 +53,9 @@ pub struct Config { pub smart_case: bool, /// Automatic insertion of pairs to parentheses, brackets, etc. Defaults to true. pub auto_pairs: bool, + /// Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. Defaults to 400ms. + #[serde(skip_serializing, deserialize_with = "deserialize_duration_millis")] + pub idle_timeout: Duration, } #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] @@ -72,6 +83,7 @@ impl Default for Config { middle_click_paste: true, smart_case: true, auto_pairs: true, + idle_timeout: Duration::from_millis(400), } } } -- cgit v1.2.3-70-g09d2 From 76b1bbc23ad5fc47765472cd9e83727a43c97ff3 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Sun, 10 Oct 2021 12:33:22 +0900 Subject: Allow trigger_offset to be unused for now --- helix-term/src/ui/completion.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'helix-term/src') diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 72b03274..ba009c50 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -70,6 +70,7 @@ impl menu::Item for CompletionItem { pub struct Completion { popup: Popup>, start_offset: usize, + #[allow(dead_code)] trigger_offset: usize, // TODO: maintain a completioncontext with trigger kind & trigger char } -- cgit v1.2.3-70-g09d2 From 4d07eaa48bc4fc0c75e0346406fb6dedfc7db743 Mon Sep 17 00:00:00 2001 From: Leoi Hung Kin Date: Fri, 15 Oct 2021 16:36:39 +0800 Subject: Prevent LSP Messages from displaying when a prompt is presented (#824) * Prevent LSP Messages from displaying when a prompt is presented * use match guard--- helix-term/src/application.rs | 33 ++++++++++++++++++++++++--------- helix-term/src/compositor.rs | 6 ++++++ 2 files changed, 30 insertions(+), 9 deletions(-) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index c39a9173..7667441b 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -295,14 +295,6 @@ impl Application { server_id: usize, ) { use helix_lsp::{Call, MethodCall, Notification}; - let editor_view = self - .compositor - .find(std::any::type_name::()) - .expect("expected at least one EditorView"); - let editor_view = editor_view - .as_any_mut() - .downcast_mut::() - .unwrap(); match call { Call::Notification(helix_lsp::jsonrpc::Notification { method, params, .. }) => { @@ -412,7 +404,19 @@ impl Application { Notification::LogMessage(params) => { log::info!("window/logMessage: {:?}", params); } - Notification::ProgressMessage(params) => { + Notification::ProgressMessage(params) + if !self + .compositor + .has_component(std::any::type_name::()) => + { + let editor_view = self + .compositor + .find(std::any::type_name::()) + .expect("expected at least one EditorView"); + let editor_view = editor_view + .as_any_mut() + .downcast_mut::() + .unwrap(); let lsp::ProgressParams { token, value } = params; let lsp::ProgressParamsValue::WorkDone(work) = value; @@ -487,6 +491,9 @@ impl Application { self.editor.set_status(status); } } + Notification::ProgressMessage(_params) => { + // do nothing + } } } Call::MethodCall(helix_lsp::jsonrpc::MethodCall { @@ -521,6 +528,14 @@ impl Application { MethodCall::WorkDoneProgressCreate(params) => { self.lsp_progress.create(server_id, params.token); + let editor_view = self + .compositor + .find(std::any::type_name::()) + .expect("expected at least one EditorView"); + let editor_view = editor_view + .as_any_mut() + .downcast_mut::() + .unwrap(); let spinner = editor_view.spinners_mut().get_or_create(server_id); if spinner.is_stopped() { spinner.start(); diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 36e54ede..cad1df05 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -171,6 +171,12 @@ impl Compositor { (None, CursorKind::Hidden) } + pub fn has_component(&self, type_name: &str) -> bool { + self.layers + .iter() + .any(|component| component.type_name() == type_name) + } + pub fn find(&mut self, type_name: &str) -> Option<&mut dyn Component> { self.layers .iter_mut() -- cgit v1.2.3-70-g09d2 From c71b49497d8fc8ee487b7cfeafb7392b71a13d17 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Fri, 15 Oct 2021 21:04:26 -0400 Subject: Set CWD when editor is started with a directory (#849) --- helix-term/src/application.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'helix-term/src') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 7667441b..b3fa79ee 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -100,6 +100,7 @@ impl Application { if !args.files.is_empty() { let first = &args.files[0]; // we know it's not empty if first.is_dir() { + std::env::set_current_dir(&first)?; editor.new_file(Action::VerticalSplit); compositor.push(Box::new(ui::file_picker(first.clone()))); } else { -- cgit v1.2.3-70-g09d2 From 2c0468ffd16de1f835ac9c4e39692a682273fb7b Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Sat, 16 Oct 2021 18:43:07 +0900 Subject: fix: If backspacing past the start offset, cancel completion Refs #822 --- helix-term/src/ui/completion.rs | 4 ++++ helix-term/src/ui/menu.rs | 8 ++++++++ 2 files changed, 12 insertions(+) (limited to 'helix-term/src') diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index ba009c50..c75b24f1 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -215,6 +215,10 @@ impl Completion { let text = Cow::from(fragment); // TODO: logic is same as ui/picker menu.score(&text); + } else { + // we backspaced before the start offset, clear the menu + // this will cause the editor to remove the completion popup + menu.clear(); } } diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index dab0c34f..055593fd 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -90,6 +90,14 @@ impl Menu { self.recalculate = true; } + pub fn clear(&mut self) { + self.matches.clear(); + + // reset cursor position + self.cursor = None; + self.scroll = 0; + } + pub fn move_up(&mut self) { let len = self.matches.len(); let pos = self.cursor.map_or(0, |i| (i + len.saturating_sub(1)) % len) % len; -- cgit v1.2.3-70-g09d2 From 89707a858f593c99d44af173e9fb2c0d72b8697e Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sat, 16 Oct 2021 21:57:41 +0800 Subject: Make auto-completion a config (#853) --- book/src/configuration.md | 1 + helix-term/src/application.rs | 2 +- helix-view/src/editor.rs | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'helix-term/src') diff --git a/book/src/configuration.md b/book/src/configuration.md index f30146dd..d47f95d9 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -19,6 +19,7 @@ To override global configuration parameters, create a `config.toml` file located | `line-number` | Line number display (`absolute`, `relative`) | `absolute` | | `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` | | `auto-pairs` | Enable automatic insertion of pairs to parenthese, brackets, etc. | `true` | +| `auto-completion` | Enable automatic pop up of auto-completion. | `true` | | `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` | ## LSP diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index b3fa79ee..0e7d0e55 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -238,7 +238,7 @@ impl Application { use crate::commands::{completion, Context}; use helix_view::document::Mode; - if doc_mut!(self.editor).mode != Mode::Insert { + if doc_mut!(self.editor).mode != Mode::Insert || !self.config.editor.auto_completion { return; } let editor_view = self diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index d0ea6653..90e3bf47 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -47,12 +47,14 @@ pub struct Config { pub shell: Vec, /// Line number mode. pub line_number: LineNumber, - /// Middle click paste support. Defaults to true + /// Middle click paste support. Defaults to true. pub middle_click_paste: bool, /// Smart case: Case insensitive searching unless pattern contains upper case characters. Defaults to true. pub smart_case: bool, /// Automatic insertion of pairs to parentheses, brackets, etc. Defaults to true. pub auto_pairs: bool, + /// Automatic auto-completion, automatically pop up without user trigger. Defaults to true. + pub auto_completion: bool, /// Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. Defaults to 400ms. #[serde(skip_serializing, deserialize_with = "deserialize_duration_millis")] pub idle_timeout: Duration, @@ -83,6 +85,7 @@ impl Default for Config { middle_click_paste: true, smart_case: true, auto_pairs: true, + auto_completion: true, idle_timeout: Duration::from_millis(400), } } -- cgit v1.2.3-70-g09d2