aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authora-kenji <aks.kenji@protonmail.com>2021-04-03 21:19:39 +0200
committera-kenji <aks.kenji@protonmail.com>2021-04-03 21:19:39 +0200
commit4f5f189373603d29fc8b042b72aae375efbd0a1c (patch)
treed63b769a0c218d4956316fd3128f96ed33c2d9cf /src/common
parentMerge branch 'main' of https://github.com/zellij-org/zellij into config-file (diff)
parentAdd Kyle to governance.md (diff)
downloadsl0ppij-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.rs8
-rw-r--r--src/common/input/handler.rs10
-rw-r--r--src/common/mod.rs24
-rw-r--r--src/common/os_input_output.rs32
-rw-r--r--src/common/screen.rs30
-rw-r--r--src/common/utils/shared.rs13
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<_>>()