mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-25 18:21:51 +03:00
Merge branch 'main' of https://github.com/zellij-org/zellij into config-loading
This commit is contained in:
commit
55d2a4cea9
15
.github/workflows/release.yml
vendored
15
.github/workflows/release.yml
vendored
@ -18,6 +18,7 @@ jobs:
|
|||||||
- linux musl x64
|
- linux musl x64
|
||||||
- linux musl aarch64
|
- linux musl aarch64
|
||||||
- macos x64
|
- macos x64
|
||||||
|
- macos aarch64
|
||||||
include:
|
include:
|
||||||
- build: linux musl x64
|
- build: linux musl x64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@ -30,7 +31,11 @@ jobs:
|
|||||||
- build: macos x64
|
- build: macos x64
|
||||||
os: macos-latest
|
os: macos-latest
|
||||||
rust: beta
|
rust: beta
|
||||||
target: x86_64-apple-darwin
|
target: x86_64-apple-darwin
|
||||||
|
- build: macos aarch64
|
||||||
|
os: macos-latest
|
||||||
|
rust: beta
|
||||||
|
target: aarch64-apple-darwin
|
||||||
steps:
|
steps:
|
||||||
- name: Set release tag
|
- name: Set release tag
|
||||||
run: |
|
run: |
|
||||||
@ -64,6 +69,14 @@ jobs:
|
|||||||
- name: Install wasm-opt
|
- name: Install wasm-opt
|
||||||
run: brew install binaryen
|
run: brew install binaryen
|
||||||
|
|
||||||
|
# Workaround for <https://github.com/actions/virtual-environments/issues/2557>
|
||||||
|
- name: Switch Xcode SDK
|
||||||
|
if: runner.os == 'macos'
|
||||||
|
run: |
|
||||||
|
cat <<EOF >> "$GITHUB_ENV"
|
||||||
|
SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
|
||||||
|
EOF
|
||||||
|
|
||||||
- name: Build release binary
|
- name: Build release binary
|
||||||
run: cargo make ci-build-release ${{ matrix.target }}
|
run: cargo make ci-build-release ${{ matrix.target }}
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ 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)
|
* 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)
|
* 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)
|
* 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)
|
||||||
|
* Implemented simple plugin timers via the `set_timeout()` call (https://github.com/zellij-org/zellij/pull/394)
|
||||||
* Added more configuration locations, changed `ZELLIJ_CONFIG` to `ZELLIJ_CONFIG_FILE` (https://github.com/zellij-org/zellij/pull/391)
|
* Added more configuration locations, changed `ZELLIJ_CONFIG` to `ZELLIJ_CONFIG_FILE` (https://github.com/zellij-org/zellij/pull/391)
|
||||||
|
|
||||||
## [0.5.1] - 2021-04-23
|
## [0.5.1] - 2021-04-23
|
||||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2217,7 +2217,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zellij-tile"
|
name = "zellij-tile"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -36,7 +36,7 @@ lazy_static = "1.4.0"
|
|||||||
wasmer = "1.0.0"
|
wasmer = "1.0.0"
|
||||||
wasmer-wasi = "1.0.0"
|
wasmer-wasi = "1.0.0"
|
||||||
interprocess = "1.0.1"
|
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]
|
[dependencies.async-std]
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -40,8 +40,7 @@ use pty_bus::{PtyBus, PtyInstruction};
|
|||||||
use screen::{Screen, ScreenInstruction};
|
use screen::{Screen, ScreenInstruction};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use utils::consts::ZELLIJ_IPC_PIPE;
|
use utils::consts::ZELLIJ_IPC_PIPE;
|
||||||
use wasm_vm::PluginEnv;
|
use wasm_vm::{wasi_read_string, wasi_write_object, zellij_exports, PluginEnv, PluginInstruction};
|
||||||
use wasm_vm::{wasi_stdout, wasi_write_string, zellij_imports, 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, ModeInfo};
|
use zellij_tile::data::{EventType, ModeInfo};
|
||||||
@ -460,6 +459,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
let send_pty_instructions = send_pty_instructions.clone();
|
let send_pty_instructions = send_pty_instructions.clone();
|
||||||
let send_screen_instructions = send_screen_instructions.clone();
|
let send_screen_instructions = send_screen_instructions.clone();
|
||||||
let send_app_instructions = send_app_instructions.clone();
|
let send_app_instructions = send_app_instructions.clone();
|
||||||
|
let send_plugin_instructions = send_plugin_instructions.clone();
|
||||||
|
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let mut plugin_id = 0;
|
let mut plugin_id = 0;
|
||||||
@ -504,16 +504,17 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
send_pty_instructions: send_pty_instructions.clone(),
|
send_pty_instructions: send_pty_instructions.clone(),
|
||||||
send_screen_instructions: send_screen_instructions.clone(),
|
send_screen_instructions: send_screen_instructions.clone(),
|
||||||
send_app_instructions: send_app_instructions.clone(),
|
send_app_instructions: send_app_instructions.clone(),
|
||||||
|
send_plugin_instructions: send_plugin_instructions.clone(),
|
||||||
wasi_env,
|
wasi_env,
|
||||||
subscriptions: Arc::new(Mutex::new(HashSet::new())),
|
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 instance = Instance::new(&module, &zellij.chain_back(wasi)).unwrap();
|
||||||
|
|
||||||
let start = instance.exports.get_function("_start").unwrap();
|
let start = instance.exports.get_function("_start").unwrap();
|
||||||
|
|
||||||
// This eventually calls the `.init()` method
|
// This eventually calls the `.load()` method
|
||||||
start.call(&[]).unwrap();
|
start.call(&[]).unwrap();
|
||||||
|
|
||||||
plugin_map.insert(plugin_id, (instance, plugin_env));
|
plugin_map.insert(plugin_id, (instance, plugin_env));
|
||||||
@ -527,10 +528,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
let event_type = EventType::from_str(&event.to_string()).unwrap();
|
let event_type = EventType::from_str(&event.to_string()).unwrap();
|
||||||
if (pid.is_none() || pid == Some(i)) && subs.contains(&event_type) {
|
if (pid.is_none() || pid == Some(i)) && subs.contains(&event_type) {
|
||||||
let update = instance.exports.get_function("update").unwrap();
|
let update = instance.exports.get_function("update").unwrap();
|
||||||
wasi_write_string(
|
wasi_write_object(&plugin_env.wasi_env, &event);
|
||||||
&plugin_env.wasi_env,
|
|
||||||
&serde_json::to_string(&event).unwrap(),
|
|
||||||
);
|
|
||||||
update.call(&[]).unwrap();
|
update.call(&[]).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,7 +543,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
.call(&[Value::I32(rows as i32), Value::I32(cols as i32)])
|
.call(&[Value::I32(rows as i32), Value::I32(cols as i32)])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap();
|
buf_tx.send(wasi_read_string(&plugin_env.wasi_env)).unwrap();
|
||||||
}
|
}
|
||||||
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
|
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
|
||||||
PluginInstruction::Quit => break,
|
PluginInstruction::Quit => break,
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
process,
|
||||||
sync::{mpsc::Sender, Arc, Mutex},
|
sync::{mpsc::Sender, Arc, Mutex},
|
||||||
|
thread,
|
||||||
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
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::{Event, EventType};
|
use zellij_tile::data::{Event, EventType, PluginIds};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext,
|
pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext,
|
||||||
@ -23,48 +27,53 @@ pub enum PluginInstruction {
|
|||||||
#[derive(WasmerEnv, Clone)]
|
#[derive(WasmerEnv, Clone)]
|
||||||
pub struct PluginEnv {
|
pub struct PluginEnv {
|
||||||
pub plugin_id: u32,
|
pub plugin_id: u32,
|
||||||
|
// FIXME: This should be a big bundle of all of the channels
|
||||||
pub send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
pub send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
||||||
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
||||||
pub send_pty_instructions: SenderWithContext<PtyInstruction>, // FIXME: This should be a big bundle of all of the channels
|
pub send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||||
|
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||||
pub wasi_env: WasiEnv,
|
pub wasi_env: WasiEnv,
|
||||||
pub subscriptions: Arc<Mutex<HashSet<EventType>>>,
|
pub subscriptions: Arc<Mutex<HashSet<EventType>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin API ---------------------------------------------------------------------------------------------------------
|
// Plugin API ---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
pub fn zellij_imports(store: &Store, plugin_env: &PluginEnv) -> ImportObject {
|
pub fn zellij_exports(store: &Store, plugin_env: &PluginEnv) -> ImportObject {
|
||||||
imports! {
|
macro_rules! zellij_export {
|
||||||
"zellij" => {
|
($($host_function:ident),+ $(,)?) => {
|
||||||
"host_subscribe" => Function::new_native_with_env(store, plugin_env.clone(), host_subscribe),
|
imports! {
|
||||||
"host_unsubscribe" => Function::new_native_with_env(store, plugin_env.clone(), host_unsubscribe),
|
"zellij" => {
|
||||||
"host_open_file" => Function::new_native_with_env(store, plugin_env.clone(), host_open_file),
|
$(stringify!($host_function) =>
|
||||||
"host_set_invisible_borders" => Function::new_native_with_env(store, plugin_env.clone(), host_set_invisible_borders),
|
Function::new_native_with_env(store, plugin_env.clone(), $host_function),)+
|
||||||
"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),
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zellij_export! {
|
||||||
|
host_subscribe,
|
||||||
|
host_unsubscribe,
|
||||||
|
host_set_invisible_borders,
|
||||||
|
host_set_max_height,
|
||||||
|
host_set_selectable,
|
||||||
|
host_get_plugin_ids,
|
||||||
|
host_open_file,
|
||||||
|
host_set_timeout,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host_subscribe(plugin_env: &PluginEnv) {
|
fn host_subscribe(plugin_env: &PluginEnv) {
|
||||||
let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
|
let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
|
||||||
let new: HashSet<EventType> = serde_json::from_str(&wasi_stdout(&plugin_env.wasi_env)).unwrap();
|
let new: HashSet<EventType> = wasi_read_object(&plugin_env.wasi_env);
|
||||||
subscriptions.extend(new);
|
subscriptions.extend(new);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host_unsubscribe(plugin_env: &PluginEnv) {
|
fn host_unsubscribe(plugin_env: &PluginEnv) {
|
||||||
let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
|
let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
|
||||||
let old: HashSet<EventType> = serde_json::from_str(&wasi_stdout(&plugin_env.wasi_env)).unwrap();
|
let old: HashSet<EventType> = wasi_read_object(&plugin_env.wasi_env);
|
||||||
subscriptions.retain(|k| !old.contains(k));
|
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) {
|
fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
|
||||||
let selectable = selectable != 0;
|
let selectable = selectable != 0;
|
||||||
plugin_env
|
plugin_env
|
||||||
@ -98,10 +107,54 @@ fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn host_get_plugin_ids(plugin_env: &PluginEnv) {
|
||||||
|
let ids = PluginIds {
|
||||||
|
plugin_id: plugin_env.plugin_id,
|
||||||
|
zellij_pid: process::id(),
|
||||||
|
};
|
||||||
|
wasi_write_object(&plugin_env.wasi_env, &ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn host_open_file(plugin_env: &PluginEnv) {
|
||||||
|
let path: PathBuf = wasi_read_object(&plugin_env.wasi_env);
|
||||||
|
plugin_env
|
||||||
|
.send_pty_instructions
|
||||||
|
.send(PtyInstruction::SpawnTerminal(Some(path)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) {
|
||||||
|
// There is a fancy, high-performance way to do this with zero additional threads:
|
||||||
|
// If the plugin thread keeps a BinaryHeap of timer structs, it can manage multiple and easily `.peek()` at the
|
||||||
|
// next time to trigger in O(1) time. Once the wake-up time is known, the `wasm` thread can use `recv_timeout()`
|
||||||
|
// to wait for an event with the timeout set to be the time of the next wake up. If events come in in the meantime,
|
||||||
|
// they are handled, but if the timeout triggers, we replace the event from `recv()` with an
|
||||||
|
// `Update(pid, TimerEvent)` and pop the timer from the Heap (or reschedule it). No additional threads for as many
|
||||||
|
// timers as we'd like.
|
||||||
|
//
|
||||||
|
// But that's a lot of code, and this is a few lines:
|
||||||
|
let send_plugin_instructions = plugin_env.send_plugin_instructions.clone();
|
||||||
|
let update_target = Some(plugin_env.plugin_id);
|
||||||
|
thread::spawn(move || {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
thread::sleep(Duration::from_secs_f64(secs));
|
||||||
|
// FIXME: The way that elapsed time is being calculated here is not exact; it doesn't take into account the
|
||||||
|
// time it takes an event to actually reach the plugin after it's sent to the `wasm` thread.
|
||||||
|
let elapsed_time = Instant::now().duration_since(start_time).as_secs_f64();
|
||||||
|
|
||||||
|
send_plugin_instructions
|
||||||
|
.send(PluginInstruction::Update(
|
||||||
|
update_target,
|
||||||
|
Event::Timer(elapsed_time),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Helper Functions ---------------------------------------------------------------------------------------------------
|
// Helper Functions ---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// FIXME: Unwrap city
|
// FIXME: Unwrap city
|
||||||
pub fn wasi_stdout(wasi_env: &WasiEnv) -> String {
|
pub fn wasi_read_string(wasi_env: &WasiEnv) -> String {
|
||||||
let mut state = wasi_env.state();
|
let mut state = wasi_env.state();
|
||||||
let wasi_file = state.fs.stdout_mut().unwrap().as_mut().unwrap();
|
let wasi_file = state.fs.stdout_mut().unwrap().as_mut().unwrap();
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
@ -114,3 +167,12 @@ pub fn wasi_write_string(wasi_env: &WasiEnv, buf: &str) {
|
|||||||
let wasi_file = state.fs.stdin_mut().unwrap().as_mut().unwrap();
|
let wasi_file = state.fs.stdin_mut().unwrap().as_mut().unwrap();
|
||||||
writeln!(wasi_file, "{}\r", buf).unwrap();
|
writeln!(wasi_file, "{}\r", buf).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wasi_write_object(wasi_env: &WasiEnv, object: &impl Serialize) {
|
||||||
|
wasi_write_string(wasi_env, &serde_json::to_string(&object).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wasi_read_object<T: DeserializeOwned>(wasi_env: &WasiEnv) -> T {
|
||||||
|
let json = wasi_read_string(wasi_env);
|
||||||
|
serde_json::from_str(&json).unwrap()
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "zellij-tile"
|
name = "zellij-tile"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
authors = ["Brooks J Rady <b.j.rady@gmail.com>"]
|
authors = ["Brooks J Rady <b.j.rady@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "A small client-side library for writing Zellij plugins"
|
description = "A small client-side library for writing Zellij plugins"
|
||||||
|
@ -23,13 +23,15 @@ pub enum Key {
|
|||||||
Esc,
|
Esc,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
||||||
#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))]
|
#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))]
|
||||||
#[strum_discriminants(name(EventType))]
|
#[strum_discriminants(name(EventType))]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
ModeUpdate(ModeInfo),
|
ModeUpdate(ModeInfo),
|
||||||
TabUpdate(Vec<TabInfo>),
|
TabUpdate(Vec<TabInfo>),
|
||||||
KeyPress(Key),
|
KeyPress(Key),
|
||||||
|
Timer(f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes the different input modes, which change the way that keystrokes will be interpreted.
|
/// Describes the different input modes, which change the way that keystrokes will be interpreted.
|
||||||
@ -68,17 +70,23 @@ impl Default for InputMode {
|
|||||||
/// Represents the contents of the help message that is printed in the status bar,
|
/// 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
|
/// which indicates the current [`InputMode`] and what the keybinds for that mode
|
||||||
/// are. Related to the default `status-bar` plugin.
|
/// 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 struct ModeInfo {
|
||||||
pub mode: InputMode,
|
pub mode: InputMode,
|
||||||
// FIXME: This should probably return Keys and Actions, then sort out strings plugin-side
|
// FIXME: This should probably return Keys and Actions, then sort out strings plugin-side
|
||||||
pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description>
|
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 {
|
pub struct TabInfo {
|
||||||
/* subset of fields to publish to plugins */
|
/* subset of fields to publish to plugins */
|
||||||
pub position: usize,
|
pub position: usize,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub active: bool,
|
pub active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||||
|
pub struct PluginIds {
|
||||||
|
pub plugin_id: u32,
|
||||||
|
pub zellij_pid: u32,
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use serde::de::DeserializeOwned;
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use std::{io, path::Path};
|
use std::{io, path::Path};
|
||||||
|
|
||||||
use crate::data::*;
|
use crate::data::*;
|
||||||
@ -6,12 +6,12 @@ use crate::data::*;
|
|||||||
// Subscription Handling
|
// Subscription Handling
|
||||||
|
|
||||||
pub fn subscribe(event_types: &[EventType]) {
|
pub fn subscribe(event_types: &[EventType]) {
|
||||||
println!("{}", serde_json::to_string(event_types).unwrap());
|
object_to_stdout(&event_types);
|
||||||
unsafe { host_subscribe() };
|
unsafe { host_subscribe() };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unsubscribe(event_types: &[EventType]) {
|
pub fn unsubscribe(event_types: &[EventType]) {
|
||||||
println!("{}", serde_json::to_string(event_types).unwrap());
|
object_to_stdout(&event_types);
|
||||||
unsafe { host_unsubscribe() };
|
unsafe { host_unsubscribe() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,21 +21,31 @@ 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_selectable(selectable: bool) {
|
||||||
|
unsafe { host_set_selectable(if selectable { 1 } else { 0 }) };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_invisible_borders(invisible_borders: bool) {
|
pub fn set_invisible_borders(invisible_borders: bool) {
|
||||||
unsafe { host_set_invisible_borders(if invisible_borders { 1 } else { 0 }) };
|
unsafe { host_set_invisible_borders(if invisible_borders { 1 } else { 0 }) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_selectable(selectable: bool) {
|
// Query Functions
|
||||||
unsafe { host_set_selectable(if selectable { 1 } else { 0 }) };
|
pub fn get_plugin_ids() -> PluginIds {
|
||||||
|
unsafe { host_get_plugin_ids() };
|
||||||
|
object_from_stdin()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host Functions
|
// Host Functions
|
||||||
|
|
||||||
pub fn open_file(path: &Path) {
|
pub fn open_file(path: &Path) {
|
||||||
println!("{}", path.to_string_lossy());
|
object_to_stdout(&path);
|
||||||
unsafe { host_open_file() };
|
unsafe { host_open_file() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout(secs: f64) {
|
||||||
|
unsafe { host_set_timeout(secs) };
|
||||||
|
}
|
||||||
|
|
||||||
// Internal Functions
|
// Internal Functions
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -45,12 +55,19 @@ pub fn object_from_stdin<T: DeserializeOwned>() -> T {
|
|||||||
serde_json::from_str(&json).unwrap()
|
serde_json::from_str(&json).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn object_to_stdout(object: &impl Serialize) {
|
||||||
|
println!("{}", serde_json::to_string(object).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[link(wasm_import_module = "zellij")]
|
#[link(wasm_import_module = "zellij")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn host_subscribe();
|
fn host_subscribe();
|
||||||
fn host_unsubscribe();
|
fn host_unsubscribe();
|
||||||
fn host_open_file();
|
|
||||||
fn host_set_max_height(max_height: i32);
|
fn host_set_max_height(max_height: i32);
|
||||||
fn host_set_selectable(selectable: i32);
|
fn host_set_selectable(selectable: i32);
|
||||||
fn host_set_invisible_borders(invisible_borders: i32);
|
fn host_set_invisible_borders(invisible_borders: i32);
|
||||||
|
fn host_get_plugin_ids();
|
||||||
|
fn host_open_file();
|
||||||
|
fn host_set_timeout(secs: f64);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user