diff options
Diffstat (limited to 'helix-view')
-rw-r--r-- | helix-view/src/document.rs | 43 | ||||
-rw-r--r-- | helix-view/src/editor.rs | 75 |
2 files changed, 74 insertions, 44 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index e9a8097c..4d5a23b6 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -9,11 +9,11 @@ use std::sync::Arc; use helix_core::{ chars::{char_is_linebreak, char_is_whitespace}, history::History, - syntax::{LanguageConfiguration, LOADER}, + syntax::{self, LanguageConfiguration}, ChangeSet, Diagnostic, Rope, Selection, State, Syntax, Transaction, }; -use crate::{DocumentId, ViewId}; +use crate::{DocumentId, Theme, ViewId}; use std::collections::HashMap; @@ -236,7 +236,11 @@ impl Document { } // TODO: async fn? - pub fn load(path: PathBuf) -> Result<Self, Error> { + pub fn load( + path: PathBuf, + theme: Option<&Theme>, + config_loader: Option<&syntax::Loader>, + ) -> Result<Self, Error> { use std::{fs::File, io::BufReader}; let doc = if !path.exists() { @@ -256,6 +260,10 @@ impl Document { doc.set_path(&path)?; doc.detect_indent_style(); + if let Some(loader) = config_loader { + doc.detect_language(theme, loader); + } + Ok(doc) } @@ -330,12 +338,10 @@ impl Document { } } - fn detect_language(&mut self) { - if let Some(path) = self.path() { - let loader = LOADER.get().unwrap(); - let language_config = loader.language_config_for_file_name(path); - let scopes = loader.scopes(); - self.set_language(language_config, scopes); + pub fn detect_language(&mut self, theme: Option<&Theme>, config_loader: &syntax::Loader) { + if let Some(path) = &self.path { + let language_config = config_loader.language_config_for_file_name(path); + self.set_language(theme, language_config); } } @@ -472,18 +478,16 @@ impl Document { // and error out when document is saved self.path = Some(path); - // try detecting the language based on filepath - self.detect_language(); - Ok(()) } pub fn set_language( &mut self, + theme: Option<&Theme>, language_config: Option<Arc<helix_core::syntax::LanguageConfiguration>>, - scopes: &[String], ) { if let Some(language_config) = language_config { + let scopes = theme.map(|theme| theme.scopes()).unwrap_or(&[]); if let Some(highlight_config) = language_config.highlight_config(scopes) { let syntax = Syntax::new(&self.text, highlight_config); self.syntax = Some(syntax); @@ -497,12 +501,15 @@ impl Document { }; } - pub fn set_language2(&mut self, scope: &str) { - let loader = LOADER.get().unwrap(); - let language_config = loader.language_config_for_scope(scope); - let scopes = loader.scopes(); + pub fn set_language2( + &mut self, + scope: &str, + theme: Option<&Theme>, + config_loader: Arc<syntax::Loader>, + ) { + let language_config = config_loader.language_config_for_scope(scope); - self.set_language(language_config, scopes); + self.set_language(theme, language_config); } pub fn set_language_server(&mut self, language_server: Option<Arc<helix_lsp::Client>>) { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index db8ae87a..83d5cbf6 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1,10 +1,14 @@ -use crate::{theme::Theme, tree::Tree, Document, DocumentId, RegisterSelection, View, ViewId}; +use crate::{ + theme::{self, Theme}, + tree::Tree, + Document, DocumentId, RegisterSelection, View, ViewId, +}; +use helix_core::syntax; use tui::layout::Rect; use tui::terminal::CursorKind; use futures_util::future; -use std::path::PathBuf; -use std::time::Duration; +use std::{path::PathBuf, sync::Arc, time::Duration}; use slotmap::SlotMap; @@ -24,6 +28,9 @@ pub struct Editor { pub theme: Theme, pub language_servers: helix_lsp::Registry, + pub syn_loader: Arc<syntax::Loader>, + pub theme_loader: Arc<theme::Loader>, + pub status_msg: Option<(String, Severity)>, } @@ -35,27 +42,11 @@ pub enum Action { } impl Editor { - pub fn new(mut area: tui::layout::Rect) -> Self { - use helix_core::config_dir; - let config = std::fs::read(config_dir().join("theme.toml")); - // load $HOME/.config/helix/theme.toml, fallback to default config - let toml = config - .as_deref() - .unwrap_or(include_bytes!("../../theme.toml")); - let theme: Theme = toml::from_slice(toml).expect("failed to parse theme.toml"); - - // initialize language registry - use helix_core::syntax::{Loader, LOADER}; - - // load $HOME/.config/helix/languages.toml, fallback to default config - let config = std::fs::read(helix_core::config_dir().join("languages.toml")); - let toml = config - .as_deref() - .unwrap_or(include_bytes!("../../languages.toml")); - - let config = toml::from_slice(toml).expect("Could not parse languages.toml"); - LOADER.get_or_init(|| Loader::new(config, theme.scopes().to_vec())); - + pub fn new( + mut area: tui::layout::Rect, + themes: Arc<theme::Loader>, + config_loader: Arc<syntax::Loader>, + ) -> Self { let language_servers = helix_lsp::Registry::new(); // HAXX: offset the render area height by 1 to account for prompt/commandline @@ -66,8 +57,10 @@ impl Editor { documents: SlotMap::with_key(), count: None, selected_register: RegisterSelection::default(), - theme, + theme: themes.default(), language_servers, + syn_loader: config_loader, + theme_loader: themes, registers: Registers::default(), status_msg: None, } @@ -85,6 +78,32 @@ impl Editor { self.status_msg = Some((error, Severity::Error)); } + pub fn set_theme(&mut self, theme: Theme) { + let scopes = theme.scopes(); + for config in self + .syn_loader + .language_configs_iter() + .filter(|cfg| cfg.is_highlight_initialized()) + { + config.highlight_config(scopes); + } + + self.theme = theme; + self._refresh(); + } + + pub fn set_theme_from_name(&mut self, theme: &str) { + let theme = match self.theme_loader.load(theme.as_ref()) { + Ok(theme) => theme, + Err(e) => { + log::warn!("failed setting theme `{}` - {}", theme, e); + return; + } + }; + + self.set_theme(theme); + } + fn _refresh(&mut self) { for (view, _) in self.tree.views_mut() { let doc = &self.documents[view.doc]; @@ -168,7 +187,7 @@ impl Editor { let id = if let Some(id) = id { id } else { - let mut doc = Document::load(path)?; + let mut doc = Document::load(path, Some(&self.theme), Some(&self.syn_loader))?; // try to find a language server based on the language name let language_server = doc @@ -254,6 +273,10 @@ impl Editor { self.documents.iter().map(|(_id, doc)| doc) } + pub fn documents_mut(&mut self) -> impl Iterator<Item = &mut Document> { + self.documents.iter_mut().map(|(_id, doc)| doc) + } + // pub fn current_document(&self) -> Document { // let id = self.view().doc; // let doc = &mut editor.documents[id]; |