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-term/src/application.rs | 7 ++++--- helix-term/src/ui/lsp.rs | 9 +++++++-- helix-term/src/ui/markdown.rs | 8 +++++--- helix-term/src/ui/mod.rs | 4 ++-- helix-term/src/ui/picker.rs | 11 +++++++---- helix-term/src/ui/prompt.rs | 9 +++++++-- 6 files changed, 32 insertions(+), 16 deletions(-) (limited to 'helix-term') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index b844b5f0..30df3981 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -66,7 +66,7 @@ pub struct Application { #[allow(dead_code)] theme_loader: Arc, #[allow(dead_code)] - syn_loader: Arc, + syn_loader: Arc>, signals: Signals, jobs: Jobs, @@ -122,7 +122,7 @@ impl Application { }) .unwrap_or_else(|| theme_loader.default_theme(true_color)); - let syn_loader = std::sync::Arc::new(lang_loader); + let syn_loader = Arc::new(ArcSwap::from_pointee(lang_loader)); #[cfg(not(feature = "integration"))] let backend = CrosstermBackend::new(stdout(), &config.editor); @@ -391,7 +391,8 @@ impl Application { /// refresh language config after config change fn refresh_language_config(&mut self) -> Result<(), Error> { let lang_loader = helix_core::config::user_lang_loader()?; - self.syn_loader = std::sync::Arc::new(lang_loader); + + self.syn_loader.store(Arc::new(lang_loader)); self.editor.syn_loader = self.syn_loader.clone(); for document in self.editor.documents.values_mut() { document.detect_language(self.syn_loader.clone()); diff --git a/helix-term/src/ui/lsp.rs b/helix-term/src/ui/lsp.rs index 7037b155..879f963e 100644 --- a/helix-term/src/ui/lsp.rs +++ b/helix-term/src/ui/lsp.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use arc_swap::ArcSwap; use helix_core::syntax; use helix_view::graphics::{Margin, Rect, Style}; use tui::buffer::Buffer; @@ -18,13 +19,17 @@ pub struct SignatureHelp { active_param_range: Option<(usize, usize)>, language: String, - config_loader: Arc, + config_loader: Arc>, } impl SignatureHelp { pub const ID: &'static str = "signature-help"; - pub fn new(signature: String, language: String, config_loader: Arc) -> Self { + pub fn new( + signature: String, + language: String, + config_loader: Arc>, + ) -> Self { Self { signature, signature_doc: None, diff --git a/helix-term/src/ui/markdown.rs b/helix-term/src/ui/markdown.rs index 5cf530ad..749d5850 100644 --- a/helix-term/src/ui/markdown.rs +++ b/helix-term/src/ui/markdown.rs @@ -1,4 +1,5 @@ use crate::compositor::{Component, Context}; +use arc_swap::ArcSwap; use tui::{ buffer::Buffer as Surface, text::{Span, Spans, Text}, @@ -31,7 +32,7 @@ pub fn highlighted_code_block<'a>( text: &str, language: &str, theme: Option<&Theme>, - config_loader: Arc, + config_loader: Arc>, additional_highlight_spans: Option)>>, ) -> Text<'a> { let mut spans = Vec::new(); @@ -48,6 +49,7 @@ pub fn highlighted_code_block<'a>( let ropeslice = RopeSlice::from(text); let syntax = config_loader + .load() .language_configuration_for_injection_string(&InjectionLanguageMarker::Name( language.into(), )) @@ -121,7 +123,7 @@ pub fn highlighted_code_block<'a>( pub struct Markdown { contents: String, - config_loader: Arc, + config_loader: Arc>, } // TODO: pre-render and self reference via Pin @@ -140,7 +142,7 @@ impl Markdown { ]; const INDENT: &'static str = " "; - pub fn new(contents: String, config_loader: Arc) -> Self { + pub fn new(contents: String, config_loader: Arc>) -> Self { Self { contents, config_loader, diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index efa2473e..d27e8355 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -336,8 +336,8 @@ pub mod completers { pub fn language(editor: &Editor, input: &str) -> Vec { let text: String = "text".into(); - let language_ids = editor - .syn_loader + let loader = editor.syn_loader.load(); + let language_ids = loader .language_configs() .map(|config| &config.language_id) .chain(std::iter::once(&text)); diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 4be5a11e..c2728888 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -461,14 +461,17 @@ impl Picker { // Then attempt to highlight it if it has no language set if doc.language_config().is_none() { - if let Some(language_config) = doc.detect_language_config(&cx.editor.syn_loader) { + if let Some(language_config) = doc.detect_language_config(&cx.editor.syn_loader.load()) + { doc.language = Some(language_config.clone()); let text = doc.text().clone(); let loader = cx.editor.syn_loader.clone(); let job = tokio::task::spawn_blocking(move || { - let syntax = language_config.highlight_config(&loader.scopes()).and_then( - |highlight_config| Syntax::new(text.slice(..), highlight_config, loader), - ); + let syntax = language_config + .highlight_config(&loader.load().scopes()) + .and_then(|highlight_config| { + Syntax::new(text.slice(..), highlight_config, loader) + }); let callback = move |editor: &mut Editor, compositor: &mut Compositor| { let Some(syntax) = syntax else { log::info!("highlighting picker item failed"); diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 3764bba6..a6ee7f05 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -1,5 +1,6 @@ use crate::compositor::{Component, Compositor, Context, Event, EventResult}; use crate::{alt, ctrl, key, shift, ui}; +use arc_swap::ArcSwap; use helix_core::syntax; use helix_view::input::KeyEvent; use helix_view::keyboard::KeyCode; @@ -34,7 +35,7 @@ pub struct Prompt { callback_fn: CallbackFn, pub doc_fn: DocFn, next_char_handler: Option, - language: Option<(&'static str, Arc)>, + language: Option<(&'static str, Arc>)>, } #[derive(Clone, Copy, PartialEq, Eq)] @@ -98,7 +99,11 @@ impl Prompt { self } - pub fn with_language(mut self, language: &'static str, loader: Arc) -> Self { + pub fn with_language( + mut self, + language: &'static str, + loader: Arc>, + ) -> Self { self.language = Some((language, loader)); self } -- cgit v1.2.3-70-g09d2