From fe869e5dc7a8cd6c2c2e3945816bd890956eef3a Mon Sep 17 00:00:00 2001 From: kyfanc Date: Tue, 13 Feb 2024 18:58:53 +0800 Subject: fix lsp config reload (#9415) `syn_loader` was replaced rather than interior value being replace, old value was still being referenced and not updated after `:config-refresh`. By using `ArcSwap` like for `config`, each `.load()` call will return the most updated value. Co-authored-by: kyfan --- helix-core/src/syntax.rs | 30 +++++++++++++++++++++++------- helix-core/tests/indent.rs | 10 ++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'helix-core') diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 5d45deaf..a9344448 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -1000,7 +1000,7 @@ thread_local! { pub struct Syntax { layers: HopSlotMap, root: LayerId, - loader: Arc, + loader: Arc>, } fn byte_range_to_str(range: std::ops::Range, source: RopeSlice) -> Cow { @@ -1011,7 +1011,7 @@ impl Syntax { pub fn new( source: RopeSlice, config: Arc, - loader: Arc, + loader: Arc>, ) -> Option { let root_layer = LanguageLayer { tree: None, @@ -1055,9 +1055,10 @@ impl Syntax { let mut queue = VecDeque::new(); queue.push_back(self.root); - let scopes = self.loader.scopes.load(); + let loader = self.loader.load(); + let scopes = loader.scopes.load(); let injection_callback = |language: &InjectionLanguageMarker| { - self.loader + loader .language_configuration_for_injection_string(language) .and_then(|language_config| language_config.highlight_config(&scopes)) }; @@ -2663,7 +2664,12 @@ mod test { let mut cursor = QueryCursor::new(); let config = HighlightConfiguration::new(language, "", "", "").unwrap(); - let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap(); + let syntax = Syntax::new( + source.slice(..), + Arc::new(config), + Arc::new(ArcSwap::from_pointee(loader)), + ) + .unwrap(); let root = syntax.tree().root_node(); let mut test = |capture, range| { @@ -2738,7 +2744,12 @@ mod test { fn main() {} ", ); - let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap(); + let syntax = Syntax::new( + source.slice(..), + Arc::new(config), + Arc::new(ArcSwap::from_pointee(loader)), + ) + .unwrap(); let tree = syntax.tree(); let root = tree.root_node(); assert_eq!(root.kind(), "source_file"); @@ -2829,7 +2840,12 @@ mod test { let language = get_language(language_name).unwrap(); let config = HighlightConfiguration::new(language, "", "", "").unwrap(); - let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap(); + let syntax = Syntax::new( + source.slice(..), + Arc::new(config), + Arc::new(ArcSwap::from_pointee(loader)), + ) + .unwrap(); let root = syntax .tree() diff --git a/helix-core/tests/indent.rs b/helix-core/tests/indent.rs index de1434f7..53265e0b 100644 --- a/helix-core/tests/indent.rs +++ b/helix-core/tests/indent.rs @@ -1,10 +1,11 @@ +use arc_swap::ArcSwap; use helix_core::{ indent::{indent_level_for_line, treesitter_indent_for_pos, IndentStyle}, syntax::{Configuration, Loader}, Syntax, }; use ropey::Rope; -use std::{ops::Range, path::PathBuf, process::Command}; +use std::{ops::Range, path::PathBuf, process::Command, sync::Arc}; #[test] fn test_treesitter_indent_rust() { @@ -197,7 +198,12 @@ fn test_treesitter_indent( let indent_style = IndentStyle::from_str(&language_config.indent.as_ref().unwrap().unit); let highlight_config = language_config.highlight_config(&[]).unwrap(); let text = doc.slice(..); - let syntax = Syntax::new(text, highlight_config, std::sync::Arc::new(loader)).unwrap(); + let syntax = Syntax::new( + text, + highlight_config, + Arc::new(ArcSwap::from_pointee(loader)), + ) + .unwrap(); let indent_query = language_config.indent_query().unwrap(); for i in 0..doc.len_lines() { -- cgit v1.2.3-70-g09d2