mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-26 02:32:21 +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",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.1.57"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@ -1290,7 +1284,7 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
|
checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"redox_syscall 0.2.5",
|
"redox_syscall",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1300,7 +1294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"redox_syscall 0.2.5",
|
"redox_syscall",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1621,7 +1615,7 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"rand",
|
"rand",
|
||||||
"redox_syscall 0.2.5",
|
"redox_syscall",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
@ -1637,16 +1631,15 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termion_temporary_zellij_fork"
|
name = "termion"
|
||||||
version = "1.6.0"
|
version = "1.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "65175afb01727f72d690bc8b2a2ac411c0243ec43988b7bd96d428301197bed0"
|
checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"numtoa",
|
"numtoa",
|
||||||
"redox_syscall 0.1.57",
|
"redox_syscall",
|
||||||
"redox_termios",
|
"redox_termios",
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2269,7 +2262,7 @@ dependencies = [
|
|||||||
"strip-ansi-escapes",
|
"strip-ansi-escapes",
|
||||||
"structopt",
|
"structopt",
|
||||||
"strum",
|
"strum",
|
||||||
"termion_temporary_zellij_fork",
|
"termion",
|
||||||
"termios",
|
"termios",
|
||||||
"toml",
|
"toml",
|
||||||
"unicode-truncate",
|
"unicode-truncate",
|
||||||
|
@ -27,7 +27,7 @@ signal-hook = "0.1.10"
|
|||||||
strip-ansi-escapes = "0.1.0"
|
strip-ansi-escapes = "0.1.0"
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
# termion = { git = "https://gitlab.com/TheLostLambda/termion.git", version = "1.6.0", features = ["serde"] }
|
# 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"
|
termios = "0.3"
|
||||||
unicode-truncate = "0.2.0"
|
unicode-truncate = "0.2.0"
|
||||||
unicode-width = "0.1.8"
|
unicode-width = "0.1.8"
|
||||||
|
@ -278,6 +278,7 @@ use crate::wasm_vm::PluginInstruction;
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum PluginContext {
|
pub enum PluginContext {
|
||||||
Load,
|
Load,
|
||||||
|
Update,
|
||||||
Render,
|
Render,
|
||||||
Input,
|
Input,
|
||||||
GlobalInput,
|
GlobalInput,
|
||||||
@ -290,6 +291,7 @@ impl From<&PluginInstruction> for PluginContext {
|
|||||||
fn from(plugin_instruction: &PluginInstruction) -> Self {
|
fn from(plugin_instruction: &PluginInstruction) -> Self {
|
||||||
match *plugin_instruction {
|
match *plugin_instruction {
|
||||||
PluginInstruction::Load(..) => PluginContext::Load,
|
PluginInstruction::Load(..) => PluginContext::Load,
|
||||||
|
PluginInstruction::Update(_) => PluginContext::Update,
|
||||||
PluginInstruction::Render(..) => PluginContext::Render,
|
PluginInstruction::Render(..) => PluginContext::Render,
|
||||||
PluginInstruction::Input(..) => PluginContext::Input,
|
PluginInstruction::Input(..) => PluginContext::Input,
|
||||||
PluginInstruction::GlobalInput(_) => PluginContext::GlobalInput,
|
PluginInstruction::GlobalInput(_) => PluginContext::GlobalInput,
|
||||||
|
@ -11,7 +11,7 @@ use crate::wasm_vm::{NaughtyEventType, PluginInputType, PluginInstruction};
|
|||||||
use crate::CommandIsExecuting;
|
use crate::CommandIsExecuting;
|
||||||
|
|
||||||
use termion::input::TermReadEventsAndRaw;
|
use termion::input::TermReadEventsAndRaw;
|
||||||
use zellij_tile::data::{Help, InputMode};
|
use zellij_tile::data::{Event, Help, InputMode, Key};
|
||||||
|
|
||||||
use super::keybinds::key_to_actions;
|
use super::keybinds::key_to_actions;
|
||||||
|
|
||||||
@ -61,6 +61,7 @@ impl InputHandler {
|
|||||||
'input_loop: loop {
|
'input_loop: loop {
|
||||||
//@@@ I think this should actually just iterate over stdin directly
|
//@@@ I think this should actually just iterate over stdin directly
|
||||||
let stdin_buffer = self.os_input.read_from_stdin();
|
let stdin_buffer = self.os_input.read_from_stdin();
|
||||||
|
// FIXME: Kill me someday (soon)
|
||||||
drop(
|
drop(
|
||||||
self.send_plugin_instructions
|
self.send_plugin_instructions
|
||||||
.send(PluginInstruction::GlobalInput(stdin_buffer.clone())),
|
.send(PluginInstruction::GlobalInput(stdin_buffer.clone())),
|
||||||
@ -69,6 +70,11 @@ impl InputHandler {
|
|||||||
match key_result {
|
match key_result {
|
||||||
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);
|
||||||
|
drop(
|
||||||
|
self.send_plugin_instructions
|
||||||
|
.send(PluginInstruction::Update(Event::KeyPress(key))),
|
||||||
|
);
|
||||||
// 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
|
||||||
@ -320,3 +326,31 @@ pub fn input_loop(
|
|||||||
)
|
)
|
||||||
.handle_input();
|
.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 std::collections::HashMap;
|
||||||
|
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use termion::event::Key;
|
|
||||||
use zellij_tile::data::*;
|
use zellij_tile::data::*;
|
||||||
|
|
||||||
type Keybinds = HashMap<InputMode, ModeKeybinds>;
|
type Keybinds = HashMap<InputMode, ModeKeybinds>;
|
||||||
|
@ -40,7 +40,7 @@ use wasm_vm::{
|
|||||||
};
|
};
|
||||||
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::InputMode;
|
use zellij_tile::data::{InputMode, Key};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum ApiCommand {
|
pub enum ApiCommand {
|
||||||
@ -456,6 +456,33 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
.collect();
|
.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");
|
||||||
@ -522,6 +549,17 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
pid_tx.send(plugin_id).unwrap();
|
pid_tx.send(plugin_id).unwrap();
|
||||||
plugin_id += 1;
|
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) => {
|
PluginInstruction::Render(buf_tx, pid, rows, cols) => {
|
||||||
let (instance, plugin_env) = plugin_map.get(&pid).unwrap();
|
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 =
|
let handle_key =
|
||||||
instance.exports.get_function("handle_key").unwrap();
|
instance.exports.get_function("handle_key").unwrap();
|
||||||
for key in input_bytes.keys().flatten() {
|
for key in input_bytes.keys().flatten() {
|
||||||
|
let key = cast_termion_key(key);
|
||||||
wasi_write_string(
|
wasi_write_string(
|
||||||
&plugin_env.wasi_env,
|
&plugin_env.wasi_env,
|
||||||
&serde_json::to_string(&key).unwrap(),
|
&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())
|
.get_function(handler_map.get(&event).unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for key in input_bytes.keys().flatten() {
|
for key in input_bytes.keys().flatten() {
|
||||||
|
let key = cast_termion_key(key);
|
||||||
wasi_write_string(
|
wasi_write_string(
|
||||||
&plugin_env.wasi_env,
|
&plugin_env.wasi_env,
|
||||||
&serde_json::to_string(&key).unwrap(),
|
&serde_json::to_string(&key).unwrap(),
|
||||||
@ -589,6 +629,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
let handler =
|
let handler =
|
||||||
instance.exports.get_function("handle_global_key").unwrap();
|
instance.exports.get_function("handle_global_key").unwrap();
|
||||||
for key in input_bytes.keys().flatten() {
|
for key in input_bytes.keys().flatten() {
|
||||||
|
let key = cast_termion_key(key);
|
||||||
wasi_write_string(
|
wasi_write_string(
|
||||||
&plugin_env.wasi_env,
|
&plugin_env.wasi_env,
|
||||||
&serde_json::to_string(&key).unwrap(),
|
&serde_json::to_string(&key).unwrap(),
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use wasmer::{imports, Function, ImportObject, Store, WasmerEnv};
|
use wasmer::{imports, Function, ImportObject, Store, WasmerEnv};
|
||||||
use wasmer_wasi::WasiEnv;
|
use wasmer_wasi::WasiEnv;
|
||||||
use zellij_tile::data::{EventType, TabInfo};
|
use zellij_tile::data::{Event, EventType, TabInfo};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
input::handler::get_help, pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction,
|
input::handler::get_help, pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction,
|
||||||
@ -30,6 +30,7 @@ pub enum PluginInputType {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PluginInstruction {
|
pub enum PluginInstruction {
|
||||||
Load(Sender<u32>, PathBuf, Vec<NaughtyEventType>),
|
Load(Sender<u32>, PathBuf, Vec<NaughtyEventType>),
|
||||||
|
Update(Event),
|
||||||
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
|
Input(PluginInputType, Vec<u8>), // plugin id, input bytes
|
||||||
GlobalInput(Vec<u8>), // input bytes
|
GlobalInput(Vec<u8>), // input bytes
|
||||||
|
@ -23,7 +23,7 @@ pub enum Key {
|
|||||||
Esc,
|
Esc,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
#[derive(Debug, Clone, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
||||||
#[strum_discriminants(derive(Hash, Serialize, Deserialize))]
|
#[strum_discriminants(derive(Hash, Serialize, Deserialize))]
|
||||||
#[strum_discriminants(name(EventType))]
|
#[strum_discriminants(name(EventType))]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
@ -7,6 +7,7 @@ use data::*;
|
|||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub trait ZellijTile {
|
pub trait ZellijTile {
|
||||||
fn load(&mut self) {}
|
fn load(&mut self) {}
|
||||||
|
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
|
// FIXME: Everything below this line should be purged
|
||||||
fn handle_key(&mut self, key: Key) {}
|
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]
|
#[no_mangle]
|
||||||
pub fn render(rows: i32, cols: i32) {
|
pub fn render(rows: i32, cols: i32) {
|
||||||
STATE.with(|state| {
|
STATE.with(|state| {
|
||||||
|
@ -45,7 +45,9 @@ pub fn get_tabs() -> Vec<TabInfo> {
|
|||||||
deserialize_from_stdin().unwrap_or_default()
|
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();
|
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).ok()
|
||||||
|
Loading…
Reference in New Issue
Block a user