diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-06-17 14:41:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-17 14:41:49 +0200 |
commit | 63e3a1eae2e727a808084d9fe9ff6eca7816ef7e (patch) | |
tree | 445840cba9b3193eca8d5fc73e9cffa610f510ca | |
parent | 044519f53740d02b6feabe379bc618a1ce5c4ec2 (diff) |
feat(plugins): more plugin api methods (#2550)
* feat(plugins): close, focus, rename pane, rename tab and show_self api methods
* style(fmt): rustfmt
19 files changed, 994 insertions, 1 deletions
diff --git a/default-plugins/fixture-plugin-for-tests/src/main.rs b/default-plugins/fixture-plugin-for-tests/src/main.rs index 2107137d1..9ce45f8af 100644 --- a/default-plugins/fixture-plugin-for-tests/src/main.rs +++ b/default-plugins/fixture-plugin-for-tests/src/main.rs @@ -183,6 +183,33 @@ impl ZellijPlugin for State { Key::Ctrl('p') => { hide_self(); }, + Key::Ctrl('q') => { + let should_float_if_hidden = false; + show_self(should_float_if_hidden); + }, + Key::Ctrl('r') => { + close_terminal_pane(1); + }, + Key::Ctrl('s') => { + close_plugin_pane(1); + }, + Key::Ctrl('t') => { + let should_float_if_hidden = false; + focus_terminal_pane(1, should_float_if_hidden); + }, + Key::Ctrl('u') => { + let should_float_if_hidden = false; + focus_plugin_pane(1, should_float_if_hidden); + }, + Key::Ctrl('v') => { + rename_terminal_pane(1, "new terminal_pane_name"); + }, + Key::Ctrl('w') => { + rename_plugin_pane(1, "new plugin_pane_name"); + }, + Key::Ctrl('x') => { + rename_tab(1, "new tab name"); + }, _ => {}, }, Event::CustomMessage(message, payload) => { diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs index 557769f02..465529609 100644 --- a/zellij-server/src/panes/plugin_pane.rs +++ b/zellij-server/src/panes/plugin_pane.rs @@ -571,6 +571,10 @@ impl Pane for PluginPane { self.pane_name.to_owned() } } + fn rename(&mut self, buf: Vec<u8>) { + self.pane_name = String::from_utf8_lossy(&buf).to_string(); + self.set_should_render(true); + } } impl PluginPane { diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index df74afd69..a01d815b5 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -745,6 +745,10 @@ impl Pane for TerminalPane { None => false, } } + fn rename(&mut self, buf: Vec<u8>) { + self.pane_name = String::from_utf8_lossy(&buf).to_string(); + self.set_should_render(true); + } } impl TerminalPane { diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs index 6084c9fe9..3ec8485b0 100644 --- a/zellij-server/src/plugins/unit/plugin_tests.rs +++ b/zellij-server/src/plugins/unit/plugin_tests.rs @@ -3608,3 +3608,483 @@ pub fn hide_self_plugin_command() { .clone(); assert_snapshot!(format!("{:#?}", new_tab_event)); } + +#[test] +#[ignore] +pub fn show_self_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::FocusPaneWithId, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('q')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::FocusPaneWithId(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn close_terminal_pane_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::ClosePane, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('r')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::ClosePane(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn close_plugin_pane_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::ClosePane, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('s')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::ClosePane(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn focus_terminal_pane_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::FocusPaneWithId, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('t')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::FocusPaneWithId(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn focus_plugin_pane_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::FocusPaneWithId, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('u')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::FocusPaneWithId(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn rename_terminal_pane_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::RenamePane, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('v')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::RenamePane(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn rename_plugin_pane_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::RenamePane, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('w')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::RenamePane(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} + +#[test] +#[ignore] +pub fn rename_tab_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let (plugin_thread_sender, screen_receiver, mut teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + }; + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::RenameTab, + screen_receiver, + 1 + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + plugin_title, + run_plugin, + tab_index, + client_id, + size, + )); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(Key::Ctrl('x')), // this triggers the enent in the fixture plugin + )])); + std::thread::sleep(std::time::Duration::from_millis(100)); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::RenameTab(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap new file mode 100644 index 000000000..269986f12 --- /dev/null +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap @@ -0,0 +1,13 @@ +--- +source: zellij-server/src/plugins/./unit/plugin_tests.rs +assertion_line: 3789 +expression: "format!(\"{:#?}\", new_tab_event)" +--- +Some( + ClosePane( + Plugin( + 1, + ), + None, + ), +) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap new file mode 100644 index 000000000..778d07b9b --- /dev/null +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap @@ -0,0 +1,13 @@ +--- +source: zellij-server/src/plugins/./unit/plugin_tests.rs +assertion_line: 3729 +expression: "format!(\"{:#?}\", new_tab_event)" +--- +Some( + ClosePane( + Terminal( + 1, + ), + None, + ), +) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap new file mode 100644 index 000000000..d830391ef --- /dev/null +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap @@ -0,0 +1,14 @@ +--- +source: zellij-server/src/plugins/./unit/plugin_tests.rs +assertion_line: 3909 +expression: "format!(\"{:#?}\", new_tab_event)" +--- +Some( + FocusPaneWithId( + Plugin( + 1, + ), + |