Skip to content

Commit daaafa2

Browse files
committed
Simplify theme overrides
Theme overrides are now loaded the same way key overrides are loaded. The config file, `theme.ron`, does not have to contain a complete theme anymore. Instead, it is possible to specify only the values that are supposed to override their corresponding default values.
1 parent 999912c commit daaafa2

File tree

3 files changed

+42
-50
lines changed

3 files changed

+42
-50
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2929

3030
### Breaking Change
3131
* `focus_XYZ` key bindings are merged into the `move_XYZ` set, so only one way to bind arrow-like keys from now on ([#1539](https://github.com/extrawurst/gitui/issues/1539))
32+
* The format of `theme.ron` has changed
3233

3334
### Added
3435
* allow reset (soft,mixed,hard) from commit log ([#1500](https://github.com/extrawurst/gitui/issues/1500))
@@ -41,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4142
* allow `copy` file path on revision files and status tree [[@yanganto]](https://github.com/yanganto) ([#1516](https://github.com/extrawurst/gitui/pull/1516))
4243
* print message of where log will be written if `-l` is set ([#1472](https://github.com/extrawurst/gitui/pull/1472))
4344
* show remote branches in log [[@cruessler](https://github.com/cruessler)] ([#1501](https://github.com/extrawurst/gitui/issues/1501))
45+
* simplify theme overrides [[@cruessler](https://github.com/cruessler)] ([#1367](https://github.com/extrawurst/gitui/issues/1367))
4446

4547
### Fixes
4648
* fixed side effect of crossterm 0.26 on windows that caused double input of all keys [[@pm100]](https://github/pm100) ([#1686](https://github.com/extrawurst/gitui/pull/1686))

src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,7 @@ fn main() -> Result<()> {
138138
let key_config = KeyConfig::init()
139139
.map_err(|e| eprintln!("KeyConfig loading error: {e}"))
140140
.unwrap_or_default();
141-
let theme = Theme::init(&cliargs.theme)
142-
.map_err(|e| eprintln!("Theme loading error: {e}"))
143-
.unwrap_or_default();
141+
let theme = Theme::init(&cliargs.theme);
144142

145143
setup_terminal()?;
146144
defer! {

src/ui/style.rs

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
use anyhow::Result;
21
use asyncgit::{DiffLineType, StatusItemType};
32
use ratatui::style::{Color, Modifier, Style};
4-
use ron::{
5-
de::from_bytes,
6-
ser::{to_string_pretty, PrettyConfig},
7-
};
83
use serde::{Deserialize, Serialize};
9-
use std::{
10-
fs::{self, File},
11-
io::{Read, Write},
12-
path::PathBuf,
13-
rc::Rc,
14-
};
4+
use std::{fs::File, path::PathBuf, rc::Rc};
5+
use struct_patch::Patch;
156

167
pub type SharedTheme = Rc<Theme>;
178

18-
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
9+
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Patch)]
10+
#[patch_derive(Deserialize)]
1911
pub struct Theme {
2012
selected_tab: Color,
2113
command_fg: Color,
@@ -261,44 +253,16 @@ impl Theme {
261253
.bg(self.push_gauge_bg)
262254
}
263255

264-
// This will only be called when theme.ron doesn't already exists
265-
fn save(&self, theme_file: &PathBuf) -> Result<()> {
266-
let mut file = File::create(theme_file)?;
267-
let data = to_string_pretty(self, PrettyConfig::default())?;
268-
file.write_all(data.as_bytes())?;
269-
Ok(())
270-
}
271-
272-
fn read_file(theme_file: PathBuf) -> Result<Self> {
273-
let mut f = File::open(theme_file)?;
274-
let mut buffer = Vec::new();
275-
f.read_to_end(&mut buffer)?;
276-
Ok(from_bytes(&buffer)?)
277-
}
256+
pub fn init(theme_path: &PathBuf) -> Self {
257+
let mut theme = Self::default();
278258

279-
pub fn init(file: &PathBuf) -> Result<Self> {
280-
if file.exists() {
281-
match Self::read_file(file.clone()) {
282-
Err(e) => {
283-
let config_path = file.clone();
284-
let config_path_old =
285-
format!("{}.old", file.to_string_lossy());
286-
fs::rename(
287-
config_path.clone(),
288-
config_path_old.clone(),
289-
)?;
290-
291-
Self::default().save(file)?;
292-
293-
Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
294-
e,config_path_old,config_path.to_string_lossy()))
295-
}
296-
Ok(res) => Ok(res),
259+
if let Ok(file) = File::open(theme_path) {
260+
if let Ok(patch) = ron::de::from_reader(file) {
261+
theme.apply(patch);
297262
}
298-
} else {
299-
Self::default().save(file)?;
300-
Ok(Self::default())
301263
}
264+
265+
theme
302266
}
303267
}
304268

@@ -329,3 +293,31 @@ impl Default for Theme {
329293
}
330294
}
331295
}
296+
297+
#[cfg(test)]
298+
mod tests {
299+
use super::*;
300+
use pretty_assertions::assert_eq;
301+
use std::io::Write;
302+
use tempfile::NamedTempFile;
303+
304+
#[test]
305+
fn test_smoke() {
306+
let mut file = NamedTempFile::new().unwrap();
307+
308+
writeln!(
309+
file,
310+
r"
311+
(
312+
selection_bg: Some(White),
313+
)
314+
"
315+
)
316+
.unwrap();
317+
318+
let theme = Theme::init(&file.path().to_path_buf());
319+
320+
assert_eq!(theme.selection_fg, Theme::default().selection_fg);
321+
assert_eq!(theme.selection_bg, Color::White);
322+
}
323+
}

0 commit comments

Comments
 (0)