From ce97a2f05fcddf81d8210ec6b25411f8fd7d867a Mon Sep 17 00:00:00 2001 From: wojciechkepka Date: Sat, 19 Jun 2021 13:26:52 +0200 Subject: Add ability to change theme on editor --- helix-core/src/indent.rs | 37 ++++++++--------- helix-core/src/lib.rs | 2 +- helix-core/src/syntax.rs | 101 +++++++++++++++++++++++++++-------------------- 3 files changed, 77 insertions(+), 63 deletions(-) (limited to 'helix-core/src') diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 58124ed2..8e0379e2 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -254,26 +254,23 @@ where Configuration, IndentationConfiguration, Lang, LanguageConfiguration, Loader, }; use once_cell::sync::OnceCell; - let loader = Loader::new( - Configuration { - language: vec![LanguageConfiguration { - scope: "source.rust".to_string(), - file_types: vec!["rs".to_string()], - language_id: Lang::Rust, - highlight_config: OnceCell::new(), - // - roots: vec![], - auto_format: false, - language_server: None, - indent: Some(IndentationConfiguration { - tab_width: 4, - unit: String::from(" "), - }), - indent_query: OnceCell::new(), - }], - }, - Vec::new(), - ); + let loader = Loader::new(Configuration { + language: vec![LanguageConfiguration { + scope: "source.rust".to_string(), + file_types: vec!["rs".to_string()], + language_id: Lang::Rust, + highlight_config: OnceCell::new(), + // + roots: vec![], + auto_format: false, + language_server: None, + indent: Some(IndentationConfiguration { + tab_width: 4, + unit: String::from(" "), + }), + indent_query: OnceCell::new(), + }], + }); // set runtime path so we can find the queries let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 03741719..d669fa49 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -50,7 +50,7 @@ pub fn find_root(root: Option<&str>) -> Option { } #[cfg(not(embed_runtime))] -fn runtime_dir() -> std::path::PathBuf { +pub fn runtime_dir() -> std::path::PathBuf { if let Ok(dir) = std::env::var("HELIX_RUNTIME") { return dir.into(); } diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index ae058eb1..78623fd6 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -1,6 +1,8 @@ use crate::{regex::Regex, Change, Rope, RopeSlice, Transaction}; pub use helix_syntax::{get_language, get_language_name, Lang}; +use arc_swap::ArcSwap; + use std::{ borrow::Cow, cell::RefCell, @@ -143,35 +145,48 @@ fn read_query(language: &str, filename: &str) -> String { } impl LanguageConfiguration { - pub fn highlight_config(&self, scopes: &[String]) -> Option> { - self.highlight_config - .get_or_init(|| { - let language = get_language_name(self.language_id).to_ascii_lowercase(); + fn initialize_highlight(&self, scopes: &[String]) -> Option> { + let language = get_language_name(self.language_id).to_ascii_lowercase(); - let highlights_query = read_query(&language, "highlights.scm"); - // always highlight syntax errors - // highlights_query += "\n(ERROR) @error"; + let highlights_query = read_query(&language, "highlights.scm"); + // always highlight syntax errors + // highlights_query += "\n(ERROR) @error"; - let injections_query = read_query(&language, "injections.scm"); + let injections_query = read_query(&language, "injections.scm"); - let locals_query = ""; + let locals_query = ""; - if highlights_query.is_empty() { - None - } else { - let language = get_language(self.language_id); - let mut config = HighlightConfiguration::new( - language, - &highlights_query, - &injections_query, - locals_query, - ) - .unwrap(); // TODO: no unwrap - config.configure(scopes); - Some(Arc::new(config)) - } - }) - .clone() + if highlights_query.is_empty() { + None + } else { + let language = get_language(self.language_id); + let mut config = HighlightConfiguration::new( + language, + &highlights_query, + &injections_query, + locals_query, + ) + .unwrap(); // TODO: no unwrap + config.configure(scopes); + Some(Arc::new(config)) + } + } + + pub fn highlight_config(&self, scopes: &[String]) -> Option> { + if let Some(config) = self.highlight_config.get() { + if let Some(config) = config { + config.configure(scopes); + } + config.clone() + } else { + self.highlight_config + .get_or_init(|| self.initialize_highlight(scopes)) + .clone() + } + } + + pub fn is_highlight_initialized(&self) -> bool { + self.highlight_config.get().is_some() } pub fn indent_query(&self) -> Option<&IndentQuery> { @@ -190,22 +205,18 @@ impl LanguageConfiguration { } } -pub static LOADER: OnceCell = OnceCell::new(); - #[derive(Debug)] pub struct Loader { // highlight_names ? language_configs: Vec>, language_config_ids_by_file_type: HashMap, // Vec - scopes: Vec, } impl Loader { - pub fn new(config: Configuration, scopes: Vec) -> Self { + pub fn new(config: Configuration) -> Self { let mut loader = Self { language_configs: Vec::new(), language_config_ids_by_file_type: HashMap::new(), - scopes, }; for config in config.language { @@ -225,10 +236,6 @@ impl Loader { loader } - pub fn scopes(&self) -> &[String] { - &self.scopes - } - pub fn language_config_for_file_name(&self, path: &Path) -> Option> { // Find all the language configurations that match this file name // or a suffix of the file name. @@ -253,6 +260,10 @@ impl Loader { .find(|config| config.scope == scope) .cloned() } + + pub fn language_configs_iter(&self) -> impl Iterator> { + self.language_configs.iter() + } } pub struct TsParser { @@ -771,7 +782,7 @@ pub struct HighlightConfiguration { combined_injections_query: Option, locals_pattern_index: usize, highlights_pattern_index: usize, - highlight_indices: Vec>, + highlight_indices: ArcSwap>>, non_local_variable_patterns: Vec, injection_content_capture_index: Option, injection_language_capture_index: Option, @@ -923,7 +934,7 @@ impl HighlightConfiguration { } } - let highlight_indices = vec![None; query.capture_names().len()]; + let highlight_indices = ArcSwap::from_pointee(vec![None; query.capture_names().len()]); Ok(Self { language, query, @@ -956,17 +967,20 @@ impl HighlightConfiguration { /// /// When highlighting, results are returned as `Highlight` values, which contain the index /// of the matched highlight this list of highlight names. - pub fn configure(&mut self, recognized_names: &[String]) { + pub fn configure(&self, recognized_names: &[String]) { let mut capture_parts = Vec::new(); - self.highlight_indices.clear(); - self.highlight_indices - .extend(self.query.capture_names().iter().map(move |capture_name| { + let indices: Vec<_> = self + .query + .capture_names() + .iter() + .map(move |capture_name| { capture_parts.clear(); capture_parts.extend(capture_name.split('.')); let mut best_index = None; let mut best_match_len = 0; for (i, recognized_name) in recognized_names.iter().enumerate() { + let recognized_name = recognized_name; let mut len = 0; let mut matches = true; for part in recognized_name.split('.') { @@ -982,7 +996,10 @@ impl HighlightConfiguration { } } best_index.map(Highlight) - })); + }) + .collect(); + + self.highlight_indices.store(Arc::new(indices)); } } @@ -1561,7 +1578,7 @@ where } } - let current_highlight = layer.config.highlight_indices[capture.index as usize]; + let current_highlight = layer.config.highlight_indices.load()[capture.index as usize]; // If this node represents a local definition, then store the current // highlight value on the local scope entry representing this node. -- cgit v1.2.3-70-g09d2 From 6825e195099de6e4eab64e26a230cf8a9c9521b7 Mon Sep 17 00:00:00 2001 From: wojciechkepka Date: Sat, 19 Jun 2021 13:52:28 +0200 Subject: Only reconfiure highlights when setting theme --- helix-core/src/syntax.rs | 19 +++++++++---------- helix-view/src/editor.rs | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'helix-core/src') diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 78623fd6..81b6d5a0 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -172,19 +172,18 @@ impl LanguageConfiguration { } } - pub fn highlight_config(&self, scopes: &[String]) -> Option> { - if let Some(config) = self.highlight_config.get() { - if let Some(config) = config { - config.configure(scopes); - } - config.clone() - } else { - self.highlight_config - .get_or_init(|| self.initialize_highlight(scopes)) - .clone() + pub fn reconfigure(&self, scopes: &[String]) { + if let Some(Some(config)) = self.highlight_config.get() { + config.configure(scopes); } } + pub fn highlight_config(&self, scopes: &[String]) -> Option> { + self.highlight_config + .get_or_init(|| self.initialize_highlight(scopes)) + .clone() + } + pub fn is_highlight_initialized(&self) -> bool { self.highlight_config.get().is_some() } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 83d5cbf6..35a547ad 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -85,7 +85,7 @@ impl Editor { .language_configs_iter() .filter(|cfg| cfg.is_highlight_initialized()) { - config.highlight_config(scopes); + config.reconfigure(scopes); } self.theme = theme; -- cgit v1.2.3-70-g09d2 From e9a3245aae0e4380201cffcff7ebe06c129823c5 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Fri, 18 Jun 2021 17:47:10 +0900 Subject: Re-export unicode crates from helix_core --- Cargo.lock | 2 -- helix-core/src/lib.rs | 8 ++++++-- helix-term/Cargo.toml | 3 --- helix-term/src/ui/prompt.rs | 6 ++++-- 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'helix-core/src') diff --git a/Cargo.lock b/Cargo.lock index 960d55f1..896f7bc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -329,8 +329,6 @@ dependencies = [ "serde_json", "tokio", "toml", - "unicode-segmentation", - "unicode-width", ] [[package]] diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index d669fa49..4a9ac891 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -18,6 +18,12 @@ mod state; pub mod syntax; mod transaction; +pub mod unicode { + pub use unicode_general_category as category; + pub use unicode_segmentation as segmentation; + pub use unicode_width as width; +} + static RUNTIME_DIR: once_cell::sync::Lazy = once_cell::sync::Lazy::new(runtime_dir); @@ -97,8 +103,6 @@ pub use ropey::{Rope, RopeSlice}; pub use tendril::StrTendril as Tendril; -pub use unicode_general_category::get_general_category; - #[doc(inline)] pub use {regex, tree_sitter}; diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 24741796..385af64c 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -54,6 +54,3 @@ toml = "0.5" serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } - -unicode-segmentation = "1.7" -unicode-width = "0.1" diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index d1413209..22158e78 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -6,8 +6,10 @@ use helix_view::{Editor, Theme}; use std::{borrow::Cow, ops::RangeFrom}; use tui::terminal::CursorKind; -use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete}; -use unicode_width::UnicodeWidthStr; +use helix_core::{ + unicode::segmentation::{GraphemeCursor, GraphemeIncomplete}, + unicode::width::UnicodeWidthStr, +}; pub type Completion = (RangeFrom, Cow<'static, str>); -- cgit v1.2.3-70-g09d2