From 2cb1462005dc01d068e5318b81269c150aa8737a Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 21 Apr 2024 01:59:22 -0400 Subject: [PATCH] allow configuring smart tab to always trigger completion instead --- helix-term/src/commands.rs | 15 +++++++------ helix-term/src/handlers/completion.rs | 31 +++++++++++++++++++++++++++ helix-term/src/ui/menu.rs | 1 + helix-view/src/editor.rs | 9 ++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index cc7b84c4b..c9c87a288 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3759,7 +3759,7 @@ fn insert(doc: &Rope, selection: &Selection, ch: char) -> Option { } use helix_core::auto_pairs; - use helix_view::editor::SmartTabConfig; + use helix_view::editor::{SmartTabConfig, SmartTabMode}; pub fn insert_char(cx: &mut Context, c: char) { let (view, doc) = current_ref!(cx.editor); @@ -3784,10 +3784,10 @@ pub fn smart_tab(cx: &mut Context) { let (view, doc) = current_ref!(cx.editor); let view_id = view.id; - if matches!( - cx.editor.config().smart_tab, - Some(SmartTabConfig { enable: true, .. }) - ) { + if let Some(SmartTabConfig { + enable: true, mode, .. + }) = &cx.editor.config().smart_tab + { let cursors_after_whitespace = doc.selection(view_id).ranges().iter().all(|range| { let cursor = range.cursor(doc.text().slice(..)); let current_line_num = doc.text().char_to_line(cursor); @@ -3797,7 +3797,10 @@ pub fn smart_tab(cx: &mut Context) { }); if !cursors_after_whitespace { - move_parent_node_end(cx); + match mode { + SmartTabMode::MoveParentNodeEnd => move_parent_node_end(cx), + SmartTabMode::Completion => completion(cx), + } return; } } diff --git a/helix-term/src/handlers/completion.rs b/helix-term/src/handlers/completion.rs index 491ca5638..76110d53b 100644 --- a/helix-term/src/handlers/completion.rs +++ b/helix-term/src/handlers/completion.rs @@ -13,6 +13,7 @@ use helix_lsp::util::pos_to_lsp_pos; use helix_stdx::rope::RopeSliceExt; use helix_view::document::{Mode, SavePoint}; +use helix_view::editor::{SmartTabConfig, SmartTabMode}; use helix_view::handlers::lsp::CompletionEvent; use helix_view::{DocumentId, Editor, ViewId}; use tokio::sync::mpsc::Sender; @@ -415,6 +416,20 @@ fn completion_post_command_hook( name: "delete_char_backward", .. } => update_completions(cx, None), + MappableCommand::Static { + name: "smart_tab", .. + } => { + if !matches!( + cx.editor.config().smart_tab, + Some(SmartTabConfig { + enable: true, + mode: SmartTabMode::Completion, + .. + }) + ) { + clear_completions(cx) + } + } _ => clear_completions(cx), } } else { @@ -438,6 +453,22 @@ fn completion_post_command_hook( name: "completion" | "insert_mode" | "append_mode", .. } => return Ok(()), + MappableCommand::Static { + name: "smart_tab", .. + } => { + if matches!( + cx.editor.config().smart_tab, + Some(SmartTabConfig { + enable: true, + mode: SmartTabMode::Completion, + .. + }) + ) { + return Ok(()); + } else { + CompletionEvent::Cancel + } + } _ => CompletionEvent::Cancel, }; send_blocking(tx, event); diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index c0e60b33e..7b296bd06 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -274,6 +274,7 @@ fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult { Some(SmartTabConfig { enable: true, supersede_menu: true, + .. }) ) { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index d7058d3ef..bd76c596d 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -343,6 +343,7 @@ pub struct Config { pub struct SmartTabConfig { pub enable: bool, pub supersede_menu: bool, + pub mode: SmartTabMode, } impl Default for SmartTabConfig { @@ -350,10 +351,18 @@ fn default() -> Self { SmartTabConfig { enable: true, supersede_menu: false, + mode: SmartTabMode::MoveParentNodeEnd, } } } +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)] +#[serde(rename_all = "kebab-case")] +pub enum SmartTabMode { + MoveParentNodeEnd, + Completion, +} + #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct TerminalConfig {