diff --git a/src/app.rs b/src/app.rs index 390f2f72cf..600f1a89c7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -23,7 +23,7 @@ use crossbeam_channel::Sender; use crossterm::event::{Event, KeyEvent}; use std::{ cell::{Cell, RefCell}, - path::{Path, PathBuf}, + path::Path, rc::Rc, }; use tui::{ @@ -74,11 +74,12 @@ impl App { pub fn new( sender: &Sender, input: Input, - theme_path: PathBuf, + theme: Theme, + key_config: KeyConfig, ) -> Self { let queue = Queue::default(); - let theme = Rc::new(Theme::init(theme_path)); - let key_config = Rc::new(KeyConfig::init()); + let theme = Rc::new(theme); + let key_config = Rc::new(key_config); Self { input, diff --git a/src/keys.rs b/src/keys.rs index 01ff9b5021..18f8afea18 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -5,12 +5,12 @@ use crate::get_app_config_path; use anyhow::Result; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use ron::{ - de::from_bytes, + self, ser::{to_string_pretty, PrettyConfig}, }; use serde::{Deserialize, Serialize}; use std::{ - fs::File, + fs::{self, File}, io::{Read, Write}, path::PathBuf, rc::Rc, @@ -127,15 +127,14 @@ impl Default for KeyConfig { } impl KeyConfig { - fn save(&self) -> Result<()> { - let config_file = Self::get_config_file()?; - let mut file = File::create(config_file)?; + fn save(&self, file: PathBuf) -> Result<()> { + let mut file = File::create(file)?; let data = to_string_pretty(self, PrettyConfig::default())?; file.write_all(data.as_bytes())?; Ok(()) } - fn get_config_file() -> Result { + pub fn get_config_file() -> Result { let app_home = get_app_config_path()?; Ok(app_home.join("key_config.ron")) } @@ -144,31 +143,31 @@ impl KeyConfig { let mut f = File::open(config_file)?; let mut buffer = Vec::new(); f.read_to_end(&mut buffer)?; - Ok(from_bytes(&buffer)?) + Ok(ron::de::from_bytes(&buffer)?) } - fn init_internal() -> Result { - let file = Self::get_config_file()?; + pub fn init(file: PathBuf) -> Result { if file.exists() { - Ok(Self::read_file(file)?) - } else { - let def = Self::default(); - if def.save().is_err() { - log::warn!( - "failed to store default key config to disk." - ) - } - Ok(def) - } - } + match Self::read_file(file.clone()) { + Err(e) => { + let config_path = file.clone(); + let config_path_old = + format!("{}.old", file.to_string_lossy()); + fs::rename( + config_path.clone(), + config_path_old.clone(), + )?; + + Self::default().save(file)?; - pub fn init() -> Self { - match Self::init_internal() { - Ok(v) => v, - Err(e) => { - log::error!("failed loading key binding: {}", e); - Self::default() + Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}", + e,config_path_old,config_path.to_string_lossy())) + } + Ok(res) => Ok(res), } + } else { + Self::default().save(file)?; + Ok(Self::default()) } } diff --git a/src/main.rs b/src/main.rs index deaa47043d..cfae967f87 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ use crossterm::{ ExecutableCommand, }; use input::{Input, InputEvent, InputState}; +use keys::KeyConfig; use profiler::Profiler; use scopeguard::defer; use scopetime::scope_time; @@ -61,6 +62,7 @@ use tui::{ backend::{Backend, CrosstermBackend}, Terminal, }; +use ui::style::Theme; static TICK_INTERVAL: Duration = Duration::from_secs(5); static SPINNER_INTERVAL: Duration = Duration::from_millis(80); @@ -88,6 +90,13 @@ fn main() -> Result<()> { return Ok(()); } + let key_config = KeyConfig::init(KeyConfig::get_config_file()?) + .map_err(|e| eprintln!("KeyConfig loading error: {}", e)) + .unwrap_or_default(); + let theme = Theme::init(cliargs.theme) + .map_err(|e| eprintln!("Theme loading error: {}", e)) + .unwrap_or_default(); + setup_terminal()?; defer! { shutdown_terminal().expect("shutdown failed"); @@ -105,7 +114,7 @@ fn main() -> Result<()> { let ticker = tick(TICK_INTERVAL); let spinner_ticker = tick(SPINNER_INTERVAL); - let mut app = App::new(&tx_git, input, cliargs.theme); + let mut app = App::new(&tx_git, input, theme, key_config); let mut spinner = Spinner::default(); let mut first_update = true; diff --git a/src/ui/style.rs b/src/ui/style.rs index 2a2aa34556..b06d275013 100644 --- a/src/ui/style.rs +++ b/src/ui/style.rs @@ -9,7 +9,7 @@ use ron::{ }; use serde::{Deserialize, Serialize}; use std::{ - fs::File, + fs::{self, File}, io::{Read, Write}, path::PathBuf, rc::Rc, @@ -250,22 +250,30 @@ impl Theme { Ok(from_bytes(&buffer)?) } - fn init_internal(theme: PathBuf) -> Result { - if theme.exists() { - Ok(Self::read_file(theme)?) - } else { - // This will only be called when theme.ron doesn't already exists - let def = Self::default(); - if def.save(theme).is_err() { - log::warn!("failed to store default theme to disk.") + pub fn init(file: PathBuf) -> Result { + if file.exists() { + match Self::read_file(file.clone()) { + Err(e) => { + let config_path = file.clone(); + let config_path_old = + format!("{}.old", file.to_string_lossy()); + fs::rename( + config_path.clone(), + config_path_old.clone(), + )?; + + Self::default().save(file)?; + + Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}", + e,config_path_old,config_path.to_string_lossy())) + } + Ok(res) => Ok(res), } - Ok(def) + } else { + Self::default().save(file)?; + Ok(Self::default()) } } - - pub fn init(theme_path: PathBuf) -> Self { - Self::init_internal(theme_path).unwrap_or_default() - } } impl Default for Theme {