diff --git a/Cargo.lock b/Cargo.lock index cf17f056b..8863337ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,6 +496,7 @@ dependencies = [ "tree-sitter", "unicode-segmentation", "unicode-width", + "xdg", ] [[package]] @@ -1390,3 +1391,9 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index d95c0f476..4b1566d71 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -21,3 +21,5 @@ once_cell = "1.4" regex = "1" serde = { version = "1.0", features = ["derive"] } + +xdg = "2.0" diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index b3ce3c47b..dda9863b5 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -44,6 +44,13 @@ pub(crate) fn find_first_non_whitespace_char(text: RopeSlice, line_num: usize) - None } +pub fn config_dir() -> std::path::PathBuf { + // TODO: allow env var override + let xdg_dirs = + xdg::BaseDirectories::with_prefix("helix").expect("Unable to find XDG directories!"); + xdg_dirs.get_config_home() +} + pub use ropey::{Rope, RopeSlice}; pub use tendril::StrTendril as Tendril; diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index a2ea59933..612f8cf08 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -74,10 +74,17 @@ fn main() { setup_logging(verbosity).expect("failed to initialize logging."); // initialize language registry + use helix_core::config_dir; use helix_core::syntax::{Loader, LOADER}; - let toml = include_str!("../../languages.toml"); + + // load $HOME/.config/helix/languages.toml, fallback to default config + let config = std::fs::read(config_dir().join("languages.toml")); + let toml = config + .as_deref() + .unwrap_or(include_bytes!("../../languages.toml")); + LOADER.get_or_init(|| { - let config = toml::from_str(toml).expect("Could not parse languages.toml"); + let config = toml::from_slice(toml).expect("Could not parse languages.toml"); Loader::new(config) }); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 531571f7c..0eab4fe70 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -25,9 +25,13 @@ pub enum Action { impl Editor { pub fn new(executor: &'static smol::Executor<'static>, mut area: tui::layout::Rect) -> Self { - // TODO: load from config dir - let toml = include_str!("../../theme.toml"); - let theme: Theme = toml::from_str(&toml).expect("failed to parse theme.toml"); + 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"); let language_servers = helix_lsp::Registry::new();