diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2023-08-29 10:16:53 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2023-08-29 10:16:53 -0400 |
commit | 31beaabe6b2cf4119aacae6c1722cdc1e5ba2f5b (patch) | |
tree | 095ec193999ac9ad3494a2abf039ff1dc7da00d2 | |
parent | 40ab1b0125c86b6554f2a23d90053c805d7a857a (diff) |
command chaining support
- breaks existing keymap configs
-`command` field is renamed to `commands`
- now an array instead of a single string
-rw-r--r-- | config/keymap.toml | 292 | ||||
-rw-r--r-- | src/commands/numbered_command.rs | 7 | ||||
-rw-r--r-- | src/commands/show_help.rs | 30 | ||||
-rw-r--r-- | src/commands/show_tasks.rs | 22 | ||||
-rw-r--r-- | src/config/keymap/keymapping.rs | 87 | ||||
-rw-r--r-- | src/event/process_event.rs | 6 | ||||
-rw-r--r-- | src/key_command/command_keybind.rs | 13 | ||||
-rw-r--r-- | src/run.rs | 94 | ||||
-rw-r--r-- | src/ui/widgets/tui_help.rs | 12 |
9 files changed, 311 insertions, 252 deletions
diff --git a/config/keymap.toml b/config/keymap.toml index ca8bce4..b59ccb9 100644 --- a/config/keymap.toml +++ b/config/keymap.toml @@ -1,172 +1,172 @@ [default_view] keymap = [ - { keys = ["escape"], command = "escape" }, - { keys = ["ctrl+t"], command = "new_tab" }, - { keys = ["alt+t"], command = "new_tab --cursor" }, - { keys = ["T"], command = "new_tab --current" }, - { keys = ["W"], command = "close_tab" }, - { keys = ["ctrl+w"], command = "close_tab" }, - { keys = ["q"], command = "close_tab" }, - { keys = ["ctrl+c"], command = "quit" }, - { keys = ["Q"], command = "quit --output-current-directory" }, - - { keys = ["R"], command = "reload_dirlist" }, - { keys = ["z", "h"], command = "toggle_hidden" }, - { keys = ["ctrl+h"], command = "toggle_hidden" }, - { keys = ["\t"], command = "tab_switch 1" }, - { keys = ["backtab"], command = "tab_switch -1" }, - - { keys = ["alt+1"], command = "tab_switch_index 1" }, - { keys = ["alt+2"], command = "tab_switch_index 2" }, - { keys = ["alt+3"], command = "tab_switch_index 3" }, - { keys = ["alt+4"], command = "tab_switch_index 4" }, - { keys = ["alt+5"], command = "tab_switch_index 5" }, - - { keys = ["1"], command = "numbered_command 1" }, - { keys = ["2"], command = "numbered_command 2" }, - { keys = ["3"], command = "numbered_command 3" }, - { keys = ["4"], command = "numbered_command 4" }, - { keys = ["5"], command = "numbered_command 5" }, - { keys = ["6"], command = "numbered_command 6" }, - { keys = ["7"], command = "numbered_command 7" }, - { keys = ["8"], command = "numbered_command 8" }, - { keys = ["9"], command = "numbered_command 9" }, + { keys = ["escape"], commands = ["escape"] }, + { keys = ["ctrl+t"], commands = ["new_tab"] }, + { keys = ["alt+t"], commands = ["new_tab --cursor"] }, + { keys = ["T"], commands = ["new_tab --current"] }, + { keys = ["W"], commands = ["close_tab"] }, + { keys = ["ctrl+w"], commands = ["close_tab"] }, + { keys = ["q"], commands = ["close_tab"] }, + { keys = ["ctrl+c"], commands = ["quit"] }, + { keys = ["Q"], commands = ["quit --output-current-directory"] }, + + { keys = ["R"], commands = ["reload_dirlist"] }, + { keys = ["z", "h"], commands = ["toggle_hidden"] }, + { keys = ["ctrl+h"], commands = ["toggle_hidden"] }, + { keys = ["\t"], commands = ["tab_switch 1"] }, + { keys = ["backtab"], commands = ["tab_switch -1"] }, + + { keys = ["alt+1"], commands = ["tab_switch_index 1"] }, + { keys = ["alt+2"], commands = ["tab_switch_index 2"] }, + { keys = ["alt+3"], commands = ["tab_switch_index 3"] }, + { keys = ["alt+4"], commands = ["tab_switch_index 4"] }, + { keys = ["alt+5"], commands = ["tab_switch_index 5"] }, + + { keys = ["1"], commands = ["numbered_command 1"] }, + { keys = ["2"], commands = ["numbered_command 2"] }, + { keys = ["3"], commands = ["numbered_command 3"] }, + { keys = ["4"], commands = ["numbered_command 4"] }, + { keys = ["5"], commands = ["numbered_command 5"] }, + { keys = ["6"], commands = ["numbered_command 6"] }, + { keys = ["7"], commands = ["numbered_command 7"] }, + { keys = ["8"], commands = ["numbered_command 8"] }, + { keys = ["9"], commands = ["numbered_command 9"] }, # arrow keys - { keys = ["arrow_up"], command = "cursor_move_up" }, - { keys = ["arrow_down"], command = "cursor_move_down" }, - { keys = ["arrow_left"], command = "cd .." }, - { keys = ["arrow_right"], command = "open" }, - { keys = ["\n"], command = "open" }, - { keys = ["home"], command = "cursor_move_home" }, - { keys = ["end"], command = "cursor_move_end" }, - { keys = ["page_up"], command = "cursor_move_page_up" }, - { keys = ["page_down"], command = "cursor_move_page_down" }, - { keys = ["ctrl+u"], command = "cursor_move_page_up 0.5" }, - { keys = ["ctrl+d"], command = "cursor_move_page_down 0.5" }, - { keys = ["ctrl+b"], command = "cursor_move_page_up" }, - { keys = ["ctrl+f"], command = "cursor_move_page_down" }, + { keys = ["arrow_up"], commands = ["cursor_move_up"] }, + { keys = ["arrow_down"], commands = ["cursor_move_down"] }, + { keys = ["arrow_left"], commands = ["cd .."] }, + { keys = ["arrow_right"], commands = ["open"] }, + { keys = ["\n"], commands = ["open"] }, + { keys = ["home"], commands = ["cursor_move_home"] }, + { keys = ["end"], commands = ["cursor_move_end"] }, + { keys = ["page_up"], commands = ["cursor_move_page_up"] }, + { keys = ["page_down"], commands = ["cursor_move_page_down"] }, + { keys = ["ctrl+u"], commands = ["cursor_move_page_up 0.5"] }, + { keys = ["ctrl+d"], commands = ["cursor_move_page_down 0.5"] }, + { keys = ["ctrl+b"], commands = ["cursor_move_page_up"] }, + { keys = ["ctrl+f"], commands = ["cursor_move_page_down"] }, # vim-like keybindings - { keys = ["j"], command = "cursor_move_down" }, - { keys = ["k"], command = "cursor_move_up" }, - { keys = ["h"], command = "cd .." }, - { keys = ["l"], command = "open" }, - { keys = ["g", "g"], command = "cursor_move_home" }, - { keys = ["G"], command = "cursor_move_end" }, - { keys = ["r"], command = "open_with" }, - - { keys = ["H"], command = "cursor_move_page_home" }, - { keys = ["L"], command = "cursor_move_page_middle" }, - { keys = ["M"], command = "cursor_move_page_end" }, - - { keys = ["["], command = "parent_cursor_move_up" }, - { keys = ["]"], command = "parent_cursor_move_down" }, - - { keys = ["c", "d"], command = ":cd " }, - { keys = ["d", "d"], command = "cut_files" }, - { keys = ["y", "y"], command = "copy_files" }, - { keys = ["y", "n"], command = "copy_filename" }, - { keys = ["y", "."], command = "copy_filename_without_extension" }, - { keys = ["y", "p"], command = "copy_filepath" }, - { keys = ["y", "a"], command = "copy_filepath --all-selected=true" }, - { keys = ["y", "d"], command = "copy_dirpath" }, - - { keys = ["p", "l"], command = "symlink_files --relative=false" }, - { keys = ["p", "L"], command = "symlink_files --relative=true" }, - - { keys = ["delete"], command = "delete_files" }, - { keys = ["d", "D"], command = "delete_files" }, - - { keys = ["p", "p"], command = "paste_files" }, - { keys = ["p", "o"], command = "paste_files --overwrite=true" }, - - { keys = ["a"], command = "rename_append" }, - { keys = ["A"], command = "rename_prepend" }, - - { keys = ["f", "t"], command = ":touch " }, - - { keys = [" "], command = "select --toggle=true" }, - { keys = ["t"], command = "select --all=true --toggle=true" }, - { keys = ["V"], command = "toggle_visual" }, - - { keys = ["w"], command = "show_tasks --exit-key=w" }, - { keys = ["b", "b"], command = "bulk_rename" }, - { keys = ["="], command = "set_mode" }, - - { keys = [":"], command = ":" }, - { keys = [";"], command = ":" }, - - { keys = ["'"], command = ":shell " }, - { keys = ["m", "k"], command = ":mkdir " }, - { keys = ["c", "w"], command = ":rename " }, - - { keys = ["/"], command = ":search " }, - { keys = ["|"], command = ":search_inc " }, - { keys = ["\\"], command = ":search_glob " }, - { keys = ["S"], command = "search_fzf" }, - { keys = ["C"], command = "subdir_fzf" }, - - { keys = ["n"], command = "search_next" }, - { keys = ["N"], command = "search_prev" }, - - { keys = ["s", "r"], command = "sort reverse" }, - { keys = ["s", "l"], command = "sort lexical" }, - { keys = ["s", "m"], command = "sort mtime" }, - { keys = ["s", "n"], command = "sort natural" }, - { keys = ["s", "s"], command = "sort size" }, - { keys = ["s", "e"], command = "sort ext" }, - - { keys = ["m", "s"], command = "linemode size" }, - { keys = ["m", "m"], command = "linemode mtime" }, - { keys = ["m", "M"], command = "linemode size | mtime" }, - { keys = ["m", "u"], command = "linemode user" }, - { keys = ["m", "U"], command = "linemode user | group" }, - { keys = ["m", "p"], command = "linemode perm" }, - - { keys = ["g", "r"], command = "cd /" }, - { keys = ["g", "c"], command = "cd ~/.config" }, - { keys = ["g", "d"], command = "cd ~/Downloads" }, - { keys = ["g", "e"], command = "cd /etc" }, - { keys = ["g", "h"], command = "cd ~/" }, - { keys = ["?"], command = "help" }, + { keys = ["j"], commands = ["cursor_move_down"] }, + { keys = ["k"], commands = ["cursor_move_up"] }, + { keys = ["h"], commands = ["cd .."] }, + { keys = ["l"], commands = ["open"] }, + { keys = ["g", "g"], commands = ["cursor_move_home"] }, + { keys = ["G"], commands = ["cursor_move_end"] }, + { keys = ["r"], commands = ["open_with"] }, + + { keys = ["H"], commands = ["cursor_move_page_home"] }, + { keys = ["L"], commands = ["cursor_move_page_middle"] }, + { keys = ["M"], commands = ["cursor_move_page_end"] }, + + { keys = ["["], commands = ["parent_cursor_move_up"] }, + { keys = ["]"], commands = ["parent_cursor_move_down"] }, + + { keys = ["c", "d"], commands = [":cd "] }, + { keys = ["d", "d"], commands = ["cut_files"] }, + { keys = ["y", "y"], commands = ["copy_files"] }, + { keys = ["y", "n"], commands = ["copy_filename"] }, + { keys = ["y", "."], commands = ["copy_filename_without_extension"] }, + { keys = ["y", "p"], commands = ["copy_filepath"] }, + { keys = ["y", "a"], commands = ["copy_filepath --all-selected=true"] }, + { keys = ["y", "d"], commands = ["copy_dirpath"] }, + + { keys = ["p", "l"], commands = ["symlink_files --relative=false"] }, + { keys = ["p", "L"], commands = ["symlink_files --relative=true"] }, + + { keys = ["delete"], commands = ["delete_files"] }, + { keys = ["d", "D"], commands = ["delete_files"] }, + + { keys = ["p", "p"], commands = ["paste_files"] }, + { keys = ["p", "o"], commands = ["paste_files --overwrite=true"] }, + + { keys = ["a"], commands = ["rename_append"] }, + { keys = ["A"], commands = ["rename_prepend"] }, + + { keys = ["f", "t"], commands = [":touch "] }, + + { keys = [" "], commands = ["select --toggle=true"] }, + { keys = ["t"], commands = ["select --all=true --toggle=true"] }, + { keys = ["V"], commands = ["toggle_visual"] }, + + { keys = ["w"], commands = ["show_tasks --exit-key=w"] }, + { keys = ["b", "b"], commands = ["bulk_rename"] }, + { keys = ["="], commands = ["set_mode"] }, + + { keys = [":"], commands = [":"] }, + { keys = [";"], commands = [":"] }, + + { keys = ["'"], commands = [":shell "] }, + { keys = ["m", "k"], commands = [":mkdir "] }, + { keys = ["c", "w"], commands = [":rename "] }, + + { keys = ["/"], commands = [":search "] }, + { keys = ["|"], commands = [":search_inc "] }, + { keys = ["\\"], commands = [":search_glob "] }, + { keys = ["S"], commands = ["search_fzf"] }, + { keys = ["C"], commands = ["subdir_fzf"] }, + + { keys = ["n"], commands = ["search_next"] }, + { keys = ["N"], commands = ["search_prev"] }, + + { keys = ["s", "r"], commands = ["sort reverse"] }, + { keys = ["s", "l"], commands = ["sort lexical"] }, + { keys = ["s", "m"], commands = ["sort mtime"] }, + { keys = ["s", "n"], commands = ["sort natural"] }, + { keys = ["s", "s"], commands = ["sort size"] }, + { keys = ["s", "e"], commands = ["sort ext"] }, + + { keys = ["m", "s"], commands = ["linemode size"] }, + { keys = ["m", "m"], commands = ["linemode mtime"] }, + { keys = ["m", "M"], commands = ["linemode size | mtime"] }, + { keys = ["m", "u"], commands = ["linemode user"] }, + { keys = ["m", "U"], commands = ["linemode user | group"] }, + { keys = ["m", "p"], commands = ["linemode perm"] }, + + { keys = ["g", "r"], commands = ["cd /"] }, + { keys = ["g", "c"], commands = ["cd ~/.config"] }, + { keys = ["g", "d"], commands = ["cd ~/Downloads"] }, + { keys = ["g", "e"], commands = ["cd /etc"] }, + { keys = ["g", "h"], commands = ["cd ~/"] }, + { keys = ["?"], commands = ["help"] }, ] [task_view] keymap = [ # arrow keys - { keys = ["arrow_up"], command = "cursor_move_up" }, - { keys = ["arrow_down"], command = "cursor_move_down" }, - { keys = ["home"], command = "cursor_move_home" }, - { keys = ["end"], command = "cursor_move_end" }, + { keys = ["arrow_up"], commands = ["cursor_move_up"] }, + { keys = ["arrow_down"], commands = ["cursor_move_down"] }, + { keys = ["home"], commands = ["cursor_move_home"] }, + { keys = ["end"], commands = ["cursor_move_end"] }, # vim-like keybindings - { keys = ["j"], command = "cursor_move_down" }, - { keys = ["k"], command = "cursor_move_up" }, - { keys = ["g", "g"], command = "cursor_move_home" }, - { keys = ["G"], command = "cursor_move_end" }, + { keys = ["j"], commands = ["cursor_move_down"] }, + { keys = ["k"], commands = ["cursor_move_up"] }, + { keys = ["g", "g"], commands = ["cursor_move_home"] }, + { keys = ["G"], commands = ["cursor_move_end"] }, - { keys = ["w"], command = "show_tasks" }, - { keys = ["escape"], command = "show_tasks" }, + { keys = ["w"], commands = ["show_tasks"] }, + { keys = ["escape"], commands = ["show_tasks"] }, ] [help_view] keymap = [ # arrow keys - { keys = ["arrow_up"], command = "cursor_move_up" }, - { keys = ["arrow_down"], command = "cursor_move_down" }, - { keys = ["home"], command = "cursor_move_home" }, - { keys = ["end"], command = "cursor_move_end" }, + { keys = ["arrow_up"], commands = ["cursor_move_up"] }, + { keys = ["arrow_down"], commands = ["cursor_move_down"] }, + { keys = ["home"], commands = ["cursor_move_home"] }, + { keys = ["end"], commands = ["cursor_move_end"] }, # vim-like keybindings - { keys = ["j"], command = "cursor_move_down" }, - { keys = ["k"], command = "cursor_move_up" }, - { keys = ["g", "g"], command = "cursor_move_home" }, - { keys = ["G"], command = "cursor_move_end" }, + { keys = ["j"], commands = ["cursor_move_down"] }, + { keys = ["k"], commands = ["cursor_move_up"] }, + { keys = ["g", "g"], commands = ["cursor_move_home"] }, + { keys = ["G"], commands = ["cursor_move_end"] }, - { keys = ["w"], command = "show_tasks" }, - { keys = ["escape"], command = "show_tasks" }, + { keys = ["w"], commands = ["show_tasks"] }, + { keys = ["escape"], commands = ["show_tasks"] }, ] diff --git a/src/commands/numbered_command.rs b/src/commands/numbered_command.rs index 266446a..b66e38c 100644 --- a/src/commands/numbered_command.rs +++ b/src/commands/numbered_command.rs @@ -52,8 +52,11 @@ pub fn numbered_command( prefix.push(c); } key => match keymap.default_view.get(&key) { - Some(CommandKeybind::SimpleKeybind { command, .. }) => { - return command.numbered_execute(num_prefix, context, backend, keymap); + Some(CommandKeybind::SimpleKeybind { commands, .. }) => { + for command in commands { + let _ = + command.numbered_execute(num_prefix, context, backend, keymap); + } } _ => { return Err(JoshutoError::new( diff --git a/src/commands/show_help.rs b/src/commands/show_help.rs index 6702efd..5d06105 100644 --- a/src/commands/show_help.rs +++ b/src/commands/show_help.rs @@ -48,18 +48,28 @@ pub fn help_loop( Event::Key(Key::Char('3')) => sort_by = 2, Event::Key(Key::Char('/')) => search_query.push('/'), event => { - if let Some(CommandKeybind::SimpleKeybind { command, .. }) = + if let Some(CommandKeybind::SimpleKeybind { commands, .. }) = keymap_t.help_view.get(&event) { - match command { - Command::CursorMoveUp { .. } => move_offset(&mut offset, -1), - Command::CursorMoveDown { .. } => move_offset(&mut offset, 1), - Command::CursorMoveHome => offset = 0, - Command::CursorMoveEnd => offset = 255, - Command::CursorMovePageUp(_) => move_offset(&mut offset, -10), - Command::CursorMovePageDown(_) => move_offset(&mut offset, 10), - Command::CloseTab | Command::Help => break, - _ => (), + for command in commands { + match command { + Command::CursorMoveUp { .. } => { + move_offset(&mut offset, -1) + } + Command::CursorMoveDown { .. } => { + move_offset(&mut offset, 1) + } + Command::CursorMoveHome => offset = 0, + Command::CursorMoveEnd => offset = 255, + Command::CursorMovePageUp(_) => { + move_offset(&mut offset, -10) + } + Command::CursorMovePageDown(_) => { + move_offset(&mut offset, 10) + } + Command::CloseTab | Command::Help => break, + _ => (), + } } } } diff --git a/src/commands/show_tasks.rs b/src/commands/show_tasks.rs index e05edac..4f70d7c 100644 --- a/src/commands/show_tasks.rs +++ b/src/commands/show_tasks.rs @@ -15,7 +15,9 @@ pub fn show_tasks( ) -> JoshutoResult { context.flush_event(); - loop { + let mut exit = false; + + while !exit { backend.render(TuiWorkerView::new(context)); if let Ok(event) = context.poll_event() { @@ -28,17 +30,23 @@ pub fn show_tasks( .message_queue_mut() .push_info(format!("Unmapped input: {}", key.to_string())); } - Some(CommandKeybind::SimpleKeybind { command, .. }) => { - if let Command::ShowTasks = command { - break; + Some(CommandKeybind::SimpleKeybind { commands, .. }) => { + for command in commands { + if let Command::ShowTasks = command { + exit = true; + } } } Some(CommandKeybind::CompositeKeybind(m)) => { - let cmd = + let commands = process_event::poll_event_until_simple_keybind(backend, context, m); - if let Some(Command::ShowTasks) = cmd { - break; + if let Some(commands) = commands { + for command in commands { + if let Command::ShowTasks = command { + exit = true; + } + } } } } diff --git a/src/config/keymap/keymapping.rs b/src/config/keymap/keymapping.rs index 0b3e122..33c7407 100644 --- a/src/config/keymap/keymapping.rs +++ b/src/config/keymap/keymapping.rs @@ -8,7 +8,7 @@ use termion::event::Event; use crate::config::{parse_config_or_default, TomlConfigFile}; use crate::error::JoshutoResult; -use crate::key_command::{AppCommand, Command, CommandKeybind}; +use crate::key_command::{Command, CommandKeybind}; use crate::traits::ToString; use crate::util::keyparse::str_to_event; @@ -20,9 +20,9 @@ enum KeymapError { #[derive(Clone, Debug, Deserialize)] struct CommandKeymap { - pub command: String, - pub description: Option<String>, pub keys: Vec<String>, + pub commands: Vec<String>, + pub description: Option<String>, } #[derive(Clone, Debug, Deserialize)] @@ -63,38 +63,53 @@ impl AppKeyMapping { } } -fn vec_to_map(vec: &[CommandKeymap]) -> HashMap<Event, CommandKeybind> { +fn command_keymaps_vec_to_map(keymaps: &[CommandKeymap]) -> HashMap<Event, CommandKeybind> { let mut hashmap = HashMap::new(); - for m in vec { - match Command::from_str(m.command.as_str()) { - Ok(command) => { - let events: Vec<Event> = m - .keys - .iter() - .filter_map(|s| str_to_event(s.as_str())) - .collect(); - - if events.len() != m.keys.len() { - eprintln!("Failed to parse events: {:?}", m.keys); - continue; + for keymap in keymaps { + if keymap.commands.is_empty() { + eprintln!("Keymap `commands` cannot be empty"); + continue; + } + let commands: Vec<Command> = keymap + .commands + .iter() + .filter_map(|cmd_str| match Command::from_str(cmd_str) { + Ok(s) => Some(s), + Err(err) => { + eprintln!("Keymap error: {}", err); + None } + }) + .collect(); + + if commands.len() != keymap.commands.len() { + eprintln!("Failed to parse commands: {:?}", keymap.commands); + continue; + } + + let key_events: Vec<Event> = keymap + .keys + .iter() + .filter_map(|s| str_to_event(s.as_str())) + .collect(); + + if key_events.len() != keymap.keys.len() { + eprintln!("Failed to parse keys: {:?}", keymap.keys); + continue; + } - let command_str = command.command(); - let command_description = m.description.to_owned(); - let result = insert_keycommand(&mut hashmap, command, command_description, &events); - match result { - Ok(_) => {} - Err(e) => match e { - KeymapError::Conflict => { - let events_str: Vec<String> = - events.iter().map(|e| e.to_string()).collect(); - eprintln!("Error: Ambiguous Keymapping: Multiple commands mapped to key sequence {:?} {}", events_str, command_str); - } - }, + let command_description = keymap.description.to_owned(); + if let Err(err) = + insert_keycommand(&mut hashmap, commands, command_description, &key_events) + { + match err { + KeymapError::Conflict => { + let events_str: Vec<String> = + key_events.iter().map(|e| e.to_string()).collect(); + eprintln!("Error: Ambiguous Keymapping: Multiple commands mapped to key sequence {:?} {:?}", events_str, keymap.commands); } } - Err(e) => eprintln!("Keymap error: {}", e), } } hashmap @@ -103,9 +118,9 @@ fn vec_to_map(vec: &[CommandKeymap]) -> HashMap<Event, CommandKeybind> { impl From<AppKeyMappingRaw> for AppKeyMapping { fn from(raw: AppKeyMappingRaw) -> Self { let mut keymaps = Self::new(); - keymaps.default_view = vec_to_map(&raw.default_view.keymap); - keymaps.task_view = vec_to_map(&raw.task_view.keymap); - keymaps.help_view = vec_to_map(&raw.help_view.keymap); + keymaps.default_view = command_keymaps_vec_to_map(&raw.default_view.keymap); + keymaps.task_view = command_keymaps_vec_to_map(&raw.task_view.keymap); + keymaps.help_view = command_keymaps_vec_to_map(&raw.help_view.keymap); keymaps } } @@ -126,7 +141,7 @@ impl std::default::Default for AppKeyMapping { fn insert_keycommand( keymap: &mut KeyMapping, - keycommand: Command, + commands: Vec<Command>, description: Option<String>, events: &[Event], ) -> Result<(), KeymapError> { @@ -140,7 +155,7 @@ fn insert_keycommand( match keymap.entry(event) { Entry::Occupied(_) => return Err(KeymapError::Conflict), Entry::Vacant(entry) => entry.insert(CommandKeybind::SimpleKeybind { - command: keycommand, + commands, description, }), }; @@ -150,13 +165,13 @@ fn insert_keycommand( match keymap.entry(event) { Entry::Occupied(mut entry) => match entry.get_mut() { CommandKeybind::CompositeKeybind(ref mut m) => { - insert_keycommand(m, keycommand, description, &events[1..]) + insert_keycommand(m, commands, description, &events[1..]) } _ => Err(KeymapError::Conflict), }, Entry::Vacant(entry) => { let mut new_map = KeyMapping::new(); - let result = insert_keycommand(&mut new_map, keycommand, description, &events[1..]); + let result = insert_keycommand(&mut new_map, commands, description, &events[1..]); if result.is_ok() { let composite_command = CommandKeybind::CompositeKeybind(new_map); entry.insert(composite_command); diff --git a/src/event/process_event.rs b/src/event/process_event.rs index b7126bf..c1c9663 100644 --- a/src/event/process_event.rs +++ b/src/event/process_event.rs @@ -26,7 +26,7 @@ pub fn poll_event_until_simple_keybind<'a>( backend: &mut ui::AppBackend, context: &mut AppContext, keymap: &'a KeyMapping, -) -> Option<&'a Command> { +) -> Option<&'a Vec<Command>> { let mut keymap = keymap; context.flush_event(); @@ -40,8 +40,8 @@ pub fn poll_event_until_simple_keybind<'a>( match event { Event::Key(Key::Esc) => return None, event => match keymap.get(&event) { - Some(CommandKeybind::SimpleKeybind { command, .. }) => { - return Some(command); + Some(CommandKeybind::SimpleKeybind { commands, .. }) => { + return Some(commands); } Some(CommandKeybind::CompositeKeybind(m)) => { keymap = m; diff --git a/src/key_command/command_keybind.rs b/src/key_command/command_keybind.rs index 97e5de3..522458b 100644 --- a/src/key_command/command_keybind.rs +++ b/src/key_command/command_keybind.rs @@ -4,7 +4,7 @@ use crate::key_command::Command; #[derive(Debug)] pub enum CommandKeybind { SimpleKeybind { - command: Command, + commands: Vec<Command>, description: Option<String>, }, CompositeKeybind(KeyMapping), @@ -14,13 +14,18 @@ impl std::fmt::Display for CommandKeybind { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { CommandKeybind::SimpleKeybind { - command: _, + commands: _, description: Some(desc), } => write!(f, "{}", desc), CommandKeybind::SimpleKeybind { - command: cmd, + commands, description: None, - } => write!(f, "{}", cmd), + } => { + for cmd in commands { + write!(f, "{}, ", cmd)?; + } + Ok(()) + } CommandKeybind::CompositeKeybind(_) => write!(f, "..."), } } @@ -10,6 +10,7 @@ use crate::traits::ToString; use crate::ui; use crate::ui::views; use crate::ui::views::TuiView; +use crate::ui::AppBackend; use uuid::Uuid; @@ -61,57 +62,74 @@ pub fn run_loop( Err(_) => return Ok(()), // TODO }; - // handle the event - match event { - AppEvent::Termion(Event::Mouse(event)) => { - process_event::process_mouse(event, context, backend, &keymap_t); - preview_default::load_preview(context, backend); + // update the file system supervisor that watches for changes in the FS + if context.config_ref().watch_files { + context.update_watcher(); + } + + // process user input + process_input(context, backend, &keymap_t, event); + } // end of main loop + Ok(()) +} + +#[inline] +fn process_input( + context: &mut AppContext, + backend: &mut AppBackend, + keymap_t: &AppKeyMapping, + event: AppEvent, +) { + // handle the event + match event { + AppEvent::Termion(Event::Mouse(event)) => { + process_event::process_mouse(event, context, backend, keymap_t); + preview_default::load_preview(context, backend); + } + AppEvent::Termion(key) => { + if context.message_queue_ref().current_message().is_some() { + context.message_queue_mut().pop_front(); } - AppEvent::Termion(key) => { - if context.message_queue_ref().current_message().is_some() { - context.message_queue_mut().pop_front(); + match key { + // in the event where mouse input is not supported + // but we still want to register scroll + Event::Unsupported(s) => { + process_event::process_unsupported(context, backend, keymap_t, s); } - match key { - // in the event where mouse input is not supported - // but we still want to register scroll - Event::Unsupported(s) => { - process_event::process_unsupported(context, backend, &keymap_t, s); + key => match keymap_t.default_view.get(&key) { + None => { + context + .message_queue_mut() + .push_info(format!("Unmapped input: {}", key.to_string())); } - key => match keymap_t.default_view.get(&key) { - None => { - context - .message_queue_mut() - .push_info(format!("Unmapped input: {}", key.to_string())); - } - Some(CommandKeybind::SimpleKeybind { command, .. }) => { - if let Err(e) = command.execute(context, backend, &keymap_t) { + Some(CommandKeybind::SimpleKeybind { commands, .. }) => { + for command in commands { + if let Err(e) = command.execute(context, backend, keymap_t) { context.message_queue_mut().push_error(e.to_string()); + break; } } - Some(CommandKeybind::CompositeKeybind(m)) => { - let cmd = - process_event::poll_event_until_simple_keybind(backend, context, m); + } + Some(CommandKeybind::CompositeKeybind(m)) => { + let commands = + process_event::poll_event_until_simple_keybind(backend, context, m); - if let Some(command) = cmd { - if let Err(e) = command.execute(context, backend, &keymap_t) { + if let Some(commands) = commands { + for command in commands { + if let Err(e) = command.execute(context, backend, keymap_t) { context.message_queue_mut().push_error(e.to_string()); + break; } } } - }, - } - preview_default::load_preview(context, backend); - context.flush_event(); + } + }, } - event => process_event::process_noninteractive(event, context), + preview_default::load_preview(context, backend); + context.flush_event(); } - - // update the file system supervisor that watches for changes in the FS - if context.config_ref().watch_files { - context.update_watcher(); - } - } // end of main loop - Ok(()) + event => process_event::process_noninteractive(event, context), + } } fn calculate_ui_context(context: &mut AppContext, area: Rect) { diff --git a/src/ui/widgets/tui_help.rs b/src/ui/widgets/tui_help.rs index 84f0c3d..7e5f5f2 100644 --- a/src/ui/widgets/tui_help.rs +++ b/src/ui/widgets/tui_help.rs @@ -125,13 +125,13 @@ pub fn get_raw_keymap_table<'a>( let key = key_event_to_string(event); let (command, comment) = match bind { CommandKeybind::SimpleKeybind { - command, - description: None, - } => (format!("{}", command), command.comment()), - CommandKeybind::SimpleKeybind { - command, + commands, description: Some(desc), - } => (format!("{}", command), desc.as_str()), + } => (format!("{}", commands[0]), desc.as_str()), + CommandKeybind::SimpleKeybind { + commands, + description: None, + } => (format!("{}", commands[0]), commands[0].comment()), CommandKeybind::CompositeKeybind(sub_keymap) => { let mut sub_rows = get_raw_keymap_table(sub_keymap, "", sort_by); for _ in 0..sub_rows.len() { |