diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index fc253f91..7ab810fd 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -251,22 +251,25 @@ 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![], - language_server: None, - indent: Some(IndentationConfiguration { - tab_width: 4, - unit: String::from(" "), - }), - indent_query: OnceCell::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![], + language_server: None, + indent: Some(IndentationConfiguration { + tab_width: 4, + unit: String::from(" "), + }), + indent_query: OnceCell::new(), + }], + }, + Vec::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/syntax.rs b/helix-core/src/syntax.rs index febbf821..ec95708b 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -166,13 +166,15 @@ 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) -> Self { + pub fn new(config: Configuration, scopes: Vec) -> Self { let mut loader = Self { language_configs: Vec::new(), language_config_ids_by_file_type: HashMap::new(), + scopes, }; for config in config.language { @@ -192,6 +194,10 @@ 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. diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index 3f37c295..0b55921a 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -152,18 +152,6 @@ FLAGS: setup_logging(logpath, args.verbosity).context("failed to initialize logging")?; - // 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).context("Could not parse languages.toml")?; - LOADER.get_or_init(|| Loader::new(config)); - // TODO: use the thread local executor to spawn the application task separately from the work pool let mut app = Application::new(args).context("unable to create new appliction")?; app.run().await; diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index cf4a6faa..7a7617c0 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -131,9 +131,8 @@ impl Document { } } - // TODO: passing scopes here is awkward // TODO: async fn? - pub fn load(path: PathBuf, scopes: &[String]) -> Result { + pub fn load(path: PathBuf) -> Result { use std::{env, fs::File, io::BufReader}; let _current_dir = env::current_dir()?; @@ -143,15 +142,8 @@ impl Document { // TODO: create if not found let mut doc = Self::new(doc); - - let language_config = LOADER - .get() - .unwrap() - .language_config_for_file_name(path.as_path()); - doc.set_language(language_config, scopes); - - // canonicalize path to absolute value - doc.path = Some(std::fs::canonicalize(path)?); + // set the path and try detecting the language + doc.set_path(&path)?; Ok(doc) } @@ -218,6 +210,15 @@ 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 set_path(&mut self, path: &Path) -> Result<(), std::io::Error> { // canonicalize path to absolute value let current_dir = std::env::current_dir()?; @@ -229,6 +230,10 @@ impl Document { self.path = Some(path); } } + + // try detecting the language based on filepath + self.detect_language(); + Ok(()) } @@ -251,8 +256,10 @@ impl Document { }; } - pub fn set_language2(&mut self, scope: &str, scopes: &[String]) { - let language_config = LOADER.get().unwrap().language_config_for_scope(scope); + 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(); self.set_language(language_config, scopes); } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index e7b25814..d991f250 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -36,6 +36,18 @@ impl Editor { .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())); + let language_servers = helix_lsp::Registry::new(); // HAXX: offset the render area height by 1 to account for prompt/commandline @@ -135,7 +147,7 @@ impl Editor { let id = if let Some(id) = id { id } else { - let mut doc = Document::load(path, self.theme.scopes())?; + let mut doc = Document::load(path)?; // try to find a language server based on the language name let language_server = doc