summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrooks J Rady <b.j.rady@gmail.com>2021-04-27 14:57:54 +0100
committerBrooks J Rady <b.j.rady@gmail.com>2021-04-27 14:57:54 +0100
commit2814c3027271d15b4af345bdde03591bb189cbce (patch)
tree192290907893d4454c23360f1c5f6f66118af30d
parentea1a7dfc7d35585232193f7da30466ce8ee575dc (diff)
feat(plugin): added the `get_plugin_ids()` query function
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/common/mod.rs10
-rw-r--r--src/common/wasm_vm.rs59
-rw-r--r--zellij-tile/Cargo.toml2
-rw-r--r--zellij-tile/src/data.rs14
-rw-r--r--zellij-tile/src/shim.rs13
7 files changed, 68 insertions, 34 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5fc7175c3..615cc385d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2217,7 +2217,7 @@ dependencies = [
[[package]]
name = "zellij-tile"
-version = "1.0.0"
+version = "1.1.0"
dependencies = [
"serde",
"serde_json",
diff --git a/Cargo.toml b/Cargo.toml
index df330008a..4aa44e47d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -36,7 +36,7 @@ lazy_static = "1.4.0"
wasmer = "1.0.0"
wasmer-wasi = "1.0.0"
interprocess = "1.0.1"
-zellij-tile = { path = "zellij-tile/", version = "1.0.0" }
+zellij-tile = { path = "zellij-tile/", version = "1.1.0" }
[dependencies.async-std]
version = "1.3.0"
diff --git a/src/common/mod.rs b/src/common/mod.rs
index 79e487806..d525a3fe2 100644
--- a/src/common/mod.rs
+++ b/src/common/mod.rs
@@ -40,8 +40,7 @@ use pty_bus::{PtyBus, PtyInstruction};
use screen::{Screen, ScreenInstruction};
use serde::{Deserialize, Serialize};
use utils::consts::ZELLIJ_IPC_PIPE;
-use wasm_vm::PluginEnv;
-use wasm_vm::{wasi_stdout, wasi_write_string, zellij_imports, PluginInstruction};
+use wasm_vm::{wasi_stdout, wasi_write_json, zellij_exports, PluginEnv, PluginInstruction};
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
use wasmer_wasi::{Pipe, WasiState};
use zellij_tile::data::{EventType, ModeInfo};
@@ -506,7 +505,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
subscriptions: Arc::new(Mutex::new(HashSet::new())),
};
- let zellij = zellij_imports(&store, &plugin_env);
+ let zellij = zellij_exports(&store, &plugin_env);
let instance = Instance::new(&module, &zellij.chain_back(wasi)).unwrap();
let start = instance.exports.get_function("_start").unwrap();
@@ -525,10 +524,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
let event_type = EventType::from_str(&event.to_string()).unwrap();
if (pid.is_none() || pid == Some(i)) && subs.contains(&event_type) {
let update = instance.exports.get_function("update").unwrap();
- wasi_write_string(
- &plugin_env.wasi_env,
- &serde_json::to_string(&event).unwrap(),
- );
+ wasi_write_json(&plugin_env.wasi_env, &event);
update.call(&[]).unwrap();
}
}
diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs
index 29b110aed..ef3df61a6 100644
--- a/src/common/wasm_vm.rs
+++ b/src/common/wasm_vm.rs
@@ -1,11 +1,13 @@
+use serde::Serialize;
use std::{
collections::HashSet,
path::PathBuf,
+ process,
sync::{mpsc::Sender, Arc, Mutex},
};
use wasmer::{imports, Function, ImportObject, Store, WasmerEnv};
use wasmer_wasi::WasiEnv;
-use zellij_tile::data::{Event, EventType};
+use zellij_tile::data::{Event, EventType, PluginIds};
use super::{
pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext,
@@ -32,17 +34,26 @@ pub struct PluginEnv {
// Plugin API ---------------------------------------------------------------------------------------------------------
-pub fn zellij_imports(store: &Store, plugin_env: &PluginEnv) -> ImportObject {
- imports! {
- "zellij" => {
- "host_subscribe" => Function::new_native_with_env(store, plugin_env.clone(), host_subscribe),
- "host_unsubscribe" => Function::new_native_with_env(store, plugin_env.clone(), host_unsubscribe),
- "host_open_file" => Function::new_native_with_env(store, plugin_env.clone(), host_open_file),
- "host_set_invisible_borders" => Function::new_native_with_env(store, plugin_env.clone(), host_set_invisible_borders),
- "host_set_max_height" => Function::new_native_with_env(store, plugin_env.clone(), host_set_max_height),
- "host_set_selectable" => Function::new_native_with_env(store, plugin_env.clone(), host_set_selectable),
+pub fn zellij_exports(store: &Store, plugin_env: &PluginEnv) -> ImportObject {
+ macro_rules! zellij_export {
+ ($($host_function:ident),+ $(,)?) => {
+ imports! {
+ "zellij" => {
+ $("$host_function" => Function::new_native_with_env(store, plugin_env.clone(), $host_function),)+
+ }
+ }
}
}
+
+ zellij_export! {
+ host_subscribe,
+ host_unsubscribe,
+ host_set_invisible_borders,
+ host_set_max_height,
+ host_set_selectable,
+ host_get_plugin_ids,
+ host_open_file,
+ }
}
fn host_subscribe(plugin_env: &PluginEnv) {
@@ -57,14 +68,6 @@ fn host_unsubscribe(plugin_env: &PluginEnv) {
subscriptions.retain(|k| !old.contains(k));
}
-fn host_open_file(plugin_env: &PluginEnv) {
- let path = PathBuf::from(wasi_stdout(&plugin_env.wasi_env).lines().next().unwrap());
- plugin_env
- .send_pty_instructions
- .send(PtyInstruction::SpawnTerminal(Some(path)))
- .unwrap();
-}
-
fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
let selectable = selectable != 0;
plugin_env
@@ -98,6 +101,22 @@ fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) {
.unwrap()
}
+fn host_get_plugin_ids(plugin_env: &PluginEnv) {
+ let ids = PluginIds {
+ plugin_id: plugin_env.plugin_id,
+ zellij_pid: process::id(),
+ };
+ wasi_write_json(&plugin_env.wasi_env, &ids);
+}
+
+fn host_open_file(plugin_env: &PluginEnv) {
+ let path = PathBuf::from(wasi_stdout(&plugin_env.wasi_env).lines().next().unwrap());
+ plugin_env
+ .send_pty_instructions
+ .send(PtyInstruction::SpawnTerminal(Some(path)))
+ .unwrap();
+}
+
// Helper Functions ---------------------------------------------------------------------------------------------------
// FIXME: Unwrap city
@@ -114,3 +133,7 @@ pub fn wasi_write_string(wasi_env: &WasiEnv, buf: &str) {
let wasi_file = state.fs.stdin_mut().unwrap().as_mut().unwrap();
writeln!(wasi_file, "{}\r", buf).unwrap();
}
+
+pub fn wasi_write_json(wasi_env: &WasiEnv, object: &impl Serialize) {
+ wasi_write_string(wasi_env, &serde_json::to_string(&object).unwrap());
+}
diff --git a/zellij-tile/Cargo.toml b/zellij-tile/Cargo.toml
index 5a299cb1e..f59cf7b3e 100644
--- a/zellij-tile/Cargo.toml
+++ b/zellij-tile/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "zellij-tile"
-version = "1.0.0"
+version = "1.1.0"
authors = ["Brooks J Rady <b.j.rady@gmail.com>"]
edition = "2018"
description = "A small client-side library for writing Zellij plugins"
diff --git a/zellij-tile/src/data.rs b/zellij-tile/src/data.rs
index 85d12245b..e7ddb319c 100644
--- a/zellij-tile/src/data.rs
+++ b/zellij-tile/src/data.rs
@@ -23,7 +23,9 @@ pub enum Key {
Esc,
}
-#[derive(Debug, Clone, EnumDiscriminants, ToString, Serialize, Deserialize)]
+#[derive(
+ Debug, Clone, PartialEq, Eq, Hash, EnumDiscriminants, ToString, Serialize, Deserialize,
+)]
#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))]
#[strum_discriminants(name(EventType))]
pub enum Event {
@@ -68,17 +70,23 @@ impl Default for InputMode {
/// Represents the contents of the help message that is printed in the status bar,
/// which indicates the current [`InputMode`] and what the keybinds for that mode
/// are. Related to the default `status-bar` plugin.
-#[derive(Default, Debug, Clone, Serialize, Deserialize)]
+#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ModeInfo {
pub mode: InputMode,
// FIXME: This should probably return Keys and Actions, then sort out strings plugin-side
pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description>
}
-#[derive(Debug, Default, Clone, Deserialize, Serialize)]
+#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct TabInfo {
/* subset of fields to publish to plugins */
pub position: usize,
pub name: String,
pub active: bool,
}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
+pub struct PluginIds {
+ pub plugin_id: u32,
+ pub zellij_pid: u32,
+}
diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs
index 42a646a1f..ca15919fe 100644
--- a/zellij-tile/src/shim.rs
+++ b/zellij-tile/src/shim.rs
@@ -21,12 +21,18 @@ pub fn set_max_height(max_height: i32) {
unsafe { host_set_max_height(max_height) };
}
+pub fn set_selectable(selectable: bool) {
+ unsafe { host_set_selectable(if selectable { 1 } else { 0 }) };
+}
+
pub fn set_invisible_borders(invisible_borders: bool) {
unsafe { host_set_invisible_borders(if invisible_borders { 1 } else { 0 }) };
}
-pub fn set_selectable(selectable: bool) {
- unsafe { host_set_selectable(if selectable { 1 } else { 0 }) };
+// Query Functions
+pub fn get_plugin_ids() -> PluginIds {
+ unsafe { host_get_plugin_ids() };
+ object_from_stdin()
}
// Host Functions
@@ -49,8 +55,9 @@ pub fn object_from_stdin<T: DeserializeOwned>() -> T {
extern "C" {
fn host_subscribe();
fn host_unsubscribe();
- fn host_open_file();
fn host_set_max_height(max_height: i32);
fn host_set_selectable(selectable: i32);
fn host_set_invisible_borders(invisible_borders: i32);
+ fn host_get_plugin_ids();
+ fn host_open_file();
}