aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/input
diff options
context:
space:
mode:
authordenis <denismaximov98@gmail.com>2021-05-01 13:45:01 +0300
committerdenis <denismaximov98@gmail.com>2021-05-01 13:45:01 +0300
commiteabecde90b1617ce4c29be9d5af3f52ccb67e45f (patch)
tree0d0dafa594269045f084383a9719f2a4995fe7ea /src/common/input
parentwip: more cleaning up (diff)
parentdocs(changelog): performance improvements (diff)
downloadsl0ppij-eabecde90b1617ce4c29be9d5af3f52ccb67e45f.tar.gz
sl0ppij-eabecde90b1617ce4c29be9d5af3f52ccb67e45f.tar.xz
sl0ppij-eabecde90b1617ce4c29be9d5af3f52ccb67e45f.zip
chore: painless merge this time
Diffstat (limited to 'src/common/input')
-rw-r--r--src/common/input/actions.rs2
-rw-r--r--src/common/input/config.rs58
-rw-r--r--src/common/input/handler.rs16
-rw-r--r--src/common/input/keybinds.rs286
4 files changed, 57 insertions, 305 deletions
diff --git a/src/common/input/actions.rs b/src/common/input/actions.rs
index 3bcadf15..46a8e1d6 100644
--- a/src/common/input/actions.rs
+++ b/src/common/input/actions.rs
@@ -39,6 +39,8 @@ pub enum Action {
PageScrollDown,
/// Toggle between fullscreen focus pane and normal layout.
ToggleFocusFullscreen,
+ /// Toggle between sending text commands to all panes and normal mode.
+ ToggleActiveSyncPanes,
/// Open a new pane in the specified direction (relative to focus).
/// If no direction is specified, will try to use the biggest available space.
NewPane(Option<Direction>),
diff --git a/src/common/input/config.rs b/src/common/input/config.rs
index 542116d9..62ec3dfe 100644
--- a/src/common/input/config.rs
+++ b/src/common/input/config.rs
@@ -7,8 +7,8 @@ use std::path::{Path, PathBuf};
use super::keybinds::{Keybinds, KeybindsFromYaml};
use crate::cli::ConfigCli;
+use crate::common::install;
-use directories_next::ProjectDirs;
use serde::Deserialize;
type ConfigResult = Result<Config, ConfigError>;
@@ -33,6 +33,8 @@ pub enum ConfigError {
Io(io::Error),
// Io error with path context
IoPath(io::Error, PathBuf),
+ // Internal Deserialisation Error
+ FromUtf8(std::string::FromUtf8Error),
}
impl Default for Config {
@@ -63,18 +65,11 @@ impl Config {
}
}
- /// Deserializes the config from a default platform specific path,
- /// merges the default configuration - options take precedence.
- fn from_default_path() -> ConfigResult {
- let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
- let mut config_path: PathBuf = project_dirs.config_dir().to_owned();
- config_path.push("config.yaml");
-
- match Config::new(&config_path) {
- Ok(config) => Ok(config),
- Err(ConfigError::IoPath(_, _)) => Ok(Config::default()),
- Err(e) => Err(e),
- }
+ /// Gets default configuration from assets
+ // TODO Deserialize the Configuration from bytes &[u8],
+ // once serde-yaml supports zero-copy
+ pub fn from_default_assets() -> ConfigResult {
+ Self::from_yaml(String::from_utf8(install::DEFAULT_CONFIG.to_vec())?.as_str())
}
/// Entry point of the configuration
@@ -82,20 +77,37 @@ impl Config {
pub fn from_cli_config(
location: Option<PathBuf>,
cli_config: Option<ConfigCli>,
+ config_dir: Option<PathBuf>,
) -> ConfigResult {
if let Some(path) = location {
return Config::new(&path);
}
- match cli_config {
- Some(ConfigCli::Config { clean, .. }) if clean => Ok(Config::default()),
- Some(_) | None => Ok(Config::from_default_path()?),
+ if let Some(ConfigCli::Config { clean, .. }) = cli_config {
+ if clean {
+ return Config::from_default_assets();
+ }
+ }
+
+ if let Some(config) = config_dir {
+ let path = config.join("config.yaml");
+ if path.exists() {
+ Config::new(&path)
+ } else {
+ Config::from_default_assets()
+ }
+ } else {
+ Config::from_default_assets()
}
}
/// In order not to mess up tests from changing configurations
#[cfg(test)]
- pub fn from_cli_config(_: Option<PathBuf>, _: Option<ConfigCli>) -> ConfigResult {
+ pub fn from_cli_config(
+ _: Option<PathBuf>,
+ _: Option<ConfigCli>,
+ _: Option<PathBuf>,
+ ) -> ConfigResult {
Ok(Config::default())
}
}
@@ -108,6 +120,7 @@ impl Display for ConfigError {
write!(formatter, "IoError: {}, File: {}", err, path.display(),)
}
ConfigError::Serde(ref err) => write!(formatter, "Deserialisation error: {}", err),
+ ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err),
}
}
}
@@ -118,6 +131,7 @@ impl std::error::Error for ConfigError {
ConfigError::Io(ref err) => Some(err),
ConfigError::IoPath(ref err, _) => Some(err),
ConfigError::Serde(ref err) => Some(err),
+ ConfigError::FromUtf8(ref err) => Some(err),
}
}
}
@@ -134,6 +148,12 @@ impl From<serde_yaml::Error> for ConfigError {
}
}
+impl From<std::string::FromUtf8Error> for ConfigError {
+ fn from(err: std::string::FromUtf8Error) -> ConfigError {
+ ConfigError::FromUtf8(err)
+ }
+}
+
// The unit test location.
#[cfg(test)]
mod config_test {
@@ -142,14 +162,14 @@ mod config_test {
#[test]
fn clean_option_equals_default_config() {
let cli_config = ConfigCli::Config { clean: true };
- let config = Config::from_cli_config(None, Some(cli_config)).unwrap();
+ let config = Config::from_cli_config(None, Some(cli_config), None).unwrap();
let default = Config::default();
assert_eq!(config, default);
}
#[test]
fn no_config_option_file_equals_default_config() {
- let config = Config::from_cli_config(None, None).unwrap();
+ let config = Config::from_cli_config(None, None, None).unwrap();
let default = Config::default();
assert_eq!(config, default);
}
diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs
index bbb594a3..eda71eea 100644
--- a/src/common/input/handler.rs
+++ b/src/common/input/handler.rs
@@ -59,7 +59,6 @@ impl InputHandler {
fn handle_input(&mut self) {
let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow());
err_ctx.add_call(ContextType::StdinHandler);
- let keybinds = self.config.keybinds.clone();
let alt_left_bracket = vec![27, 91];
loop {
if self.should_exit {
@@ -71,14 +70,14 @@ impl InputHandler {
Ok((event, raw_bytes)) => match event {
termion::event::Event::Key(key) => {
let key = cast_termion_key(key);
- self.handle_key(&key, raw_bytes, &keybinds);
+ self.handle_key(&key, raw_bytes);
}
termion::event::Event::Unsupported(unsupported_key) => {
// we have to do this because of a bug in termion
// this should be a key event and not an unsupported event
if unsupported_key == alt_left_bracket {
let key = Key::Alt('[');
- self.handle_key(&key, raw_bytes, &keybinds);
+ self.handle_key(&key, raw_bytes);
}
}
termion::event::Event::Mouse(_) => {
@@ -91,8 +90,9 @@ impl InputHandler {
}
}
}
- fn handle_key(&mut self, key: &Key, raw_bytes: Vec<u8>, keybinds: &Keybinds) {
- for action in Keybinds::key_to_actions(&key, raw_bytes, &self.mode, &keybinds) {
+ fn handle_key(&mut self, key: &Key, raw_bytes: Vec<u8>) {
+ let keybinds = &self.config.keybinds;
+ for action in Keybinds::key_to_actions(&key, raw_bytes, &self.mode, keybinds) {
let should_exit = self.dispatch_action(action);
if should_exit {
self.should_exit = true;
@@ -245,6 +245,11 @@ impl InputHandler {
.send(ScreenInstruction::SwitchTabPrev)
.unwrap();
}
+ Action::ToggleActiveSyncPanes => {
+ self.send_screen_instructions
+ .send(ScreenInstruction::ToggleActiveSyncPanes)
+ .unwrap();
+ }
Action::CloseTab => {
self.command_is_executing.closing_pane();
self.send_screen_instructions
@@ -295,6 +300,7 @@ pub fn get_mode_info(mode: InputMode) -> ModeInfo {
keybinds.push(("d".to_string(), "Down split".to_string()));
keybinds.push(("r".to_string(), "Right split".to_string()));
keybinds.push(("x".to_string(), "Close".to_string()));
+ keybinds.push(("s".to_string(), "Sync".to_string()));
keybinds.push(("f".to_string(), "Fullscreen".to_string()));
}
InputMode::Tab => {
diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs
index ee039f83..9842fbe2 100644
--- a/src/common/input/keybinds.rs
+++ b/src/common/input/keybinds.rs
@@ -1,7 +1,8 @@
//! Mapping of inputs to sequences of actions.
use std::collections::HashMap;
-use super::actions::{Action, Direction};
+use super::actions::Action;
+use super::config;
use serde::Deserialize;
use strum::IntoEnumIterator;
@@ -57,14 +58,9 @@ enum Unbind {
impl Default for Keybinds {
fn default() -> Keybinds {
- let mut defaults = Keybinds::new();
-
- for mode in InputMode::iter() {
- defaults
- .0
- .insert(mode, Keybinds::get_defaults_for_mode(&mode));
- }
- defaults
+ config::Config::from_default_assets()
+ .expect("Keybinds from default assets Error")
+ .keybinds
}
}
@@ -109,278 +105,6 @@ impl Keybinds {
keybinds
}
- /// Returns the default keybinds for a given [`InputMode`].
- fn get_defaults_for_mode(mode: &InputMode) -> ModeKeybinds {
- let mut defaults = HashMap::new();
-
- match *mode {
- InputMode::Normal => {
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Locked)],
- );
- defaults.insert(Key::Ctrl('p'), vec![Action::SwitchToMode(InputMode::Pane)]);
- defaults.insert(
- Key::Ctrl('r'),
- vec![Action::SwitchToMode(InputMode::Resize)],
- );
- defaults.insert(Key::Ctrl('t'), vec![Action::SwitchToMode(InputMode::Tab)]);
- defaults.insert(
- Key::Ctrl('s'),
- vec![Action::SwitchToMode(InputMode::Scroll)],
- );
- defaults.insert(Key::Ctrl('q'), vec![Action::Quit]);
-
- defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
- defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
- defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
- }
- InputMode::Locked => {
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- }
- InputMode::Resize => {
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Locked)],
- );
- defaults.insert(Key::Ctrl('p'), vec![Action::SwitchToMode(InputMode::Pane)]);
- defaults.insert(
- Key::Ctrl('r'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(Key::Ctrl('t'), vec![Action::SwitchToMode(InputMode::Tab)]);
- defaults.insert(
- Key::Ctrl('s'),
- vec![Action::SwitchToMode(InputMode::Scroll)],
- );
- defaults.insert(Key::Ctrl('q'), vec![Action::Quit]);
- defaults.insert(Key::Esc, vec![Action::SwitchToMode(InputMode::Normal)]);
- defaults.insert(
- Key::Char('\n'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Char(' '),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
-
- defaults.insert(Key::Char('h'), vec![Action::Resize(Direction::Left)]);
- defaults.insert(Key::Char('j'), vec![Action::Resize(Direction::Down)]);
- defaults.insert(Key::Char('k'), vec![Action::Resize(Direction::Up)]);
- defaults.insert(Key::Char('l'), vec![Action::Resize(Direction::Right)]);
-
- defaults.insert(Key::Left, vec![Action::Resize(Direction::Left)]);
- defaults.insert(Key::Down, vec![Action::Resize(Direction::Down)]);
- defaults.insert(Key::Up, vec![Action::Resize(Direction::Up)]);
- defaults.insert(Key::Right, vec![Action::Resize(Direction::Right)]);
-
- defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
- defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
- defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
- }
- InputMode::Pane => {
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Locked)],
- );
- defaults.insert(
- Key::Ctrl('p'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Ctrl('r'),
- vec![Action::SwitchToMode(InputMode::Resize)],
- );
- defaults.insert(Key::Ctrl('t'), vec![Action::SwitchToMode(InputMode::Tab)]);
- defaults.insert(
- Key::Ctrl('s'),
- vec![Action::SwitchToMode(InputMode::Scroll)],
- );
- defaults.insert(Key::Ctrl('q'), vec![Action::Quit]);
- defaults.insert(Key::Esc, vec![Action::SwitchToMode(InputMode::Normal)]);
- defaults.insert(
- Key::Char('\n'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Char(' '),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
-
- defaults.insert(Key::Char('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Char('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Char('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Char('l'), vec![Action::MoveFocus(Direction::Right)]);
-
- defaults.insert(Key::Left, vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Down, vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Up, vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Right, vec![Action::MoveFocus(Direction::Right)]);
-
- defaults.insert(Key::Char('p'), vec![Action::SwitchFocus]);
- defaults.insert(Key::Char('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Char('d'), vec![Action::NewPane(Some(Direction::Down))]);
- defaults.insert(
- Key::Char('r'),
- vec![Action::NewPane(Some(Direction::Right))],
- );
- defaults.insert(Key::Char('x'), vec![Action::CloseFocus]);
- defaults.insert(Key::Char('f'), vec![Action::ToggleFocusFullscreen]);
-
- defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
- defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
- defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
- }
- InputMode::Tab => {
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Locked)],
- );
- defaults.insert(Key::Ctrl('p'), vec![Action::SwitchToMode(InputMode::Pane)]);
- defaults.insert(
- Key::Ctrl('r'),
- vec![Action::SwitchToMode(InputMode::Resize)],
- );
- defaults.insert(
- Key::Ctrl('t'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Ctrl('s'),
- vec![Action::SwitchToMode(InputMode::Scroll)],
- );
- defaults.insert(Key::Ctrl('q'), vec![Action::Quit]);
- defaults.insert(Key::Esc, vec![Action::SwitchToMode(InputMode::Normal)]);
- defaults.insert(
- Key::Char('\n'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Char(' '),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
-
- defaults.insert(Key::Char('h'), vec![Action::GoToPreviousTab]);
- defaults.insert(Key::Char('j'), vec![Action::GoToNextTab]);
- defaults.insert(Key::Char('k'), vec![Action::GoToPreviousTab]);
- defaults.insert(Key::Char('l'), vec![Action::GoToNextTab]);
-
- defaults.insert(Key::Left, vec![Action::GoToPreviousTab]);
- defaults.insert(Key::Down, vec![Action::GoToNextTab]);
- defaults.insert(Key::Up, vec![Action::GoToPreviousTab]);
- defaults.insert(Key::Right, vec![Action::GoToNextTab]);
-
- defaults.insert(Key::Char('n'), vec![Action::NewTab]);
- defaults.insert(Key::Char('x'), vec![Action::CloseTab]);
-
- defaults.insert(
- Key::Char('r'),
- vec![
- Action::SwitchToMode(InputMode::RenameTab),
- Action::TabNameInput(vec![0]),
- ],
- );
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- for i in '1'..='9' {
- defaults.insert(Key::Char(i), vec![Action::GoToTab(i.to_digit(10).unwrap())]);
- }
- defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
- defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
- defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
- }
- InputMode::Scroll => {
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Locked)],
- );
- defaults.insert(Key::Ctrl('p'), vec![Action::SwitchToMode(InputMode::Pane)]);
- defaults.insert(
- Key::Ctrl('r'),
- vec![Action::SwitchToMode(InputMode::Resize)],
- );
- defaults.insert(Key::Ctrl('t'), vec![Action::SwitchToMode(InputMode::Tab)]);
- defaults.insert(
- Key::Ctrl('s'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(Key::Ctrl('q'), vec![Action::Quit]);
- defaults.insert(Key::Esc, vec![Action::SwitchToMode(InputMode::Normal)]);
- defaults.insert(
- Key::Char('\n'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Char(' '),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
-
- defaults.insert(Key::Char('j'), vec![Action::ScrollDown]);
- defaults.insert(Key::Char('k'), vec![Action::ScrollUp]);
-
- defaults.insert(Key::Ctrl('f'), vec![Action::PageScrollDown]);
- defaults.insert(Key::Ctrl('b'), vec![Action::PageScrollUp]);
- defaults.insert(Key::PageDown, vec![Action::PageScrollDown]);
- defaults.insert(Key::PageUp, vec![Action::PageScrollUp]);
-
- defaults.insert(Key::Down, vec![Action::ScrollDown]);
- defaults.insert(Key::Up, vec![Action::ScrollUp]);
-
- defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
- defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
- defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
- }
- InputMode::RenameTab => {
- defaults.insert(Key::Char('\n'), vec![Action::SwitchToMode(InputMode::Tab)]);
- defaults.insert(
- Key::Ctrl('g'),
- vec![Action::SwitchToMode(InputMode::Normal)],
- );
- defaults.insert(
- Key::Esc,
- vec![
- Action::TabNameInput(vec![0x1b]),
- Action::SwitchToMode(InputMode::Tab),
- ],
- );
-
- defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
- defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
- defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
- defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
- defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
- defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
- defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
- }
- }
- ModeKeybinds(defaults)
- }
-
/// Converts a [`Key`] terminal event to a sequence of [`Action`]s according to the current
/// [`InputMode`] and [`Keybinds`].
pub fn key_to_actions(