on master help sign in
Try to detect language when document file path is set

Fixes #91

commit06d8d3f55fbf02bb4d938ecbc479cd60309a0a5d authorBlaž Hrastnik <blaz@mxxn.io> dateFri 4 Jun 2021, 10:50 (5 years ago) parent8afd4e1
5 files changed+59−43
helix-core/src/indent.rs+19−16 helix-core/src/syntax.rs+7−1 helix-term/src/main.rs−12 helix-view/src/document.rs+20−13 helix-view/src/editor.rs+13−1
helix-core/src/indent.rs+19−16
@@ -251,22 +251,25 @@ where
251251 Configuration, IndentationConfiguration, Lang, LanguageConfiguration, Loader,
252252 };
253253 use once_cell::sync::OnceCell;
254− let loader = Loader::new(Configuration {
255− language: vec![LanguageConfiguration {
256− scope: "source.rust".to_string(),
257− file_types: vec!["rs".to_string()],
258− language_id: Lang::Rust,
259− highlight_config: OnceCell::new(),
260− //
261− roots: vec![],
262− language_server: None,
263− indent: Some(IndentationConfiguration {
264− tab_width: 4,
265− unit: String::from(" "),
266− }),
267− indent_query: OnceCell::new(),
268− }],
269− });
254+ let loader = Loader::new(
255+ Configuration {
256+ language: vec![LanguageConfiguration {
257+ scope: "source.rust".to_string(),
258+ file_types: vec!["rs".to_string()],
259+ language_id: Lang::Rust,
260+ highlight_config: OnceCell::new(),
261+ //
262+ roots: vec![],
263+ language_server: None,
264+ indent: Some(IndentationConfiguration {
265+ tab_width: 4,
266+ unit: String::from(" "),
267+ }),
268+ indent_query: OnceCell::new(),
269+ }],
270+ },
271+ Vec::new(),
272+ );
270273
271274 // set runtime path so we can find the queries
272275 let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
helix-core/src/syntax.rs+7−1
@@ -166,13 +166,15 @@ pub struct Loader {
166166 // highlight_names ?
167167 language_configs: Vec<Arc<LanguageConfiguration>>,
168168 language_config_ids_by_file_type: HashMap<String, usize>, // Vec<usize>
169+ scopes: Vec<String>,
169170}
170171
171172impl Loader {
172− pub fn new(config: Configuration) -> Self {
173+ pub fn new(config: Configuration, scopes: Vec<String>) -> Self {
173174 let mut loader = Self {
174175 language_configs: Vec::new(),
175176 language_config_ids_by_file_type: HashMap::new(),
177+ scopes,
176178 };
177179
178180 for config in config.language {
@@ -192,6 +194,10 @@ impl Loader {
192194 loader
193195 }
194196
197+ pub fn scopes(&self) -> &[String] {
198+ &self.scopes
199+ }
200+
195201 pub fn language_config_for_file_name(&self, path: &Path) -> Option<Arc<LanguageConfiguration>> {
196202 // Find all the language configurations that match this file name
197203 // or a suffix of the file name.
helix-term/src/main.rs−12
@@ -152,18 +152,6 @@ FLAGS:
152152
153153 setup_logging(logpath, args.verbosity).context("failed to initialize logging")?;
154154
155− // initialize language registry
156− use helix_core::syntax::{Loader, LOADER};
157−
158− // load $HOME/.config/helix/languages.toml, fallback to default config
159− let config = std::fs::read(helix_core::config_dir().join("languages.toml"));
160− let toml = config
161− .as_deref()
162− .unwrap_or(include_bytes!("../../languages.toml"));
163−
164− let config = toml::from_slice(toml).context("Could not parse languages.toml")?;
165− LOADER.get_or_init(|| Loader::new(config));
166−
167155 // TODO: use the thread local executor to spawn the application task separately from the work pool
168156 let mut app = Application::new(args).context("unable to create new appliction")?;
169157 app.run().await;
helix-view/src/document.rs+20−13
@@ -131,9 +131,8 @@ impl Document {
131131 }
132132 }
133133
134− // TODO: passing scopes here is awkward
135134 // TODO: async fn?
136− pub fn load(path: PathBuf, scopes: &[String]) -> Result<Self, Error> {
135+ pub fn load(path: PathBuf) -> Result<Self, Error> {
137136 use std::{env, fs::File, io::BufReader};
138137 let _current_dir = env::current_dir()?;
139138
@@ -143,15 +142,8 @@ impl Document {
143142 // TODO: create if not found
144143
145144 let mut doc = Self::new(doc);
146−
147− let language_config = LOADER
148− .get()
149− .unwrap()
150− .language_config_for_file_name(path.as_path());
151− doc.set_language(language_config, scopes);
152−
153− // canonicalize path to absolute value
154− doc.path = Some(std::fs::canonicalize(path)?);
145+ // set the path and try detecting the language
146+ doc.set_path(&path)?;
155147
156148 Ok(doc)
157149 }
@@ -218,6 +210,15 @@ impl Document {
218210 }
219211 }
220212
213+ fn detect_language(&mut self) {
214+ if let Some(path) = self.path() {
215+ let loader = LOADER.get().unwrap();
216+ let language_config = loader.language_config_for_file_name(path);
217+ let scopes = loader.scopes();
218+ self.set_language(language_config, scopes);
219+ }
220+ }
221+
221222 pub fn set_path(&mut self, path: &Path) -> Result<(), std::io::Error> {
222223 // canonicalize path to absolute value
223224 let current_dir = std::env::current_dir()?;
@@ -229,6 +230,10 @@ impl Document {
229230 self.path = Some(path);
230231 }
231232 }
233+
234+ // try detecting the language based on filepath
235+ self.detect_language();
236+
232237 Ok(())
233238 }
234239
@@ -251,8 +256,10 @@ impl Document {
251256 };
252257 }
253258
254− pub fn set_language2(&mut self, scope: &str, scopes: &[String]) {
255− let language_config = LOADER.get().unwrap().language_config_for_scope(scope);
259+ pub fn set_language2(&mut self, scope: &str) {
260+ let loader = LOADER.get().unwrap();
261+ let language_config = loader.language_config_for_scope(scope);
262+ let scopes = loader.scopes();
256263
257264 self.set_language(language_config, scopes);
258265 }
helix-view/src/editor.rs+13−1
@@ -36,6 +36,18 @@ impl Editor {
3636 .unwrap_or(include_bytes!("../../theme.toml"));
3737 let theme: Theme = toml::from_slice(toml).expect("failed to parse theme.toml");
3838
39+ // initialize language registry
40+ use helix_core::syntax::{Loader, LOADER};
41+
42+ // load $HOME/.config/helix/languages.toml, fallback to default config
43+ let config = std::fs::read(helix_core::config_dir().join("languages.toml"));
44+ let toml = config
45+ .as_deref()
46+ .unwrap_or(include_bytes!("../../languages.toml"));
47+
48+ let config = toml::from_slice(toml).expect("Could not parse languages.toml");
49+ LOADER.get_or_init(|| Loader::new(config, theme.scopes().to_vec()));
50+
3951 let language_servers = helix_lsp::Registry::new();
4052
4153 // HAXX: offset the render area height by 1 to account for prompt/commandline
@@ -135,7 +147,7 @@ impl Editor {
135147 let id = if let Some(id) = id {
136148 id
137149 } else {
138− let mut doc = Document::load(path, self.theme.scopes())?;
150+ let mut doc = Document::load(path)?;
139151
140152 // try to find a language server based on the language name
141153 let language_server = doc