diff options
| author | a-kenji <aks.kenji@protonmail.com> | 2021-04-03 21:19:39 +0200 |
|---|---|---|
| committer | a-kenji <aks.kenji@protonmail.com> | 2021-04-03 21:19:39 +0200 |
| commit | 4f5f189373603d29fc8b042b72aae375efbd0a1c (patch) | |
| tree | d63b769a0c218d4956316fd3128f96ed33c2d9cf /src/common | |
| parent | Merge branch 'main' of https://github.com/zellij-org/zellij into config-file (diff) | |
| parent | Add Kyle to governance.md (diff) | |
| download | sl0ppij-4f5f189373603d29fc8b042b72aae375efbd0a1c.tar.gz sl0ppij-4f5f189373603d29fc8b042b72aae375efbd0a1c.tar.xz sl0ppij-4f5f189373603d29fc8b042b72aae375efbd0a1c.zip | |
Merge branch 'main' of https://github.com/zellij-org/zellij into config-file
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/errors.rs | 8 | ||||
| -rw-r--r-- | src/common/input/handler.rs | 10 | ||||
| -rw-r--r-- | src/common/mod.rs | 24 | ||||
| -rw-r--r-- | src/common/os_input_output.rs | 32 | ||||
| -rw-r--r-- | src/common/screen.rs | 30 | ||||
| -rw-r--r-- | src/common/utils/shared.rs | 13 |
6 files changed, 89 insertions, 28 deletions
diff --git a/src/common/errors.rs b/src/common/errors.rs index f5aeae85..00284cd4 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -42,7 +42,7 @@ pub fn handle_panic( msg, location.file(), location.line(), - backtrace + backtrace, ), (Some(location), None) => format!( "{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked: {}:{}\n\u{1b}[0;0m{:?}", @@ -200,7 +200,8 @@ pub enum ScreenContext { CloseTab, GoToTab, UpdateTabName, - ChangeInputMode, + TerminalResize, + ChangeMode, } // FIXME: Just deriving EnumDiscriminants from strum will remove the need for any of this!!! @@ -241,7 +242,8 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::CloseTab => ScreenContext::CloseTab, ScreenInstruction::GoToTab(_) => ScreenContext::GoToTab, ScreenInstruction::UpdateTabName(_) => ScreenContext::UpdateTabName, - ScreenInstruction::ChangeInputMode(_) => ScreenContext::ChangeInputMode, + ScreenInstruction::TerminalResize => ScreenContext::TerminalResize, + ScreenInstruction::ChangeMode(_) => ScreenContext::ChangeMode, } } } diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index 0d30530a..7db14d64 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -82,9 +82,11 @@ impl InputHandler { break 'input_loop; } } - termion::event::Event::Mouse(_) | termion::event::Event::Unsupported(_) => { - unimplemented!("Mouse and unsupported events aren't supported!"); - } + termion::event::Event::Mouse(_) + | termion::event::Event::Unsupported(_) => { + // Mouse and unsupported events aren't implemented yet, + // use a NoOp untill then. + } }, Err(err) => panic!("Encountered read error: {:?}", err), } @@ -128,7 +130,7 @@ impl InputHandler { )) .unwrap(); self.send_screen_instructions - .send(ScreenInstruction::ChangeInputMode(mode)) + .send(ScreenInstruction::ChangeMode(get_mode_info(mode))) .unwrap(); self.send_screen_instructions .send(ScreenInstruction::Render) diff --git a/src/common/mod.rs b/src/common/mod.rs index 57c21155..e9b74d58 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -38,7 +38,7 @@ use wasm_vm::PluginEnv; use wasm_vm::{wasi_stdout, wasi_write_string, zellij_imports, PluginInstruction}; use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value}; use wasmer_wasi::{Pipe, WasiState}; -use zellij_tile::data::{EventType, InputMode}; +use zellij_tile::data::{EventType, ModeInfo}; #[derive(Serialize, Deserialize, Debug)] pub enum ApiCommand { @@ -264,7 +264,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { &full_screen_ws, os_input, max_panes, - InputMode::Normal, + ModeInfo::default(), ); loop { let (event, mut err_ctx) = screen @@ -397,8 +397,11 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { ScreenInstruction::UpdateTabName(c) => { screen.update_active_tab_name(c); } - ScreenInstruction::ChangeInputMode(input_mode) => { - screen.change_input_mode(input_mode); + ScreenInstruction::TerminalResize => { + screen.resize_to_screen(); + } + ScreenInstruction::ChangeMode(mode_info) => { + screen.change_mode(mode_info); } ScreenInstruction::Quit => { break; @@ -514,6 +517,19 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { }) .unwrap(); + let _signal_thread = thread::Builder::new() + .name("signal_listener".to_string()) + .spawn({ + let os_input = os_input.clone(); + let send_screen_instructions = send_screen_instructions.clone(); + move || { + os_input.receive_sigwinch(Box::new(move || { + let _ = send_screen_instructions.send(ScreenInstruction::TerminalResize); + })); + } + }) + .unwrap(); + // TODO: currently we don't wait for this to quit // because otherwise the app will hang. Need to fix this so it both // listens to the ipc-bus and is able to quit cleanly diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs index 043a9aea..de0c6a3b 100644 --- a/src/common/os_input_output.rs +++ b/src/common/os_input_output.rs @@ -13,6 +13,8 @@ use std::path::PathBuf; use std::process::{Child, Command}; use std::sync::{Arc, Mutex}; +use signal_hook::{consts::signal::*, iterator::Signals}; + use std::env; fn into_raw_mode(pid: RawFd) { @@ -65,7 +67,7 @@ pub fn set_terminal_size_using_fd(fd: RawFd, columns: u16, rows: u16) { /// process exits. fn handle_command_exit(mut child: Child) { // register the SIGINT signal (TODO handle more signals) - let signals = ::signal_hook::iterator::Signals::new(&[::signal_hook::SIGINT]).unwrap(); + let mut signals = ::signal_hook::iterator::Signals::new(&[SIGINT]).unwrap(); 'handle_exit: loop { // test whether the child process has exited match child.try_wait() { @@ -82,10 +84,15 @@ fn handle_command_exit(mut child: Child) { } for signal in signals.pending() { - if signal == signal_hook::SIGINT { - child.kill().unwrap(); - child.wait().unwrap(); - break 'handle_exit; + // FIXME: We need to handle more signals here! + #[allow(clippy::single_match)] + match signal { + SIGINT => { + child.kill().unwrap(); + child.wait().unwrap(); + break 'handle_exit; + } + _ => {} } } } @@ -188,6 +195,7 @@ pub trait OsApi: Send + Sync { fn get_stdout_writer(&self) -> Box<dyn io::Write>; /// Returns a [`Box`] pointer to this [`OsApi`] struct. fn box_clone(&self) -> Box<dyn OsApi>; + fn receive_sigwinch(&self, cb: Box<dyn Fn()>); } impl OsApi for OsInputOutput { @@ -238,6 +246,20 @@ impl OsApi for OsInputOutput { waitpid(Pid::from_raw(pid), None).unwrap(); Ok(()) } + fn receive_sigwinch(&self, cb: Box<dyn Fn()>) { + let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT]).unwrap(); + for signal in signals.forever() { + match signal { + SIGWINCH => { + cb(); + } + SIGTERM | SIGINT | SIGQUIT => { + break; + } + _ => unreachable!(), + } + } + } } impl Clone for Box<dyn OsApi> { diff --git a/src/common/screen.rs b/src/common/screen.rs index 5208834a..121f21bd 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -13,7 +13,7 @@ use crate::tab::Tab; use crate::{errors::ErrorContext, wasm_vm::PluginInstruction}; use crate::{layout::Layout, panes::PaneId}; -use zellij_tile::data::{Event, InputMode, TabInfo}; +use zellij_tile::data::{Event, ModeInfo, TabInfo}; /// Instructions that can be sent to the [`Screen`]. #[derive(Debug, Clone)] @@ -50,7 +50,8 @@ pub enum ScreenInstruction { CloseTab, GoToTab(u32), UpdateTabName(Vec<u8>), - ChangeInputMode(InputMode), + TerminalResize, + ChangeMode(ModeInfo), } /// A [`Screen`] holds multiple [`Tab`]s, each one holding multiple [`panes`](crate::client::panes). @@ -74,7 +75,7 @@ pub struct Screen { active_tab_index: Option<usize>, /// The [`OsApi`] this [`Screen`] uses. os_api: Box<dyn OsApi>, - input_mode: InputMode, + mode_info: ModeInfo, } impl Screen { @@ -87,7 +88,7 @@ impl Screen { full_screen_ws: &PositionAndSize, os_api: Box<dyn OsApi>, max_panes: Option<usize>, - input_mode: InputMode, + mode_info: ModeInfo, ) -> Self { Screen { receiver: receive_screen_instructions, @@ -99,7 +100,7 @@ impl Screen { active_tab_index: None, tabs: BTreeMap::new(), os_api, - input_mode, + mode_info, } } @@ -119,7 +120,7 @@ impl Screen { self.send_app_instructions.clone(), self.max_panes, Some(PaneId::Terminal(pane_id)), - self.input_mode, + self.mode_info.clone(), ); self.active_tab_index = Some(tab_index); self.tabs.insert(tab_index, tab); @@ -213,6 +214,15 @@ impl Screen { } } + pub fn resize_to_screen(&mut self) { + let new_screen_size = self.os_api.get_terminal_size_using_fd(0); + self.full_screen_ws = new_screen_size; + for (_, tab) in self.tabs.iter_mut() { + tab.resize_whole_tab(new_screen_size); + } + self.render(); + } + /// Renders this [`Screen`], which amounts to rendering its active [`Tab`]. pub fn render(&mut self) { if let Some(active_tab) = self.get_active_tab_mut() { @@ -261,7 +271,7 @@ impl Screen { self.send_app_instructions.clone(), self.max_panes, None, - self.input_mode, + self.mode_info.clone(), ); tab.apply_layout(layout, new_pids); self.active_tab_index = Some(tab_index); @@ -301,10 +311,10 @@ impl Screen { } self.update_tabs(); } - pub fn change_input_mode(&mut self, input_mode: InputMode) { - self.input_mode = input_mode; + pub fn change_mode(&mut self, mode_info: ModeInfo) { + self.mode_info = mode_info; for tab in self.tabs.values_mut() { - tab.input_mode = self.input_mode; + tab.mode_info = self.mode_info.clone(); } } } diff --git a/src/common/utils/shared.rs b/src/common/utils/shared.rs index 9717837a..93892d4f 100644 --- a/src/common/utils/shared.rs +++ b/src/common/utils/shared.rs @@ -11,9 +11,18 @@ fn ansi_len(s: &str) -> usize { .count() } -pub fn pad_to_size(s: &str, rows: usize, columns: usize) -> String { +pub fn adjust_to_size(s: &str, rows: usize, columns: usize) -> String { s.lines() - .map(|l| [l, &str::repeat(" ", columns - ansi_len(l))].concat()) + .map(|l| { + let actual_len = ansi_len(l); + if actual_len > columns { + let mut line = String::from(l); + line.truncate(columns); + return line; + } else { + return [l, &str::repeat(" ", columns - ansi_len(l))].concat(); + } + }) .chain(iter::repeat(str::repeat(" ", columns))) .take(rows) .collect::<Vec<_>>() |
