diff options
| author | Aram Drevekenin <aram@poor.dev> | 2024-05-27 16:15:09 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-27 16:15:09 +0200 |
| commit | 62c37a87cca5aaa8b0e580b973b93513ed616dba (patch) | |
| tree | 5836dba1572dd4e95cc6e312f82b1ad4f263957e /default-plugins/session-manager | |
| parent | docs(changelog): ooo plugin events fix (diff) | |
| download | sl0ppij-62c37a87cca5aaa8b0e580b973b93513ed616dba.tar.gz sl0ppij-62c37a87cca5aaa8b0e580b973b93513ed616dba.tar.xz sl0ppij-62c37a87cca5aaa8b0e580b973b93513ed616dba.zip | |
feat(keybindings): support multiple modifiers (eg. Ctrl+Alt) and the kitty keyboard protocol (#3383)
* parse kitty keys from STDIN
* work
* work
* replace internal Key representation with the new KeyWithModifier in all the places
* work
* work
* allow disabling with config
* adjust ordering
* handle enabling/disabling properly on the client
* support multiple modifiers without kitty too
* normalize uppercase keys
* get tests to pass
* various cleanups
* style(fmt): rustfmt
Diffstat (limited to 'default-plugins/session-manager')
| -rw-r--r-- | default-plugins/session-manager/src/main.rs | 407 | ||||
| -rw-r--r-- | default-plugins/session-manager/src/new_session_info.rs | 17 |
2 files changed, 238 insertions, 186 deletions
diff --git a/default-plugins/session-manager/src/main.rs b/default-plugins/session-manager/src/main.rs index 9f37a34a..05a33286 100644 --- a/default-plugins/session-manager/src/main.rs +++ b/default-plugins/session-manager/src/main.rs @@ -175,7 +175,7 @@ impl State { fn reset_selected_index(&mut self) { self.sessions.reset_selected_index(); } - fn handle_key(&mut self, key: Key) -> bool { + fn handle_key(&mut self, key: KeyWithModifier) -> bool { if self.error.is_some() { self.error = None; return true; @@ -186,197 +186,246 @@ impl State { ActiveScreen::ResurrectSession => self.handle_resurrect_session_key(key), } } - fn handle_new_session_key(&mut self, key: Key) -> bool { + fn handle_new_session_key(&mut self, key: KeyWithModifier) -> bool { let mut should_render = false; - if let Key::Down = key { - self.new_session_info.handle_key(key); - should_render = true; - } else if let Key::Up = key { - self.new_session_info.handle_key(key); - should_render = true; - } else if let Key::Char(character) = key { - if character == '\n' { - self.handle_selection(); - } else { + match key.bare_key { + BareKey::Down if key.has_no_modifiers() => { self.new_session_info.handle_key(key); - } - should_render = true; - } else if let Key::Backspace = key { - self.new_session_info.handle_key(key); - should_render = true; - } else if let Key::Ctrl('w') = key { - self.active_screen = ActiveScreen::NewSession; - should_render = true; - } else if let Key::BackTab = key { - self.toggle_active_screen(); - should_render = true; - } else if let Key::Ctrl('f') = key { - let request_id = Uuid::new_v4(); - let mut config = BTreeMap::new(); - let mut args = BTreeMap::new(); - self.request_ids.push(request_id.to_string()); - // we insert this into the config so that a new plugin will be opened (the plugin's - // uniqueness is determined by its name/url as well as its config) - config.insert("request_id".to_owned(), request_id.to_string()); - // we also insert this into the args so that the plugin will have an easier access to - // it - args.insert("request_id".to_owned(), request_id.to_string()); - pipe_message_to_plugin( - MessageToPlugin::new("filepicker") - .with_plugin_url("filepicker") - .with_plugin_config(config) - .new_plugin_instance_should_have_pane_title( - "Select folder for the new session...", - ) - .with_args(args), - ); - should_render = true; - } else if let Key::Ctrl('c') = key { - self.new_session_info.new_session_folder = None; - should_render = true; - } else if let Key::Esc = key { - self.new_session_info.handle_key(key); - should_render = true; + should_render = true; + }, + BareKey::Up if key.has_no_modifiers() => { + self.new_session_info.handle_key(key); + should_render = true; + }, + BareKey::Char(character) if key.has_no_modifiers() => { + if character == '\n' { + self.handle_selection(); + } else { + self.new_session_info.handle_key(key); + } + should_render = true; + }, + BareKey::Backspace if key.has_no_modifiers() => { + self.new_session_info.handle_key(key); + should_render = true; + }, + BareKey::Char('w') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.active_screen = ActiveScreen::NewSession; + should_render = true; + }, + BareKey::Tab if key.has_no_modifiers() => { + self.toggle_active_screen(); + should_render = true; + }, + BareKey::Char('f') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + let request_id = Uuid::new_v4(); + let mut config = BTreeMap::new(); + let mut args = BTreeMap::new(); + self.request_ids.push(request_id.to_string()); + // we insert this into the config so that a new plugin will be opened (the plugin's + // uniqueness is determined by its name/url as well as its config) + config.insert("request_id".to_owned(), request_id.to_string()); + // we also insert this into the args so that the plugin will have an easier access to + // it + args.insert("request_id".to_owned(), request_id.to_string()); + pipe_message_to_plugin( + MessageToPlugin::new("filepicker") + .with_plugin_url("filepicker") + .with_plugin_config(config) + .new_plugin_instance_should_have_pane_title( + "Select folder for the new session...", + ) + .with_args(args), + ); + should_render = true; + }, + BareKey::Char('c') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.new_session_info.new_session_folder = None; + should_render = true; + }, + BareKey::Esc if key.has_no_modifiers() => { + self.new_session_info.handle_key(key); + should_render = true; + }, + _ => {}, } should_render } - fn handle_attach_to_session(&mut self, key: Key) -> bool { + fn handle_attach_to_session(&mut self, key: KeyWithModifier) -> bool { let mut should_render = false; if self.show_kill_all_sessions_warning { - if let Key::Char('y') = key { - let all_other_sessions = self.sessions.all_other_sessions(); - kill_sessions(&all_other_sessions); - self.reset_selected_index(); - self.search_term.clear(); - self.sessions - .update_search_term(&self.search_term, &self.colors); - self.show_kill_all_sessions_warning = false - } else if let Key::Char('n') | Key::Esc | Key::Ctrl('c') = key { - self.show_kill_all_sessions_warning = false - } - should_render = true; - } else if let Key::Right = key { - self.sessions.result_expand(); - should_render = true; - } else if let Key::Left = key { - self.sessions.result_shrink(); - should_render = true; - } else if let Key::Down = key { - self.sessions.move_selection_down(); - should_render = true; - } else if let Key::Up = key { - self.sessions.move_selection_up(); - should_render = true; - } else if let Key::Char(character) = key { - if character == '\n' { - self.handle_selection(); - } else if let Some(new_session_name) = self.renaming_session_name.as_mut() { - new_session_name.push(character); - } else { - self.search_term.push(character); - self.sessions - .update_search_term(&self.search_term, &self.colors); - } - should_render = true; - } else if let Key::Backspace = key { - if let Some(new_session_name) = self.renaming_session_name.as_mut() { - if new_session_name.is_empty() { - self.renaming_session_name = None; - } else { - new_session_name.pop(); - } - } else { - self.search_term.pop(); - self.sessions - .update_search_term(&self.search_term, &self.colors); - } - should_render = true; - } else if let Key::Ctrl('w') = key { - self.active_screen = ActiveScreen::NewSession; - should_render = true; - } else if let Key::Ctrl('r') = key { - self.renaming_session_name = Some(String::new()); - should_render = true; - } else if let Key::Delete = key { - if let Some(selected_session_name) = self.sessions.get_selected_session_name() { - kill_sessions(&[selected_session_name]); - self.reset_selected_index(); - self.search_term.clear(); - self.sessions - .update_search_term(&self.search_term, &self.colors); - } else { - self.show_error("Must select session before killing it."); - } - should_render = true; - } else if let Key::Ctrl('d') = key { - let all_other_sessions = self.sessions.all_other_sessions(); - if all_other_sessions.is_empty() { - self.show_error("No other sessions to kill. Quit to kill the current one."); - } else { - self.show_kill_all_sessions_warning = true; - } - should_render = true; - } else if let Key::Ctrl('x') = key { - disconnect_other_clients(); - } else if let Key::Ctrl('c') = key { - if !self.search_term.is_empty() { - self.search_term.clear(); - self.sessions - .update_search_term(&self.search_term, &self.colors); - self.reset_selected_index(); - } else if !self.is_welcome_screen { - self.reset_selected_index(); - hide_self(); + match key.bare_key { + BareKey::Char('y') if key.has_no_modifiers() => { + let all_other_sessions = self.sessions.all_other_sessions(); + kill_sessions(&all_other_sessions); + self.reset_selected_index(); + self.search_term.clear(); + self.sessions + .update_search_term(&self.search_term, &self.colors); + self.show_kill_all_sessions_warning = false; + should_render = true; + }, + BareKey::Char('n') | BareKey::Esc if key.has_no_modifiers() => { + self.show_kill_all_sessions_warning = false; + should_render = true; + }, + BareKey::Char('c') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.show_kill_all_sessions_warning = false; + should_render = true; + }, + _ => {}, } - should_render = true; - } else if let Key::BackTab = key { - self.toggle_active_screen(); - should_render = true; - } else if let Key::Esc = key { - if self.renaming_session_name.is_some() { - self.renaming_session_name = None; - should_render = true; - } else if !self.is_welcome_screen { - hide_self(); + } else { + match key.bare_key { + BareKey::Right if key.has_no_modifiers() => { + self.sessions.result_expand(); + should_render = true; + }, + BareKey::Left if key.has_no_modifiers() => { + self.sessions.result_shrink(); + should_render = true; + }, + BareKey::Down if key.has_no_modifiers() => { + self.sessions.move_selection_down(); + should_render = true; + }, + BareKey::Up if key.has_no_modifiers() => { + self.sessions.move_selection_up(); + should_render = true; + }, + BareKey::Char(character) if key.has_no_modifiers() => { + if character == '\n' { + self.handle_selection(); + } else if let Some(new_session_name) = self.renaming_session_name.as_mut() { + new_session_name.push(character); + } else { + self.search_term.push(character); + self.sessions + .update_search_term(&self.search_term, &self.colors); + } + should_render = true; + }, + BareKey::Backspace if key.has_no_modifiers() => { + if let Some(new_session_name) = self.renaming_session_name.as_mut() { + if new_session_name.is_empty() { + self.renaming_session_name = None; + } else { + new_session_name.pop(); + } + } else { + self.search_term.pop(); + self.sessions + .update_search_term(&self.search_term, &self.colors); + } + should_render = true; + }, + BareKey::Char('w') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.active_screen = ActiveScreen::NewSession; + should_render = true; + }, + BareKey::Char('r') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.renaming_session_name = Some(String::new()); + should_render = true; + }, + BareKey::Delete if key.has_no_modifiers() => { + if let Some(selected_session_name) = self.sessions.get_selected_session_name() { + kill_sessions(&[selected_session_name]); + self.reset_selected_index(); + self.search_term.clear(); + self.sessions + .update_search_term(&self.search_term, &self.colors); + } else { + self.show_error("Must select session before killing it."); + } + should_render = true; + }, + BareKey::Char('d') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + let all_other_sessions = self.sessions.all_other_sessions(); + if all_other_sessions.is_empty() { + self.show_error("No other sessions to kill. Quit to kill the current one."); + } else { + self.show_kill_all_sessions_warning = true; + } + should_render = true; + }, + BareKey::Char('x') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + disconnect_other_clients() + }, + BareKey::Char('c') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + if !self.search_term.is_empty() { + self.search_term.clear(); + self.sessions + .update_search_term(&self.search_term, &self.colors); + self.reset_selected_index(); + } else if !self.is_welcome_screen { + self.reset_selected_index(); + hide_self(); + } + should_render = true; + }, + BareKey::Tab if key.has_no_modifiers() => { + self.toggle_active_screen(); + should_render = true; + }, + BareKey::Esc if key.has_no_modifiers() => { + if self.renaming_session_name.is_some() { + self.renaming_session_name = None; + should_render = true; + } else if !self.is_welcome_screen { + hide_self(); + } + }, + _ => {}, } } should_render } - fn handle_resurrect_session_key(&mut self, key: Key) -> bool { + fn handle_resurrect_session_key(&mut self, key: KeyWithModifier) -> bool { let mut should_render = false; - if let Key::Down = key { - self.resurrectable_sessions.move_selection_down(); - should_render = true; - } else if let Key::Up = key { - self.resurrectable_sessions.move_selection_up(); - should_render = true; - } else if let Key::Char(character) = key { - if character == '\n' { - self.handle_selection(); - } else { - self.resurrectable_sessions.handle_character(character); - } - should_render = true; - } else if let Key::Backspace = key { - self.resurrectable_sessions.handle_backspace(); - should_render = true; - } else if let Key::Ctrl('w') = key { - self.active_screen = ActiveScreen::NewSession; - should_render = true; - } else if let Key::BackTab = key { - self.toggle_active_screen(); - should_render = true; - } else if let Key::Delete = key { - self.resurrectable_sessions.delete_selected_session(); - should_render = true; - } else if let Key::Ctrl('d') = key { - self.resurrectable_sessions - .show_delete_all_sessions_warning(); - should_render = true; - } else if let Key::Esc = key { - if !self.is_welcome_screen { - hide_self(); - } + match key.bare_key { + BareKey::Down if key.has_no_modifiers() => { + self.resurrectable_sessions.move_selection_down(); + should_render = true; + }, + BareKey::Up if key.has_no_modifiers() => { + self.resurrectable_sessions.move_selection_up(); + should_render = true; + }, + BareKey::Char(character) if key.has_no_modifiers() => { + if character == '\n' { + self.handle_selection(); + } else { + self.resurrectable_sessions.handle_character(character); + } + should_render = true; + }, + BareKey::Backspace if key.has_no_modifiers() => { + self.resurrectable_sessions.handle_backspace(); + should_render = true; + }, + BareKey::Char('w') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.active_screen = ActiveScreen::NewSession; + should_render = true; + }, + BareKey::Tab if key.has_no_modifiers() => { + self.toggle_active_screen(); + should_render = true; + }, + BareKey::Delete if key.has_no_modifiers() => { + self.resurrectable_sessions.delete_selected_session(); + should_render = true; + }, + BareKey::Char('d') if key.has_modifiers(&[KeyModifier::Ctrl]) => { + self.resurrectable_sessions + .show_delete_all_sessions_warning(); + should_render = true; + }, + BareKey::Esc if key.has_no_modifiers() => { + if !self.is_welcome_screen { + hide_self(); + } + }, + _ => {}, } should_render } diff --git a/default-plugins/session-manager/src/new_session_info.rs b/default-plugins/session-manager/src/new_session_info.rs index 3527b7dc..a6ff7901 100644 --- a/default-plugins/session-manager/src/new_session_info.rs +++ b/default-plugins/session-manager/src/new_session_info.rs @@ -70,21 +70,24 @@ impl NewSessionInfo { }, } } - pub fn handle_key(&mut self, key: Key) { - match key { - Key::Backspace => { + pub fn handle_key(&mut self, key: KeyWithModifier) { + match key.bare_key { + BareKey::Backspace if key.has_no_modifiers() => { self.handle_backspace(); }, - Key::Ctrl('c') | Key::Esc => { + BareKey::Char('c') if key.has_modifiers(&[KeyModifier::Ctrl]) => { self.handle_break(); }, - Key::Char(character) => { + BareKey::Esc if key.has_no_modifiers() => { + self.handle_break(); + }, + BareKey::Char(character) if key.has_no_modifiers() => { self.add_char(character); }, - Key::Up => { + BareKey::Up if key.has_no_modifiers() => { self.move_selection_up(); }, - Key::Down => { + BareKey::Down if key.has_no_modifiers() => { self.move_selection_down(); }, _ => {}, |
