Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--helix-core/src/syntax.rs11
-rw-r--r--helix-term/src/application.rs3
-rw-r--r--helix-term/src/commands/typed.rs5
-rw-r--r--helix-term/src/ui/picker.rs9
-rw-r--r--helix-view/src/document.rs76
-rw-r--r--helix-view/src/editor.rs20
-rw-r--r--helix-view/src/gutter.rs7
-rw-r--r--helix-view/src/view.rs7
8 files changed, 94 insertions, 44 deletions
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 6a2c28d1..dfc32342 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -274,6 +274,15 @@ struct FileTypeGlobMatcher {
file_types: Vec<FileTypeGlob>,
}
+impl Default for FileTypeGlobMatcher {
+ fn default() -> Self {
+ Self {
+ matcher: globset::GlobSet::empty(),
+ file_types: Default::default(),
+ }
+ }
+}
+
impl FileTypeGlobMatcher {
fn new(file_types: Vec<FileTypeGlob>) -> Result<Self, globset::Error> {
let mut builder = globset::GlobSetBuilder::new();
@@ -299,7 +308,7 @@ impl FileTypeGlobMatcher {
// Expose loader as Lazy<> global since it's always static?
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct Loader {
// highlight_names ?
language_configs: Vec<Arc<LanguageConfiguration>>,
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 16a26cb2..6f3485a8 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -389,8 +389,9 @@ impl Application {
let lang_loader = helix_core::config::user_lang_loader()?;
self.editor.syn_loader.store(Arc::new(lang_loader));
+ let loader = self.editor.syn_loader.load();
for document in self.editor.documents.values_mut() {
- document.detect_language(self.editor.syn_loader.clone());
+ document.detect_language(&loader);
let diagnostics = Editor::doc_diagnostics(
&self.editor.language_servers,
&self.editor.diagnostics,
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index c35ff714..db2942ea 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -2090,10 +2090,11 @@ fn language(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> any
let doc = doc_mut!(cx.editor);
+ let loader = cx.editor.syn_loader.load();
if &args[0] == DEFAULT_LANGUAGE_NAME {
- doc.set_language(None, None)
+ doc.set_language(None, &loader)
} else {
- doc.set_language_by_language_id(&args[0], cx.editor.syn_loader.clone())?;
+ doc.set_language_by_language_id(&args[0], &loader)?;
}
doc.detect_indent_and_line_ending();
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index a6ce91a6..5a4b3afb 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -624,7 +624,14 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
if content_type.is_binary() {
return Ok(CachedPreview::Binary);
}
- Document::open(&path, None, None, editor.config.clone()).map_or(
+ Document::open(
+ &path,
+ None,
+ false,
+ editor.config.clone(),
+ editor.syn_loader.clone(),
+ )
+ .map_or(
Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"Cannot open document",
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 417483e0..34a3df82 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -209,6 +209,11 @@ pub struct Document {
// NOTE: ideally this would live on the handler for color swatches. This is blocked on a
// large refactor that would make `&mut Editor` available on the `DocumentDidChange` event.
pub color_swatch_controller: TaskController,
+
+ // NOTE: this field should eventually go away - we should use the Editor's syn_loader instead
+ // of storing a copy on every doc. Then we can remove the surrounding `Arc` and use the
+ // `ArcSwap` directly.
+ syn_loader: Arc<ArcSwap<syntax::Loader>>,
}
#[derive(Debug, Clone, Default)]
@@ -679,6 +684,7 @@ impl Document {
text: Rope,
encoding_with_bom_info: Option<(&'static Encoding, bool)>,
config: Arc<dyn DynAccess<Config>>,
+ syn_loader: Arc<ArcSwap<syntax::Loader>>,
) -> Self {
let (encoding, has_bom) = encoding_with_bom_info.unwrap_or((encoding::UTF_8, false));
let line_ending = config.load().default_line_ending.into();
@@ -721,13 +727,17 @@ impl Document {
jump_labels: HashMap::new(),
color_swatches: None,
color_swatch_controller: TaskController::new(),
+ syn_loader,
}
}
- pub fn default(config: Arc<dyn DynAccess<Config>>) -> Self {
+ pub fn default(
+ config: Arc<dyn DynAccess<Config>>,
+ syn_loader: Arc<ArcSwap<syntax::Loader>>,
+ ) -> Self {
let line_ending: LineEnding = config.load().default_line_ending.into();
let text = Rope::from(line_ending.as_str());
- Self::from(text, None, config)
+ Self::from(text, None, config, syn_loader)
}
// TODO: async fn?
@@ -736,8 +746,9 @@ impl Document {
pub fn open(
path: &Path,
mut encoding: Option<&'static Encoding>,
- config_loader: Option<Arc<ArcSwap<syntax::Loader>>>,
+ detect_language: bool,
config: Arc<dyn DynAccess<Config>>,
+ syn_loader: Arc<ArcSwap<syntax::Loader>>,
) -> Result<Self, DocumentOpenError> {
// If the path is not a regular file (e.g.: /dev/random) it should not be opened.
if path.metadata().is_ok_and(|metadata| !metadata.is_file()) {
@@ -763,12 +774,13 @@ impl Document {
(Rope::from(line_ending.as_str()), encoding, false)
};
- let mut doc = Self::from(rope, Some((encoding, has_bom)), config);
+ let loader = syn_loader.load();
+ let mut doc = Self::from(rope, Some((encoding, has_bom)), config, syn_loader);
// set the path and try detecting the language
doc.set_path(Some(path));
- if let Some(loader) = config_loader {
- doc.detect_language(loader);
+ if detect_language {
+ doc.detect_language(&loader);
}
doc.editor_config = editor_config;
@@ -1122,12 +1134,8 @@ impl Document {
}
/// Detect the programming language based on the file type.
- pub fn detect_language(&mut self, config_loader: Arc<ArcSwap<syntax::Loader>>) {
- let loader = config_loader.load();
- self.set_language(
- self.detect_language_config(&loader),
- Some(Arc::clone(&config_loader)),
- );
+ pub fn detect_language(&mut self, loader: &syntax::Loader) {
+ self.set_language(self.detect_language_config(loader), loader);
}
/// Detect the programming language based on the file type.
@@ -1277,20 +1285,20 @@ impl Document {
pub fn set_language(
&mut self,
language_config: Option<Arc<syntax::config::LanguageConfiguration>>,
- loader: Option<Arc<ArcSwap<syntax::Loader>>>,
+ loader: &syntax::Loader,
) {
- if let (Some(language_config), Some(loader)) = (language_config, loader) {
- if let Some(highlight_config) =
- language_config.highlight_config(&(*loader).load().scopes())
- {
- self.syntax = Syntax::new(self.text.slice(..), highlight_config, loader);
- }
-
- self.language = Some(language_config);
- } else {
- self.syntax = None;
- self.language = None;
- };
+ self.language = language_config;
+ self.syntax = self
+ .language
+ .as_ref()
+ .and_then(|config| config.highlight_config(&loader.scopes()))
+ .and_then(|highlight_config| {
+ Syntax::new(
+ self.text.slice(..),
+ highlight_config,
+ self.syn_loader.clone(),
+ )
+ });
}
/// Set the programming language for the file if you know the language but don't have the
@@ -1298,13 +1306,12 @@ impl Document {
pub fn set_language_by_language_id(
&mut self,
language_id: &str,
- config_loader: Arc<ArcSwap<syntax::Loader>>,
+ loader: &syntax::Loader,
) -> anyhow::Result<()> {
- let language_config = (*config_loader)
- .load()
+ let language_config = loader
.language_config_for_language_id(language_id)
.ok_or_else(|| anyhow!("invalid language id: {}", language_id))?;
- self.set_language(Some(language_config), Some(config_loader));
+ self.set_language(Some(language_config), loader);
Ok(())
}
@@ -2319,6 +2326,7 @@ mod test {
text,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
let view = ViewId::default();
doc.set_selection(view, Selection::single(0, 0));
@@ -2357,6 +2365,7 @@ mod test {
text,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
let view = ViewId::default();
doc.set_selection(view, Selection::single(5, 5));
@@ -2470,9 +2479,12 @@ mod test {
#[test]
fn test_line_ending() {
assert_eq!(
- Document::default(Arc::new(ArcSwap::new(Arc::new(Config::default()))))
- .text()
- .to_string(),
+ Document::default(
+ Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default()))
+ )
+ .text()
+ .to_string(),
helix_core::NATIVE_LINE_ENDING.as_str()
);
}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 5509bba3..ab763a96 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -1478,9 +1478,9 @@ impl Editor {
}
pub fn refresh_doc_language(&mut self, doc_id: DocumentId) {
- let loader = self.syn_loader.clone();
+ let loader = self.syn_loader.load();
let doc = doc_mut!(self, &doc_id);
- doc.detect_language(loader);
+ doc.detect_language(&loader);
doc.detect_editor_config();
doc.detect_indent_and_line_ending();
self.refresh_language_servers(doc_id);
@@ -1740,7 +1740,10 @@ impl Editor {
}
pub fn new_file(&mut self, action: Action) -> DocumentId {
- self.new_file_from_document(action, Document::default(self.config.clone()))
+ self.new_file_from_document(
+ action,
+ Document::default(self.config.clone(), self.syn_loader.clone()),
+ )
}
pub fn new_file_from_stdin(&mut self, action: Action) -> Result<DocumentId, Error> {
@@ -1749,6 +1752,7 @@ impl Editor {
helix_core::Rope::default(),
Some((encoding, has_bom)),
self.config.clone(),
+ self.syn_loader.clone(),
);
let doc_id = self.new_file_from_document(action, doc);
let doc = doc_mut!(self, &doc_id);
@@ -1777,8 +1781,9 @@ impl Editor {
let mut doc = Document::open(
&path,
None,
- Some(self.syn_loader.clone()),
+ true,
self.config.clone(),
+ self.syn_loader.clone(),
)?;
let diagnostics =
@@ -1874,7 +1879,12 @@ impl Editor {
.iter()
.map(|(&doc_id, _)| doc_id)
.next()
- .unwrap_or_else(|| self.new_document(Document::default(self.config.clone())));
+ .unwrap_or_else(|| {
+ self.new_document(Document::default(
+ self.config.clone(),
+ self.syn_loader.clone(),
+ ))
+ });
let view = View::new(doc_id, self.config().gutters.clone());
let view_id = self.tree.insert(view);
let doc = doc_mut!(self, &doc_id);
diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs
index bc87d836..c2cbc0da 100644
--- a/helix-view/src/gutter.rs
+++ b/helix-view/src/gutter.rs
@@ -334,7 +334,7 @@ mod tests {
use crate::graphics::Rect;
use crate::DocumentId;
use arc_swap::ArcSwap;
- use helix_core::Rope;
+ use helix_core::{syntax, Rope};
#[test]
fn test_default_gutter_widths() {
@@ -346,6 +346,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
assert_eq!(view.gutters.layout.len(), 5);
@@ -371,6 +372,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
assert_eq!(view.gutters.layout.len(), 1);
@@ -389,6 +391,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
assert_eq!(view.gutters.layout.len(), 2);
@@ -411,6 +414,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
let rope = Rope::from_str("a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np");
@@ -418,6 +422,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
assert_eq!(view.gutters.layout.len(), 2);
diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs
index d6f10753..6d237e20 100644
--- a/helix-view/src/view.rs
+++ b/helix-view/src/view.rs
@@ -699,7 +699,7 @@ mod tests {
use super::*;
use arc_swap::ArcSwap;
- use helix_core::Rope;
+ use helix_core::{syntax, Rope};
// 1 diagnostic + 1 spacer + 3 linenr (< 1000 lines) + 1 spacer + 1 diff
const DEFAULT_GUTTER_OFFSET: u16 = 7;
@@ -719,6 +719,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
doc.ensure_view_init(view.id);
@@ -894,6 +895,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
doc.ensure_view_init(view.id);
assert_eq!(
@@ -924,6 +926,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
doc.ensure_view_init(view.id);
assert_eq!(
@@ -948,6 +951,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
doc.ensure_view_init(view.id);
@@ -1032,6 +1036,7 @@ mod tests {
rope,
None,
Arc::new(ArcSwap::new(Arc::new(Config::default()))),
+ Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),
);
doc.ensure_view_init(view.id);