Skip to content

Commit

Permalink
Unify config loading
Browse files Browse the repository at this point in the history
* RUNTIME_DIR now behaves similar to the other
  runtime files
* lib.rs cleanup
  * merge_toml_values: Moved function explanation
    comment in a function call to its
    documentation.
* slight appalication.rs cleanup
* Reduce use of relative filepaths with a helix_loader::repo_paths.rs
  • Loading branch information
gibbz00 committed Jan 17, 2023
1 parent 42df636 commit 9798137
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 106 deletions.
4 changes: 2 additions & 2 deletions helix-loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ pub fn user_lang_config_file() -> PathBuf {

/// Default built-in languages.toml.
pub fn default_lang_configs() -> toml::Value {
toml::from_slice(ineclude_bytes!("../..languages.toml")).unwrap())
.expect("Could not parse built-in languages.toml to valid toml")
toml::from_slice(&std::fs::read(repo_paths::default_lang_configs()).unwrap())
.expect("Could not parse built-in languages.toml to valid toml")
}

/// Searces for language.toml in config path (user config) and in 'helix' directories
Expand Down
35 changes: 35 additions & 0 deletions helix-loader/src/repo_paths.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::path::{Path, PathBuf};

pub fn project_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent().unwrap().to_path_buf()
}

pub fn book_gen() -> PathBuf {
project_root().join("book/src/generated/")
}

pub fn ts_queries() -> PathBuf {
project_root().join("runtime/queries")
}

pub fn themes() -> PathBuf {
project_root().join("runtime/themes")
}

pub fn default_config_dir() -> PathBuf {
// TODO: would be nice to move config files away from project root folder
project_root()
}

pub fn default_lang_configs() -> PathBuf {
default_config_dir().join("languages.toml")
}

pub fn default_theme() -> PathBuf {
default_config_dir().join("theme.toml")
}

