diff --git a/CHANGELOG.md b/CHANGELOG.md index 50343541c6..0153a8f735 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased ### Added +* Select syntax highlighting theme out of the defaults from syntect [[@vasilismanol](https://github.com/vasilismanol)] ([#1931](https://github.com/extrawurst/gitui/issues/1931)) * new command-line option to override the default log file path (`--logfile`) [[@acuteenvy](https://github.com/acuteenvy)] ([#2539](https://github.com/gitui-org/gitui/pull/2539)) ### Changed diff --git a/src/components/syntax_text.rs b/src/components/syntax_text.rs index aaf348ddaf..7a82aca273 100644 --- a/src/components/syntax_text.rs +++ b/src/components/syntax_text.rs @@ -117,6 +117,7 @@ impl SyntaxTextComponent { AsyncSyntaxJob::new( content.clone(), path.clone(), + self.theme.get_syntax(), ), ); diff --git a/src/popups/blame_file.rs b/src/popups/blame_file.rs index 80369b0470..273ca5ace3 100644 --- a/src/popups/blame_file.rs +++ b/src/popups/blame_file.rs @@ -576,6 +576,7 @@ impl BlameFilePopup { job.spawn(AsyncSyntaxJob::new( text, params.file_path.clone(), + self.theme.get_syntax(), )); } diff --git a/src/ui/style.rs b/src/ui/style.rs index 839ec380fb..7913835766 100644 --- a/src/ui/style.rs +++ b/src/ui/style.rs @@ -1,3 +1,4 @@ +use crate::ui::syntax_text::DEFAULT_SYNTAX_THEME; use anyhow::Result; use asyncgit::{DiffLineType, StatusItemType}; use ratatui::style::{Color, Modifier, Style}; @@ -34,6 +35,7 @@ pub struct Theme { branch_fg: Color, line_break: String, block_title_focused: Color, + syntax: String, } impl Theme { @@ -298,6 +300,10 @@ impl Theme { Ok(()) } + pub fn get_syntax(&self) -> String { + self.syntax.clone() + } + pub fn init(theme_path: &PathBuf) -> Self { let mut theme = Self::default(); @@ -353,6 +359,9 @@ impl Default for Theme { branch_fg: Color::LightYellow, line_break: "ΒΆ".to_string(), block_title_focused: Color::Reset, + // Available themes can be found in: + // [ThemeSet::load_defaults function](https://github.com/trishume/syntect/blob/7fe13c0fd53cdfa0f9fea1aa14c5ba37f81d8b71/src/dumps.rs#L215). + syntax: DEFAULT_SYNTAX_THEME.to_string(), } } } @@ -378,6 +387,7 @@ mod tests { ( selection_bg: Some("Black"), selection_fg: Some("#ffffff"), + syntax: Some("InspiredGitHub") ) "## ) @@ -388,7 +398,9 @@ mod tests { assert_eq!(theme.selected_tab, Theme::default().selected_tab); assert_ne!(theme.selection_bg, Theme::default().selection_bg); + assert_ne!(theme.syntax, Theme::default().syntax); assert_eq!(theme.selection_bg, Color::Black); assert_eq!(theme.selection_fg, Color::Rgb(255, 255, 255)); + assert_eq!(theme.syntax, "InspiredGitHub"); } } diff --git a/src/ui/syntax_text.rs b/src/ui/syntax_text.rs index 20820df915..e0cd5bf6c5 100644 --- a/src/ui/syntax_text.rs +++ b/src/ui/syntax_text.rs @@ -21,6 +21,8 @@ use syntect::{ use crate::{AsyncAppNotification, SyntaxHighlightProgress}; +pub const DEFAULT_SYNTAX_THEME: &str = "base16-eighties.dark"; + struct SyntaxLine { items: Vec<(Style, usize, Range)>, } @@ -70,6 +72,7 @@ impl SyntaxText { text: String, file_path: &Path, params: &RunParams, + syntax: &str, ) -> asyncgit::Result { scope_time!("syntax_highlighting"); let mut state = { @@ -86,9 +89,12 @@ impl SyntaxText { ParseState::new(syntax) }; - let highlighter = Highlighter::new( - &THEME_SET.themes["base16-eighties.dark"], - ); + let theme = + THEME_SET.themes.get(syntax).unwrap_or_else(|| { + log::error!("The syntax theme:\"{}\" cannot be found. Using default theme:\"{}\" instead.", syntax, DEFAULT_SYNTAX_THEME); + &THEME_SET.themes[DEFAULT_SYNTAX_THEME] + }); + let highlighter = Highlighter::new(theme); let mut syntax_lines: Vec = Vec::new(); @@ -212,14 +218,20 @@ enum JobState { #[derive(Clone, Default)] pub struct AsyncSyntaxJob { state: Arc>>, + syntax: String, } impl AsyncSyntaxJob { - pub fn new(content: String, path: String) -> Self { + pub fn new( + content: String, + path: String, + syntax: String, + ) -> Self { Self { state: Arc::new(Mutex::new(Some(JobState::Request(( content, path, ))))), + syntax, } } @@ -255,6 +267,7 @@ impl AsyncJob for AsyncSyntaxJob { content, Path::new(&path), ¶ms, + &self.syntax, )?; JobState::Response(syntax) }