diff options
| author | a-kenji <aks.kenji@protonmail.com> | 2021-03-05 19:23:06 +0100 |
|---|---|---|
| committer | a-kenji <aks.kenji@protonmail.com> | 2021-03-05 19:23:06 +0100 |
| commit | c644a1c2437ac439425eaa185d4f69911cf5ee45 (patch) | |
| tree | 0ca25130d142ba9c26f88a32a7f53daa464a312d /src | |
| parent | poke at creating Macros (diff) | |
| download | sl0ppij-c644a1c2437ac439425eaa185d4f69911cf5ee45.tar.gz sl0ppij-c644a1c2437ac439425eaa185d4f69911cf5ee45.tar.xz sl0ppij-c644a1c2437ac439425eaa185d4f69911cf5ee45.zip | |
poking
Diffstat (limited to 'src')
| -rw-r--r-- | src/cli.rs | 4 | ||||
| -rw-r--r-- | src/common/config.rs | 85 | ||||
| -rw-r--r-- | src/common/input/handler.rs | 19 | ||||
| -rw-r--r-- | src/common/input/keybinds.rs | 2 | ||||
| -rw-r--r-- | src/common/input/macros.rs | 4 | ||||
| -rw-r--r-- | src/common/mod.rs | 20 |
6 files changed, 83 insertions, 51 deletions
@@ -24,6 +24,10 @@ pub struct CliArgs { #[structopt(short, long)] pub layout: Option<PathBuf>, + /// Path to the configuration yaml file + #[structopt(short, long)] + pub config: Option<PathBuf>, + #[structopt(short, long)] pub debug: bool, } diff --git a/src/common/config.rs b/src/common/config.rs index 2ce25bff..705c1592 100644 --- a/src/common/config.rs +++ b/src/common/config.rs @@ -1,14 +1,15 @@ //! Deserializes configuration options. use std; -use std::collections::HashMap; +//use std::collections::HashMap; use std::error; use std::fmt::{self, Display}; use std::fs::File; -use std::io::{self,Read}; +use std::io::{self, Read}; use std::path::PathBuf; -use super::input::{keybinds,handler}; +use super::input::{keybinds, macros}; +use directories_next::ProjectDirs; use serde::Deserialize; /// Intermediate struct @@ -16,17 +17,17 @@ use serde::Deserialize; //} - /// Intermediate struct -//#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize)] pub struct ConfigFromYaml { - keybinds: HashMap<handler::InputMode,Vec<keybinds::Keybinds>>, + keybinds: Option<keybinds::Keybinds>, + macros: Option<Vec<macros::Macro>>, } ///// Deserialized config state #[derive(Debug, Clone, Default, Deserialize)] pub struct Config { - keybinds: Vec<keybinds::Keybinds>, + pub keybinds: keybinds::Keybinds, } #[derive(Debug)] @@ -43,36 +44,51 @@ pub enum ConfigError { Serde(serde_yaml::Error), //Eof, // io::Error - Io(io::Error) + Io(io::Error), } impl Config { /// Deserializes from given path - pub fn new(path: &PathBuf) -> Result<Config,ConfigError> { - let config_deserialized: Config; + pub fn new(path: &PathBuf) -> Result<Config, ConfigError> { + let config: Config; + let config_deserialized: ConfigFromYaml; let mut config_string = String::new(); + // TODO fix this unwrap match File::open(path) { Ok(mut file) => { file.read_to_string(&mut config_string)?; config_deserialized = serde_yaml::from_str(&config_string)?; + config = Config { + keybinds: config_deserialized + .keybinds + .unwrap_or_else(|| keybinds::get_default_keybinds().unwrap()), + } } - Err(_) => { + Err(e) => { // TODO logging, if a file is not found // at an expected position - should not // panic @a-kenji - config_deserialized = Config::default(); + eprintln!("{}", e); + config = Config::default(); } } - Ok(config_deserialized) + Ok(config) } -} -//impl de::Error for ConfigError { - //fn custom<T: Display>(msg: T) -> Self { - //ConfigError::Message(msg.to_string()) - //} -//} + pub fn from_option_or_default(option: Option<PathBuf>) -> Result<Config, ConfigError> { + let config; + if let Some(config_path) = option { + config = Config::new(&config_path)?; + } else { + let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap(); + //let config_path = PathBuf::from(project_dirs.config_dir().as_os_str()); + let config_path = project_dirs.config_dir().to_owned().into(); + config = Config::new(&config_path)?; + } + return Ok(config); + } +} impl Display for ConfigError { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -88,25 +104,17 @@ impl Display for ConfigError { } impl std::error::Error for ConfigError { - fn description(&self) -> &str { + fn cause(&self) -> Option<&dyn error::Error> { match *self { - //ConfigError::Message(ref err) => err, - ConfigError::Io(ref err) => err.to_string().as_str(), - ConfigError::Serde(ref err) => err.to_string().as_str(), + // N.B. Both of these implicitly cast `err` from their concrete + // types (either `&io::Error` or `&num::ParseIntError`) + // to a trait object `&Error`. This works because both error types + // implement `Error`. + ConfigError::Io(ref err) => Some(err), + //ConfigError::Message(ref err) => Some(err), + ConfigError::Serde(ref err) => Some(err), } } - - fn cause(&self) -> Option<&dyn error::Error> { - match *self { - // N.B. Both of these implicitly cast `err` from their concrete - // types (either `&io::Error` or `&num::ParseIntError`) - // to a trait object `&Error`. This works because both error types - // implement `Error`. - ConfigError::Io(ref err) => Some(err), - //ConfigError::Message(ref err) => Some(err), - ConfigError::Serde(ref err) => Some(err), - } -} } impl From<io::Error> for ConfigError { @@ -120,10 +128,3 @@ impl From<serde_yaml::Error> for ConfigError { ConfigError::Serde(err) } } - -//impl From<de::Error::Message> for ConfigError { - //fn from(err: de::Error::Message) -> ConfigError { - //ConfigError::Message(err) - //} -//} - diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index 5c4f1971..9d8b2cf2 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -2,6 +2,7 @@ use super::actions::Action; use super::keybinds::get_default_keybinds; +use crate::common::config::Config; use crate::common::{update_state, AppInstruction, AppState, SenderWithContext, OPENCALLS}; use crate::errors::ContextType; use crate::os_input_output::OsApi; @@ -22,6 +23,7 @@ struct InputHandler { /// The current input mode mode: InputMode, os_input: Box<dyn OsApi>, + config: Config, command_is_executing: CommandIsExecuting, send_screen_instructions: SenderWithContext<ScreenInstruction>, send_pty_instructions: SenderWithContext<PtyInstruction>, @@ -34,6 +36,7 @@ impl InputHandler { fn new( os_input: Box<dyn OsApi>, command_is_executing: CommandIsExecuting, + config: Config, send_screen_instructions: SenderWithContext<ScreenInstruction>, send_pty_instructions: SenderWithContext<PtyInstruction>, send_plugin_instructions: SenderWithContext<PluginInstruction>, @@ -42,6 +45,7 @@ impl InputHandler { InputHandler { mode: InputMode::Normal, os_input, + config, command_is_executing, send_screen_instructions, send_pty_instructions, @@ -59,6 +63,8 @@ impl InputHandler { self.send_app_instructions.update(err_ctx); self.send_screen_instructions.update(err_ctx); if let Ok(keybinds) = get_default_keybinds() { + let mut merged_keybinds = keybinds; + merged_keybinds.extend(self.config.keybinds.clone().into_iter()); 'input_loop: loop { //@@@ I think this should actually just iterate over stdin directly let stdin_buffer = self.os_input.read_from_stdin(); @@ -76,9 +82,14 @@ impl InputHandler { // been revised. Sorry about this (@categorille) if { let mut should_break = false; - for action in - key_to_actions(&key, raw_bytes, &self.mode, &keybinds) - { + // Hacked on way to have a means of testing Macros, needs to + // get properly integrated + for action in key_to_actions( + &key, + raw_bytes, + &self.mode, + &merged_keybinds, + ) { should_break |= self.dispatch_action(action); } should_break @@ -324,6 +335,7 @@ pub fn get_help(mode: InputMode) -> Help { /// its [`InputHandler::handle_input()`] loop. pub fn input_loop( os_input: Box<dyn OsApi>, + config: Config, command_is_executing: CommandIsExecuting, send_screen_instructions: SenderWithContext<ScreenInstruction>, send_pty_instructions: SenderWithContext<PtyInstruction>, @@ -333,6 +345,7 @@ pub fn input_loop( let _handler = InputHandler::new( os_input, command_is_executing, + config, send_screen_instructions, send_pty_instructions, send_plugin_instructions, diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs index 0ea0695f..8799649d 100644 --- a/src/common/input/keybinds.rs +++ b/src/common/input/keybinds.rs @@ -23,7 +23,7 @@ pub fn get_default_keybinds() -> Result<Keybinds, String> { Ok(defaults) } -/// Returns the default keybinds for a givent [`InputMode`]. +/// Returns the default keybinds for a given [`InputMode`]. fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> { let mut defaults = ModeKeybinds::new(); diff --git a/src/common/input/macros.rs b/src/common/input/macros.rs index cbd14332..4b7c6df1 100644 --- a/src/common/input/macros.rs +++ b/src/common/input/macros.rs @@ -2,11 +2,11 @@ //! defined predictable order. use super::actions::Action; - + use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] pub struct Macro { name: Option<String>, - sequence: Vec<Action> + sequence: Vec<Action>, } diff --git a/src/common/mod.rs b/src/common/mod.rs index 5ba2e15d..c8b2ec98 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,5 +1,5 @@ -pub mod config; pub mod command_is_executing; +pub mod config; pub mod errors; pub mod input; pub mod install; @@ -46,10 +46,17 @@ pub enum ApiCommand { MoveFocus, } // FIXME: It would be good to add some more things to this over time -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct AppState { pub input_mode: InputMode, - pub config : Config, +} + +impl Default for AppState { + fn default() -> Self { + AppState { + input_mode: InputMode::default(), + } + } } // FIXME: Make this a method on the big `Communication` struct, so that app_tx can be extracted @@ -158,8 +165,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { .get_stdout_writer() .write(take_snapshot.as_bytes()) .unwrap(); + let mut app_state = AppState::default(); + let config = Config::from_option_or_default(opts.config) + .map_err(|e| eprintln!{"Config Error: {}", e}) + .unwrap(); + let command_is_executing = CommandIsExecuting::new(); let full_screen_ws = os_input.get_terminal_size_using_fd(0); @@ -638,9 +650,11 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { let send_pty_instructions = send_pty_instructions.clone(); let send_plugin_instructions = send_plugin_instructions.clone(); let os_input = os_input.clone(); + let config = config.clone(); move || { input_loop( os_input, + config, command_is_executing, send_screen_instructions, send_pty_instructions, |
