summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2023-08-29 10:16:53 -0400
committerJeff Zhao <jeff.no.zhao@gmail.com>2023-08-29 10:16:53 -0400
commit31beaabe6b2cf4119aacae6c1722cdc1e5ba2f5b (patch)
tree095ec193999ac9ad3494a2abf039ff1dc7da00d2
parent40ab1b0125c86b6554f2a23d90053c805d7a857a (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.toml292
-rw-r--r--src/commands/numbered_command.rs7
-rw-r--r--src/commands/show_help.rs30
-rw-r--r--src/commands/show_tasks.rs22
-rw-r--r--src/config/keymap/keymapping.rs87
-rw-r--r--src/event/process_event.rs6
-rw-r--r--src/key_command/command_keybind.rs13
-rw-r--r--src/run.rs94
-rw-r--r--src/ui/widgets/tui_help.rs12
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, "..."),
}
}
diff --git a/src/run.rs b/src/run.rs
index d6b2466..764106e 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -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() {