Skip to content

Commit 8f22b76

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 3e0ec29 commit 8f22b76

File tree

3 files changed

+43
-50
lines changed

3 files changed

+43
-50
lines changed

CHANGELOG.md

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

1818
### Breaking Change
1919
* `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))
20+
* The format of `theme.ron` has changed
2021

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

3234
### Fixes
3335
* commit msg history ordered the wrong way ([#1445](https://github.com/extrawurst/gitui/issues/1445))

src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ fn main() -> Result<()> {
130130
let key_config = KeyConfig::init()
131131
.map_err(|e| eprintln!("KeyConfig loading error: {e}"))
132132
.unwrap_or_default();
133-
let theme = Theme::init(&cliargs.theme)
134-
.map_err(|e| eprintln!("Theme loading error: {e}"))
135-
.unwrap_or_default();
133+
let theme = Theme::init(&cliargs.theme);
136134

137135
setup_terminal()?;
138136
defer! {

src/ui/style.rs

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

168
pub type SharedTheme = Rc<Theme>;
179

18-
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
10+
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Patch)]
11+
#[patch_derive(Deserialize)]
1912
pub struct Theme {
2013
selected_tab: Color,
2114
command_fg: Color,
@@ -261,44 +254,16 @@ impl Theme {
261254
.bg(self.push_gauge_bg)
262255
}
263256

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-
}
257+
pub fn init(theme_path: &PathBuf) -> Self {
258+
let mut theme = Self::default();
278259

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),
260+
if let Ok(file) = File::open(theme_path) {
261+
if let Ok(patch) = ron::de::from_reader(file) {
262+
theme.apply(patch);
297263
}
298-
} else {
299-
Self::default().save(file)?;
300-
Ok(Self::default())
301264
}
265+
266+
theme
302267
}
303268
}
304269

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

0 commit comments

Comments
 (0)