From 3c88d971e5f929ef6bb6449196318e7577a2afe8 Mon Sep 17 00:00:00 2001 From: may Date: Thu, 30 Oct 2025 02:55:38 +0100 Subject: [PATCH 1/3] feat: determine auto-pairs from injection --- helix-term/src/commands.rs | 9 ++++++--- helix-view/src/document.rs | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 430d4430aaeb..f8341e544a3c 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -4152,7 +4152,7 @@ pub mod insert { let (view, doc) = current_ref!(cx.editor); let text = doc.text(); let selection = doc.selection(view.id); - let auto_pairs = doc.auto_pairs(cx.editor); + let auto_pairs = doc.auto_pairs(cx.editor, view); let transaction = auto_pairs .as_ref() @@ -4324,7 +4324,8 @@ pub mod insert { // insert an additional line which is indented one level // more and place the cursor there let on_auto_pair = doc - .auto_pairs(cx.editor) + .auto_pairs(cx.editor, view) + .as_deref() .and_then(|pairs| pairs.get(prev)) .is_some_and(|pair| pair.open == prev && pair.close == curr); @@ -4412,7 +4413,9 @@ pub mod insert { let text = doc.text().slice(..); let tab_width = doc.tab_width(); let indent_width = doc.indent_width(); - let auto_pairs = doc.auto_pairs(cx.editor); + + let auto_pairs = doc.auto_pairs(cx.editor, view); + let auto_pairs = auto_pairs.as_deref(); let transaction = Transaction::delete_by_selection(doc.text(), doc.selection(view.id), |range| { diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index e52dbe0f956f..eae46660e2e6 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -2170,7 +2170,7 @@ impl Document { /// language config with auto pairs configured, returns that; /// otherwise, falls back to the global auto pairs config. If the global /// config is false, then ignore language settings. - pub fn auto_pairs<'a>(&'a self, editor: &'a Editor) -> Option<&'a AutoPairs> { + pub fn auto_pairs<'a>(&'a self, editor: &'a Editor, view: &View) -> Option> { let global_config = (editor.auto_pairs).as_ref(); // NOTE: If the user specifies the global auto pairs config as false, then @@ -2182,10 +2182,18 @@ impl Document { } } - match &self.language { - Some(lang) => lang.as_ref().auto_pairs.as_ref().or(global_config), - None => global_config, - } + self.syntax + .as_ref() + .and_then(|syntax| { + let selection = self.selection(view.id).primary(); + let (start, end) = selection.into_byte_range(self.text().slice(..)); + let layer = syntax.layer_for_byte_range(start as u32, end as u32); + + let loader: &syntax::Loader = &editor.syn_loader.load(); + let lang_config = loader.language(syntax.layer(layer).language).config(); + lang_config.auto_pairs.clone().map(Cow::Owned) + }) + .or(global_config.map(Cow::Borrowed)) } pub fn snippet_ctx(&self) -> SnippetRenderCtx { From 18ec33776c22a548faf9033f27df8754f23c8e96 Mon Sep 17 00:00:00 2001 From: may Date: Fri, 31 Oct 2025 20:41:28 +0100 Subject: [PATCH 2/3] perf: save a clone in the fn auto_pairs --- helix-term/src/commands.rs | 13 ++++++++----- helix-view/src/document.rs | 12 ++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index f8341e544a3c..4c12b0239854 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -58,6 +58,7 @@ use helix_view::{ }; use anyhow::{anyhow, bail, ensure, Context as _}; +use arc_swap::access::DynAccess; use insert::*; use movement::Movement; @@ -4152,7 +4153,9 @@ pub mod insert { let (view, doc) = current_ref!(cx.editor); let text = doc.text(); let selection = doc.selection(view.id); - let auto_pairs = doc.auto_pairs(cx.editor, view); + + let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load(); + let auto_pairs = doc.auto_pairs(cx.editor, loader, view); let transaction = auto_pairs .as_ref() @@ -4320,12 +4323,12 @@ pub mod insert { ), }; + let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load(); // If we are between pairs (such as brackets), we want to // insert an additional line which is indented one level // more and place the cursor there let on_auto_pair = doc - .auto_pairs(cx.editor, view) - .as_deref() + .auto_pairs(cx.editor, loader, view) .and_then(|pairs| pairs.get(prev)) .is_some_and(|pair| pair.open == prev && pair.close == curr); @@ -4414,8 +4417,8 @@ pub mod insert { let tab_width = doc.tab_width(); let indent_width = doc.indent_width(); - let auto_pairs = doc.auto_pairs(cx.editor, view); - let auto_pairs = auto_pairs.as_deref(); + let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load(); + let auto_pairs = doc.auto_pairs(cx.editor, loader, view); let transaction = Transaction::delete_by_selection(doc.text(), doc.selection(view.id), |range| { diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index eae46660e2e6..36fc3524917b 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -2170,7 +2170,12 @@ impl Document { /// language config with auto pairs configured, returns that; /// otherwise, falls back to the global auto pairs config. If the global /// config is false, then ignore language settings. - pub fn auto_pairs<'a>(&'a self, editor: &'a Editor, view: &View) -> Option> { + pub fn auto_pairs<'a>( + &'a self, + editor: &'a Editor, + loader: &'a syntax::Loader, + view: &View, + ) -> Option<&'a AutoPairs> { let global_config = (editor.auto_pairs).as_ref(); // NOTE: If the user specifies the global auto pairs config as false, then @@ -2189,11 +2194,10 @@ impl Document { let (start, end) = selection.into_byte_range(self.text().slice(..)); let layer = syntax.layer_for_byte_range(start as u32, end as u32); - let loader: &syntax::Loader = &editor.syn_loader.load(); let lang_config = loader.language(syntax.layer(layer).language).config(); - lang_config.auto_pairs.clone().map(Cow::Owned) + lang_config.auto_pairs.as_ref() }) - .or(global_config.map(Cow::Borrowed)) + .or(global_config) } pub fn snippet_ctx(&self) -> SnippetRenderCtx { From 2a74127088d9dc92c3601dae44aa1e8f85e78c32 Mon Sep 17 00:00:00 2001 From: may Date: Mon, 3 Nov 2025 16:11:06 +0100 Subject: [PATCH 3/3] fix build in typed.rs why is this failing? what did i do? i am so confused. --- helix-term/src/commands/typed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 9d4bc9944f52..b928dd4f28d0 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1862,7 +1862,7 @@ fn tree_sitter_layers( bail!("Syntax information is not available"); }; - let loader = cx.editor.syn_loader.load(); + let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load(); let text = doc.text().slice(..); let cursor = doc.selection(view.id).primary().cursor(text); let byte = text.char_to_byte(cursor) as u32;