Wrap up the plugin system refactor, running everything through update()
This commit is contained in:
parent
84a5cf95d1
commit
b6f945da35
16 changed files with 121 additions and 307 deletions
|
|
@ -5,8 +5,6 @@ parts:
|
||||||
split_size:
|
split_size:
|
||||||
Fixed: 1
|
Fixed: 1
|
||||||
plugin: tab-bar
|
plugin: tab-bar
|
||||||
events:
|
|
||||||
- Tab
|
|
||||||
- direction: Vertical
|
- direction: Vertical
|
||||||
expansion_boundary: true
|
expansion_boundary: true
|
||||||
- direction: Vertical
|
- direction: Vertical
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ parts:
|
||||||
split_size:
|
split_size:
|
||||||
Fixed: 1
|
Fixed: 1
|
||||||
plugin: tab-bar
|
plugin: tab-bar
|
||||||
events:
|
|
||||||
- Tab
|
|
||||||
- direction: Vertical
|
- direction: Vertical
|
||||||
parts:
|
parts:
|
||||||
- direction: Horizontal
|
- direction: Horizontal
|
||||||
|
|
|
||||||
|
|
@ -12,23 +12,10 @@ pub struct LinePart {
|
||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
enum BarMode {
|
|
||||||
Normal,
|
|
||||||
Rename,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for BarMode {
|
|
||||||
fn default() -> Self {
|
|
||||||
BarMode::Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct State {
|
struct State {
|
||||||
tabs: Vec<TabInfo>,
|
tabs: Vec<TabInfo>,
|
||||||
mode: BarMode,
|
mode: InputMode,
|
||||||
new_name: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ARROW_SEPARATOR: &str = "";
|
static ARROW_SEPARATOR: &str = "";
|
||||||
|
|
@ -51,12 +38,14 @@ impl ZellijTile for State {
|
||||||
set_selectable(false);
|
set_selectable(false);
|
||||||
set_invisible_borders(true);
|
set_invisible_borders(true);
|
||||||
set_max_height(1);
|
set_max_height(1);
|
||||||
subscribe(&[EventType::TabUpdate]);
|
subscribe(&[EventType::TabUpdate, EventType::ModeUpdate]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, event: Event) {
|
fn update(&mut self, event: Event) {
|
||||||
if let Event::TabUpdate(tabs) = event {
|
match event {
|
||||||
self.tabs = tabs;
|
Event::ModeUpdate(mode_info) => self.mode = mode_info.mode,
|
||||||
|
Event::TabUpdate(tabs) => self.tabs = tabs,
|
||||||
|
_ => unimplemented!(), // FIXME: This should be unreachable, but this could be cleaner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,11 +57,9 @@ impl ZellijTile for State {
|
||||||
let mut active_tab_index = 0;
|
let mut active_tab_index = 0;
|
||||||
for t in self.tabs.iter_mut() {
|
for t in self.tabs.iter_mut() {
|
||||||
let mut tabname = t.name.clone();
|
let mut tabname = t.name.clone();
|
||||||
if t.active && self.mode == BarMode::Rename {
|
if t.active && self.mode == InputMode::RenameTab {
|
||||||
if self.new_name.is_empty() {
|
if tabname.is_empty() {
|
||||||
tabname = String::from("Enter name...");
|
tabname = String::from("Enter name...");
|
||||||
} else {
|
|
||||||
tabname = self.new_name.clone();
|
|
||||||
}
|
}
|
||||||
active_tab_index = t.position;
|
active_tab_index = t.position;
|
||||||
} else if t.active {
|
} else if t.active {
|
||||||
|
|
@ -88,19 +75,4 @@ impl ZellijTile for State {
|
||||||
}
|
}
|
||||||
println!("{}\u{1b}[48;5;238m\u{1b}[0K", s);
|
println!("{}\u{1b}[48;5;238m\u{1b}[0K", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_tab_rename_keypress(&mut self, key: Key) {
|
|
||||||
self.mode = BarMode::Rename;
|
|
||||||
match key {
|
|
||||||
Key::Char('\n') | Key::Esc => {
|
|
||||||
self.mode = BarMode::Normal;
|
|
||||||
self.new_name.clear();
|
|
||||||
}
|
|
||||||
Key::Char(c) => self.new_name = format!("{}{}", self.new_name, c),
|
|
||||||
Key::Backspace | Key::Delete => {
|
|
||||||
self.new_name.pop();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
use crate::utils::consts::ZELLIJ_ROOT_LAYOUT_DIR;
|
|
||||||
use directories_next::ProjectDirs;
|
use directories_next::ProjectDirs;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::{fs::File, io::prelude::*};
|
use std::{fs::File, io::prelude::*};
|
||||||
|
|
||||||
use crate::common::wasm_vm::NaughtyEventType;
|
|
||||||
use crate::panes::PositionAndSize;
|
use crate::panes::PositionAndSize;
|
||||||
|
|
||||||
fn split_space_to_parts_vertically(
|
fn split_space_to_parts_vertically(
|
||||||
|
|
@ -181,19 +179,15 @@ pub struct Layout {
|
||||||
pub plugin: Option<PathBuf>,
|
pub plugin: Option<PathBuf>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub expansion_boundary: bool,
|
pub expansion_boundary: bool,
|
||||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
||||||
pub events: Vec<NaughtyEventType>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
pub fn new(layout_path: PathBuf) -> Self {
|
pub fn new(layout_path: PathBuf) -> Self {
|
||||||
let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
|
let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
|
||||||
let layout_dir = project_dirs.data_dir().join("layouts/");
|
let layout_dir = project_dirs.data_dir().join("layouts/");
|
||||||
let root_layout_dir = Path::new(ZELLIJ_ROOT_LAYOUT_DIR);
|
|
||||||
let mut layout_file = File::open(&layout_path)
|
let mut layout_file = File::open(&layout_path)
|
||||||
.or_else(|_| File::open(&layout_path.with_extension("yaml")))
|
.or_else(|_| File::open(&layout_path.with_extension("yaml")))
|
||||||
.or_else(|_| File::open(&layout_dir.join(&layout_path).with_extension("yaml")))
|
.or_else(|_| File::open(&layout_dir.join(&layout_path).with_extension("yaml")))
|
||||||
.or_else(|_| File::open(root_layout_dir.join(&layout_path).with_extension("yaml")))
|
|
||||||
.unwrap_or_else(|_| panic!("cannot find layout {}", &layout_path.display()));
|
.unwrap_or_else(|_| panic!("cannot find layout {}", &layout_path.display()));
|
||||||
|
|
||||||
let mut layout = String::new();
|
let mut layout = String::new();
|
||||||
|
|
|
||||||
|
|
@ -258,11 +258,7 @@ impl Tab {
|
||||||
if let Some(plugin) = &layout.plugin {
|
if let Some(plugin) = &layout.plugin {
|
||||||
let (pid_tx, pid_rx) = channel();
|
let (pid_tx, pid_rx) = channel();
|
||||||
self.send_plugin_instructions
|
self.send_plugin_instructions
|
||||||
.send(PluginInstruction::Load(
|
.send(PluginInstruction::Load(pid_tx, plugin.clone()))
|
||||||
pid_tx,
|
|
||||||
plugin.clone(),
|
|
||||||
layout.events.clone(),
|
|
||||||
))
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let pid = pid_rx.recv().unwrap();
|
let pid = pid_rx.recv().unwrap();
|
||||||
let new_plugin = PluginPane::new(
|
let new_plugin = PluginPane::new(
|
||||||
|
|
@ -301,7 +297,6 @@ impl Tab {
|
||||||
self.toggle_active_pane_fullscreen();
|
self.toggle_active_pane_fullscreen();
|
||||||
}
|
}
|
||||||
if !self.has_panes() {
|
if !self.has_panes() {
|
||||||
// FIXME: This could use a second look
|
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
|
|
@ -352,7 +347,6 @@ impl Tab {
|
||||||
if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns()
|
if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns()
|
||||||
&& terminal_to_split.rows() > terminal_to_split.min_height() * 2
|
&& terminal_to_split.rows() > terminal_to_split.min_height() * 2
|
||||||
{
|
{
|
||||||
// FIXME: This could use a second look
|
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
|
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
|
||||||
let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
|
let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
|
||||||
|
|
@ -373,7 +367,6 @@ impl Tab {
|
||||||
self.active_terminal = Some(pid);
|
self.active_terminal = Some(pid);
|
||||||
}
|
}
|
||||||
} else if terminal_to_split.columns() > terminal_to_split.min_width() * 2 {
|
} 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 {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
|
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
|
||||||
let new_terminal = TerminalPane::new(term_pid, right_winsize);
|
let new_terminal = TerminalPane::new(term_pid, right_winsize);
|
||||||
|
|
@ -403,7 +396,6 @@ impl Tab {
|
||||||
self.toggle_active_pane_fullscreen();
|
self.toggle_active_pane_fullscreen();
|
||||||
}
|
}
|
||||||
if !self.has_panes() {
|
if !self.has_panes() {
|
||||||
// FIXME: This could use a second look
|
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
|
|
@ -414,47 +406,44 @@ impl Tab {
|
||||||
self.panes.insert(pid, Box::new(new_terminal));
|
self.panes.insert(pid, Box::new(new_terminal));
|
||||||
self.active_terminal = Some(pid);
|
self.active_terminal = Some(pid);
|
||||||
}
|
}
|
||||||
} else {
|
} else if let PaneId::Terminal(term_pid) = pid {
|
||||||
// FIXME: This could use a second look
|
// TODO: check minimum size of active terminal
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
let active_pane_id = &self.get_active_pane_id().unwrap();
|
||||||
// TODO: check minimum size of active terminal
|
let active_pane = self.panes.get_mut(active_pane_id).unwrap();
|
||||||
let active_pane_id = &self.get_active_pane_id().unwrap();
|
if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
|
||||||
let active_pane = self.panes.get_mut(active_pane_id).unwrap();
|
self.send_pty_instructions
|
||||||
if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
|
.send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
|
||||||
self.send_pty_instructions
|
.unwrap();
|
||||||
.send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
|
return;
|
||||||
.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);
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn vertical_split(&mut self, pid: PaneId) {
|
pub fn vertical_split(&mut self, pid: PaneId) {
|
||||||
|
|
@ -463,7 +452,6 @@ impl Tab {
|
||||||
self.toggle_active_pane_fullscreen();
|
self.toggle_active_pane_fullscreen();
|
||||||
}
|
}
|
||||||
if !self.has_panes() {
|
if !self.has_panes() {
|
||||||
// FIXME: This could use a second look
|
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
if let PaneId::Terminal(term_pid) = pid {
|
||||||
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
|
|
@ -474,47 +462,44 @@ impl Tab {
|
||||||
self.panes.insert(pid, Box::new(new_terminal));
|
self.panes.insert(pid, Box::new(new_terminal));
|
||||||
self.active_terminal = Some(pid);
|
self.active_terminal = Some(pid);
|
||||||
}
|
}
|
||||||
} else {
|
} else if let PaneId::Terminal(term_pid) = pid {
|
||||||
// FIXME: This could use a second look
|
// TODO: check minimum size of active terminal
|
||||||
if let PaneId::Terminal(term_pid) = pid {
|
let active_pane_id = &self.get_active_pane_id().unwrap();
|
||||||
// TODO: check minimum size of active terminal
|
let active_pane = self.panes.get_mut(active_pane_id).unwrap();
|
||||||
let active_pane_id = &self.get_active_pane_id().unwrap();
|
if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
|
||||||
let active_pane = self.panes.get_mut(active_pane_id).unwrap();
|
self.send_pty_instructions
|
||||||
if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
|
.send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
|
||||||
self.send_pty_instructions
|
.unwrap();
|
||||||
.send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
|
return;
|
||||||
.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);
|
|
||||||
|
|
||||||
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(
|
|
||||||
*active_terminal_pid,
|
|
||||||
left_winsize.columns as u16,
|
|
||||||
left_winsize.rows as u16,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.active_terminal = Some(pid);
|
|
||||||
self.render();
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
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(
|
||||||
|
*active_terminal_pid,
|
||||||
|
left_winsize.columns as u16,
|
||||||
|
left_winsize.rows as u16,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.active_terminal = Some(pid);
|
||||||
|
self.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_active_pane(&self) -> Option<&dyn Pane> {
|
pub fn get_active_pane(&self) -> Option<&dyn Pane> {
|
||||||
|
|
@ -1680,6 +1665,7 @@ impl Tab {
|
||||||
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
|
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.render();
|
||||||
}
|
}
|
||||||
pub fn resize_left(&mut self) {
|
pub fn resize_left(&mut self) {
|
||||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||||
|
|
@ -1691,6 +1677,7 @@ impl Tab {
|
||||||
self.reduce_pane_and_surroundings_left(&active_pane_id, count);
|
self.reduce_pane_and_surroundings_left(&active_pane_id, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.render();
|
||||||
}
|
}
|
||||||
pub fn resize_down(&mut self) {
|
pub fn resize_down(&mut self) {
|
||||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||||
|
|
@ -1702,6 +1689,7 @@ impl Tab {
|
||||||
self.reduce_pane_and_surroundings_down(&active_pane_id, count);
|
self.reduce_pane_and_surroundings_down(&active_pane_id, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.render();
|
||||||
}
|
}
|
||||||
pub fn resize_up(&mut self) {
|
pub fn resize_up(&mut self) {
|
||||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||||
|
|
@ -1713,6 +1701,7 @@ impl Tab {
|
||||||
self.reduce_pane_and_surroundings_up(&active_pane_id, count);
|
self.reduce_pane_and_surroundings_up(&active_pane_id, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.render();
|
||||||
}
|
}
|
||||||
pub fn move_focus(&mut self) {
|
pub fn move_focus(&mut self) {
|
||||||
if !self.has_selectable_panes() {
|
if !self.has_selectable_panes() {
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,6 @@ pub enum PluginContext {
|
||||||
Load,
|
Load,
|
||||||
Update,
|
Update,
|
||||||
Render,
|
Render,
|
||||||
Input,
|
|
||||||
Unload,
|
Unload,
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
@ -293,7 +292,6 @@ impl From<&PluginInstruction> for PluginContext {
|
||||||
PluginInstruction::Load(..) => PluginContext::Load,
|
PluginInstruction::Load(..) => PluginContext::Load,
|
||||||
PluginInstruction::Update(..) => PluginContext::Update,
|
PluginInstruction::Update(..) => PluginContext::Update,
|
||||||
PluginInstruction::Render(..) => PluginContext::Render,
|
PluginInstruction::Render(..) => PluginContext::Render,
|
||||||
PluginInstruction::Input(..) => PluginContext::Input,
|
|
||||||
PluginInstruction::Unload(_) => PluginContext::Unload,
|
PluginInstruction::Unload(_) => PluginContext::Unload,
|
||||||
PluginInstruction::Quit => PluginContext::Quit,
|
PluginInstruction::Quit => PluginContext::Quit,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,5 +49,4 @@ pub enum Action {
|
||||||
CloseTab,
|
CloseTab,
|
||||||
GoToTab(u32),
|
GoToTab(u32),
|
||||||
TabNameInput(Vec<u8>),
|
TabNameInput(Vec<u8>),
|
||||||
SaveTabName,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::errors::ContextType;
|
||||||
use crate::os_input_output::OsApi;
|
use crate::os_input_output::OsApi;
|
||||||
use crate::pty_bus::PtyInstruction;
|
use crate::pty_bus::PtyInstruction;
|
||||||
use crate::screen::ScreenInstruction;
|
use crate::screen::ScreenInstruction;
|
||||||
use crate::wasm_vm::{NaughtyEventType, PluginInputType, PluginInstruction};
|
use crate::wasm_vm::PluginInstruction;
|
||||||
use crate::CommandIsExecuting;
|
use crate::CommandIsExecuting;
|
||||||
|
|
||||||
use termion::input::{TermRead, TermReadEventsAndRaw};
|
use termion::input::{TermRead, TermReadEventsAndRaw};
|
||||||
|
|
@ -66,11 +66,6 @@ impl InputHandler {
|
||||||
Ok((event, raw_bytes)) => match event {
|
Ok((event, raw_bytes)) => match event {
|
||||||
termion::event::Event::Key(key) => {
|
termion::event::Event::Key(key) => {
|
||||||
let key = cast_termion_key(key);
|
let key = cast_termion_key(key);
|
||||||
// FIXME: This is a bit of a hack to get resizing to work!
|
|
||||||
drop(
|
|
||||||
self.send_screen_instructions
|
|
||||||
.send(ScreenInstruction::Render),
|
|
||||||
);
|
|
||||||
// FIXME this explicit break is needed because the current test
|
// FIXME this explicit break is needed because the current test
|
||||||
// framework relies on it to not create dead threads that loop
|
// framework relies on it to not create dead threads that loop
|
||||||
// and eat up CPUs. Do not remove until the test framework has
|
// and eat up CPUs. Do not remove until the test framework has
|
||||||
|
|
@ -237,27 +232,10 @@ impl InputHandler {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
Action::TabNameInput(c) => {
|
Action::TabNameInput(c) => {
|
||||||
self.send_plugin_instructions
|
|
||||||
.send(PluginInstruction::Input(
|
|
||||||
PluginInputType::Event(NaughtyEventType::Tab),
|
|
||||||
c.clone(),
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
self.send_screen_instructions
|
self.send_screen_instructions
|
||||||
.send(ScreenInstruction::UpdateTabName(c))
|
.send(ScreenInstruction::UpdateTabName(c))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
Action::SaveTabName => {
|
|
||||||
self.send_plugin_instructions
|
|
||||||
.send(PluginInstruction::Input(
|
|
||||||
PluginInputType::Event(NaughtyEventType::Tab),
|
|
||||||
vec![b'\n'],
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
self.send_screen_instructions
|
|
||||||
.send(ScreenInstruction::UpdateTabName(vec![b'\n']))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
Action::NoOp => {}
|
Action::NoOp => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -226,10 +226,7 @@ fn get_defaults_for_mode(mode: &InputMode) -> ModeKeybinds {
|
||||||
defaults.insert(Key::Up, vec![Action::ScrollUp]);
|
defaults.insert(Key::Up, vec![Action::ScrollUp]);
|
||||||
}
|
}
|
||||||
InputMode::RenameTab => {
|
InputMode::RenameTab => {
|
||||||
defaults.insert(
|
defaults.insert(Key::Char('\n'), vec![Action::SwitchToMode(InputMode::Tab)]);
|
||||||
Key::Char('\n'),
|
|
||||||
vec![Action::SaveTabName, Action::SwitchToMode(InputMode::Tab)],
|
|
||||||
);
|
|
||||||
defaults.insert(
|
defaults.insert(
|
||||||
Key::Ctrl('g'),
|
Key::Ctrl('g'),
|
||||||
vec![Action::SwitchToMode(InputMode::Normal)],
|
vec![Action::SwitchToMode(InputMode::Normal)],
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ pub mod utils;
|
||||||
pub mod wasm_vm;
|
pub mod wasm_vm;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::{collections::HashMap, fs};
|
use std::{collections::HashMap, fs};
|
||||||
|
|
@ -32,16 +32,12 @@ use os_input_output::OsApi;
|
||||||
use pty_bus::{PtyBus, PtyInstruction};
|
use pty_bus::{PtyBus, PtyInstruction};
|
||||||
use screen::{Screen, ScreenInstruction};
|
use screen::{Screen, ScreenInstruction};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use termion::input::TermRead;
|
use utils::consts::ZELLIJ_IPC_PIPE;
|
||||||
use utils::consts::{ZELLIJ_IPC_PIPE, ZELLIJ_ROOT_PLUGIN_DIR};
|
|
||||||
use wasm_vm::PluginEnv;
|
use wasm_vm::PluginEnv;
|
||||||
use wasm_vm::{
|
use wasm_vm::{wasi_stdout, wasi_write_string, zellij_imports, PluginInstruction};
|
||||||
wasi_stdout, wasi_write_string, zellij_imports, NaughtyEventType, PluginInputType,
|
|
||||||
PluginInstruction,
|
|
||||||
};
|
|
||||||
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
||||||
use wasmer_wasi::{Pipe, WasiState};
|
use wasmer_wasi::{Pipe, WasiState};
|
||||||
use zellij_tile::data::{EventType, InputMode, Key};
|
use zellij_tile::data::{EventType, InputMode};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum ApiCommand {
|
pub enum ApiCommand {
|
||||||
|
|
@ -352,8 +348,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||||
.get_active_tab_mut()
|
.get_active_tab_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_pane_selectable(id, selectable);
|
.set_pane_selectable(id, selectable);
|
||||||
// FIXME: Is this needed?
|
|
||||||
screen.render();
|
|
||||||
}
|
}
|
||||||
ScreenInstruction::SetMaxHeight(id, max_height) => {
|
ScreenInstruction::SetMaxHeight(id, max_height) => {
|
||||||
screen
|
screen
|
||||||
|
|
@ -417,42 +411,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let mut plugin_id = 0;
|
let mut plugin_id = 0;
|
||||||
let mut plugin_map = HashMap::new();
|
let mut plugin_map = HashMap::new();
|
||||||
let handler_map: HashMap<NaughtyEventType, String> = [(
|
|
||||||
NaughtyEventType::Tab,
|
|
||||||
"handle_tab_rename_keypress".to_string(),
|
|
||||||
)]
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
move || loop {
|
move || loop {
|
||||||
// FIXME: This 100% *must* be destroyed before this makes in into main!!!!!!!!!!!
|
|
||||||
fn cast_termion_key(event: termion::event::Key) -> Key {
|
|
||||||
match event {
|
|
||||||
termion::event::Key::Backspace => Key::Backspace,
|
|
||||||
termion::event::Key::Left => Key::Left,
|
|
||||||
termion::event::Key::Right => Key::Right,
|
|
||||||
termion::event::Key::Up => Key::Up,
|
|
||||||
termion::event::Key::Down => Key::Down,
|
|
||||||
termion::event::Key::Home => Key::Home,
|
|
||||||
termion::event::Key::End => Key::End,
|
|
||||||
termion::event::Key::PageUp => Key::PageUp,
|
|
||||||
termion::event::Key::PageDown => Key::PageDown,
|
|
||||||
termion::event::Key::BackTab => Key::BackTab,
|
|
||||||
termion::event::Key::Delete => Key::Delete,
|
|
||||||
termion::event::Key::Insert => Key::Insert,
|
|
||||||
termion::event::Key::F(n) => Key::F(n),
|
|
||||||
termion::event::Key::Char(c) => Key::Char(c),
|
|
||||||
termion::event::Key::Alt(c) => Key::Alt(c),
|
|
||||||
termion::event::Key::Ctrl(c) => Key::Ctrl(c),
|
|
||||||
termion::event::Key::Null => Key::Null,
|
|
||||||
termion::event::Key::Esc => Key::Esc,
|
|
||||||
_ => {
|
|
||||||
unimplemented!("Encountered an unknown key!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (event, mut err_ctx) = receive_plugin_instructions
|
let (event, mut err_ctx) = receive_plugin_instructions
|
||||||
.recv()
|
.recv()
|
||||||
.expect("failed to receive event on channel");
|
.expect("failed to receive event on channel");
|
||||||
|
|
@ -461,18 +420,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||||
send_pty_instructions.update(err_ctx);
|
send_pty_instructions.update(err_ctx);
|
||||||
send_app_instructions.update(err_ctx);
|
send_app_instructions.update(err_ctx);
|
||||||
match event {
|
match event {
|
||||||
PluginInstruction::Load(pid_tx, path, events) => {
|
PluginInstruction::Load(pid_tx, path) => {
|
||||||
let project_dirs =
|
let project_dirs =
|
||||||
ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
|
ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
|
||||||
let plugin_dir = project_dirs.data_dir().join("plugins/");
|
let plugin_dir = project_dirs.data_dir().join("plugins/");
|
||||||
// FIXME: This really shouldn't need to exist anymore, let's get rid of it!
|
|
||||||
let root_plugin_dir = Path::new(ZELLIJ_ROOT_PLUGIN_DIR);
|
|
||||||
let wasm_bytes = fs::read(&path)
|
let wasm_bytes = fs::read(&path)
|
||||||
.or_else(|_| fs::read(&path.with_extension("wasm")))
|
.or_else(|_| fs::read(&path.with_extension("wasm")))
|
||||||
.or_else(|_| fs::read(&plugin_dir.join(&path).with_extension("wasm")))
|
.or_else(|_| fs::read(&plugin_dir.join(&path).with_extension("wasm")))
|
||||||
.or_else(|_| {
|
|
||||||
fs::read(&root_plugin_dir.join(&path).with_extension("wasm"))
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|_| panic!("cannot find plugin {}", &path.display()));
|
.unwrap_or_else(|_| panic!("cannot find plugin {}", &path.display()));
|
||||||
|
|
||||||
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
|
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
|
||||||
|
|
@ -504,7 +458,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||||
send_app_instructions: send_app_instructions.clone(),
|
send_app_instructions: send_app_instructions.clone(),
|
||||||
wasi_env,
|
wasi_env,
|
||||||
subscriptions: Arc::new(Mutex::new(HashSet::new())),
|
subscriptions: Arc::new(Mutex::new(HashSet::new())),
|
||||||
events,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let zellij = zellij_imports(&store, &plugin_env);
|
let zellij = zellij_imports(&store, &plugin_env);
|
||||||
|
|
@ -546,29 +499,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||||
|
|
||||||
buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap();
|
buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap();
|
||||||
}
|
}
|
||||||
// FIXME: Deduplicate this with the callback below!
|
|
||||||
PluginInstruction::Input(input_type, input_bytes) => {
|
|
||||||
let PluginInputType::Event(event) = input_type;
|
|
||||||
for (instance, plugin_env) in plugin_map.values() {
|
|
||||||
if !plugin_env.events.contains(&event) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let handle_key = instance
|
|
||||||
.exports
|
|
||||||
.get_function(handler_map.get(&event).unwrap())
|
|
||||||
.unwrap();
|
|
||||||
for key in input_bytes.keys().flatten() {
|
|
||||||
let key = cast_termion_key(key);
|
|
||||||
wasi_write_string(
|
|
||||||
&plugin_env.wasi_env,
|
|
||||||
&serde_json::to_string(&key).unwrap(),
|
|
||||||
);
|
|
||||||
handle_key.call(&[]).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(send_screen_instructions.send(ScreenInstruction::Render));
|
|
||||||
}
|
|
||||||
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
|
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
|
||||||
PluginInstruction::Quit => break,
|
PluginInstruction::Quit => break,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,15 +82,10 @@ fn handle_command_exit(mut child: Child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for signal in signals.pending() {
|
for signal in signals.pending() {
|
||||||
// FIXME: We need to handle more signals here!
|
if signal == signal_hook::SIGINT {
|
||||||
#[allow(clippy::single_match)]
|
child.kill().unwrap();
|
||||||
match signal {
|
child.wait().unwrap();
|
||||||
signal_hook::SIGINT => {
|
break 'handle_exit;
|
||||||
child.kill().unwrap();
|
|
||||||
child.wait().unwrap();
|
|
||||||
break 'handle_exit;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ pub struct Screen {
|
||||||
active_tab_index: Option<usize>,
|
active_tab_index: Option<usize>,
|
||||||
/// The [`OsApi`] this [`Screen`] uses.
|
/// The [`OsApi`] this [`Screen`] uses.
|
||||||
os_api: Box<dyn OsApi>,
|
os_api: Box<dyn OsApi>,
|
||||||
tabname_buf: String,
|
|
||||||
input_mode: InputMode,
|
input_mode: InputMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,7 +99,6 @@ impl Screen {
|
||||||
active_tab_index: None,
|
active_tab_index: None,
|
||||||
tabs: BTreeMap::new(),
|
tabs: BTreeMap::new(),
|
||||||
os_api,
|
os_api,
|
||||||
tabname_buf: String::new(),
|
|
||||||
input_mode,
|
input_mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -288,25 +286,20 @@ impl Screen {
|
||||||
|
|
||||||
pub fn update_active_tab_name(&mut self, buf: Vec<u8>) {
|
pub fn update_active_tab_name(&mut self, buf: Vec<u8>) {
|
||||||
let s = str::from_utf8(&buf).unwrap();
|
let s = str::from_utf8(&buf).unwrap();
|
||||||
|
let active_tab = self.get_active_tab_mut().unwrap();
|
||||||
match s {
|
match s {
|
||||||
"\0" => {
|
"\0" => {
|
||||||
self.tabname_buf = String::new();
|
active_tab.name = String::new();
|
||||||
}
|
|
||||||
"\n" => {
|
|
||||||
let new_name = self.tabname_buf.clone();
|
|
||||||
let active_tab = self.get_active_tab_mut().unwrap();
|
|
||||||
active_tab.name = new_name;
|
|
||||||
self.update_tabs();
|
|
||||||
self.render();
|
|
||||||
}
|
}
|
||||||
"\u{007F}" | "\u{0008}" => {
|
"\u{007F}" | "\u{0008}" => {
|
||||||
//delete and backspace keys
|
//delete and backspace keys
|
||||||
self.tabname_buf.pop();
|
active_tab.name.pop();
|
||||||
}
|
}
|
||||||
c => {
|
c => {
|
||||||
self.tabname_buf.push_str(c);
|
active_tab.name.push_str(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.update_tabs();
|
||||||
}
|
}
|
||||||
pub fn change_input_mode(&mut self, input_mode: InputMode) {
|
pub fn change_input_mode(&mut self, input_mode: InputMode) {
|
||||||
self.input_mode = input_mode;
|
self.input_mode = input_mode;
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,3 @@ pub const ZELLIJ_TMP_DIR: &str = "/tmp/zellij";
|
||||||
pub const ZELLIJ_TMP_LOG_DIR: &str = "/tmp/zellij/zellij-log";
|
pub const ZELLIJ_TMP_LOG_DIR: &str = "/tmp/zellij/zellij-log";
|
||||||
pub const ZELLIJ_TMP_LOG_FILE: &str = "/tmp/zellij/zellij-log/log.txt";
|
pub const ZELLIJ_TMP_LOG_FILE: &str = "/tmp/zellij/zellij-log/log.txt";
|
||||||
pub const ZELLIJ_IPC_PIPE: &str = "/tmp/zellij/ipc";
|
pub const ZELLIJ_IPC_PIPE: &str = "/tmp/zellij/ipc";
|
||||||
pub const ZELLIJ_ROOT_PLUGIN_DIR: &str = "/usr/share/zellij/plugins";
|
|
||||||
pub const ZELLIJ_ROOT_LAYOUT_DIR: &str = "/usr/share/zellij/layouts";
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
|
@ -12,22 +11,11 @@ use super::{
|
||||||
pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext,
|
pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Hash, Eq, Serialize, Deserialize)]
|
|
||||||
pub enum NaughtyEventType {
|
|
||||||
Tab,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum PluginInputType {
|
|
||||||
Event(NaughtyEventType),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PluginInstruction {
|
pub enum PluginInstruction {
|
||||||
Load(Sender<u32>, PathBuf, Vec<NaughtyEventType>),
|
Load(Sender<u32>, PathBuf),
|
||||||
Update(Option<u32>, Event), // Focused plugin / broadcast, event data
|
Update(Option<u32>, Event), // Focused plugin / broadcast, event data
|
||||||
Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
|
Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
|
||||||
Input(PluginInputType, Vec<u8>), // plugin id, input bytes
|
|
||||||
Unload(u32),
|
Unload(u32),
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +28,6 @@ pub struct PluginEnv {
|
||||||
pub send_pty_instructions: SenderWithContext<PtyInstruction>, // FIXME: This should be a big bundle of all of the channels
|
pub send_pty_instructions: SenderWithContext<PtyInstruction>, // FIXME: This should be a big bundle of all of the channels
|
||||||
pub wasi_env: WasiEnv,
|
pub wasi_env: WasiEnv,
|
||||||
pub subscriptions: Arc<Mutex<HashSet<EventType>>>,
|
pub subscriptions: Arc<Mutex<HashSet<EventType>>>,
|
||||||
pub events: Vec<NaughtyEventType>, // FIXME: Murder this very soon (should not survive into main)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin API ---------------------------------------------------------------------------------------------------------
|
// Plugin API ---------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ pub trait ZellijTile {
|
||||||
fn load(&mut self) {}
|
fn load(&mut self) {}
|
||||||
fn update(&mut self, event: Event) {}
|
fn update(&mut self, event: Event) {}
|
||||||
fn render(&mut self, rows: usize, cols: usize) {}
|
fn render(&mut self, rows: usize, cols: usize) {}
|
||||||
// FIXME: Everything below this line should be purged
|
|
||||||
fn handle_tab_rename_keypress(&mut self, key: Key) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
@ -29,9 +27,7 @@ macro_rules! register_tile {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn update() {
|
pub fn update() {
|
||||||
STATE.with(|state| {
|
STATE.with(|state| {
|
||||||
state
|
state.borrow_mut().update($crate::shim::object_from_stdin());
|
||||||
.borrow_mut()
|
|
||||||
.update($crate::shim::deserialize_from_stdin().unwrap());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,14 +37,5 @@ macro_rules! register_tile {
|
||||||
state.borrow_mut().render(rows as usize, cols as usize);
|
state.borrow_mut().render(rows as usize, cols as usize);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn handle_tab_rename_keypress() {
|
|
||||||
STATE.with(|state| {
|
|
||||||
state
|
|
||||||
.borrow_mut()
|
|
||||||
.handle_tab_rename_keypress($crate::shim::get_key());
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,7 @@ use std::{io, path::Path};
|
||||||
|
|
||||||
use crate::data::*;
|
use crate::data::*;
|
||||||
|
|
||||||
pub fn get_key() -> Key {
|
// Subscription Handling
|
||||||
deserialize_from_stdin().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn subscribe(event_types: &[EventType]) {
|
pub fn subscribe(event_types: &[EventType]) {
|
||||||
println!("{}", serde_json::to_string(event_types).unwrap());
|
println!("{}", serde_json::to_string(event_types).unwrap());
|
||||||
|
|
@ -17,31 +15,34 @@ pub fn unsubscribe(event_types: &[EventType]) {
|
||||||
unsafe { host_unsubscribe() };
|
unsafe { host_unsubscribe() };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file(path: &Path) {
|
// Plugin Settings
|
||||||
println!("{}", path.to_string_lossy());
|
|
||||||
unsafe { host_open_file() };
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_max_height(max_height: i32) {
|
pub fn set_max_height(max_height: i32) {
|
||||||
unsafe { host_set_max_height(max_height) };
|
unsafe { host_set_max_height(max_height) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_invisible_borders(invisible_borders: bool) {
|
pub fn set_invisible_borders(invisible_borders: bool) {
|
||||||
let invisible_borders = if invisible_borders { 1 } else { 0 };
|
unsafe { host_set_invisible_borders(if invisible_borders { 1 } else { 0 }) };
|
||||||
unsafe { host_set_invisible_borders(invisible_borders) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_selectable(selectable: bool) {
|
pub fn set_selectable(selectable: bool) {
|
||||||
let selectable = if selectable { 1 } else { 0 };
|
unsafe { host_set_selectable(if selectable { 1 } else { 0 }) };
|
||||||
unsafe { host_set_selectable(selectable) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Host Functions
|
||||||
|
|
||||||
|
pub fn open_file(path: &Path) {
|
||||||
|
println!("{}", path.to_string_lossy());
|
||||||
|
unsafe { host_open_file() };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal Functions
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
// FIXME: Make this just return T and do a .unwrap() at the end; also naming?
|
pub fn object_from_stdin<T: DeserializeOwned>() -> T {
|
||||||
pub fn deserialize_from_stdin<T: DeserializeOwned>() -> Option<T> {
|
|
||||||
let mut json = String::new();
|
let mut json = String::new();
|
||||||
io::stdin().read_line(&mut json).unwrap();
|
io::stdin().read_line(&mut json).unwrap();
|
||||||
serde_json::from_str(&json).ok()
|
serde_json::from_str(&json).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[link(wasm_import_module = "zellij")]
|
#[link(wasm_import_module = "zellij")]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue