diff --git a/CHANGELOG.md b/CHANGELOG.md index 13befd08f3..86dbdfe0ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added +* `theme.ron` now supports customizing line break symbol ([#1894](https://github.com/extrawurst/gitui/issues/1894)) + ## [0.24.3] - 2023-09-09 ### Fixes diff --git a/THEMES.md b/THEMES.md index b1d36f90f2..ff3be94a59 100644 --- a/THEMES.md +++ b/THEMES.md @@ -31,3 +31,21 @@ Notes: * using a color like `yellow` might appear in whatever your terminal/theme defines for `yellow` * valid colors can be found in tui-rs' [Color](https://docs.rs/tui/0.12.0/tui/style/enum.Color.html) struct. * all customizable theme elements can be found in [`style.rs` in the `impl Default for Theme` block](https://github.com/extrawurst/gitui/blob/master/src/ui/style.rs#L305) + +## Customizing line breaks + +If you want to change how the line break is displayed in the diff, you can also specify `line_break` in your `theme.ron`: + +``` +( + line_break: Some("¶"), +) +``` + +Note that if you want to turn it off, you should use a blank string: + +``` +( + line_break: Some(""), +) +``` diff --git a/src/components/diff.rs b/src/components/diff.rs index ad7fb73e94..6a2d433af1 100644 --- a/src/components/diff.rs +++ b/src/components/diff.rs @@ -462,7 +462,7 @@ impl DiffComponent { let content = if !is_content_line && line.content.as_ref().is_empty() { - String::from(strings::symbol::LINE_BREAK) + theme.line_break() } else { tabs_to_spaces(line.content.as_ref().to_string()) }; @@ -958,3 +958,75 @@ impl Component for DiffComponent { self.focused = focus; } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::ui::style::Theme; + use std::io::Write; + use std::rc::Rc; + use tempfile::NamedTempFile; + + #[test] + fn test_line_break() { + let diff_line = DiffLine { + content: "".into(), + line_type: DiffLineType::Add, + position: Default::default(), + }; + + { + let default_theme = Rc::new(Theme::default()); + + assert_eq!( + DiffComponent::get_line_to_add( + 4, + &diff_line, + false, + false, + false, + &default_theme, + 0 + ) + .spans + .last() + .unwrap(), + &Span::styled( + Cow::from("¶\n"), + default_theme + .diff_line(diff_line.line_type, false) + ) + ); + } + + { + let mut file = NamedTempFile::new().unwrap(); + + writeln!( + file, + r#" +( + line_break: Some("+") +) +"# + ) + .unwrap(); + + let theme = + Rc::new(Theme::init(&file.path().to_path_buf())); + + assert_eq!( + DiffComponent::get_line_to_add( + 4, &diff_line, false, false, false, &theme, 0 + ) + .spans + .last() + .unwrap(), + &Span::styled( + Cow::from("+\n"), + theme.diff_line(diff_line.line_type, false) + ) + ); + } + } +} diff --git a/src/main.rs b/src/main.rs index 6321fff581..c0f41a2770 100644 --- a/src/main.rs +++ b/src/main.rs @@ -157,7 +157,7 @@ fn main() -> Result<()> { let quit_state = run_app( app_start, repo_path.clone(), - theme, + theme.clone(), key_config.clone(), &input, updater, diff --git a/src/strings.rs b/src/strings.rs index 31ca11381c..8134b5b6f6 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -42,7 +42,6 @@ pub mod symbol { pub const CHECKMARK: &str = "\u{2713}"; //✓ pub const SPACE: &str = "\u{02FD}"; //˽ pub const EMPTY_SPACE: &str = " "; - pub const LINE_BREAK: &str = "¶"; pub const FOLDER_ICON_COLLAPSED: &str = "\u{25b8}"; //▸ pub const FOLDER_ICON_EXPANDED: &str = "\u{25be}"; //▾ pub const EMPTY_STR: &str = ""; diff --git a/src/ui/style.rs b/src/ui/style.rs index fa570e3325..c54350d745 100644 --- a/src/ui/style.rs +++ b/src/ui/style.rs @@ -8,7 +8,7 @@ use struct_patch::Patch; pub type SharedTheme = Rc; -#[derive(Serialize, Deserialize, Debug, Copy, Clone, Patch)] +#[derive(Serialize, Deserialize, Debug, Clone, Patch)] #[patch_derive(Serialize, Deserialize)] pub struct Theme { selected_tab: Color, @@ -32,6 +32,7 @@ pub struct Theme { push_gauge_fg: Color, tag_fg: Color, branch_fg: Color, + line_break: String, } impl Theme { @@ -192,6 +193,10 @@ impl Theme { Style::default().fg(self.danger_fg) } + pub fn line_break(&self) -> String { + self.line_break.clone() + } + pub fn commandbar(&self, enabled: bool, line: usize) -> Style { if enabled { Style::default().fg(self.command_fg) @@ -278,7 +283,7 @@ impl Theme { // This is supposed to be called when theme.ron doesn't already exists. fn save_patch(&self, theme_path: &PathBuf) -> Result<()> { let mut file = File::create(theme_path)?; - let patch = self.into_patch_by_diff(Self::default()); + let patch = self.clone().into_patch_by_diff(Self::default()); let data = to_string_pretty(&patch, PrettyConfig::default())?; file.write_all(data.as_bytes())?; @@ -336,6 +341,7 @@ impl Default for Theme { push_gauge_fg: Color::Reset, tag_fg: Color::LightMagenta, branch_fg: Color::LightYellow, + line_break: "¶".to_string(), } } }