Try to detect language when document file path is set

Fixes #91
This commit is contained in:
Blaž Hrastnik 2021-06-04 10:50:03 +09:00
parent 8afd4e1bc2
commit 06d8d3f55f
5 changed files with 59 additions and 43 deletions

View file

@ -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"));

View file

@ -166,13 +166,15 @@ pub struct Loader {
// highlight_names ?
language_configs: Vec<Arc<LanguageConfiguration>>,
language_config_ids_by_file_type: HashMap<String, usize>, // Vec<usize>
scopes: Vec<String>,
}
impl Loader {
pub fn new(config: Configuration) -> Self {
pub fn new(config: Configuration, scopes: Vec<String>) -> 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<Arc<LanguageConfiguration>> {
// Find all the language configurations that match this file name
// or a suffix of the file name.

View file

@ -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;

View file

@ -131,9 +131,8 @@ impl Document {
}
}
// TODO: passing scopes here is awkward
// TODO: async fn?
pub fn load(path: PathBuf, scopes: &[String]) -> Result<Self, Error> {
pub fn load(path: PathBuf) -> Result<Self, Error> {
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);
}

View file

@ -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