aboutsummaryrefslogtreecommitdiffstats
path: root/default-plugins/session-manager
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-05-27 16:15:09 +0200
committerGitHub <noreply@github.com>2024-05-27 16:15:09 +0200
commit62c37a87cca5aaa8b0e580b973b93513ed616dba (patch)
tree5836dba1572dd4e95cc6e312f82b1ad4f263957e /default-plugins/session-manager
parentdocs(changelog): ooo plugin events fix (diff)
downloadsl0ppij-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.rs407
-rw-r--r--default-plugins/session-manager/src/new_session_info.rs17
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();
},
_ => {},