on master help sign in
Store theme scopes on the loader, this way theme isn't passed around
53d881fBlaž Hrastnik
helix-core/src/syntax.rs+23−30
@@ -8,7 +8,7 @@ use crate::{
8
8
9pub use helix_syntax::get_language;
9pub use helix_syntax::get_language;
10
10
11−use arc_swap::ArcSwap;
11+use arc_swap::{ArcSwap, Guard};
12use slotmap::{DefaultKey as LayerId, HopSlotMap};
12use slotmap::{DefaultKey as LayerId, HopSlotMap};
13
13
14use std::{
14use std::{
@@ -264,12 +264,16 @@ impl LanguageConfiguration {
264 }
264 }
265}
265}
266
266
267+// Expose loader as Lazy<> global since it's always static?
268+
267#[derive(Debug)]
269#[derive(Debug)]
268pub struct Loader {
270pub struct Loader {
269 // highlight_names ?
271 // highlight_names ?
270 language_configs: Vec<Arc<LanguageConfiguration>>,
272 language_configs: Vec<Arc<LanguageConfiguration>>,
271 language_config_ids_by_file_type: HashMap<String, usize>, // Vec<usize>
273 language_config_ids_by_file_type: HashMap<String, usize>, // Vec<usize>
272 language_config_ids_by_shebang: HashMap<String, usize>,
274 language_config_ids_by_shebang: HashMap<String, usize>,
275+
276+ scopes: ArcSwap<Vec<String>>,
273}
277}
274
278
275impl Loader {
279impl Loader {
@@ -278,6 +282,7 @@ impl Loader {
278 language_configs: Vec::new(),
282 language_configs: Vec::new(),
279 language_config_ids_by_file_type: HashMap::new(),
283 language_config_ids_by_file_type: HashMap::new(),
280 language_config_ids_by_shebang: HashMap::new(),
284 language_config_ids_by_shebang: HashMap::new(),
285+ scopes: ArcSwap::from_pointee(Vec::new()),
281 };
286 };
282
287
283 for config in config.language {
288 for config in config.language {
@@ -363,8 +368,22 @@ impl Loader {
363 }
368 }
364 None
369 None
365 }
370 }
366− pub fn language_configs_iter(&self) -> impl Iterator<Item = &Arc<LanguageConfiguration>> {
371+
372+ pub fn set_scopes(&self, scopes: Vec<String>) {
373+ self.scopes.store(Arc::new(scopes));
374+
375+ // Reconfigure existing grammars
376+ for config in self
367− self.language_configs.iter()
377+ .language_configs
378+ .iter()
379+ .filter(|cfg| cfg.is_highlight_initialized())
380+ {
381+ config.reconfigure(&self.scopes());
382+ }
383+ }
384+
385+ pub fn scopes(&self) -> Guard<Arc<Vec<String>>> {
386+ self.scopes.load()
368 }
387 }
369}
388}
370
389
@@ -447,33 +466,7 @@ impl Syntax {
447 self.loader
466 self.loader
448 .language_configuration_for_injection_string(language)
467 .language_configuration_for_injection_string(language)
449 .and_then(|language_config| {
468 .and_then(|language_config| {
450− // TODO: get these theme.scopes from somewhere, probably make them settable on Loader
451− let scopes = &[
452− "attribute",
453− "constant",
454− "function.builtin",
455− "function",
456− "keyword",
457− "operator",
458− "property",
459− "punctuation",
460− "punctuation.bracket",
461− "punctuation.delimiter",
462− "string",
463− "string.special",
464− "tag",
465− "type",
466− "type.builtin",
467− "variable",
468− "variable.builtin",
469− "variable.parameter",
470− ];
471− language_config.highlight_config(
469+ language_config.highlight_config(&self.loader.scopes.load())
472− &scopes
473− .iter()
474− .map(|scope| scope.to_string())
475− .collect::<Vec<_>>(),
476− )
477 })
470 })
478 };
471 };
479
472
helix-term/src/ui/picker.rs+1−1
@@ -139,7 +139,7 @@ impl<T> FilePicker<T> {
139 (size, _) if size > MAX_FILE_SIZE_FOR_PREVIEW => CachedPreview::LargeFile,
139 (size, _) if size > MAX_FILE_SIZE_FOR_PREVIEW => CachedPreview::LargeFile,
140 _ => {
140 _ => {
141 // TODO: enable syntax highlighting; blocked by async rendering
141 // TODO: enable syntax highlighting; blocked by async rendering
142− Document::open(path, None, Some(&editor.theme), None)
142+ Document::open(path, None, None)
143 .map(|doc| CachedPreview::Document(Box::new(doc)))
143 .map(|doc| CachedPreview::Document(Box::new(doc)))
144 .unwrap_or(CachedPreview::NotFound)
144 .unwrap_or(CachedPreview::NotFound)
145 }
145 }
helix-view/src/document.rs+6−11
@@ -19,7 +19,7 @@ use helix_core::{
19};
19};
20use helix_lsp::util::LspFormatting;
20use helix_lsp::util::LspFormatting;
21
21
22−use crate::{DocumentId, Theme, ViewId};
22+use crate::{DocumentId, ViewId};
23
23
24/// 8kB of buffer space for encoding and decoding `Rope`s.
24/// 8kB of buffer space for encoding and decoding `Rope`s.
25const BUF_SIZE: usize = 8192;
25const BUF_SIZE: usize = 8192;
@@ -358,7 +358,6 @@ impl Document {
358 pub fn open(
358 pub fn open(
359 path: &Path,
359 path: &Path,
360 encoding: Option<&'static encoding::Encoding>,
360 encoding: Option<&'static encoding::Encoding>,
361− theme: Option<&Theme>,
362 config_loader: Option<Arc<syntax::Loader>>,
361 config_loader: Option<Arc<syntax::Loader>>,
363 ) -> Result<Self, Error> {
362 ) -> Result<Self, Error> {
364 // Open the file if it exists, otherwise assume it is a new file (and thus empty).
363 // Open the file if it exists, otherwise assume it is a new file (and thus empty).
@@ -376,7 +375,7 @@ impl Document {
376 // set the path and try detecting the language
375 // set the path and try detecting the language
377 doc.set_path(Some(path))?;
376 doc.set_path(Some(path))?;
378 if let Some(loader) = config_loader {
377 if let Some(loader) = config_loader {
379− doc.detect_language(theme, loader);
378+ doc.detect_language(loader);
380 }
379 }
381
380
382 doc.detect_indent_and_line_ending();
381 doc.detect_indent_and_line_ending();
@@ -498,12 +497,12 @@ impl Document {
498 }
497 }
499
498
500 /// Detect the programming language based on the file type.
499 /// Detect the programming language based on the file type.
501− pub fn detect_language(&mut self, theme: Option<&Theme>, config_loader: Arc<syntax::Loader>) {
500+ pub fn detect_language(&mut self, config_loader: Arc<syntax::Loader>) {
502 if let Some(path) = &self.path {
501 if let Some(path) = &self.path {
503 let language_config = config_loader
502 let language_config = config_loader
504 .language_config_for_file_name(path)
503 .language_config_for_file_name(path)
505 .or_else(|| config_loader.language_config_for_shebang(self.text()));
504 .or_else(|| config_loader.language_config_for_shebang(self.text()));
506− self.set_language(theme, language_config, Some(config_loader));
505+ self.set_language(language_config, Some(config_loader));
507 }
506 }
508 }
507 }
509
508
@@ -577,16 +576,13 @@ impl Document {
577 /// if it exists.
576 /// if it exists.
578 pub fn set_language(
577 pub fn set_language(
579 &mut self,
578 &mut self,
580− theme: Option<&Theme>,
581 language_config: Option<Arc<helix_core::syntax::LanguageConfiguration>>,
579 language_config: Option<Arc<helix_core::syntax::LanguageConfiguration>>,
582 loader: Option<Arc<helix_core::syntax::Loader>>,
580 loader: Option<Arc<helix_core::syntax::Loader>>,
583 ) {
581 ) {
584 if let (Some(language_config), Some(loader)) = (language_config, loader) {
582 if let (Some(language_config), Some(loader)) = (language_config, loader) {
585− let scopes = theme.map(|theme| theme.scopes()).unwrap_or(&[]);
586− if let Some(highlight_config) = language_config.highlight_config(scopes) {
583+ if let Some(highlight_config) = language_config.highlight_config(&loader.scopes()) {
587 let syntax = Syntax::new(&self.text, highlight_config, loader);
584 let syntax = Syntax::new(&self.text, highlight_config, loader);
588 self.syntax = Some(syntax);
585 self.syntax = Some(syntax);
589− // TODO: config.configure(scopes) is now delayed, is that ok?
590 }
586 }
591
587
592 self.language = Some(language_config);
588 self.language = Some(language_config);
@@ -601,12 +597,11 @@ impl Document {
601 pub fn set_language2(
597 pub fn set_language2(
602 &mut self,
598 &mut self,
603 scope: &str,
599 scope: &str,
604− theme: Option<&Theme>,
605 config_loader: Arc<syntax::Loader>,
600 config_loader: Arc<syntax::Loader>,
606 ) {
601 ) {
607 let language_config = config_loader.language_config_for_scope(scope);
602 let language_config = config_loader.language_config_for_scope(scope);
608
603
609− self.set_language(theme, language_config, Some(config_loader));
604+ self.set_language(language_config, Some(config_loader));
610 }
605 }
611
606
612 /// Set the LSP.
607 /// Set the LSP.
helix-view/src/editor.rs+2−9
@@ -268,13 +268,7 @@ impl Editor {
268 }
268 }
269
269
270 let scopes = theme.scopes();
270 let scopes = theme.scopes();
271− for config in self
272− .syn_loader
271+ self.syn_loader.set_scopes(scopes.to_vec());
273− .language_configs_iter()
274− .filter(|cfg| cfg.is_highlight_initialized())
275− {
276− config.reconfigure(scopes);
277− }
278
272
279 self.theme = theme;
273 self.theme = theme;
280 self._refresh();
274 self._refresh();
@@ -283,7 +277,7 @@ impl Editor {
283 /// Refreshes the language server for a given document
277 /// Refreshes the language server for a given document
284 pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> {
278 pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> {
285 let doc = self.documents.get_mut(&doc_id)?;
279 let doc = self.documents.get_mut(&doc_id)?;
286− doc.detect_language(Some(&self.theme), self.syn_loader.clone());
280+ doc.detect_language(self.syn_loader.clone());
287 Self::launch_language_server(&mut self.language_servers, doc)
281 Self::launch_language_server(&mut self.language_servers, doc)
288 }
282 }
289
283
@@ -465,7 +459,6 @@ impl Editor {
465 let mut doc = Document::open(
459 let mut doc = Document::open(
466 &path,
460 &path,
467 None,
461 None,
468− Some(&self.theme),
469 Some(self.syn_loader.clone()),
462 Some(self.syn_loader.clone()),
470 )?;
463 )?;
471
464