aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/tab.rs
diff options
context:
space:
mode:
authorBrooks Rady <b.j.rady@gmail.com>2021-03-26 13:20:06 +0000
committerGitHub <noreply@github.com>2021-03-26 13:20:06 +0000
commitd818661c727a59312e1a43432e84fbeec79fc145 (patch)
treee8ab04124ee7f5c87cd88be63c1867c7d9b2289c /src/client/tab.rs
parentfix(render): various rendering issues (#238) (diff)
parentFix some overzealous format!() removals and a stray comment (diff)
downloadsl0ppij-d818661c727a59312e1a43432e84fbeec79fc145.tar.gz
sl0ppij-d818661c727a59312e1a43432e84fbeec79fc145.tar.xz
sl0ppij-d818661c727a59312e1a43432e84fbeec79fc145.zip
feat(plugin): refactored to a new and more general plugin API
- Changed `init()` to `load()` - Deduplicated structs that are in both `zellij` and `zellij-tile` - WASM thread now keeps a mapping of plugins and event subscriptions - Added host-functions for subscribing and unsubscribing from events - Introduced the `update(event)` callback into the API (which is called to handle plugin events) - Made mode changes send an event to the WASM thread - Removed the `AppInstruction::Get/SetState` calls (and any global state) - Removed the `get_help()` host function - Added an event system for key-presses - Added an event for updating tabs - Ported support for renaming tabs - Removed every plugin callback other than `load()`, `update(event)`, and `draw(rows, cols)` - Removed every WASM thread event other than Load, Draw, Update, Unload, and Quit - Calls render after a plugin is updated - Switched back to upstream `termion` - Loads of lint fixing - Shrunk and simplified the code!
Diffstat (limited to 'src/client/tab.rs')
-rw-r--r--src/client/tab.rs184
1 files changed, 81 insertions, 103 deletions
diff --git a/src/client/tab.rs b/src/client/tab.rs
index 081194ed..1e56fd8b 100644
--- a/src/client/tab.rs
+++ b/src/client/tab.rs
@@ -1,23 +1,21 @@
//! `Tab`s holds multiple panes. It tracks their coordinates (x/y) and size,
//! as well as how they should be resized
-use crate::common::{input::handler::InputMode, AppInstruction, SenderWithContext};
+use crate::boundaries::colors;
+use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContext};
use crate::layout::Layout;
use crate::panes::{PaneId, PositionAndSize, TerminalPane};
use crate::pty_bus::{PtyInstruction, VteEvent};
-use crate::wasm_vm::{PluginInputType, PluginInstruction};
-use crate::{
- boundaries::{colors, Boundaries},
- panes::PluginPane,
-};
+use crate::wasm_vm::PluginInstruction;
+use crate::{boundaries::Boundaries, panes::PluginPane};
use crate::{os_input_output::OsApi, utils::shared::pad_to_size};
-use serde::{Deserialize, Serialize};
use std::os::unix::io::RawFd;
use std::{
cmp::Reverse,
collections::{BTreeMap, HashSet},
};
use std::{io::Write, sync::mpsc::channel};
+use zellij_tile::data::{Event, InputMode};
const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this
const MIN_TERMINAL_HEIGHT: usize = 2;
@@ -71,14 +69,6 @@ pub struct Tab {
pub input_mode: InputMode,
}
-#[derive(Clone, Debug, Default, Serialize, Deserialize)]
-pub struct TabData {
- /* subset of fields to publish to plugins */
- pub position: usize,
- pub name: String,
- pub active: bool,
-}
-
// FIXME: Use a struct that has a pane_type enum, to reduce all of the duplication
pub trait Pane {
fn x(&self) -> usize;
@@ -268,11 +258,7 @@ impl Tab {
if let Some(plugin) = &layout.plugin {
let (pid_tx, pid_rx) = channel();
self.send_plugin_instructions
- .send(PluginInstruction::Load(
- pid_tx,
- plugin.clone(),
- layout.events.clone(),
- ))
+ .send(PluginInstruction::Load(pid_tx, plugin.clone()))
.unwrap();
let pid = pid_rx.recv().unwrap();
let new_plugin = PluginPane::new(
@@ -311,7 +297,6 @@ impl Tab {
self.toggle_active_pane_fullscreen();
}
if !self.has_panes() {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
self.os_api.set_terminal_size_using_fd(
@@ -362,7 +347,6 @@ impl Tab {
if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns()
&& terminal_to_split.rows() > terminal_to_split.min_height() * 2
{
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
@@ -383,7 +367,6 @@ impl Tab {
self.active_terminal = Some(pid);
}
} else if terminal_to_split.columns() > terminal_to_split.min_width() * 2 {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
let new_terminal = TerminalPane::new(term_pid, right_winsize);
@@ -413,7 +396,6 @@ impl Tab {
self.toggle_active_pane_fullscreen();
}
if !self.has_panes() {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
self.os_api.set_terminal_size_using_fd(
@@ -424,47 +406,44 @@ impl Tab {
self.panes.insert(pid, Box::new(new_terminal));
self.active_terminal = Some(pid);
}
- } else {
- // FIXME: This could use a second look
- if let PaneId::Terminal(term_pid) = pid {
- // TODO: check minimum size of active terminal
- let active_pane_id = &self.get_active_pane_id().unwrap();
- let active_pane = self.panes.get_mut(active_pane_id).unwrap();
- if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
- self.send_pty_instructions
- .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
- .unwrap();
- return;
- }
- let terminal_ws = PositionAndSize {
- x: active_pane.x(),
- y: active_pane.y(),
- rows: active_pane.rows(),
- columns: active_pane.columns(),
- };
- let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
+ } else if let PaneId::Terminal(term_pid) = pid {
+ // TODO: check minimum size of active terminal
+ let active_pane_id = &self.get_active_pane_id().unwrap();
+ let active_pane = self.panes.get_mut(active_pane_id).unwrap();
+ if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return;
+ }
+ let terminal_ws = PositionAndSize {
+ x: active_pane.x(),
+ y: active_pane.y(),
+ rows: active_pane.rows(),
+ columns: active_pane.columns(),
+ };
+ let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
+
+ active_pane.change_pos_and_size(&top_winsize);
- active_pane.change_pos_and_size(&top_winsize);
+ let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
+ self.os_api.set_terminal_size_using_fd(
+ new_terminal.pid,
+ bottom_winsize.columns as u16,
+ bottom_winsize.rows as u16,
+ );
+ self.panes.insert(pid, Box::new(new_terminal));
- let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
+ if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd(
- new_terminal.pid,
- bottom_winsize.columns as u16,
- bottom_winsize.rows as u16,
+ *active_terminal_pid,
+ top_winsize.columns as u16,
+ top_winsize.rows as u16,
);
- self.panes.insert(pid, Box::new(new_terminal));
-
- if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
- self.os_api.set_terminal_size_using_fd(
- *active_terminal_pid,
- top_winsize.columns as u16,
- top_winsize.rows as u16,
- );
- }
-
- self.active_terminal = Some(pid);
- self.render();
}
+
+ self.active_terminal = Some(pid);
+ self.render();
}
}
pub fn vertical_split(&mut self, pid: PaneId) {
@@ -473,7 +452,6 @@ impl Tab {
self.toggle_active_pane_fullscreen();
}
if !self.has_panes() {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
self.os_api.set_terminal_size_using_fd(
@@ -484,47 +462,44 @@ impl Tab {
self.panes.insert(pid, Box::new(new_terminal));
self.active_terminal = Some(pid);
}
- } else {
- // FIXME: This could use a second look
- if let PaneId::Terminal(term_pid) = pid {
- // TODO: check minimum size of active terminal
- let active_pane_id = &self.get_active_pane_id().unwrap();
- let active_pane = self.panes.get_mut(active_pane_id).unwrap();
- if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
- self.send_pty_instructions
- .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
- .unwrap();
- return;
- }
- let terminal_ws = PositionAndSize {
- x: active_pane.x(),
- y: active_pane.y(),
- rows: active_pane.rows(),
- columns: active_pane.columns(),
- };
- let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
+ } else if let PaneId::Terminal(term_pid) = pid {
+ // TODO: check minimum size of active terminal
+ let active_pane_id = &self.get_active_pane_id().unwrap();
+ let active_pane = self.panes.get_mut(active_pane_id).unwrap();
+ if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return;
+ }
+ let terminal_ws = PositionAndSize {
+ x: active_pane.x(),
+ y: active_pane.y(),
+ rows: active_pane.rows(),
+ columns: active_pane.columns(),
+ };
+ let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
- active_pane.change_pos_and_size(&left_winsize);
+ active_pane.change_pos_and_size(&left_winsize);
- let new_terminal = TerminalPane::new(term_pid, right_winsize);
+ let new_terminal = TerminalPane::new(term_pid, right_winsize);
+ self.os_api.set_terminal_size_using_fd(
+ new_terminal.pid,
+ right_winsize.columns as u16,
+ right_winsize.rows as u16,
+ );
+ self.panes.insert(pid, Box::new(new_terminal));
+
+ if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd(
- new_terminal.pid,
- right_winsize.columns as u16,
- right_winsize.rows as u16,
+ *active_terminal_pid,
+ left_winsize.columns as u16,
+ left_winsize.rows as u16,
);
- self.panes.insert(pid, Box::new(new_terminal));
-
- if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
- self.os_api.set_terminal_size_using_fd(
- *active_terminal_pid,
- left_winsize.columns as u16,
- left_winsize.rows as u16,
- );
- }
-
- self.active_terminal = Some(pid);
- self.render();
}
+
+ self.active_terminal = Some(pid);
+ self.render();
}
}
pub fn get_active_pane(&self) -> Option<&dyn Pane> {
@@ -568,12 +543,11 @@ impl Tab {
.expect("failed to drain terminal");
}
Some(PaneId::Plugin(pid)) => {
- self.send_plugin_instructions
- .send(PluginInstruction::Input(
- PluginInputType::Normal(pid),
- input_bytes,
- ))
- .unwrap();
+ for key in parse_keys(&input_bytes) {
+ self.send_plugin_instructions
+ .send(PluginInstruction::Update(Some(pid), Event::KeyPress(key)))
+ .unwrap()
+ }
}
_ => {}
}
@@ -1691,6 +1665,7 @@ impl Tab {
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
}
}
+ self.render();
}
pub fn resize_left(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1702,6 +1677,7 @@ impl Tab {
self.reduce_pane_and_surroundings_left(&active_pane_id, count);
}
}
+ self.render();
}
pub fn resize_down(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1713,6 +1689,7 @@ impl Tab {
self.reduce_pane_and_surroundings_down(&active_pane_id, count);
}
}
+ self.render();
}
pub fn resize_up(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1724,6 +1701,7 @@ impl Tab {
self.reduce_pane_and_surroundings_up(&active_pane_id, count);
}
}
+ self.render();
}
pub fn move_focus(&mut self) {
if !self.has_selectable_panes() {