mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 09:28:21 +00:00
Allow customizing line break visualization (#1904)
This commit is contained in:
parent
09907f3873
commit
2fd957e2c8
6 changed files with 103 additions and 5 deletions
|
|
@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
* `theme.ron` now supports customizing line break symbol ([#1894](https://github.com/extrawurst/gitui/issues/1894))
|
||||||
|
|
||||||
## [0.24.3] - 2023-09-09
|
## [0.24.3] - 2023-09-09
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
|
||||||
18
THEMES.md
18
THEMES.md
|
|
@ -31,3 +31,21 @@ Notes:
|
||||||
* using a color like `yellow` might appear in whatever your terminal/theme defines for `yellow`
|
* 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.
|
* 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)
|
* 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(""),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -462,7 +462,7 @@ impl DiffComponent {
|
||||||
|
|
||||||
let content =
|
let content =
|
||||||
if !is_content_line && line.content.as_ref().is_empty() {
|
if !is_content_line && line.content.as_ref().is_empty() {
|
||||||
String::from(strings::symbol::LINE_BREAK)
|
theme.line_break()
|
||||||
} else {
|
} else {
|
||||||
tabs_to_spaces(line.content.as_ref().to_string())
|
tabs_to_spaces(line.content.as_ref().to_string())
|
||||||
};
|
};
|
||||||
|
|
@ -958,3 +958,75 @@ impl Component for DiffComponent {
|
||||||
self.focused = focus;
|
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)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ fn main() -> Result<()> {
|
||||||
let quit_state = run_app(
|
let quit_state = run_app(
|
||||||
app_start,
|
app_start,
|
||||||
repo_path.clone(),
|
repo_path.clone(),
|
||||||
theme,
|
theme.clone(),
|
||||||
key_config.clone(),
|
key_config.clone(),
|
||||||
&input,
|
&input,
|
||||||
updater,
|
updater,
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ pub mod symbol {
|
||||||
pub const CHECKMARK: &str = "\u{2713}"; //✓
|
pub const CHECKMARK: &str = "\u{2713}"; //✓
|
||||||
pub const SPACE: &str = "\u{02FD}"; //˽
|
pub const SPACE: &str = "\u{02FD}"; //˽
|
||||||
pub const EMPTY_SPACE: &str = " ";
|
pub const EMPTY_SPACE: &str = " ";
|
||||||
pub const LINE_BREAK: &str = "¶";
|
|
||||||
pub const FOLDER_ICON_COLLAPSED: &str = "\u{25b8}"; //▸
|
pub const FOLDER_ICON_COLLAPSED: &str = "\u{25b8}"; //▸
|
||||||
pub const FOLDER_ICON_EXPANDED: &str = "\u{25be}"; //▾
|
pub const FOLDER_ICON_EXPANDED: &str = "\u{25be}"; //▾
|
||||||
pub const EMPTY_STR: &str = "";
|
pub const EMPTY_STR: &str = "";
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use struct_patch::Patch;
|
||||||
|
|
||||||
pub type SharedTheme = Rc<Theme>;
|
pub type SharedTheme = Rc<Theme>;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Patch)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Patch)]
|
||||||
#[patch_derive(Serialize, Deserialize)]
|
#[patch_derive(Serialize, Deserialize)]
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
selected_tab: Color,
|
selected_tab: Color,
|
||||||
|
|
@ -32,6 +32,7 @@ pub struct Theme {
|
||||||
push_gauge_fg: Color,
|
push_gauge_fg: Color,
|
||||||
tag_fg: Color,
|
tag_fg: Color,
|
||||||
branch_fg: Color,
|
branch_fg: Color,
|
||||||
|
line_break: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Theme {
|
impl Theme {
|
||||||
|
|
@ -192,6 +193,10 @@ impl Theme {
|
||||||
Style::default().fg(self.danger_fg)
|
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 {
|
pub fn commandbar(&self, enabled: bool, line: usize) -> Style {
|
||||||
if enabled {
|
if enabled {
|
||||||
Style::default().fg(self.command_fg)
|
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.
|
// This is supposed to be called when theme.ron doesn't already exists.
|
||||||
fn save_patch(&self, theme_path: &PathBuf) -> Result<()> {
|
fn save_patch(&self, theme_path: &PathBuf) -> Result<()> {
|
||||||
let mut file = File::create(theme_path)?;
|
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())?;
|
let data = to_string_pretty(&patch, PrettyConfig::default())?;
|
||||||
|
|
||||||
file.write_all(data.as_bytes())?;
|
file.write_all(data.as_bytes())?;
|
||||||
|
|
@ -336,6 +341,7 @@ impl Default for Theme {
|
||||||
push_gauge_fg: Color::Reset,
|
push_gauge_fg: Color::Reset,
|
||||||
tag_fg: Color::LightMagenta,
|
tag_fg: Color::LightMagenta,
|
||||||
branch_fg: Color::LightYellow,
|
branch_fg: Color::LightYellow,
|
||||||
|
line_break: "¶".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue