aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
authorwojciechkepka2021-06-19 11:26:52 +0000
committerBlaž Hrastnik2021-06-19 15:07:13 +0000
commitce97a2f05fcddf81d8210ec6b25411f8fd7d867a (patch)
tree577068168aa16545f85aac310c2a10ae2c078842 /helix-term/src
parentf424a61054a0495336862ff8d90627fb6f5ce572 (diff)
Add ability to change theme on editor
Diffstat (limited to 'helix-term/src')
-rw-r--r--helix-term/src/application.rs40
-rw-r--r--helix-term/src/ui/completion.rs43
-rw-r--r--helix-term/src/ui/markdown.rs31
3 files changed, 81 insertions, 33 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 2fae467f..08853ed0 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -1,5 +1,6 @@
+use helix_core::syntax;
use helix_lsp::{lsp, LspProgressMap};
-use helix_view::{document::Mode, Document, Editor, Theme, View};
+use helix_view::{document::Mode, theme, Document, Editor, Theme, View};
use crate::{args::Args, compositor::Compositor, config::Config, keymap::Keymaps, ui};
@@ -14,7 +15,7 @@ use std::{
time::Duration,
};
-use anyhow::Error;
+use anyhow::{Context, Error};
use crossterm::{
event::{Event, EventStream},
@@ -36,6 +37,8 @@ pub struct Application {
compositor: Compositor,
editor: Editor,
+ theme_loader: Arc<theme::Loader>,
+ syn_loader: Arc<syntax::Loader>,
callbacks: LspCallbacks,
lsp_progress: LspProgressMap,
@@ -47,7 +50,34 @@ impl Application {
use helix_view::editor::Action;
let mut compositor = Compositor::new()?;
let size = compositor.size();
- let mut editor = Editor::new(size);
+
+ let conf_dir = helix_core::config_dir();
+
+ let theme_loader =
+ std::sync::Arc::new(theme::Loader::new(&conf_dir, &helix_core::runtime_dir()));
+
+ // load $HOME/.config/helix/languages.toml, fallback to default config
+ let lang_conf = std::fs::read(conf_dir.join("languages.toml"));
+ let lang_conf = lang_conf
+ .as_deref()
+ .unwrap_or(include_bytes!("../../languages.toml"));
+
+ let theme = if let Some(theme) = &config.global.theme {
+ match theme_loader.load(theme) {
+ Ok(theme) => theme,
+ Err(e) => {
+ log::warn!("failed to load theme `{}` - {}", theme, e);
+ theme_loader.default()
+ }
+ }
+ } else {
+ theme_loader.default()
+ };
+
+ let syn_loader_conf = toml::from_slice(lang_conf).expect("Could not parse languages.toml");
+ let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
+
+ let mut editor = Editor::new(size, theme_loader.clone(), syn_loader.clone());
let mut editor_view = Box::new(ui::EditorView::new(config.keymaps));
compositor.push(editor_view);
@@ -72,10 +102,14 @@ impl Application {
editor.new_file(Action::VerticalSplit);
}
+ editor.set_theme(theme);
+
let mut app = Self {
compositor,
editor,
+ theme_loader,
+ syn_loader,
callbacks: FuturesUnordered::new(),
lsp_progress: LspProgressMap::new(),
lsp_progress_enabled: config.global.lsp_progress,
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index 06ed966d..88a71534 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -246,34 +246,43 @@ impl Component for Completion {
value: contents,
})) => {
// TODO: convert to wrapped text
- Markdown::new(format!(
- "```{}\n{}\n```\n{}",
- language,
- option.detail.as_deref().unwrap_or_default(),
- contents.clone()
- ))
+ Markdown::new(
+ format!(
+ "```{}\n{}\n```\n{}",
+ language,
+ option.detail.as_deref().unwrap_or_default(),
+ contents.clone()
+ ),
+ cx.editor.syn_loader.clone(),
+ )
}
Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
kind: lsp::MarkupKind::Markdown,
value: contents,
})) => {
// TODO: set language based on doc scope
- Markdown::new(format!(
- "```{}\n{}\n```\n{}",
- language,
- option.detail.as_deref().unwrap_or_default(),
- contents.clone()
- ))
+ Markdown::new(
+ format!(
+ "```{}\n{}\n```\n{}",
+ language,
+ option.detail.as_deref().unwrap_or_default(),
+ contents.clone()
+ ),
+ cx.editor.syn_loader.clone(),
+ )
}
None if option.detail.is_some() => {
// TODO: copied from above
// TODO: set language based on doc scope
- Markdown::new(format!(
- "```{}\n{}\n```",
- language,
- option.detail.as_deref().unwrap_or_default(),
- ))
+ Markdown::new(
+ format!(
+ "```{}\n{}\n```",
+ language,
+ option.detail.as_deref().unwrap_or_default(),
+ ),
+ cx.editor.syn_loader.clone(),
+ )
}
None => return,
};
diff --git a/helix-term/src/ui/markdown.rs b/helix-term/src/ui/markdown.rs
index be113747..91086f7b 100644
--- a/helix-term/src/ui/markdown.rs
+++ b/helix-term/src/ui/markdown.rs
@@ -7,25 +7,34 @@ use tui::{
text::Text,
};
-use std::borrow::Cow;
+use std::{borrow::Cow, sync::Arc};
-use helix_core::Position;
+use helix_core::{syntax, Position};
use helix_view::{Editor, Theme};
pub struct Markdown {
contents: String,
+
+ config_loader: Arc<syntax::Loader>,
}
// TODO: pre-render and self reference via Pin
// better yet, just use Tendril + subtendril for references
impl Markdown {
- pub fn new(contents: String) -> Self {
- Self { contents }
+ pub fn new(contents: String, config_loader: Arc<syntax::Loader>) -> Self {
+ Self {
+ contents,
+ config_loader,
+ }
}
}
-fn parse<'a>(contents: &'a str, theme: Option<&Theme>) -> tui::text::Text<'a> {
+fn parse<'a>(
+ contents: &'a str,
+ theme: Option<&Theme>,
+ loader: &syntax::Loader,
+) -> tui::text::Text<'a> {
use pulldown_cmark::{CodeBlockKind, CowStr, Event, Options, Parser, Tag};
use tui::text::{Span, Spans, Text};
@@ -79,9 +88,7 @@ fn parse<'a>(contents: &'a str, theme: Option<&Theme>) -> tui::text::Text<'a> {
use helix_core::Rope;
let rope = Rope::from(text.as_ref());
- let syntax = syntax::LOADER
- .get()
- .unwrap()
+ let syntax = loader
.language_config_for_scope(&format!("source.{}", language))
.and_then(|config| config.highlight_config(theme.scopes()))
.map(|config| Syntax::new(&rope, config));
@@ -101,9 +108,7 @@ fn parse<'a>(contents: &'a str, theme: Option<&Theme>) -> tui::text::Text<'a> {
}
HighlightEvent::Source { start, end } => {
let style = match highlights.first() {
- Some(span) => {
- theme.get(theme.scopes()[span.0].as_str())
- }
+ Some(span) => theme.get(&theme.scopes()[span.0]),
None => text_style,
};
@@ -196,7 +201,7 @@ impl Component for Markdown {
fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
use tui::widgets::{Paragraph, Widget, Wrap};
- let text = parse(&self.contents, Some(&cx.editor.theme));
+ let text = parse(&self.contents, Some(&cx.editor.theme), &self.config_loader);
let par = Paragraph::new(text)
.wrap(Wrap { trim: false })
@@ -207,7 +212,7 @@ impl Component for Markdown {
}
fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {
- let contents = parse(&self.contents, None);
+ let contents = parse(&self.contents, None, &self.config_loader);
let padding = 2;
let width = std::cmp::min(contents.width() as u16 + padding, viewport.0);
let height = std::cmp::min(contents.height() as u16 + padding, viewport.1);