pub fn default_base16_theme() -> PathBuf {
default_config_dir().join("base16_theme.toml")
}
66 changes: 25 additions & 41 deletions helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub struct Application {
#[allow(dead_code)]
theme_loader: Arc<theme::Loader>,
#[allow(dead_code)]
syn_loader: Arc<syntax::Loader>,
lang_configs_loader: Arc<syntax::Loader>,

signals: Signals,
jobs: Jobs,
Expand Down Expand Up @@ -125,7 +125,7 @@ impl Application {
pub fn new(
args: Args,
config: Config,
syn_loader_conf: syntax::LanguageConfigurations,
langauge_configurations: syntax::LanguageConfigurations,
) -> Result<Self, Error> {
#[cfg(feature = "integration")]
setup_integration_logging();
Expand Down Expand Up @@ -153,7 +153,7 @@ impl Application {
})
.unwrap_or_else(|| theme_loader.default_theme(true_color));

let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
let lang_configs_loader = std::sync::Arc::new(syntax::Loader::new(langauge_configurations));

#[cfg(not(feature = "integration"))]
let backend = CrosstermBackend::new(stdout());
Expand All @@ -168,7 +168,7 @@ impl Application {
let mut editor = Editor::new(
area,
theme_loader.clone(),
syn_loader.clone(),
lang_configs_loader.clone(),
Box::new(Map::new(Arc::clone(&config), |config: &Config| {
&config.editor
})),
Expand Down Expand Up @@ -263,7 +263,7 @@ impl Application {
config,

theme_loader,
syn_loader,
lang_configs_loader,

signals,
jobs: Jobs::new(),
Expand Down Expand Up @@ -396,32 +396,13 @@ impl Application {

/// refresh language config after config change
fn refresh_language_config(&mut self) -> Result<(), Error> {
let syntax_config = LanguageConfigurations::merged()
let language_configs = LanguageConfigurations::merged()
.map_err(|err| anyhow::anyhow!("Failed to load language config: {}", err))?;

self.syn_loader = std::sync::Arc::new(syntax::Loader::new(syntax_config));
self.editor.syn_loader = self.syn_loader.clone();
self.lang_configs_loader = std::sync::Arc::new(syntax::Loader::new(language_configs));
self.editor.lang_configs_loader = self.lang_configs_loader.clone();
for document in self.editor.documents.values_mut() {
document.detect_language(self.syn_loader.clone());
}

Ok(())
}

/// Refresh theme after config change
fn refresh_theme(&mut self, config: &Config) -> Result<(), Error> {
if let Some(theme) = config.theme.clone() {
let true_color = self.true_color();
let theme = self
.theme_loader
.load(&theme)
.map_err(|err| anyhow::anyhow!("Failed to load theme `{}`: {}", theme, err))?;

if true_color || theme.is_16_color() {
self.editor.set_theme(theme);
} else {
anyhow::bail!("theme requires truecolor support, which is not available")
}
document.detect_language(self.lang_configs_loader.clone());
}

Ok(())
Expand All @@ -432,26 +413,29 @@ impl Application {
let merged_user_config = Config::merged()
.map_err(|err| anyhow::anyhow!("Failed to load config: {}", err))?;
self.refresh_language_config()?;
self.refresh_theme(&merged_user_config)?;
// Store new config

if let Some(theme) = &self.config.load().theme {
let true_color = self.config.load().editor.true_color || crate::true_color();
let theme = self.theme_loader.load(theme)
.map_err(|err| anyhow::anyhow!("Failed to load theme `{}`: {}", theme, err))?;

if true_color || theme.is_16_color() {
self.editor.set_theme(theme);
} else {
anyhow::bail!("Theme requires truecolor support, which is not available!")
}
}

self.config.store(Arc::new(merged_user_config));
Ok(())
};

match refresh_config() {
Ok(_) => {
self.editor.set_status("Config refreshed");
}
Err(err) => {
self.editor.set_error(err.to_string());
}
Ok(_) => { self.editor.set_status("Config refreshed"); },
Err(err) => { self.editor.set_error(err.to_string()); }
}
}

fn true_color(&self) -> bool {
self.config.load().editor.true_color || crate::true_color()
}

#[cfg(windows)]
// no signal handling available on windows
pub async fn handle_signals(&mut self, _signal: ()) {}
Expand Down Expand Up @@ -542,7 +526,7 @@ impl Application {
return;
}

let loader = self.editor.syn_loader.clone();
let loader = self.editor.lang_configs_loader.clone();

// borrowing the same doc again to get around the borrow checker
let doc = doc_mut!(self.editor, &doc_save_event.doc_id);
Expand Down
4 changes: 2 additions & 2 deletions helix-term/src/commands/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ pub fn signature_help_impl(cx: &mut Context, invoked: SignatureHelpInvoked) {
let mut contents = SignatureHelp::new(
signature.label.clone(),
language.to_string(),
Arc::clone(&editor.syn_loader),
Arc::clone(&editor.lang_configs_loader),
);

let signature_doc = if config.lsp.display_signature_help_docs {
Expand Down Expand Up @@ -1193,7 +1193,7 @@ pub fn hover(cx: &mut Context) {

// skip if contents empty

let contents = ui::Markdown::new(contents, editor.syn_loader.clone());
let contents = ui::Markdown::new(contents, editor.lang_configs_loader.clone());
let popup = Popup::new("hover", contents).auto_close(true);
compositor.replace_or_push("hover", popup);
}
Expand Down
8 changes: 4 additions & 4 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ fn tree_sitter_scopes(
let callback = async move {
let call: job::Callback = Callback::EditorCompositor(Box::new(
move |editor: &mut Editor, compositor: &mut Compositor| {
let contents = ui::Markdown::new(contents, editor.syn_loader.clone());
let contents = ui::Markdown::new(contents, editor.lang_configs_loader.clone());
let popup = Popup::new("hover", contents).auto_close(true);
compositor.replace_or_push("hover", popup);
},
Expand Down Expand Up @@ -1539,7 +1539,7 @@ fn language(
if args[0] == "text" {
doc.set_language(None, None)
} else {
doc.set_language_by_language_id(&args[0], cx.editor.syn_loader.clone())?;
doc.set_language_by_language_id(&args[0], cx.editor.lang_configs_loader.clone())?;
}
doc.detect_indent_and_line_ending();

Expand Down Expand Up @@ -1675,7 +1675,7 @@ fn tree_sitter_subtree(
let callback = async move {
let call: job::Callback = Callback::EditorCompositor(Box::new(
move |editor: &mut Editor, compositor: &mut Compositor| {
let contents = ui::Markdown::new(contents, editor.syn_loader.clone());
let contents = ui::Markdown::new(contents, editor.lang_configs_loader.clone());
let popup = Popup::new("hover", contents).auto_close(true);
compositor.replace_or_push("hover", popup);
},
Expand Down Expand Up @@ -1808,7 +1808,7 @@ fn run_shell_command(
move |editor: &mut Editor, compositor: &mut Compositor| {
let contents = ui::Markdown::new(
format!("```sh\n{}\n```", output),
editor.syn_loader.clone(),
editor.lang_configs_loader.clone(),
);
let popup = Popup::new("shell", contents).position(Some(
helix_core::Position::new(editor.cursor().0.unwrap_or_default().row, 2),
Expand Down
8 changes: 4 additions & 4 deletions helix-term/src/ui/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ impl Component for Completion {
option.detail.as_deref().unwrap_or_default(),
contents
),
cx.editor.syn_loader.clone(),
cx.editor.lang_configs_loader.clone(),
)
}
Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
Expand All @@ -419,10 +419,10 @@ impl Component for Completion {
if let Some(detail) = &option.detail.as_deref() {
Markdown::new(
format!("```{}\n{}\n```\n{}", language, detail, contents),
cx.editor.syn_loader.clone(),
cx.editor.lang_configs_loader.clone(),
)
} else {
Markdown::new(contents.to_string(), cx.editor.syn_loader.clone())
Markdown::new(contents.to_string(), cx.editor.lang_configs_loader.clone())
}
}
None if option.detail.is_some() => {
Expand All @@ -435,7 +435,7 @@ impl Component for Completion {
language,
option.detail.as_deref().unwrap_or_default(),
),
cx.editor.syn_loader.clone(),
cx.editor.lang_configs_loader.clone(),
)
}
None => return,
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ pub mod completers {
let text: String = "text".into();

let language_ids = editor
.syn_loader
.lang_configs_loader
.language_configs()
.map(|config| &config.language_id)
.chain(std::iter::once(&text));
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ impl<T: Item> FilePicker<T> {
// Then attempt to highlight it if it has no language set
if let Some(doc) = doc {
if doc.language_config().is_none() {
let loader = cx.editor.syn_loader.clone();
let loader = cx.editor.lang_configs_loader.clone();
doc.detect_language(loader);
}
}
Expand Down
8 changes: 4 additions & 4 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ pub struct Editor {

pub clipboard_provider: Box<dyn ClipboardProvider>,

pub syn_loader: Arc<syntax::Loader>,
pub lang_configs_loader: Arc<syntax::Loader>,
pub theme_loader: Arc<theme::Loader>,
/// last_theme is used for theme previews. We store the current theme here,
/// and if previewing is cancelled, we can return to it.
Expand Down Expand Up @@ -809,7 +809,7 @@ impl Editor {
debugger: None,
debugger_events: SelectAll::new(),
breakpoints: HashMap::new(),
syn_loader,
lang_configs_loader: syn_loader,
theme_loader,
last_theme: None,
last_line_number: None,
Expand Down Expand Up @@ -915,7 +915,7 @@ impl Editor {
}

let scopes = theme.scopes();
self.syn_loader.set_scopes(scopes.to_vec());
self.lang_configs_loader.set_scopes(scopes.to_vec());

match preview {
ThemeAction::Preview => {
Expand Down Expand Up @@ -1134,7 +1134,7 @@ impl Editor {
let id = if let Some(id) = id {
id
} else {
let mut doc = Document::open(&path, None, Some(self.syn_loader.clone()))?;
let mut doc = Document::open(&path, None, Some(self.lang_configs_loader.clone()))?;

let _ = Self::launch_language_server(&mut self.language_servers, &mut doc);
if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {
Expand Down
7 changes: 4 additions & 3 deletions helix-view/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{

use anyhow::{anyhow, Context, Result};
use helix_core::hashmap;
use helix_loader::merge_toml_values;
use helix_loader::{merge_toml_values, repo_paths};
use log::warn;
use once_cell::sync::Lazy;
use serde::{Deserialize, Deserializer};
Expand All @@ -15,11 +15,12 @@ use crate::graphics::UnderlineStyle;
pub use crate::graphics::{Color, Modifier, Style};

pub static DEFAULT_THEME_DATA: Lazy<Value> = Lazy::new(|| {
toml::from_slice(include_bytes!("../../theme.toml")).expect("Failed to parse default theme")
toml::from_slice(&std::fs::read(repo_paths::default_theme()).unwrap())
.expect("Failed to parse default theme")
});

pub static BASE16_DEFAULT_THEME_DATA: Lazy<Value> = Lazy::new(|| {
toml::from_slice(include_bytes!("../../base16_theme.toml"))
toml::from_slice(&std::fs::read(repo_paths::default_base16_theme()).unwrap())
.expect("Failed to parse base 16 default theme")
});

Expand Down
11 changes: 6 additions & 5 deletions xtask/src/docgen.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::helpers;
use crate::path;
use crate::DynError;

use helix_core::syntax::LanguageConfigurations;
use helix_loader::repo_paths;
use helix_term::commands::TYPABLE_COMMAND_LIST;
use helix_term::health::TsFeature;
use std::fs;
Expand Down Expand Up @@ -62,9 +63,9 @@ pub fn lang_features() -> Result<String, DynError> {
cols.push("Default LSP".to_owned());

md.push_str(&md_table_heading(&cols));
let config = helpers::lang_config();
let lang_configs = LanguageConfigurations::default();

let mut langs = config
let mut langs = lang_configs
.language
.iter()
.map(|l| l.language_id.clone())
Expand All @@ -78,7 +79,7 @@ pub fn lang_features() -> Result<String, DynError> {

let mut row = Vec::new();
for lang in langs {
let lc = config
let lc = lang_configs
.language
.iter()
.find(|l| l.language_id == lang)
Expand Down Expand Up @@ -112,6 +113,6 @@ pub fn lang_features() -> Result<String, DynError> {

pub fn write(filename: &str, data: &str) {
let error = format!("Could not write to {}", filename);
let path = path::book_gen().join(filename);
let path = repo_paths::book_gen().join(filename);
fs::write(path, data).expect(&error);
}
Loading

0 comments on commit 9798137

Please sign in to comment.