mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-26 10:43:46 +03:00
feat(plugin): added the get_plugin_ids()
query function
This commit is contained in:
commit
9f567f721e
@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
* Doesn't quit anymore on single `q` press while in tab mode (https://github.com/zellij-org/zellij/pull/342)
|
||||
* Completions are not assets anymore, but commands `option --generate-completion [shell]` (https://github.com/zellij-org/zellij/pull/369)
|
||||
* Fixes in the default configuration `default.yaml` file. Adds initial tmux-compat keybindings `tmux.yaml` (https://github.com/zellij-org/zellij/pull/362)
|
||||
* Added the `get_plugin_ids()` query function to the plugin API (https://github.com/zellij-org/zellij/pull/392)
|
||||
|
||||
## [0.5.1] - 2021-04-23
|
||||
* Change config to flag (https://github.com/zellij-org/zellij/pull/300)
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2217,7 +2217,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zellij-tile"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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,27 @@ 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" => {
|
||||
$(stringify!($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 +69,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 +102,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 +134,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());
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -23,9 +23,12 @@ 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))]
|
||||
#[non_exhaustive]
|
||||
pub enum Event {
|
||||
ModeUpdate(ModeInfo),
|
||||
TabUpdate(Vec<TabInfo>),
|
||||
@ -68,17 +71,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,
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user