mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-25 18:21:51 +03:00
Initial implementation of the update callback + upstream termion
This commit is contained in:
parent
9bc7a268ce
commit
ac55e59047
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -1269,12 +1269,6 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.5"
|
||||
@ -1290,7 +1284,7 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
|
||||
dependencies = [
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1300,7 +1294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1621,7 +1615,7 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
@ -1637,16 +1631,15 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion_temporary_zellij_fork"
|
||||
version = "1.6.0"
|
||||
name = "termion"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65175afb01727f72d690bc8b2a2ac411c0243ec43988b7bd96d428301197bed0"
|
||||
checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"numtoa",
|
||||
"redox_syscall 0.1.57",
|
||||
"redox_syscall",
|
||||
"redox_termios",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2269,7 +2262,7 @@ dependencies = [
|
||||
"strip-ansi-escapes",
|
||||
"structopt",
|
||||
"strum",
|
||||
"termion_temporary_zellij_fork",
|
||||
"termion",
|
||||
"termios",
|
||||
"toml",
|
||||
"unicode-truncate",
|
||||
|
@ -27,7 +27,7 @@ signal-hook = "0.1.10"
|
||||
strip-ansi-escapes = "0.1.0"
|
||||
structopt = "0.3"
|
||||
# termion = { git = "https://gitlab.com/TheLostLambda/termion.git", version = "1.6.0", features = ["serde"] }
|
||||
termion = { package = "termion_temporary_zellij_fork", version = "1.6.0", features = ["serde"]}
|
||||
termion = "1.5.0"
|
||||
termios = "0.3"
|
||||
unicode-truncate = "0.2.0"
|
||||
unicode-width = "0.1.8"
|
||||
|
@ -278,6 +278,7 @@ use crate::wasm_vm::PluginInstruction;
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum PluginContext {
|
||||
Load,
|
||||
Update,
|
||||
Render,
|
||||
Input,
|
||||
GlobalInput,
|
||||
@ -290,6 +291,7 @@ impl From<&PluginInstruction> for PluginContext {
|
||||
fn from(plugin_instruction: &PluginInstruction) -> Self {
|
||||
match *plugin_instruction {
|
||||
PluginInstruction::Load(..) => PluginContext::Load,
|
||||
PluginInstruction::Update(_) => PluginContext::Update,
|
||||
PluginInstruction::Render(..) => PluginContext::Render,
|
||||
PluginInstruction::Input(..) => PluginContext::Input,
|
||||
PluginInstruction::GlobalInput(_) => PluginContext::GlobalInput,
|
||||
|
@ -11,7 +11,7 @@ use crate::wasm_vm::{NaughtyEventType, PluginInputType, PluginInstruction};
|
||||
use crate::CommandIsExecuting;
|
||||
|
||||
use termion::input::TermReadEventsAndRaw;
|
||||
use zellij_tile::data::{Help, InputMode};
|
||||
use zellij_tile::data::{Event, Help, InputMode, Key};
|
||||
|
||||
use super::keybinds::key_to_actions;
|
||||
|
||||
@ -61,6 +61,7 @@ impl InputHandler {
|
||||
'input_loop: loop {
|
||||
//@@@ I think this should actually just iterate over stdin directly
|
||||
let stdin_buffer = self.os_input.read_from_stdin();
|
||||
// FIXME: Kill me someday (soon)
|
||||
drop(
|
||||
self.send_plugin_instructions
|
||||
.send(PluginInstruction::GlobalInput(stdin_buffer.clone())),
|
||||
@ -69,6 +70,11 @@ impl InputHandler {
|
||||
match key_result {
|
||||
Ok((event, raw_bytes)) => match event {
|
||||
termion::event::Event::Key(key) => {
|
||||
let key = cast_termion_key(key);
|
||||
drop(
|
||||
self.send_plugin_instructions
|
||||
.send(PluginInstruction::Update(Event::KeyPress(key))),
|
||||
);
|
||||
// FIXME this explicit break is needed because the current test
|
||||
// framework relies on it to not create dead threads that loop
|
||||
// and eat up CPUs. Do not remove until the test framework has
|
||||
@ -320,3 +326,31 @@ pub fn input_loop(
|
||||
)
|
||||
.handle_input();
|
||||
}
|
||||
|
||||
// FIXME: This is an absolutely cursed function that should be destroyed as soon
|
||||
// as an alternative that doesn't touch zellij-tile can be developed...
|
||||
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!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use super::actions::{Action, Direction};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use strum::IntoEnumIterator;
|
||||
use termion::event::Key;
|
||||
use zellij_tile::data::*;
|
||||
|
||||
type Keybinds = HashMap<InputMode, ModeKeybinds>;
|
||||
|
@ -40,7 +40,7 @@ use wasm_vm::{
|
||||
};
|
||||
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
||||
use wasmer_wasi::{Pipe, WasiState};
|
||||
use zellij_tile::data::InputMode;
|
||||
use zellij_tile::data::{InputMode, Key};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum ApiCommand {
|
||||
@ -456,6 +456,33 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
.collect();
|
||||
|
||||
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
|
||||
.recv()
|
||||
.expect("failed to receive event on channel");
|
||||
@ -522,6 +549,17 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
pid_tx.send(plugin_id).unwrap();
|
||||
plugin_id += 1;
|
||||
}
|
||||
PluginInstruction::Update(event) => {
|
||||
for (instance, plugin_env) in plugin_map.values() {
|
||||
let update = instance.exports.get_function("update").unwrap();
|
||||
|
||||
wasi_write_string(
|
||||
&plugin_env.wasi_env,
|
||||
&serde_json::to_string(&event).unwrap(),
|
||||
);
|
||||
update.call(&[]).unwrap();
|
||||
}
|
||||
}
|
||||
PluginInstruction::Render(buf_tx, pid, rows, cols) => {
|
||||
let (instance, plugin_env) = plugin_map.get(&pid).unwrap();
|
||||
|
||||
@ -555,6 +593,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
let handle_key =
|
||||
instance.exports.get_function("handle_key").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(),
|
||||
@ -572,6 +611,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
.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(),
|
||||
@ -589,6 +629,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
let handler =
|
||||
instance.exports.get_function("handle_global_key").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(),
|
||||
|
@ -9,7 +9,7 @@ use std::{
|
||||
};
|
||||
use wasmer::{imports, Function, ImportObject, Store, WasmerEnv};
|
||||
use wasmer_wasi::WasiEnv;
|
||||
use zellij_tile::data::{EventType, TabInfo};
|
||||
use zellij_tile::data::{Event, EventType, TabInfo};
|
||||
|
||||
use super::{
|
||||
input::handler::get_help, pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction,
|
||||
@ -30,6 +30,7 @@ pub enum PluginInputType {
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PluginInstruction {
|
||||
Load(Sender<u32>, PathBuf, Vec<NaughtyEventType>),
|
||||
Update(Event),
|
||||
Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
|
||||
Input(PluginInputType, Vec<u8>), // plugin id, input bytes
|
||||
GlobalInput(Vec<u8>), // input bytes
|
||||
|
@ -23,7 +23,7 @@ pub enum Key {
|
||||
Esc,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
||||
#[strum_discriminants(derive(Hash, Serialize, Deserialize))]
|
||||
#[strum_discriminants(name(EventType))]
|
||||
pub enum Event {
|
||||
|
@ -7,6 +7,7 @@ use data::*;
|
||||
#[allow(unused_variables)]
|
||||
pub trait ZellijTile {
|
||||
fn load(&mut self) {}
|
||||
fn update(&mut self, event: Event) {}
|
||||
fn render(&mut self, rows: usize, cols: usize) {}
|
||||
// FIXME: Everything below this line should be purged
|
||||
fn handle_key(&mut self, key: Key) {}
|
||||
@ -28,6 +29,15 @@ macro_rules! register_tile {
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn update() {
|
||||
STATE.with(|state| {
|
||||
state
|
||||
.borrow_mut()
|
||||
.update($crate::shim::deserialize_from_stdin().unwrap());
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn render(rows: i32, cols: i32) {
|
||||
STATE.with(|state| {
|
||||
|
@ -45,7 +45,9 @@ pub fn get_tabs() -> Vec<TabInfo> {
|
||||
deserialize_from_stdin().unwrap_or_default()
|
||||
}
|
||||
|
||||
fn deserialize_from_stdin<T: DeserializeOwned>() -> Option<T> {
|
||||
#[doc(hidden)]
|
||||
// FIXME: Make this just return T and do a .unwrap() at the end; also naming?
|
||||
pub fn deserialize_from_stdin<T: DeserializeOwned>() -> Option<T> {
|
||||
let mut json = String::new();
|
||||
io::stdin().read_line(&mut json).unwrap();
|
||||
serde_json::from_str(&json).ok()
|
||||
|
Loading…
Reference in New Issue
Block a user