diff options
| author | Aram Drevekenin <aram@poor.dev> | 2021-02-09 17:36:37 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-09 17:36:37 +0100 |
| commit | 14783c2b2c3bcd3b4b01e72c46d6af3ecbdd203c (patch) | |
| tree | 7e25be8c93e85ec9fc03335f1993f319f713c614 /src/common/input | |
| parent | Merge pull request #158 from mosaic-org/add-files (diff) | |
| download | sl0ppij-14783c2b2c3bcd3b4b01e72c46d6af3ecbdd203c.tar.gz sl0ppij-14783c2b2c3bcd3b4b01e72c46d6af3ecbdd203c.tar.xz sl0ppij-14783c2b2c3bcd3b4b01e72c46d6af3ecbdd203c.zip | |
feat(ui): new keybindings and status bar (#160)
* work
* feat(statusbar): new design and keybindings
* fix(ipc): add missing const
* style(fmt): rustfmt
* style(input): remove accidental comment
Diffstat (limited to 'src/common/input')
| -rw-r--r-- | src/common/input/actions.rs | 1 | ||||
| -rw-r--r-- | src/common/input/handler.rs | 124 | ||||
| -rw-r--r-- | src/common/input/keybinds.rs | 128 |
3 files changed, 178 insertions, 75 deletions
diff --git a/src/common/input/actions.rs b/src/common/input/actions.rs index be7bcdb9..6f4a4521 100644 --- a/src/common/input/actions.rs +++ b/src/common/input/actions.rs @@ -18,6 +18,7 @@ pub enum Action { Write(Vec<u8>), /// Switch to the specified input mode SwitchToMode(handler::InputMode), + TogglePersistentMode, /// Resize focus pane in specified direction Resize(Direction), /// Switch focus to next pane in specified direction diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index b10e9df3..2a1c2c72 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -9,6 +9,7 @@ use crate::screen::ScreenInstruction; use crate::wasm_vm::PluginInstruction; use crate::CommandIsExecuting; +use serde::{Deserialize, Serialize}; use strum_macros::EnumIter; use termion::input::TermReadEventsAndRaw; @@ -16,6 +17,7 @@ use super::keybinds::key_to_action; struct InputHandler { mode: InputMode, + mode_is_persistent: bool, os_input: Box<dyn OsApi>, command_is_executing: CommandIsExecuting, send_screen_instructions: SenderWithContext<ScreenInstruction>, @@ -35,6 +37,7 @@ impl InputHandler { ) -> Self { InputHandler { mode: InputMode::Normal, + mode_is_persistent: false, os_input, command_is_executing, send_screen_instructions, @@ -68,12 +71,13 @@ impl InputHandler { &key, raw_bytes, &self.mode, &keybinds, )); //@@@ This is a hack until we dispatch more than one action per key stroke - if entry_mode == InputMode::Command - && self.mode == InputMode::Command - { + if entry_mode == self.mode && !self.mode_is_persistent { self.mode = InputMode::Normal; update_state(&self.send_app_instructions, |_| AppState { - input_mode: self.mode, + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, }); } if should_break { @@ -113,13 +117,28 @@ impl InputHandler { } Action::SwitchToMode(mode) => { self.mode = mode; + if mode == InputMode::Normal { + self.mode_is_persistent = false; + } update_state(&self.send_app_instructions, |_| AppState { - input_mode: self.mode, + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, }); self.send_screen_instructions .send(ScreenInstruction::Render) .unwrap(); } + Action::TogglePersistentMode => { + self.mode_is_persistent = !self.mode_is_persistent; + update_state(&self.send_app_instructions, |_| AppState { + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, + }); + } Action::Resize(direction) => { let screen_instr = match direction { super::actions::Direction::Left => ScreenInstruction::ResizeLeft, @@ -224,6 +243,21 @@ impl InputHandler { } } +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)] +pub struct InputState { + mode: InputMode, + persistent: bool, +} + +impl Default for InputState { + fn default() -> InputState { + InputState { + mode: InputMode::Normal, + persistent: false, + } + } +} + /// Dictates whether we're in command mode, persistent command mode, normal mode or exiting: /// - Normal mode either writes characters to the terminal, or switches to command mode /// using a particular key control @@ -231,41 +265,65 @@ impl InputHandler { /// back to normal mode /// - Persistent command mode is the same as command mode, but doesn't return automatically to /// normal mode -#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter)] +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter, Serialize, Deserialize)] pub enum InputMode { Normal, Command, - CommandPersistent, + Resize, + Pane, + Tab, + Scroll, Exiting, } -// FIXME: This should be auto-generated from the soon-to-be-added `get_default_keybinds` -pub fn get_help(mode: &InputMode) -> Vec<String> { - let command_help = vec![ - "<n/b/z> Split".into(), - "<j/k/h/l> Resize".into(), - "<p> Focus Next".into(), - "<x> Close Pane".into(), - "<q> Quit".into(), - "<PgUp/PgDown> Scroll".into(), - "<1> New Tab".into(), - "<2/3> Move Tab".into(), - "<4> Close Tab".into(), - ]; - match mode { - InputMode::Normal => vec!["<Ctrl-g> Command Mode".into()], - InputMode::Command => [ - vec![ - "<Ctrl-g> Persistent Mode".into(), - "<ESC> Normal Mode".into(), - ], - command_help, - ] - .concat(), - InputMode::CommandPersistent => { - [vec!["<ESC/Ctrl-g> Normal Mode".into()], command_help].concat() +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct Help { + pub mode: InputMode, + pub mode_is_persistent: bool, + pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description> +} + +impl Default for InputMode { + fn default() -> InputMode { + InputMode::Normal + } +} + +pub fn get_help(input_state: &InputState) -> Help { + let mut keybinds: Vec<(String, String)> = vec![]; + match input_state.mode { + InputMode::Normal | InputMode::Command | InputMode::Exiting => { + keybinds.push((format!("p"), format!("Pane mode"))); + keybinds.push((format!("t"), format!("Tab mode"))); + keybinds.push((format!("r"), format!("Resize mode"))); } - InputMode::Exiting => vec!["Bye from Mosaic!".into()], + InputMode::Resize => { + keybinds.push((format!("←↓↑→"), format!("resize pane"))); + } + InputMode::Pane => { + keybinds.push((format!("←↓↑→"), format!("move focus"))); + keybinds.push((format!("p"), format!("next pane"))); + keybinds.push((format!("n"), format!("new pane"))); + keybinds.push((format!("d"), format!("down split"))); + keybinds.push((format!("r"), format!("right split"))); + keybinds.push((format!("x"), format!("exit pane"))); + keybinds.push((format!("f"), format!("fullscreen pane"))); + } + InputMode::Tab => { + keybinds.push((format!("←↓↑→"), format!("move tab focus"))); + keybinds.push((format!("n"), format!("new tab"))); + keybinds.push((format!("x"), format!("exit tab"))); + } + InputMode::Scroll => { + keybinds.push((format!("↓↑"), format!("scroll up/down"))); + } + } + keybinds.push((format!("ESC"), format!("Back"))); + keybinds.push((format!("q"), format!("Quit"))); + Help { + mode: input_state.mode, + mode_is_persistent: input_state.persistent, + keybinds, } } diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs index c8a87d51..d6ace68d 100644 --- a/src/common/input/keybinds.rs +++ b/src/common/input/keybinds.rs @@ -28,57 +28,101 @@ fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> { match *mode { InputMode::Normal => { - // Ctrl+G -> Command Mode defaults.insert(Key::Ctrl('g'), Action::SwitchToMode(InputMode::Command)); } - command_mode @ InputMode::Command | command_mode @ InputMode::CommandPersistent => { - match command_mode { - InputMode::Command => { - // Ctrl+G -> Command Mode (Persistent) - defaults.insert( - Key::Ctrl('g'), - Action::SwitchToMode(InputMode::CommandPersistent), - ); - } - InputMode::CommandPersistent => { - // Ctrl+G -> Command Mode (Persistent) - defaults.insert(Key::Ctrl('g'), Action::SwitchToMode(InputMode::Normal)); - } - _ => unreachable!(), - } - // Esc -> Normal Mode + InputMode::Command => { + defaults.insert(Key::Char('r'), Action::SwitchToMode(InputMode::Resize)); + defaults.insert(Key::Char('p'), Action::SwitchToMode(InputMode::Pane)); + defaults.insert(Key::Char('t'), Action::SwitchToMode(InputMode::Tab)); + defaults.insert(Key::Char('s'), Action::SwitchToMode(InputMode::Scroll)); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); - // Resize commands + defaults.insert(Key::Char('q'), Action::Quit); + } + InputMode::Resize => { + defaults.insert(Key::Char('h'), Action::Resize(Direction::Left)); defaults.insert(Key::Char('j'), Action::Resize(Direction::Down)); defaults.insert(Key::Char('k'), Action::Resize(Direction::Up)); - defaults.insert(Key::Char('h'), Action::Resize(Direction::Left)); defaults.insert(Key::Char('l'), Action::Resize(Direction::Right)); - // Move pane commands - defaults.insert(Key::Char('u'), Action::MoveFocus(Direction::Down)); - defaults.insert(Key::Char('i'), Action::MoveFocus(Direction::Up)); - defaults.insert(Key::Char('y'), Action::MoveFocus(Direction::Left)); - defaults.insert(Key::Char('o'), Action::MoveFocus(Direction::Right)); - // Switch focus - // @@@ Currently just tab through panes - use right for this + + defaults.insert(Key::Left, Action::Resize(Direction::Left)); + defaults.insert(Key::Down, Action::Resize(Direction::Down)); + defaults.insert(Key::Up, Action::Resize(Direction::Up)); + defaults.insert(Key::Right, Action::Resize(Direction::Right)); + + defaults.insert(Key::Ctrl('b'), Action::Resize(Direction::Left)); + defaults.insert(Key::Ctrl('n'), Action::Resize(Direction::Down)); + defaults.insert(Key::Ctrl('p'), Action::Resize(Direction::Up)); + defaults.insert(Key::Ctrl('f'), Action::Resize(Direction::Right)); + + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); + } + InputMode::Pane => { + defaults.insert(Key::Char('h'), Action::MoveFocus(Direction::Left)); + defaults.insert(Key::Char('j'), Action::MoveFocus(Direction::Down)); + defaults.insert(Key::Char('k'), Action::MoveFocus(Direction::Up)); + defaults.insert(Key::Char('l'), Action::MoveFocus(Direction::Right)); + + defaults.insert(Key::Left, Action::MoveFocus(Direction::Left)); + defaults.insert(Key::Down, Action::MoveFocus(Direction::Down)); + defaults.insert(Key::Up, Action::MoveFocus(Direction::Up)); + defaults.insert(Key::Right, Action::MoveFocus(Direction::Right)); + + defaults.insert(Key::Ctrl('b'), Action::MoveFocus(Direction::Left)); + defaults.insert(Key::Ctrl('n'), Action::MoveFocus(Direction::Down)); + defaults.insert(Key::Ctrl('p'), Action::MoveFocus(Direction::Up)); + defaults.insert(Key::Ctrl('f'), Action::MoveFocus(Direction::Right)); + defaults.insert(Key::Char('p'), Action::SwitchFocus(Direction::Right)); - // Scroll - defaults.insert(Key::PageUp, Action::ScrollUp); - defaults.insert(Key::PageDown, Action::ScrollDown); - // Tab controls - defaults.insert(Key::Char('1'), Action::NewTab); - defaults.insert(Key::Char('2'), Action::GoToNextTab); - defaults.insert(Key::Char('3'), Action::GoToPreviousTab); - defaults.insert(Key::Char('4'), Action::CloseTab); - // New pane - defaults.insert(Key::Char('z'), Action::NewPane(None)); - defaults.insert(Key::Char('b'), Action::NewPane(Some(Direction::Down))); - defaults.insert(Key::Char('n'), Action::NewPane(Some(Direction::Right))); - // Toggle focus fullscreen - defaults.insert(Key::Char('e'), Action::ToggleFocusFullscreen); - // Close pane + defaults.insert(Key::Char('n'), Action::NewPane(None)); + defaults.insert(Key::Char('d'), Action::NewPane(Some(Direction::Down))); + defaults.insert(Key::Char('r'), Action::NewPane(Some(Direction::Right))); defaults.insert(Key::Char('x'), Action::CloseFocus); - // Close Mosaic + + defaults.insert(Key::Char('f'), Action::ToggleFocusFullscreen); + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); + } + InputMode::Tab => { + defaults.insert(Key::Char('h'), Action::GoToPreviousTab); + defaults.insert(Key::Char('j'), Action::GoToNextTab); + defaults.insert(Key::Char('k'), Action::GoToPreviousTab); + defaults.insert(Key::Char('l'), Action::GoToNextTab); + + defaults.insert(Key::Left, Action::GoToPreviousTab); + defaults.insert(Key::Down, Action::GoToNextTab); + defaults.insert(Key::Up, Action::GoToPreviousTab); + defaults.insert(Key::Right, Action::GoToNextTab); + + defaults.insert(Key::Ctrl('b'), Action::GoToPreviousTab); + defaults.insert(Key::Ctrl('n'), Action::GoToNextTab); + defaults.insert(Key::Ctrl('p'), Action::GoToPreviousTab); + defaults.insert(Key::Ctrl('f'), Action::GoToNextTab); + + defaults.insert(Key::Char('n'), Action::NewTab); + defaults.insert(Key::Char('x'), Action::CloseTab); + + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); + } + InputMode::Scroll => { + defaults.insert(Key::Char('j'), Action::ScrollDown); + defaults.insert(Key::Char('k'), Action::ScrollUp); + + defaults.insert(Key::Down, Action::ScrollDown); + defaults.insert(Key::Up, Action::ScrollUp); + + defaults.insert(Key::Ctrl('n'), Action::ScrollDown); + defaults.insert(Key::Ctrl('p'), Action::ScrollUp); + + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); } InputMode::Exiting => {} } |
