mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 08:58:21 +00:00
smarter config loading giving more diagnostics to the user about whats going wrong (#589)
This commit is contained in:
parent
52bf018515
commit
7d4b79606c
4 changed files with 63 additions and 46 deletions
|
|
@ -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<AsyncNotification>,
|
||||
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,
|
||||
|
|
|
|||
51
src/keys.rs
51
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<PathBuf> {
|
||||
pub fn get_config_file() -> Result<PathBuf> {
|
||||
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<Self> {
|
||||
let file = Self::get_config_file()?;
|
||||
pub fn init(file: PathBuf) -> Result<Self> {
|
||||
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(),
|
||||
)?;
|
||||
|
||||
pub fn init() -> Self {
|
||||
match Self::init_internal() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log::error!("failed loading key binding: {}", e);
|
||||
Self::default()
|
||||
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),
|
||||
}
|
||||
} else {
|
||||
Self::default().save(file)?;
|
||||
Ok(Self::default())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
11
src/main.rs
11
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;
|
||||
|
|
|
|||
|
|
@ -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,21 +250,29 @@ impl Theme {
|
|||
Ok(from_bytes(&buffer)?)
|
||||
}
|
||||
|
||||
fn init_internal(theme: PathBuf) -> Result<Self> {
|
||||
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.")
|
||||
}
|
||||
Ok(def)
|
||||
}
|
||||
}
|
||||
pub fn init(file: PathBuf) -> Result<Self> {
|
||||
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(),
|
||||
)?;
|
||||
|
||||
pub fn init(theme_path: PathBuf) -> Self {
|
||||
Self::init_internal(theme_path).unwrap_or_default()
|
||||
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),
|
||||
}
|
||||
} else {
|
||||
Self::default().save(file)?;
|
||||
Ok(Self::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue