From 04b294aabb1ac31ba385f6152c6f4c709bf85097 Mon Sep 17 00:00:00 2001 From: har7an <99636919+har7an@users.noreply.github.com> Date: Sat, 14 Jan 2023 05:14:17 +0000 Subject: Errors: less unwrap in server (#2069) * server/pty: Remove last `unwrap` * server/route: Remove calls to `unwrap` * server/screen: Remove calls to `unwrap` * WIP: server/plugins: Remove calls to unwrap * server/route: Apply rustfmt * server/plugins: Remove last `unwrap`s * server/screen: update tabs before rendering which was previously accidentally changed. * server/tab: Remove calls to `unwrap` * server/plugins: Add context to plugin panic reporter * changelog: Add PR #2069 --- zellij-server/src/screen.rs | 92 +++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 33 deletions(-) (limited to 'zellij-server/src/screen.rs') diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 2c5e44b55..84fbb7688 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -738,13 +738,15 @@ impl Screen { } pub fn resize_to_screen(&mut self, new_screen_size: Size) -> Result<()> { + let err_context = || format!("failed to resize to screen size: {new_screen_size:#?}"); + self.size = new_screen_size; for tab in self.tabs.values_mut() { - tab.resize_whole_tab(new_screen_size); + tab.resize_whole_tab(new_screen_size) + .with_context(err_context)?; tab.set_force_render(); } - self.render() - .with_context(|| format!("failed to resize to screen size: {new_screen_size:#?}")) + self.render().with_context(err_context) } pub fn update_pixel_dimensions(&mut self, pixel_dimensions: PixelDimensions) { @@ -970,29 +972,35 @@ impl Screen { }; // apply the layout to the new tab - let tab = self.tabs.get_mut(&tab_index).unwrap(); // TODO: no unwrap - tab.apply_layout( - layout, - floating_panes_layout, - new_terminal_ids, - new_floating_terminal_ids, - new_plugin_ids, - client_id, - ) - .with_context(err_context)?; - tab.update_input_modes().with_context(err_context)?; - tab.visible(true).with_context(err_context)?; - if let Some(drained_clients) = drained_clients { - tab.add_multiple_clients(drained_clients) - .with_context(err_context)?; - } + self.tabs + .get_mut(&tab_index) + .context("couldn't find tab with index {tab_index}") + .and_then(|tab| { + tab.apply_layout( + layout, + floating_panes_layout, + new_terminal_ids, + new_floating_terminal_ids, + new_plugin_ids, + client_id, + )?; + tab.update_input_modes()?; + tab.visible(true)?; + if let Some(drained_clients) = drained_clients { + tab.add_multiple_clients(drained_clients)?; + } + Ok(()) + }) + .with_context(err_context)?; + if !self.active_tab_indices.contains_key(&client_id) { // this means this is a new client and we need to add it to our state properly self.add_client(client_id).with_context(err_context)?; } - self.update_tabs().with_context(err_context)?; - self.render().with_context(err_context) + self.update_tabs() + .and_then(|_| self.render()) + .with_context(err_context) } pub fn add_client(&mut self, client_id: ClientId) -> Result<()> { @@ -1243,10 +1251,17 @@ impl Screen { if let Some(client_id) = client_id { match self.get_active_tab_mut(client_id) { Ok(active_tab) => { - if !active_tab.move_focus_left(client_id) { - self.switch_tab_prev(client_id) - .context("failed to move focus left")?; - } + active_tab + .move_focus_left(client_id) + .and_then(|success| { + if !success { + self.switch_tab_prev(client_id) + .context("failed to move focus to previous tab") + } else { + Ok(()) + } + }) + .with_context(err_context)?; }, Err(err) => Err::<(), _>(err).with_context(err_context).non_fatal(), }; @@ -1270,10 +1285,17 @@ impl Screen { if let Some(client_id) = client_id { match self.get_active_tab_mut(client_id) { Ok(active_tab) => { - if !active_tab.move_focus_right(client_id) { - self.switch_tab_next(client_id) - .context("failed to move focus right")?; - } + active_tab + .move_focus_right(client_id) + .and_then(|success| { + if !success { + self.switch_tab_next(client_id) + .context("failed to move focus to next tab") + } else { + Ok(()) + } + }) + .with_context(err_context)?; }, Err(err) => Err::<(), _>(err).with_context(err_context).non_fatal(), }; @@ -1560,7 +1582,8 @@ pub(crate) fn screen_thread_main( active_tab_and_connected_client_id!( screen, client_id, - |tab: &mut Tab, client_id: ClientId| tab.move_focus_left(client_id) + |tab: &mut Tab, client_id: ClientId| tab.move_focus_left(client_id), + ? ); screen.render()?; screen.unblock_input()?; @@ -1574,7 +1597,8 @@ pub(crate) fn screen_thread_main( active_tab_and_connected_client_id!( screen, client_id, - |tab: &mut Tab, client_id: ClientId| tab.move_focus_down(client_id) + |tab: &mut Tab, client_id: ClientId| tab.move_focus_down(client_id), + ? ); screen.render()?; screen.unblock_input()?; @@ -1583,7 +1607,8 @@ pub(crate) fn screen_thread_main( active_tab_and_connected_client_id!( screen, client_id, - |tab: &mut Tab, client_id: ClientId| tab.move_focus_right(client_id) + |tab: &mut Tab, client_id: ClientId| tab.move_focus_right(client_id), + ? ); screen.render()?; screen.unblock_input()?; @@ -1597,7 +1622,8 @@ pub(crate) fn screen_thread_main( active_tab_and_connected_client_id!( screen, client_id, - |tab: &mut Tab, client_id: ClientId| tab.move_focus_up(client_id) + |tab: &mut Tab, client_id: ClientId| tab.move_focus_up(client_id), + ? ); screen.render()?; screen.unblock_input()?; -- cgit v1.2.3 From f9a718872876b9ef2df263855081d9562104ce1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=87=E5=91=9C=E5=93=87=E5=91=9C=E5=91=80=E5=92=A6?= =?UTF-8?q?=E8=80=B6?= Date: Thu, 19 Jan 2023 21:28:04 +0800 Subject: Support UTF-8 character in tab name and pane name (#2102) * Support UTF-8 character in tab name and pane name * Support UTF-8 character in tab name and pane name --- zellij-server/src/screen.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zellij-server/src/screen.rs') diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 84fbb7688..b2fdf4f80 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -1118,7 +1118,7 @@ impl Screen { }, c => { // It only allows printable unicode - if buf.iter().all(|u| matches!(u, 0x20..=0x7E)) { + if buf.iter().all(|u| matches!(u, 0x20..=0x7E | 0xA0..=0xFF)) { active_tab.name.push_str(c); } }, -- cgit v1.2.3 From 650aeb12bed057572cb806e9324647dd35a05e98 Mon Sep 17 00:00:00 2001 From: Yves Biener <56591091+yves-biener@users.noreply.github.com> Date: Tue, 24 Jan 2023 13:51:11 +0100 Subject: feat: add ScrollToTop action (#2110) --- zellij-server/src/screen.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'zellij-server/src/screen.rs') diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index b2fdf4f80..fdca620d9 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -161,6 +161,7 @@ pub enum ScreenInstruction { ScrollDown(ClientId), ScrollDownAt(Position, ClientId), ScrollToBottom(ClientId), + ScrollToTop(ClientId), PageScrollUp(ClientId), PageScrollDown(ClientId), HalfPageScrollUp(ClientId), @@ -294,6 +295,7 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::ScrollUp(..) => ScreenContext::ScrollUp, ScreenInstruction::ScrollDown(..) => ScreenContext::ScrollDown, ScreenInstruction::ScrollToBottom(..) => ScreenContext::ScrollToBottom, + ScreenInstruction::ScrollToTop(..) => ScreenContext::ScrollToTop, ScreenInstruction::PageScrollUp(..) => ScreenContext::PageScrollUp, ScreenInstruction::PageScrollDown(..) => ScreenContext::PageScrollDown, ScreenInstruction::HalfPageScrollUp(..) => ScreenContext::HalfPageScrollUp, @@ -1744,6 +1746,16 @@ pub(crate) fn screen_thread_main( screen.render()?; screen.unblock_input()?; }, + ScreenInstruction::ScrollToTop(client_id) => { + active_tab_and_connected_client_id!( + screen, + client_id, + |tab: &mut Tab, client_id: ClientId| tab + .scroll_active_terminal_to_top(client_id), ? + ); + screen.render()?; + screen.unblock_input()?; + }, ScreenInstruction::PageScrollUp(client_id) => { active_tab_and_connected_client_id!( screen, -- cgit v1.2.3 From 99e8d56adb50b1b2921d4af01972c4b9fd8b6105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=87=E5=91=9C=E5=93=87=E5=91=9C=E5=91=80=E5=92=A6?= =?UTF-8?q?=E8=80=B6?= Date: Tue, 7 Feb 2023 22:45:59 +0800 Subject: feat(cli): add `GoToTabName` action to switch tab by name (#2120) * Add `GoToTabName` action to switch tab by name * rm blank file * add --create option * format * add some doc * add test case * format * add test case * change variable name --- zellij-server/src/screen.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'zellij-server/src/screen.rs') diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index fdca620d9..9a196f35d 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -196,6 +196,7 @@ pub enum ScreenInstruction { ToggleActiveSyncTab(ClientId), CloseTab(ClientId), GoToTab(u32, Option), // this Option is a hacky workaround, please do not copy this behaviour + GoToTabName(String, bool, Option), ToggleTab(ClientId), UpdateTabName(Vec, ClientId), UndoRenameTab(ClientId), @@ -317,6 +318,7 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::SwitchTabPrev(..) => ScreenContext::SwitchTabPrev, ScreenInstruction::CloseTab(..) => ScreenContext::CloseTab, ScreenInstruction::GoToTab(..) => ScreenContext::GoToTab, + ScreenInstruction::GoToTabName(..) => ScreenContext::GoToTabName, ScreenInstruction::UpdateTabName(..) => ScreenContext::UpdateTabName, ScreenInstruction::UndoRenameTab(..) => ScreenContext::UndoRenameTab, ScreenInstruction::TerminalResize(..) => ScreenContext::TerminalResize, @@ -623,6 +625,18 @@ impl Screen { Ok(()) } + /// A helper function to switch to a new tab with specified name. Return true if tab [name] has + /// been created, else false. + fn switch_active_tab_name(&mut self, name: String, client_id: ClientId) -> Result { + match self.tabs.values().find(|t| t.name == name) { + Some(new_tab) => { + self.switch_active_tab(new_tab.position, client_id)?; + Ok(true) + }, + None => Ok(false), + } + } + /// Sets this [`Screen`]'s active [`Tab`] to the next tab. pub fn switch_tab_next(&mut self, client_id: ClientId) -> Result<()> { let err_context = || format!("failed to switch to next tab for client {client_id}"); @@ -678,6 +692,10 @@ impl Screen { self.switch_active_tab(tab_index.saturating_sub(1), client_id) } + pub fn go_to_tab_name(&mut self, name: String, client_id: ClientId) -> Result { + self.switch_active_tab_name(name, client_id) + } + fn close_tab_at_index(&mut self, tab_index: usize) -> Result<()> { let err_context = || format!("failed to close tab at index {tab_index:?}"); @@ -1981,6 +1999,39 @@ pub(crate) fn screen_thread_main( screen.render()?; } }, + ScreenInstruction::GoToTabName(tab_name, create, client_id) => { + let client_id = if client_id.is_none() { + None + } else if screen + .active_tab_indices + .contains_key(&client_id.expect("This is checked above")) + { + client_id + } else { + screen.active_tab_indices.keys().next().copied() + }; + if let Some(client_id) = client_id { + if let Ok(tab_exists) = screen.go_to_tab_name(tab_name.clone(), client_id) { + screen.unblock_input()?; + screen.render()?; + if create && !tab_exists { + let tab_index = screen.get_new_tab_index(); + screen.new_tab(tab_index, client_id)?; + screen + .bus + .senders + .send_to_plugin(PluginInstruction::NewTab( + None, + None, + vec![], + Some(tab_name), + tab_index, + client_id, + ))?; + } + } + } + }, ScreenInstruction::UpdateTabName(c, client_id) => { screen.update_active_tab_name(c, client_id)?; screen.unblock_input()?; -- cgit v1.2.3