diff options
| author | Brooks Rady <b.j.rady@gmail.com> | 2021-03-26 13:20:06 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-26 13:20:06 +0000 |
| commit | d818661c727a59312e1a43432e84fbeec79fc145 (patch) | |
| tree | e8ab04124ee7f5c87cd88be63c1867c7d9b2289c /src/client/tab.rs | |
| parent | fix(render): various rendering issues (#238) (diff) | |
| parent | Fix some overzealous format!() removals and a stray comment (diff) | |
| download | sl0ppij-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.rs | 184 |
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() { |
