diff options
author | denis <denismaximov98@gmail.com> | 2021-03-30 14:17:16 +0300 |
---|---|---|
committer | Kunal Mohan <kunalmohan99@gmail.com> | 2021-04-14 01:41:34 +0530 |
commit | a4f2e002aaafd1457cd9730ea653b694ff5006ac (patch) | |
tree | 995f3b718f53b0187052b6b7753da8661ed58177 | |
parent | 699b20086433cd05aba842f0793adf42552f8df2 (diff) |
wip: helper functions for ServerInstruction
-rw-r--r-- | src/client/tab.rs | 16 | ||||
-rw-r--r-- | src/common/input/handler.rs | 2 | ||||
-rw-r--r-- | src/common/pty_bus.rs | 51 | ||||
-rw-r--r-- | src/common/screen.rs | 2 | ||||
-rw-r--r-- | src/server/mod.rs | 159 |
5 files changed, 176 insertions, 54 deletions
diff --git a/src/client/tab.rs b/src/client/tab.rs index 52265d4f7..1a0cee2a9 100644 --- a/src/client/tab.rs +++ b/src/client/tab.rs @@ -330,8 +330,8 @@ impl Tab { // can query the screen as to how many panes it needs to create a layout // fixing this will require a bit of an architecture change self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::ClosePane( - PaneId::Terminal(*unused_pid), + .send_to_server(ServerInstruction::pty_close_pane(PaneId::Terminal( + *unused_pid, ))); } self.active_terminal = self.panes.iter().map(|(id, _)| id.to_owned()).next(); @@ -380,7 +380,7 @@ impl Tab { ); if terminal_id_to_split.is_none() { self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::ClosePane(pid))); // we can't open this pane, close the pty + .send_to_server(ServerInstruction::pty_close_pane(pid)); // we can't open this pane, close the pty return; // likely no terminal large enough to split } let terminal_id_to_split = terminal_id_to_split.unwrap(); @@ -469,7 +469,7 @@ impl Tab { let active_pane = self.panes.get_mut(active_pane_id).unwrap(); if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 { self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::ClosePane(pid))); // we can't open this pane, close the pty + .send_to_server(ServerInstruction::pty_close_pane(pid)); // we can't open this pane, close the pty return; } let terminal_ws = PositionAndSize { @@ -530,7 +530,7 @@ impl Tab { let active_pane = self.panes.get_mut(active_pane_id).unwrap(); if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 { self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::ClosePane(pid))); // we can't open this pane, close the pty + .send_to_server(ServerInstruction::pty_close_pane(pid)); // we can't open this pane, close the pty return; } let terminal_ws = PositionAndSize { @@ -2139,7 +2139,7 @@ impl Tab { let terminals = self.get_pane_ids(); for &pid in terminals.iter().skip(max_panes - 1) { self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::ClosePane(pid))); + .send_to_server(ServerInstruction::pty_close_pane(pid)); self.close_pane_without_rerender(pid); } } @@ -2250,9 +2250,7 @@ impl Tab { if let Some(active_pane_id) = self.get_active_pane_id() { self.close_pane(active_pane_id); self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::ClosePane( - active_pane_id, - ))); + .send_to_server(ServerInstruction::pty_close_pane(active_pane_id)); } } pub fn scroll_active_terminal_up(&mut self) { diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index fcc766f18..2f92d1ebb 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -227,7 +227,7 @@ impl InputHandler { Action::NewTab => { self.command_is_executing.updating_tabs(); self.os_input - .send_to_server(ServerInstruction::ToPty(PtyInstruction::NewTab)); + .send_to_server(ServerInstruction::pty_new_tab()); self.command_is_executing.wait_until_tabs_are_updated(); } Action::GoToNextTab => { diff --git a/src/common/pty_bus.rs b/src/common/pty_bus.rs index b99210d65..3c26816f6 100644 --- a/src/common/pty_bus.rs +++ b/src/common/pty_bus.rs @@ -97,18 +97,12 @@ impl VteEventSender { impl vte::Perform for VteEventSender { fn print(&mut self, c: char) { self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( - self.id, - VteEvent::Print(c), - ))) + .send(ServerInstruction::pty(self.id, VteEvent::Print(c))) .unwrap(); } fn execute(&mut self, byte: u8) { self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( - self.id, - VteEvent::Execute(byte), - ))) + .send(ServerInstruction::pty(self.id, VteEvent::Execute(byte))) .unwrap(); } @@ -116,38 +110,32 @@ impl vte::Perform for VteEventSender { let params = params.iter().copied().collect(); let intermediates = intermediates.iter().copied().collect(); self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( + .send(ServerInstruction::pty( self.id, VteEvent::Hook(params, intermediates, ignore, c), - ))) + )) .unwrap(); } fn put(&mut self, byte: u8) { self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( - self.id, - VteEvent::Put(byte), - ))) + .send(ServerInstruction::pty(self.id, VteEvent::Put(byte))) .unwrap(); } fn unhook(&mut self) { self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( - self.id, - VteEvent::Unhook, - ))) + .send(ServerInstruction::pty(self.id, VteEvent::Unhook)) .unwrap(); } fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) { let params = params.iter().map(|p| p.to_vec()).collect(); self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( + .send(ServerInstruction::pty( self.id, VteEvent::OscDispatch(params, bell_terminated), - ))) + )) .unwrap(); } @@ -155,20 +143,20 @@ impl vte::Perform for VteEventSender { let params = params.iter().copied().collect(); let intermediates = intermediates.iter().copied().collect(); self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( + .send(ServerInstruction::pty( self.id, VteEvent::CsiDispatch(params, intermediates, ignore, c), - ))) + )) .unwrap(); } fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { let intermediates = intermediates.iter().copied().collect(); self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Pty( + .send(ServerInstruction::pty( self.id, VteEvent::EscDispatch(intermediates, ignore, byte), - ))) + )) .unwrap(); } } @@ -233,7 +221,7 @@ fn stream_terminal_bytes( if receive_time.elapsed() > max_render_pause { pending_render = false; send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Render)) + .send(ServerInstruction::render()) .unwrap(); last_byte_receive_time = Some(Instant::now()); } else { @@ -249,7 +237,7 @@ fn stream_terminal_bytes( if pending_render { pending_render = false; send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Render)) + .send(ServerInstruction::render()) .unwrap(); } last_byte_receive_time = None; @@ -257,16 +245,14 @@ fn stream_terminal_bytes( } } send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::Render)) + .send(ServerInstruction::render()) .unwrap(); #[cfg(not(test))] // this is a little hacky, and is because the tests end the file as soon as // we read everything, rather than hanging until there is new data // a better solution would be to fix the test fakes, but this will do for now send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::ClosePane( - PaneId::Terminal(pid), - ))) + .send(ServerInstruction::screen_close_pane(PaneId::Terminal(pid))) .unwrap(); } }) @@ -311,8 +297,9 @@ impl PtyBus { new_pane_pids.push(pid_primary); } self.send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::ApplyLayout( - (layout_path, new_pane_pids.clone()), + .send(ServerInstruction::apply_layout(( + layout_path, + new_pane_pids.clone(), ))) .unwrap(); for id in new_pane_pids { diff --git a/src/common/screen.rs b/src/common/screen.rs index 35938e8f8..6c0ae5546 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -200,7 +200,7 @@ impl Screen { // because this might be happening when the app is closing, at which point the pty thread // has already closed and this would result in an error self.os_api - .send_to_server(ServerInstruction::ToPty(PtyInstruction::CloseTab(pane_ids))); + .send_to_server(ServerInstruction::pty_close_tab(pane_ids)); if self.tabs.is_empty() { self.active_tab_index = None; self.send_app_instructions diff --git a/src/server/mod.rs b/src/server/mod.rs index ea8593027..eedc4c3fa 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,4 +1,3 @@ -use crate::cli::CliArgs; use crate::client::ClientInstruction; use crate::common::{ChannelWithContext, SenderType, SenderWithContext}; use crate::errors::{ContextType, ErrorContext, OsContext, PtyContext, ServerContext}; @@ -6,10 +5,13 @@ use crate::os_input_output::{ServerOsApi, ServerOsApiInstruction}; use crate::panes::PaneId; use crate::pty_bus::{PtyBus, PtyInstruction}; use crate::screen::ScreenInstruction; +use crate::{cli::CliArgs, common::pty_bus::VteEvent}; use serde::{Deserialize, Serialize}; +use std::os::unix::io::RawFd; use std::path::PathBuf; use std::sync::mpsc::channel; use std::thread; +use zellij_tile::prelude::InputMode; /// Instructions related to server-side application including the /// ones sent by client to server @@ -28,6 +30,147 @@ pub enum ServerInstruction { ClientExit, Exit, } +impl ServerInstruction { + // ToPty + pub fn spawn_terminal(path: Option<PathBuf>) -> Self { + Self::ToPty(PtyInstruction::SpawnTerminal(path)) + } + pub fn spawn_terminal_vertically(path: Option<PathBuf>) -> Self { + Self::ToPty(PtyInstruction::SpawnTerminalVertically(path)) + } + pub fn spawn_terminal_horizontally(path: Option<PathBuf>) -> Self { + Self::ToPty(PtyInstruction::SpawnTerminalHorizontally(path)) + } + pub fn pty_new_tab() -> Self { + Self::ToPty(PtyInstruction::NewTab) + } + pub fn pty_close_pane(id: PaneId) -> Self { + Self::ToPty(PtyInstruction::ClosePane(id)) + } + pub fn pty_close_tab(ids: Vec<PaneId>) -> Self { + Self::ToPty(PtyInstruction::CloseTab(ids)) + } + pub fn pty_exit() -> Self { + Self::ToPty(PtyInstruction::Exit) + } + + // ToScreen + pub fn render() -> Self { + Self::ToScreen(ScreenInstruction::Render) + } + pub fn new_pane(id: PaneId) -> Self { + Self::ToScreen(ScreenInstruction::NewPane(id)) + } + pub fn horizontal_split(id: PaneId) -> Self { + Self::ToScreen(ScreenInstruction::HorizontalSplit(id)) + } + pub fn vertical_split(id: PaneId) -> Self { + Self::ToScreen(ScreenInstruction::VerticalSplit(id)) + } + pub fn write_character(chars: Vec<u8>) -> Self { + Self::ToScreen(ScreenInstruction::WriteCharacter(chars)) + } + pub fn resize_left() -> Self { + Self::ToScreen(ScreenInstruction::ResizeLeft) + } + pub fn resize_right() -> Self { + Self::ToScreen(ScreenInstruction::ResizeRight) + } + pub fn resize_down() -> Self { + Self::ToScreen(ScreenInstruction::ResizeDown) + } + pub fn resize_up() -> Self { + Self::ToScreen(ScreenInstruction::ResizeUp) + } + pub fn move_focus() -> Self { + Self::ToScreen(ScreenInstruction::MoveFocus) + } + pub fn move_focus_left() -> Self { + Self::ToScreen(ScreenInstruction::MoveFocusLeft) + } + pub fn move_focus_right() -> Self { + Self::ToScreen(ScreenInstruction::MoveFocusRight) + } + pub fn move_focus_down() -> Self { + Self::ToScreen(ScreenInstruction::MoveFocusDown) + } + pub fn move_focus_up() -> Self { + Self::ToScreen(ScreenInstruction::MoveFocusUp) + } + pub fn screen_exit() -> Self { + Self::ToScreen(ScreenInstruction::Exit) + } + pub fn scroll_up() -> Self { + Self::ToScreen(ScreenInstruction::ScrollUp) + } + pub fn scroll_down() -> Self { + Self::ToScreen(ScreenInstruction::ScrollDown) + } + pub fn clear_scroll() -> Self { + Self::ToScreen(ScreenInstruction::ClearScroll) + } + pub fn close_focused_pane() -> Self { + Self::ToScreen(ScreenInstruction::CloseFocusedPane) + } + pub fn toggle_active_terminal_fullscreen() -> Self { + Self::ToScreen(ScreenInstruction::ToggleActiveTerminalFullscreen) + } + pub fn set_selectable(pane_id: PaneId, value: bool) -> Self { + Self::ToScreen(ScreenInstruction::SetSelectable(pane_id, value)) + } + pub fn set_max_height(pane_id: PaneId, max_height: usize) -> Self { + Self::ToScreen(ScreenInstruction::SetMaxHeight(pane_id, max_height)) + } + pub fn set_invisible_borders(pane_id: PaneId, value: bool) -> Self { + Self::ToScreen(ScreenInstruction::SetInvisibleBorders(pane_id, value)) + } + pub fn screen_close_pane(pane_id: PaneId) -> Self { + Self::ToScreen(ScreenInstruction::ClosePane(pane_id)) + } + pub fn apply_layout(layout: (PathBuf, Vec<RawFd>)) -> Self { + Self::ToScreen(ScreenInstruction::ApplyLayout(layout)) + } + pub fn screen_new_tab(fd: RawFd) -> Self { + Self::ToScreen(ScreenInstruction::NewTab(fd)) + } + pub fn switch_tab_prev() -> Self { + Self::ToScreen(ScreenInstruction::SwitchTabPrev) + } + pub fn switch_tab_next() -> Self { + Self::ToScreen(ScreenInstruction::SwitchTabPrev) + } + pub fn screen_close_tab() -> Self { + Self::ToScreen(ScreenInstruction::CloseTab) + } + pub fn go_to_tab(tab_id: u32) -> Self { + Self::ToScreen(ScreenInstruction::GoToTab(tab_id)) + } + pub fn update_tab_name(tab_ids: Vec<u8>) -> Self { + Self::ToScreen(ScreenInstruction::UpdateTabName(tab_ids)) + } + pub fn change_input_mode(input_mode: InputMode) -> Self { + Self::ToScreen(ScreenInstruction::ChangeInputMode(input_mode)) + } + pub fn pty(fd: RawFd, event: VteEvent) -> Self { + Self::ToScreen(ScreenInstruction::Pty(fd, event)) + } + + // OsApi + pub fn set_terminal_size_using_fd(fd: RawFd, cols: u16, rows: u16) -> Self { + Self::OsApi(ServerOsApiInstruction::SetTerminalSizeUsingFd( + fd, cols, rows, + )) + } + pub fn write_to_tty_stdin(fd: RawFd, buf: Vec<u8>) -> Self { + Self::OsApi(ServerOsApiInstruction::WriteToTtyStdin(fd, buf)) + } + pub fn tc_drain(fd: RawFd) -> Self { + Self::OsApi(ServerOsApiInstruction::TcDrain(fd)) + } + pub fn os_exit() -> Self { + Self::OsApi(ServerOsApiInstruction::Exit) + } +} pub fn start_server(mut os_input: Box<dyn ServerOsApi>, opts: CliArgs) -> thread::JoinHandle<()> { let (send_pty_instructions, receive_pty_instructions): ChannelWithContext<PtyInstruction> = @@ -80,27 +223,21 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, opts: CliArgs) -> thread let pid = pty_bus.spawn_terminal(file_to_open); pty_bus .send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::NewPane( - PaneId::Terminal(pid), - ))) + .send(ServerInstruction::new_pane(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::SpawnTerminalVertically(file_to_open) => { let pid = pty_bus.spawn_terminal(file_to_open); pty_bus .send_server_instructions - .send(ServerInstruction::ToScreen( - ScreenInstruction::VerticalSplit(PaneId::Terminal(pid)), - )) + .send(ServerInstruction::vertical_split(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::SpawnTerminalHorizontally(file_to_open) => { let pid = pty_bus.spawn_terminal(file_to_open); pty_bus .send_server_instructions - .send(ServerInstruction::ToScreen( - ScreenInstruction::HorizontalSplit(PaneId::Terminal(pid)), - )) + .send(ServerInstruction::horizontal_split(PaneId::Terminal(pid))) .unwrap(); } PtyInstruction::NewTab => { @@ -110,7 +247,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, opts: CliArgs) -> thread let pid = pty_bus.spawn_terminal(None); pty_bus .send_server_instructions - .send(ServerInstruction::ToScreen(ScreenInstruction::NewTab(pid))) + .send(ServerInstruction::screen_new_tab(pid)) .unwrap(); } } |