aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrooks Rady <b.j.rady@gmail.com>2021-03-26 13:20:06 +0000
committerGitHub <noreply@github.com>2021-03-26 13:20:06 +0000
commitd818661c727a59312e1a43432e84fbeec79fc145 (patch)
treee8ab04124ee7f5c87cd88be63c1867c7d9b2289c
parentfix(render): various rendering issues (#238) (diff)
parentFix some overzealous format!() removals and a stray comment (diff)
downloadsl0ppij-d818661c727a59312e1a43432e84fbeec79fc145.tar.gz
sl0ppij-d818661c727a59312e1a43432e84fbeec79fc145.tar.xz
sl0ppij-d818661c727a59312e1a43432e84fbeec79fc145.zip
feat(plugin): refactored to a new and more general plugin API
- Changed `init()` to `load()` - Deduplicated structs that are in both `zellij` and `zellij-tile` - WASM thread now keeps a mapping of plugins and event subscriptions - Added host-functions for subscribing and unsubscribing from events - Introduced the `update(event)` callback into the API (which is called to handle plugin events) - Made mode changes send an event to the WASM thread - Removed the `AppInstruction::Get/SetState` calls (and any global state) - Removed the `get_help()` host function - Added an event system for key-presses - Added an event for updating tabs - Ported support for renaming tabs - Removed every plugin callback other than `load()`, `update(event)`, and `draw(rows, cols)` - Removed every WASM thread event other than Load, Draw, Update, Unload, and Quit - Calls render after a plugin is updated - Switched back to upstream `termion` - Loads of lint fixing - Shrunk and simplified the code!
-rw-r--r--Cargo.lock121
-rw-r--r--Cargo.toml5
-rw-r--r--assets/layouts/default.yaml2
-rw-r--r--assets/layouts/strider.yaml2
-rwxr-xr-xbuild-all.sh18
-rw-r--r--default-tiles/status-bar/src/first_line.rs100
-rw-r--r--default-tiles/status-bar/src/main.rs22
-rw-r--r--default-tiles/status-bar/src/second_line.rs18
-rw-r--r--default-tiles/strider/src/main.rs73
-rw-r--r--default-tiles/strider/src/state.rs2
-rw-r--r--default-tiles/tab-bar/src/line.rs6
-rw-r--r--default-tiles/tab-bar/src/main.rs63
-rw-r--r--src/client/boundaries.rs135
-rw-r--r--src/client/layout.rs8
-rw-r--r--src/client/panes/plugin_pane.rs2
-rw-r--r--src/client/panes/terminal_character.rs10
-rw-r--r--src/client/tab.rs184
-rw-r--r--src/common/errors.rs22
-rw-r--r--src/common/input/actions.rs5
-rw-r--r--src/common/input/handler.rs128
-rw-r--r--src/common/input/keybinds.rs14
-rw-r--r--src/common/ipc.rs8
-rw-r--r--src/common/mod.rs184
-rw-r--r--src/common/os_input_output.rs13
-rw-r--r--src/common/screen.rs40
-rw-r--r--src/common/utils/consts.rs2
-rw-r--r--src/common/wasm_vm.rs62
-rw-r--r--zellij-tile/Cargo.toml4
-rw-r--r--zellij-tile/src/data.rs77
-rw-r--r--zellij-tile/src/lib.rs49
-rw-r--r--zellij-tile/src/prelude.rs3
-rw-r--r--zellij-tile/src/shim.rs95
32 files changed, 615 insertions, 862 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f2533abb..e446df9f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,9 +11,9 @@ dependencies = [
[[package]]
name = "adler"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bedc89c5c7b5550ffb9372eb5c5ffc7f9f705cc3f4a128bd4669b9745f555093"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ansi_term"
@@ -223,9 +223,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitvec"
-version = "0.19.4"
+version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
+checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
dependencies = [
"funty",
"radium",
@@ -536,9 +536,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "enumset"
-version = "1.0.5"
+version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c70e3089d60da62772627697a83dd166615072eebe1a52ac05f16bdbd0165dc3"
+checksum = "fbd795df6708a599abf1ee10eacc72efd052b7a5f70fdf0715e4d5151a6db9c3"
dependencies = [
"enumset_derive",
]
@@ -807,9 +807,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "indexmap"
-version = "1.6.1"
+version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
+checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
dependencies = [
"autocfg",
"hashbrown",
@@ -818,9 +818,9 @@ dependencies = [
[[package]]
name = "insta"
-version = "1.6.3"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd354a2c8c8083d58414597a4ecada1984f9b82ea7e87eeabddc869eaf120992"
+checksum = "e1b6cf41e31a7e7b78055b548826da45c7dc74e6a13a3fa6b897a17a01322f26"
dependencies = [
"console",
"lazy_static",
@@ -842,16 +842,16 @@ dependencies = [
[[package]]
name = "interprocess"
-version = "1.1.0"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98969eda6bf33b8532e8a7b8f157afc43556188741fa0df8c92b8780f8654e52"
+checksum = "1c58ec7fbda1df9a93f587b780659db3c99f61f4be27f9c82c9b37684ffd0366"
dependencies = [
"blocking",
"cfg-if 1.0.0",
"futures",
"intmap",
- "lazy_static",
"libc",
+ "once_cell",
"spinning",
"thiserror",
"winapi",
@@ -893,9 +893,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "js-sys"
-version = "0.3.47"
+version = "0.3.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65"
+checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
dependencies = [
"wasm-bindgen",
]
@@ -936,9 +936,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.86"
+version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
+checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
[[package]]
name = "libloading"
@@ -1093,9 +1093,9 @@ checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
[[package]]
name = "once_cell"
-version = "1.7.0"
+version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a"
+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "parking"
@@ -1105,9 +1105,9 @@ checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]]
name = "pin-project-lite"
-version = "0.2.4"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
+checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
[[package]]
name = "pin-utils"
@@ -1271,12 +1271,6 @@ dependencies = [
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
@@ -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]]
@@ -1370,9 +1364,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
-version = "1.0.123"
+version = "1.0.124"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
+checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
dependencies = [
"serde_derive",
]
@@ -1388,9 +1382,9 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.123"
+version = "1.0.124"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
+checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
dependencies = [
"proc-macro2",
"quote",
@@ -1399,9 +1393,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.63"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43535db9747a4ba938c0ce0a98cc631a46ebf943c9e1d604e091df6007620bf6"
+checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
dependencies = [
"itoa",
"ryu",
@@ -1582,9 +1576,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.60"
+version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
+checksum = "123a78a3596b24fee53a6464ce52d8ecbf62241e6294c7e7fe12086cd161f512"
dependencies = [
"proc-macro2",
"quote",
@@ -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]]
@@ -1890,9 +1883,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
-version = "0.2.70"
+version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
+checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@@ -1900,9 +1893,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.70"
+version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7"
+checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
dependencies = [
"bumpalo",
"lazy_static",
@@ -1915,9 +1908,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.20"
+version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3de431a2910c86679c34283a33f66f4e4abd7e0aec27b6669060148872aadf94"
+checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@@ -1927,9 +1920,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.70"
+version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c"
+checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1937,9 +1930,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.70"
+version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385"
+checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e"
dependencies = [
"proc-macro2",
"quote",
@@ -1950,9 +1943,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.70"
+version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
+checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1"
[[package]]
name = "wasmer"
@@ -2156,27 +2149,27 @@ checksum = "87cc2fe6350834b4e528ba0901e7aa405d78b89dc1fa3145359eb4de0e323fcf"
[[package]]
name = "wast"
-version = "34.0.0"
+version = "35.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3de71ea922e46a60d0bde4b27ebf24ab7c4991006fd5de23ce9c58e129b3ab3c"
+checksum = "db5ae96da18bb5926341516fd409b5a8ce4e4714da7f0a1063d3b20ac9f9a1e1"
dependencies = [
"leb128",
]
[[package]]
name = "wat"
-version = "1.0.35"
+version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "474403335b9a90b21120ab8131dd888f0a8d041c2d365ab960feddfe5a73c4b6"
+checksum = "0b0fa059022c5dabe129f02b429d67086400deb8277f89c975555dacc1dadbcc"
dependencies = [
"wast",
]
[[package]]
name = "web-sys"
-version = "0.3.47"
+version = "0.3.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3"
+checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2270,8 +2263,7 @@ dependencies = [
"strip-ansi-escapes",
"structopt",
"strum",
- "strum_macros",
- "termion_temporary_zellij_fork",
+ "termion",
"termios",
"toml",
"unicode-truncate",
@@ -2280,6 +2272,7 @@ dependencies = [
"walkdir",
"wasmer",
"wasmer-wasi",
+ "zellij-tile",
]
[[package]]
@@ -2288,4 +2281,6 @@ version = "0.5.0"
dependencies = [
"serde",
"serde_json",
+ "strum",
+ "strum_macros",
]
diff --git a/Cargo.toml b/Cargo.toml
index a811c5a1..776eb3e9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,18 +27,17 @@ serde_yaml = "0.8"
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"
vte = "0.8.0"
strum = "0.20.0"
-strum_macros = "0.20.0"
lazy_static = "1.4.0"
wasmer = "1.0.0"
wasmer-wasi = "1.0.0"
interprocess = "1.0.1"
+zellij-tile = { path = "zellij-tile/", version = "0.5.0" }
[dependencies.async-std]
version = "1.3.0"
diff --git a/assets/layouts/default.yaml b/assets/layouts/default.yaml
index f46569b7..408f2f38 100644
--- a/assets/layouts/default.yaml
+++ b/assets/layouts/default.yaml
@@ -5,8 +5,6 @@ parts:
split_size:
Fixed: 1
plugin: tab-bar
- events:
- - Tab
- direction: Vertical
expansion_boundary: true
- direction: Vertical
diff --git a/assets/layouts/strider.yaml b/assets/layouts/strider.yaml
index cd972d20..9d0f09b0 100644
--- a/assets/layouts/strider.yaml
+++ b/assets/layouts/strider.yaml
@@ -5,8 +5,6 @@ parts:
split_size:
Fixed: 1
plugin: tab-bar
- events:
- - Tab
- direction: Vertical
parts:
- direction: Horizontal
diff --git a/build-all.sh b/build-all.sh
index cdb1d0cc..f267b110 100755
--- a/build-all.sh
+++ b/build-all.sh
@@ -1,29 +1,25 @@
#!/bin/sh
-total=6
+total=5
# This is temporary while https://github.com/rust-lang/cargo/issues/7004 is open
-echo "Building zellij-tile (1/$total)..."
-cd zellij-tile
-cargo build --release --target-dir ../target
-
-echo "Building status-bar (2/$total)..."
-cd ../default-tiles/status-bar
+echo "Building status-bar (1/$total)..."
+cd default-tiles/status-bar
cargo build --release --target-dir ../../target
-echo "Building strider (3/$total)..."
+echo "Building strider (2/$total)..."
cd ../strider
cargo build --release --target-dir ../../target
-echo "Building tab-bar (4/$total)..."
+echo "Building tab-bar (3/$total)..."
cd ../tab-bar
cargo build --release --target-dir ../../target
-echo "Optimising WASM executables (5/$total)..."
+echo "Optimising WASM executables (4/$total)..."
cd ../..
wasm-opt -O target/wasm32-wasi/release/status-bar.wasm -o target/status-bar.wasm || cp target/wasm32-wasi/release/status-bar.wasm target/status-bar.wasm
wasm-opt -O target/wasm32-wasi/release/strider.wasm -o target/strider.wasm || cp target/wasm32-wasi/release/strider.wasm target/strider.wasm
wasm-opt -O target/wasm32-wasi/release/tab-bar.wasm -o target/tab-bar.wasm || cp target/wasm32-wasi/release/tab-bar.wasm target/tab-bar.wasm
-echo "Building zellij (6/$total)..."
+echo "Building zellij (5/$total)..."
cargo build --target-dir target $@
diff --git a/default-tiles/status-bar/src/first_line.rs b/default-tiles/status-bar/src/first_line.rs
index bd9c5425..0e4ec53b 100644
--- a/default-tiles/status-bar/src/first_line.rs
+++ b/default-tiles/status-bar/src/first_line.rs
@@ -1,5 +1,5 @@
use ansi_term::{ANSIStrings, Style};
-use zellij_tile::*;
+use zellij_tile::prelude::*;
use crate::colors::{BLACK, BRIGHT_GRAY, GRAY, GREEN, RED, WHITE};
use crate::{LinePart, ARROW_SEPARATOR};
@@ -70,19 +70,19 @@ fn unselected_mode_shortcut(letter: char, text: &str) -> LinePart {
.fg(BLACK)
.on(BRIGHT_GRAY)
.bold()
- .paint(format!(" <"));
+ .paint(" <");
let char_shortcut = Style::new()
.bold()
.fg(RED)
.on(BRIGHT_GRAY)
.bold()
- .paint(format!("{}", letter));
+ .paint(letter.to_string());
let char_right_separator = Style::new()
.bold()
.fg(BLACK)
.on(BRIGHT_GRAY)
.bold()
- .paint(format!(">"));
+ .paint(">");
let styled_text = Style::new()
.fg(BLACK)
.on(BRIGHT_GRAY)
@@ -90,41 +90,29 @@ fn unselected_mode_shortcut(letter: char, text: &str) -> LinePart {
.paint(format!("{} ", text));
let suffix_separator = Style::new().fg(BRIGHT_GRAY).on(GRAY).paint(ARROW_SEPARATOR);
LinePart {
- part: format!(
- "{}",
- ANSIStrings(&[
- prefix_separator,
- char_left_separator,
- char_shortcut,
- char_right_separator,
- styled_text,
- suffix_separator
- ])
- ),
+ part: ANSIStrings(&[
+ prefix_separator,
+ char_left_separator,
+ char_shortcut,
+ char_right_separator,
+ styled_text,
+ suffix_separator,
+ ])
+ .to_string(),
len: text.chars().count() + 6, // 2 for the arrows, 3 for the char separators, 1 for the character
}
}
fn selected_mode_shortcut(letter: char, text: &str) -> LinePart {
let prefix_separator = Style::new().fg(GRAY).on(GREEN).paint(ARROW_SEPARATOR);
- let char_left_separator = Style::new()
- .bold()
- .fg(BLACK)
- .on(GREEN)
- .bold()
- .paint(format!(" <"));
+ let char_left_separator = Style::new().bold().fg(BLACK).on(GREEN).bold().paint(" <");
let char_shortcut = Style::new()
.bold()
.fg(RED)
.on(GREEN)
.bold()
- .paint(format!("{}", letter));
- let char_right_separator = Style::new()
- .bold()
- .fg(BLACK)
- .on(GREEN)
- .bold()
- .paint(format!(">"));
+ .paint(letter.to_string());
+ let char_right_separator = Style::new().bold().fg(BLACK).on(GREEN).bold().paint(">");
let styled_text = Style::new()
.fg(BLACK)
.on(GREEN)
@@ -132,17 +120,15 @@ fn selected_mode_shortcut(letter: char, text: &str) -> LinePart {
.paint(format!("{} ", text));
let suffix_separator = Style::new().fg(GREEN).on(GRAY).paint(ARROW_SEPARATOR);
LinePart {
- part: format!(
- "{}",
- ANSIStrings(&[
- prefix_separator,
- char_left_separator,
- char_shortcut,
- char_right_separator,
- styled_text,
- suffix_separator
- ])
- ),
+ part: ANSIStrings(&[
+ prefix_separator,
+ char_left_separator,
+ char_shortcut,
+ char_right_separator,
+ styled_text,
+ suffix_separator,
+ ])
+ .to_string(),
len: text.chars().count() + 6, // 2 for the arrows, 3 for the char separators, 1 for the character
}
}
@@ -173,10 +159,7 @@ fn selected_mode_shortcut_single_letter(letter: char) -> LinePart {
.paint(char_shortcut_text);
let suffix_separator = Style::new().fg(GREEN).on(GRAY).paint(ARROW_SEPARATOR);
LinePart {
- part: format!(
- "{}",
- ANSIStrings(&[prefix_separator, char_shortcut, suffix_separator])
- ),
+ part: ANSIStrings(&[prefix_separator, char_shortcut, suffix_separator]).to_string(),
len,
}
}
@@ -193,10 +176,7 @@ fn unselected_mode_shortcut_single_letter(letter: char) -> LinePart {
.paint(char_shortcut_text);
let suffix_separator = Style::new().fg(BRIGHT_GRAY).on(GRAY).paint(ARROW_SEPARATOR);
LinePart {
- part: format!(
- "{}",
- ANSIStrings(&[prefix_separator, char_shortcut, suffix_separator])
- ),
+ part: ANSIStrings(&[prefix_separator, char_shortcut, suffix_separator]).to_string(),
len,
}
}
@@ -225,12 +205,8 @@ fn shortened_ctrl_key(key: &CtrlKeyShortcut) -> LinePart {
_ => shortened_text,
};
match key.mode {
- CtrlKeyMode::Unselected => {
- unselected_mode_shortcut(letter_shortcut, &format!("{}", shortened_text))
- }
- CtrlKeyMode::Selected => {
- selected_mode_shortcut(letter_shortcut, &format!("{}", shortened_text))
- }
+ CtrlKeyMode::Unselected => unselected_mode_shortcut(letter_shortcut, &shortened_text),
+ CtrlKeyMode::Selected => selected_mode_shortcut(letter_shortcut, &shortened_text),
CtrlKeyMode::Disabled => {
disabled_mode_shortcut(&format!(" <{}>{}", letter_shortcut, shortened_text))
}
@@ -282,16 +258,16 @@ pub fn superkey() -> LinePart {
let prefix_text = " Ctrl + ";
let prefix = Style::new().fg(WHITE).on(GRAY).bold().paint(prefix_text);
LinePart {
- part: format!("{}", prefix),
+ part: prefix.to_string(),
len: prefix_text.chars().count(),
}
}
-pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
+pub fn ctrl_keys(help: &ModeInfo, max_len: usize) -> LinePart {
match &help.mode {
InputMode::Locked => key_indicators(
max_len,
- &vec![
+ &[
CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Lock),
CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Pane),
CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Tab),
@@ -302,7 +278,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
),
InputMode::Resize => key_indicators(
max_len,
- &vec![
+ &[
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab),
@@ -313,7 +289,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
),
InputMode::Pane => key_indicators(
max_len,
- &vec![
+ &[
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Pane),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab),
@@ -324,7 +300,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
),
InputMode::Tab | InputMode::RenameTab => key_indicators(
max_len,
- &vec![
+ &[
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane),
CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Tab),
@@ -335,7 +311,7 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
),
InputMode::Scroll => key_indicators(
max_len,
- &vec![
+ &[
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab),
@@ -344,9 +320,9 @@ pub fn ctrl_keys(help: &Help, max_len: usize) -> LinePart {
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit),
],
),
- InputMode::Normal | _ => key_indicators(
+ InputMode::Normal => key_indicators(
max_len,
- &vec![
+ &[
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane),
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab),
diff --git a/default-tiles/status-bar/src/main.rs b/default-tiles/status-bar/src/main.rs
index 6d41fb7b..8daa158e 100644
--- a/default-tiles/status-bar/src/main.rs
+++ b/default-tiles/status-bar/src/main.rs
@@ -2,7 +2,7 @@ mod first_line;
mod second_line;
use std::fmt::{Display, Error, Formatter};
-use zellij_tile::*;
+use zellij_tile::prelude::*;
use first_line::{ctrl_keys, superkey};
use second_line::keybinds;
@@ -23,7 +23,9 @@ static ARROW_SEPARATOR: &str = "";
static MORE_MSG: &str = " ... ";
#[derive(Default)]
-struct State {}
+struct State {
+ mode_info: ModeInfo,
+}
register_tile!(State);
@@ -40,19 +42,25 @@ impl Display for LinePart {
}
impl ZellijTile for State {
- fn init(&mut self) {
+ fn load(&mut self) {
set_selectable(false);
set_invisible_borders(true);
set_max_height(2);
+ subscribe(&[EventType::ModeUpdate]);
+ }
+
+ fn update(&mut self, event: Event) {
+ if let Event::ModeUpdate(mode_info) = event {
+ self.mode_info = mode_info;
+ }
}
- fn draw(&mut self, _rows: usize, cols: usize) {
- let help = get_help();
+ fn render(&mut self, _rows: usize, cols: usize) {
let superkey = superkey();
- let ctrl_keys = ctrl_keys(&help, cols - superkey.len);
+ let ctrl_keys = ctrl_keys(&self.mode_info, cols - superkey.len);
let first_line = format!("{}{}", superkey, ctrl_keys);
- let second_line = keybinds(&help, cols);
+ let second_line = keybinds(&self.mode_info, cols);
// [48;5;238m is gray background, [0K is so that it fills the rest of the line
// [48;5;16m is black background, [0K is so that it fills the rest of the line
diff --git a/default-tiles/status-bar/src/second_line.rs b/default-tiles/status-bar/src/second_line.rs
index 45c33a8e..ebcb93dd 100644
--- a/default-tiles/status-bar/src/second_line.rs
+++ b/default-tiles/status-bar/src/second_line.rs
@@ -1,6 +1,6 @@
// use colored::*;
use ansi_term::{ANSIStrings, Style};
-use zellij_tile::*;
+use zellij_tile::prelude::*;
use crate::colors::{BLACK, GREEN, ORANGE, WHITE};
use crate::{LinePart, MORE_MSG};
@@ -97,7 +97,7 @@ fn select_pane_shortcut(is_first_shortcut: bool) -> LinePart {
}
}
-fn full_shortcut_list(help: &Help) -> LinePart {
+fn full_shortcut_list(help: &ModeInfo) -> LinePart {
match help.mode {
InputMode::Normal => LinePart::default(),
InputMode::Locked => locked_interface_indication(),
@@ -108,7 +108,7 @@ fn full_shortcut_list(help: &Help) -> LinePart {
line_part.len += shortcut.len;
line_part.part = format!("{}{}", line_part.part, shortcut,);
}
- let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0);
+ let select_pane_shortcut = select_pane_shortcut(help.keybinds.is_empty());
line_part.len += select_pane_shortcut.len;
line_part.part = format!("{}{}", line_part.part, select_pane_shortcut,);
line_part
@@ -116,7 +116,7 @@ fn full_shortcut_list(help: &Help) -> LinePart {
}
}
-fn shortened_shortcut_list(help: &Help) -> LinePart {
+fn shortened_shortcut_list(help: &ModeInfo) -> LinePart {
match help.mode {
InputMode::Normal => LinePart::default(),
InputMode::Locked => locked_interface_indication(),
@@ -127,7 +127,7 @@ fn shortened_shortcut_list(help: &Help) -> LinePart {
line_part.len += shortcut.len;
line_part.part = format!("{}{}", line_part.part, shortcut,);
}
- let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0);
+ let select_pane_shortcut = select_pane_shortcut(help.keybinds.is_empty());
line_part.len += select_pane_shortcut.len;
line_part.part = format!("{}{}", line_part.part, select_pane_shortcut,);
line_part
@@ -135,7 +135,7 @@ fn shortened_shortcut_list(help: &Help) -> LinePart {
}
}
-fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
+fn best_effort_shortcut_list(help: &ModeInfo, max_len: usize) -> LinePart {
match help.mode {
InputMode::Normal => LinePart::default(),
InputMode::Locked => {
@@ -159,7 +159,7 @@ fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
line_part.len += shortcut.len;
line_part.part = format!("{}{}", line_part.part, shortcut,);
}
- let select_pane_shortcut = select_pane_shortcut(help.keybinds.len() == 0);
+ let select_pane_shortcut = select_pane_shortcut(help.keybinds.is_empty());
if line_part.len + select_pane_shortcut.len <= max_len {
line_part.len += select_pane_shortcut.len;
line_part.part = format!("{}{}", line_part.part, select_pane_shortcut,);
@@ -169,7 +169,7 @@ fn best_effort_shortcut_list(help: &Help, max_len: usize) -> LinePart {
}
}
-pub fn keybinds(help: &Help, max_width: usize) -> LinePart {
+pub fn keybinds(help: &ModeInfo, max_width: usize) -> LinePart {
let full_shortcut_list = full_shortcut_list(help);
if full_shortcut_list.len <= max_width {
return full_shortcut_list;
@@ -178,5 +178,5 @@ pub fn keybinds(help: &Help, max_width: usize) -> LinePart {
if shortened_shortcut_list.len <= max_width {
return shortened_shortcut_list;
}
- return best_effort_shortcut_list(help, max_width);
+ best_effort_shortcut_list(help, max_width)
}
diff --git a/default-tiles/strider/src/main.rs b/default-tiles/strider/src/main.rs
index 3213b2af..c2867fe4 100644
--- a/default-tiles/strider/src/main.rs
+++ b/default-tiles/strider/src/main.rs
@@ -3,16 +3,51 @@ mod state;
use colored::*;
use state::{FsEntry, State};
use std::{cmp::min, fs::read_dir};
-use zellij_tile::*;
+use zellij_tile::prelude::*;
register_tile!(State);
impl ZellijTile for State {
- fn init(&mut self) {
+ fn load(&mut self) {
refresh_directory(self);
+ subscribe(&[EventType::KeyPress]);
}
- fn draw(&mut self, rows: usize, cols: usize) {
+ fn update(&mut self, event: Event) {
+ if let Event::KeyPress(key) = event {
+ match key {
+ Key::Up | Key::Char('k') => {
+ *self.selected_mut() = self.selected().saturating_sub(1);
+ }
+ Key::Down | Key::Char('j') => {
+ let next = self.selected().saturating_add(1);
+ *self.selected_mut() = min(self.files.len() - 1, next);
+ }
+ Key::Right | Key::Char('\n') | Key::Char('l') => {
+ match self.files[self.selected()].clone() {
+ FsEntry::Dir(p, _) => {
+ self.path = p;
+ refresh_directory(self);
+ }
+ FsEntry::File(p, _) => open_file(&p),
+ }
+ }
+ Key::Left | Key::Char('h') => {
+ self.path.pop();
+ refresh_directory(self);
+ }
+
+ Key::Char('.') => {
+ self.toggle_hidden_files();
+ refresh_directory(self);
+ }
+
+ _ => (),
+ };
+ }
+ }
+
+ fn render(&mut self, rows: usize, cols: usize) {
for i in 0..rows {
if self.selected() < self.scroll() {
*self.scroll_mut() = self.selected();
@@ -38,38 +73,6 @@ impl ZellijTile for State {
}
}
}
-
- fn handle_key(&mut self, key: Key) {
- match key {
- Key::Up | Key::Char('k') => {
- *self.selected_mut() = self.selected().saturating_sub(1);
- }
- Key::Down | Key::Char('j') => {
- let next = self.selected().saturating_add(1);
- *self.selected_mut() = min(self.files.len() - 1, next);
- }
- Key::Right | Key::Char('\n') | Key::Char('l') => {
- match self.files[self.selected()].clone() {
- FsEntry::Dir(p, _) => {
- self.path = p;
- refresh_directory(self);
- }
- FsEntry::File(p, _) => open_file(&p),
- }
- }
- Key::Left | Key::Char('h') => {
- self.path.pop();
- refresh_directory(self);
- }
-
- Key::Char('.') => {
- self.toggle_hidden_files();
- refresh_directory(self);
- }
-
- _ => (),
- };
- }
}
fn refresh_directory(state: &mut State) {
diff --git a/default-tiles/strider/src/state.rs b/default-tiles/strider/src/state.rs
index 2a9230e8..0d96ae0b 100644
--- a/default-tiles/strider/src/state.rs
+++ b/default-tiles/strider/src/state.rs
@@ -58,6 +58,6 @@ impl FsEntry {
}
pub fn is_hidden_file(&self) -> bool {
- self.name().chars().nth(0).unwrap() == '.'.into()
+ self.name().starts_with('.')
}
}
diff --git a/default-tiles/tab-bar/src/line.rs b/default-tiles/tab-bar/src/line.rs
index beca8b42..1d1c33ec 100644
--- a/default-tiles/tab-bar/src/line.rs
+++ b/default-tiles/tab-bar/src/line.rs
@@ -57,7 +57,7 @@ fn left_more_message(tab_count_to_the_left: usize) -> LinePart {
let more_text = if tab_count_to_the_left < 10000 {
format!(" ← +{} ", tab_count_to_the_left)
} else {
- format!(" ← +many ")
+ " ← +many ".to_string()
};
// 238
let more_text_len = more_text.chars().count() + 2; // 2 for the arrows
@@ -84,7 +84,7 @@ fn right_more_message(tab_count_to_the_right: usize) -> LinePart {
let more_text = if tab_count_to_the_right < 10000 {
format!(" +{} → ", tab_count_to_the_right)
} else {
- format!(" +many → ")
+ " +many → ".to_string()
};
let more_text_len = more_text.chars().count() + 1; // 2 for the arrow
let left_separator = Style::new().fg(GRAY).on(ORANGE).paint(ARROW_SEPARATOR);
@@ -130,7 +130,7 @@ fn add_next_tabs_msg(
}
fn tab_line_prefix() -> LinePart {
- let prefix_text = format!(" Zellij ");
+ let prefix_text = " Zellij ".to_string();
let prefix_text_len = prefix_text.chars().count();
let prefix_styled_text = Style::new().fg(WHITE).on(GRAY).bold().paint(prefix_text);
LinePart {
diff --git a/default-tiles/tab-bar/src/main.rs b/default-tiles/tab-bar/src/main.rs
index 8c025336..4a1f2933 100644
--- a/default-tiles/tab-bar/src/main.rs
+++ b/default-tiles/tab-bar/src/main.rs
@@ -1,7 +1,7 @@
mod line;
mod tab;
-use zellij_tile::*;
+use zellij_tile::prelude::*;
use crate::line::tab_line;
use crate::tab::tab_style;
@@ -12,25 +12,10 @@ pub struct LinePart {
len: usize,
}
-#[derive(PartialEq)]
-enum BarMode {
- Normal,
- Rename,
-}
-
-impl Default for BarMode {
- fn default() -> Self {
- BarMode::Normal
- }
-}
-
#[derive(Default)]
struct State {
- active_tab_index: usize,
- num_tabs: usize,
- tabs: Vec<TabData>,
- mode: BarMode,
- new_name: String,
+ tabs: Vec<TabInfo>,
+ mode: InputMode,
}
static ARROW_SEPARATOR: &str = "";
@@ -49,17 +34,22 @@ pub mod colors {
register_tile!(State);
impl ZellijTile for State {
- fn init(&mut self) {
+ fn load(&mut self) {
set_selectable(false);
set_invisible_borders(true);
set_max_height(1);
- self.active_tab_index = 0;
- self.num_tabs = 0;
- self.mode = BarMode::Normal;
- self.new_name = String::new();
+ subscribe(&[EventType::TabUpdate, EventType::ModeUpdate]);
+ }
+
+ fn update(&mut self, event: Event) {
+ match event {
+ Event::ModeUpdate(mode_info) => self.mode = mode_info.mode,
+ Event::TabUpdate(tabs) => self.tabs = tabs,
+ _ => unimplemented!(), // FIXME: This should be unreachable, but this could be cleaner
+ }
}
- fn draw(&mut self, _rows: usize, cols: usize) {
+ fn render(&mut self, _rows: usize, cols: usize) {
if self.tabs.is_empty() {
return;
}
@@ -67,11 +57,9 @@ impl ZellijTile for State {
let mut active_tab_index = 0;
for t in self.tabs.iter_mut() {
let mut tabname = t.name.clone();
- if t.active && self.mode == BarMode::Rename {
- if self.new_name.is_empty() {
+ if t.active && self.mode == InputMode::RenameTab {
+ if tabname.is_empty() {
tabname = String::from("Enter name...");
- } else {
- tabname = self.new_name.clone();
}
active_tab_index = t.position;
} else if t.active {
@@ -87,23 +75,4 @@ impl ZellijTile for State {
}
println!("{}\u{1b}[48;5;238m\u{1b}[0K", s);
}
-
- fn update_tabs(&mut self) {
- self.tabs = get_tabs();
- }
-
- fn handle_tab_rename_keypress(&mut self, key: Key) {
- self.mode = BarMode::Rename;
- match key {
- Key::Char('\n') | Key::Esc => {
- self.mode = BarMode::Normal;
- self.new_name.clear();
- }
- Key::Char(c) => self.new_name = format!("{}{}", self.new_name, c),
- Key::Backspace | Key::Delete => {
- self.new_name.pop();
- }
- _ => {}
- }
- }
}
diff --git a/src/client/boundaries.rs b/src/client/boundaries.rs
index 19a1058d..e498da89 100644
--- a/src/client/boundaries.rs
+++ b/src/client/boundaries.rs
@@ -1,6 +1,7 @@
-use crate::{common::input::handler::InputMode, tab::Pane};
+use crate::tab::Pane;
use ansi_term::Colour;
use std::collections::HashMap;
+use zellij_tile::data::InputMode;
use std::fmt::{Display, Error, Formatter};
@@ -82,7 +83,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::VERTICAL) => {
@@ -91,7 +92,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL) => {
@@ -100,7 +101,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::TOP_LEFT) => {
@@ -109,7 +110,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::BOTTOM_RIGHT) => {
@@ -118,7 +119,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::BOTTOM_LEFT) => {
@@ -127,7 +128,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::VERTICAL_LEFT) => {
@@ -136,7 +137,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::VERTICAL_RIGHT) => {
@@ -145,7 +146,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL_DOWN) => {
@@ -154,7 +155,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL_UP) => {
@@ -163,7 +164,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_RIGHT, boundary_type::CROSS) => {
@@ -172,7 +173,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::HORIZONTAL) => {
@@ -181,7 +182,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::VERTICAL) => {
@@ -190,7 +191,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::TOP_LEFT) => {
@@ -199,7 +200,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::BOTTOM_RIGHT) => {
@@ -208,7 +209,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::BOTTOM_LEFT) => {
@@ -217,7 +218,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::VERTICAL_LEFT) => {
@@ -226,7 +227,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::VERTICAL_RIGHT) => {
@@ -235,7 +236,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::HORIZONTAL_DOWN) => {
@@ -244,7 +245,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::HORIZONTAL_UP) => {
@@ -253,7 +254,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL, boundary_type::CROSS) => {
@@ -262,7 +263,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::VERTICAL) => {
@@ -271,7 +272,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::TOP_LEFT) => {
@@ -280,7 +281,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::BOTTOM_RIGHT) => {
@@ -289,7 +290,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::BOTTOM_LEFT) => {
@@ -298,7 +299,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::VERTICAL_LEFT) => {
@@ -307,7 +308,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::VERTICAL_RIGHT) => {
@@ -316,7 +317,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::HORIZONTAL_DOWN) => {
@@ -325,7 +326,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::HORIZONTAL_UP) => {
@@ -334,7 +335,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL, boundary_type::CROSS) => {
@@ -343,7 +344,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::TOP_LEFT) => {
@@ -352,7 +353,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::BOTTOM_RIGHT) => {
@@ -361,7 +362,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::BOTTOM_LEFT) => {
@@ -370,7 +371,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::VERTICAL_LEFT) => {
@@ -379,7 +380,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::VERTICAL_RIGHT) => {
@@ -388,7 +389,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::HORIZONTAL_DOWN) => {
@@ -397,7 +398,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::HORIZONTAL_UP) => {
@@ -406,7 +407,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::TOP_LEFT, boundary_type::CROSS) => {
@@ -415,7 +416,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::BOTTOM_RIGHT) => {
@@ -424,7 +425,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::BOTTOM_LEFT) => {
@@ -433,7 +434,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::VERTICAL_LEFT) => {
@@ -442,7 +443,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::VERTICAL_RIGHT) => {
@@ -451,7 +452,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::HORIZONTAL_DOWN) => {
@@ -460,7 +461,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::HORIZONTAL_UP) => {
@@ -469,7 +470,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_RIGHT, boundary_type::CROSS) => {
@@ -478,7 +479,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_LEFT, boundary_type::BOTTOM_LEFT) => {
@@ -487,7 +488,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_LEFT, boundary_type::VERTICAL_LEFT) => {
@@ -496,7 +497,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_LEFT, boundary_type::VERTICAL_RIGHT) => {
@@ -505,7 +506,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_LEFT, boundary_type::HORIZONTAL_DOWN) => {
@@ -514,7 +515,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_LEFT, boundary_type::HORIZONTAL_UP) => {
@@ -523,7 +524,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::BOTTOM_LEFT, boundary_type::CROSS) => {
@@ -532,7 +533,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_LEFT, boundary_type::VERTICAL_LEFT) => {
@@ -541,7 +542,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_LEFT, boundary_type::VERTICAL_RIGHT) => {
@@ -550,7 +551,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_LEFT, boundary_type::HORIZONTAL_DOWN) => {
@@ -559,7 +560,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_LEFT, boundary_type::HORIZONTAL_UP) => {
@@ -568,7 +569,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_LEFT, boundary_type::CROSS) => {
@@ -577,7 +578,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_RIGHT, boundary_type::VERTICAL_RIGHT) => {
@@ -586,7 +587,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_RIGHT, boundary_type::HORIZONTAL_DOWN) => {
@@ -595,7 +596,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_RIGHT, boundary_type::HORIZONTAL_UP) => {
@@ -604,7 +605,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::VERTICAL_RIGHT, boundary_type::CROSS) => {
@@ -613,7 +614,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL_DOWN, boundary_type::HORIZONTAL_DOWN) => {
@@ -622,7 +623,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL_DOWN, boundary_type::HORIZONTAL_UP) => {
@@ -631,7 +632,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL_DOWN, boundary_type::CROSS) => {
@@ -640,7 +641,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL_UP, boundary_type::HORIZONTAL_UP) => {
@@ -649,7 +650,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::HORIZONTAL_UP, boundary_type::CROSS) => {
@@ -658,7 +659,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(boundary_type::CROSS, boundary_type::CROSS) => {
@@ -667,7 +668,7 @@ fn combine_symbols(
Some(BoundarySymbol {
boundary_type,
invisible,
- color: color,
+ color,
})
}
(_, _) => None,
diff --git a/src/client/layout.rs b/src/client/layout.rs
index 1b383540..2d1daaf4 100644
--- a/src/client/layout.rs
+++ b/src/client/layout.rs
@@ -1,10 +1,8 @@
-use crate::utils::consts::ZELLIJ_ROOT_LAYOUT_DIR;
use directories_next::ProjectDirs;
use serde::{Deserialize, Serialize};
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use std::{fs::File, io::prelude::*};
-use crate::common::wasm_vm::EventType;
use crate::panes::PositionAndSize;
fn split_space_to_parts_vertically(
@@ -181,19 +179,15 @@ pub struct Layout {
pub plugin: Option<PathBuf>,
#[serde(default)]
pub expansion_boundary: bool,
- #[serde(default, skip_serializing_if = "Vec::is_empty")]
- pub events: Vec<EventType>,
}
impl Layout {
pub fn new(layout_path: PathBuf) -> Self {
let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
let layout_dir = project_dirs.data_dir().join("layouts/");
- let root_layout_dir = Path::new(ZELLIJ_ROOT_LAYOUT_DIR);
let mut layout_file = File::open(&layout_path)
.or_else(|_| File::open(&layout_path.with_extension("yaml")))
.or_else(|_| File::open(&layout_dir.join(&layout_path).with_extension("yaml")))
- .or_else(|_| File::open(root_layout_dir.join(&layout_path).with_extension("yaml")))
.unwrap_or_else(|_| panic!("cannot find layout {}", &layout_path.display()));
let mut layout = String::new();
diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs
index 588cffd6..4cffff5f 100644
--- a/src/client/panes/plugin_pane.rs
+++ b/src/client/panes/plugin_pane.rs
@@ -120,7 +120,7 @@ impl Pane for PluginPane {
let (buf_tx, buf_rx) = channel();
self.send_plugin_instructions
- .send(PluginInstruction::Draw(
+ .send(PluginInstruction::Render(
buf_tx,
self.pid,
self.rows(),
diff --git a/src/client/panes/terminal_character.rs b/src/client/panes/terminal_character.rs
index 80c3162b..053ebd3f 100644
--- a/src/client/panes/terminal_character.rs
+++ b/src/client/panes/terminal_character.rs
@@ -23,7 +23,7 @@ pub enum AnsiCode {
On,
Reset,
NamedColor(NamedColor),
- RGBCode((u8, u8, u8)),
+ RgbCode((u8, u8, u8)),
ColorIndex(u8),
}
@@ -336,7 +336,7 @@ impl CharacterStyles {
[36, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Cyan))),
[37, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::White))),
[38, 2, ..] => {
- let ansi_code = AnsiCode::RGBCode((
+ let ansi_code = AnsiCode::RgbCode((
*ansi_params.get(2).unwrap() as u8,
*ansi_params.get(3).unwrap() as u8,
*ansi_params.get(4).unwrap() as u8,
@@ -364,7 +364,7 @@ impl CharacterStyles {
[46, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Cyan))),
[47, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::White))),
[48, 2, ..] => {
- let ansi_code = AnsiCode::RGBCode((
+ let ansi_code = AnsiCode::RgbCode((
*ansi_params.get(2).unwrap() as u8,
*ansi_params.get(3).unwrap() as u8,
*ansi_params.get(4).unwrap() as u8,
@@ -416,7 +416,7 @@ impl Display for CharacterStyles {
}
if let Some(ansi_code) = self.foreground {
match ansi_code {
- AnsiCode::RGBCode((r, g, b)) => {
+ AnsiCode::RgbCode((r, g, b)) => {
write!(f, "\u{1b}[38;2;{};{};{}m", r, g, b)?;
}
AnsiCode::ColorIndex(color_index) => {
@@ -433,7 +433,7 @@ impl Display for CharacterStyles {
};
if let Some(ansi_code) = self.background {
match ansi_code {
- AnsiCode::RGBCode((r, g, b)) => {
+ AnsiCode::RgbCode((r, g, b)) => {
write!(f, "\u{1b}[48;2;{};{};{}m", r, g, b)?;
}
AnsiCode::ColorIndex(color_index) => {
diff --git a/src/client/tab.rs b/src/client/tab.rs
index 081194ed..1e56fd8b 100644
--- a/src/client/tab.rs
+++ b/src/client/tab.rs
@@ -1,23 +1,21 @@
//! `Tab`s holds multiple panes. It tracks their coordinates (x/y) and size,
//! as well as how they should be resized
-use crate::common::{input::handler::InputMode, AppInstruction, SenderWithContext};
+use crate::boundaries::colors;
+use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContext};
use crate::layout::Layout;
use crate::panes::{PaneId, PositionAndSize, TerminalPane};
use crate::pty_bus::{PtyInstruction, VteEvent};
-use crate::wasm_vm::{PluginInputType, PluginInstruction};
-use crate::{
- boundaries::{colors, Boundaries},
- panes::PluginPane,
-};
+use crate::wasm_vm::PluginInstruction;
+use crate::{boundaries::Boundaries, panes::PluginPane};
use crate::{os_input_output::OsApi, utils::shared::pad_to_size};
-use serde::{Deserialize, Serialize};
use std::os::unix::io::RawFd;
use std::{
cmp::Reverse,
collections::{BTreeMap, HashSet},
};
use std::{io::Write, sync::mpsc::channel};
+use zellij_tile::data::{Event, InputMode};
const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this
const MIN_TERMINAL_HEIGHT: usize = 2;
@@ -71,14 +69,6 @@ pub struct Tab {
pub input_mode: InputMode,
}
-#[derive(Clone, Debug, Default, Serialize, Deserialize)]
-pub struct TabData {
- /* subset of fields to publish to plugins */
- pub position: usize,
- pub name: String,
- pub active: bool,
-}
-
// FIXME: Use a struct that has a pane_type enum, to reduce all of the duplication
pub trait Pane {
fn x(&self) -> usize;
@@ -268,11 +258,7 @@ impl Tab {
if let Some(plugin) = &layout.plugin {
let (pid_tx, pid_rx) = channel();
self.send_plugin_instructions
- .send(PluginInstruction::Load(
- pid_tx,
- plugin.clone(),
- layout.events.clone(),
- ))
+ .send(PluginInstruction::Load(pid_tx, plugin.clone()))
.unwrap();
let pid = pid_rx.recv().unwrap();
let new_plugin = PluginPane::new(
@@ -311,7 +297,6 @@ impl Tab {
self.toggle_active_pane_fullscreen();
}
if !self.has_panes() {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
self.os_api.set_terminal_size_using_fd(
@@ -362,7 +347,6 @@ impl Tab {
if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns()
&& terminal_to_split.rows() > terminal_to_split.min_height() * 2
{
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
@@ -383,7 +367,6 @@ impl Tab {
self.active_terminal = Some(pid);
}
} else if terminal_to_split.columns() > terminal_to_split.min_width() * 2 {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
let new_terminal = TerminalPane::new(term_pid, right_winsize);
@@ -413,7 +396,6 @@ impl Tab {
self.toggle_active_pane_fullscreen();
}
if !self.has_panes() {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
self.os_api.set_terminal_size_using_fd(
@@ -424,47 +406,44 @@ impl Tab {
self.panes.insert(pid, Box::new(new_terminal));
self.active_terminal = Some(pid);
}
- } else {
- // FIXME: This could use a second look
- if let PaneId::Terminal(term_pid) = pid {
- // TODO: check minimum size of active terminal
- let active_pane_id = &self.get_active_pane_id().unwrap();
- let active_pane = self.panes.get_mut(active_pane_id).unwrap();
- if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
- self.send_pty_instructions
- .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
- .unwrap();
- return;
- }
- let terminal_ws = PositionAndSize {
- x: active_pane.x(),
- y: active_pane.y(),
- rows: active_pane.rows(),
- columns: active_pane.columns(),
- };
- let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
+ } else if let PaneId::Terminal(term_pid) = pid {
+ // TODO: check minimum size of active terminal
+ let active_pane_id = &self.get_active_pane_id().unwrap();
+ let active_pane = self.panes.get_mut(active_pane_id).unwrap();
+ if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return;
+ }
+ let terminal_ws = PositionAndSize {
+ x: active_pane.x(),
+ y: active_pane.y(),
+ rows: active_pane.rows(),
+ columns: active_pane.columns(),
+ };
+ let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
+
+ active_pane.change_pos_and_size(&top_winsize);
- active_pane.change_pos_and_size(&top_winsize);
+ let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
+ self.os_api.set_terminal_size_using_fd(
+ new_terminal.pid,
+ bottom_winsize.columns as u16,
+ bottom_winsize.rows as u16,
+ );
+ self.panes.insert(pid, Box::new(new_terminal));
- let new_terminal = TerminalPane::new(term_pid, bottom_winsize);
+ if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd(
- new_terminal.pid,
- bottom_winsize.columns as u16,
- bottom_winsize.rows as u16,
+ *active_terminal_pid,
+ top_winsize.columns as u16,
+ top_winsize.rows as u16,
);
- self.panes.insert(pid, Box::new(new_terminal));
-
- if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
- self.os_api.set_terminal_size_using_fd(
- *active_terminal_pid,
- top_winsize.columns as u16,
- top_winsize.rows as u16,
- );
- }
-
- self.active_terminal = Some(pid);
- self.render();
}
+
+ self.active_terminal = Some(pid);
+ self.render();
}
}
pub fn vertical_split(&mut self, pid: PaneId) {
@@ -473,7 +452,6 @@ impl Tab {
self.toggle_active_pane_fullscreen();
}
if !self.has_panes() {
- // FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws);
self.os_api.set_terminal_size_using_fd(
@@ -484,47 +462,44 @@ impl Tab {
self.panes.insert(pid, Box::new(new_terminal));
self.active_terminal = Some(pid);
}
- } else {
- // FIXME: This could use a second look
- if let PaneId::Terminal(term_pid) = pid {
- // TODO: check minimum size of active terminal
- let active_pane_id = &self.get_active_pane_id().unwrap();
- let active_pane = self.panes.get_mut(active_pane_id).unwrap();
- if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
- self.send_pty_instructions
- .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
- .unwrap();
- return;
- }
- let terminal_ws = PositionAndSize {
- x: active_pane.x(),
- y: active_pane.y(),
- rows: active_pane.rows(),
- columns: active_pane.columns(),
- };
- let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
+ } else if let PaneId::Terminal(term_pid) = pid {
+ // TODO: check minimum size of active terminal
+ let active_pane_id = &self.get_active_pane_id().unwrap();
+ let active_pane = self.panes.get_mut(active_pane_id).unwrap();
+ if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return;
+ }
+ let terminal_ws = PositionAndSize {
+ x: active_pane.x(),
+ y: active_pane.y(),
+ rows: active_pane.rows(),
+ columns: active_pane.columns(),
+ };
+ let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
- active_pane.change_pos_and_size(&left_winsize);
+ active_pane.change_pos_and_size(&left_winsize);
- let new_terminal = TerminalPane::new(term_pid, right_winsize);
+ let new_terminal = TerminalPane::new(term_pid, right_winsize);
+ self.os_api.set_terminal_size_using_fd(
+ new_terminal.pid,
+ right_winsize.columns as u16,
+ right_winsize.rows as u16,
+ );
+ self.panes.insert(pid, Box::new(new_terminal));
+
+ if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd(
- new_terminal.pid,
- right_winsize.columns as u16,
- right_winsize.rows as u16,
+ *active_terminal_pid,
+ left_winsize.columns as u16,
+ left_winsize.rows as u16,
);
- self.panes.insert(pid, Box::new(new_terminal));
-
- if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
- self.os_api.set_terminal_size_using_fd(
- *active_terminal_pid,
- left_winsize.columns as u16,
- left_winsize.rows as u16,
- );
- }
-
- self.active_terminal = Some(pid);
- self.render();
}
+
+ self.active_terminal = Some(pid);
+ self.render();
}
}
pub fn get_active_pane(&self) -> Option<&dyn Pane> {
@@ -568,12 +543,11 @@ impl Tab {
.expect("failed to drain terminal");
}
Some(PaneId::Plugin(pid)) => {
- self.send_plugin_instructions
- .send(PluginInstruction::Input(
- PluginInputType::Normal(pid),
- input_bytes,
- ))
- .unwrap();
+ for key in parse_keys(&input_bytes) {
+ self.send_plugin_instructions
+ .send(PluginInstruction::Update(Some(pid), Event::KeyPress(key)))
+ .unwrap()
+ }
}
_ => {}
}
@@ -1691,6 +1665,7 @@ impl Tab {
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
}
}
+ self.render();
}
pub fn resize_left(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1702,6 +1677,7 @@ impl Tab {
self.reduce_pane_and_surroundings_left(&active_pane_id, count);
}
}
+ self.render();
}
pub fn resize_down(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1713,6 +1689,7 @@ impl Tab {
self.reduce_pane_and_surroundings_down(&active_pane_id, count);
}
}
+ self.render();
}
pub fn resize_up(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1724,6 +1701,7 @@ impl Tab {
self.reduce_pane_and_surroundings_up(&active_pane_id, count);
}
}
+ self.render();
}
pub fn move_focus(&mut self) {
if !self.has_selectable_panes() {
diff --git a/src/common/errors.rs b/src/common/errors.rs
index eeebf93f..f5aeae85 100644
--- a/src/common/errors.rs
+++ b/src/common/errors.rs
@@ -133,7 +133,7 @@ pub enum ContextType {
Plugin(PluginContext),
/// An app-related call.
App(AppContext),
- IPCServer,
+ IpcServer,
StdinHandler,
AsyncTask,
/// An empty, placeholder call. This should be thought of as representing no call at all.
@@ -152,7 +152,7 @@ impl Display for ContextType {
ContextType::Plugin(c) => write!(f, "{}plugin_thread: {}{:?}", purple, green, c),
ContextType::App(c) => write!(f, "{}main_thread: {}{:?}", purple, green, c),
- ContextType::IPCServer => write!(f, "{}ipc_server: {}AcceptInput", purple, green),
+ ContextType::IpcServer => write!(f, "{}ipc_server: {}AcceptInput", purple, green),
ContextType::StdinHandler => {
write!(f, "{}stdin_handler_thread: {}AcceptInput", purple, green)
}
@@ -164,6 +164,7 @@ impl Display for ContextType {
}
}
+// FIXME: Just deriving EnumDiscriminants from strum will remove the need for any of this!!!
/// Stack call representations corresponding to the different types of [`ScreenInstruction`]s.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ScreenContext {
@@ -202,6 +203,7 @@ pub enum ScreenContext {
ChangeInputMode,
}
+// FIXME: Just deriving EnumDiscriminants from strum will remove the need for any of this!!!
impl From<&ScreenInstruction> for ScreenContext {
fn from(screen_instruction: &ScreenInstruction) -> Self {
match *screen_instruction {
@@ -278,24 +280,20 @@ use crate::wasm_vm::PluginInstruction;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PluginContext {
Load,
- Draw,
- Input,
- GlobalInput,
+ Update,
+ Render,
Unload,
Quit,
- Tabs,
}
impl From<&PluginInstruction> for PluginContext {
fn from(plugin_instruction: &PluginInstruction) -> Self {
match *plugin_instruction {
PluginInstruction::Load(..) => PluginContext::Load,
- PluginInstruction::Draw(..) => PluginContext::Draw,
- PluginInstruction::Input(..) => PluginContext::Input,
- PluginInstruction::GlobalInput(_) => PluginContext::GlobalInput,
+ PluginInstruction::Update(..) => PluginContext::Update,
+ PluginInstruction::Render(..) => PluginContext::Render,
PluginInstruction::Unload(_) => PluginContext::Unload,
PluginInstruction::Quit => PluginContext::Quit,
- PluginInstruction::UpdateTabs(..) => PluginContext::Tabs,
}
}
}
@@ -303,8 +301,6 @@ impl From<&PluginInstruction> for PluginContext {
/// Stack call representations corresponding to the different types of [`AppInstruction`]s.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AppContext {
- GetState,
- SetState,
Exit,
Error,
}
@@ -312,8 +308,6 @@ pub enum AppContext {
impl From<&AppInstruction> for AppContext {
fn from(app_instruction: &AppInstruction) -> Self {
match *app_instruction {
- AppInstruction::GetState(_) => AppContext::GetState,
- AppInstruction::SetState(_) => AppContext::SetState,
AppInstruction::Exit => AppContext::Exit,
AppInstruction::Error(_) => AppContext::Error,
}
diff --git a/src/common/input/actions.rs b/src/common/input/actions.rs
index 88a7036f..f4226864 100644
--- a/src/common/input/actions.rs
+++ b/src/common/input/actions.rs
@@ -1,6 +1,6 @@
//! Definition of the actions that can be bound to keys.
-use super::handler;
+use zellij_tile::data::InputMode;
/// The four directions (left, right, up, down).
#[derive(Clone, Debug)]
@@ -19,7 +19,7 @@ pub enum Action {
/// Write to the terminal.
Write(Vec<u8>),
/// Switch to the specified input mode.
- SwitchToMode(handler::InputMode),
+ SwitchToMode(InputMode),
/// Resize focus pane in specified direction.
Resize(Direction),
/// Switch focus to next pane in specified direction.
@@ -49,5 +49,4 @@ pub enum Action {
CloseTab,
GoToTab(u32),
TabNameInput(Vec<u8>),
- SaveTabName,
}
diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs
index 2d5e965f..33f4e5dc 100644
--- a/src/common/input/handler.rs
+++ b/src/common/input/handler.rs
@@ -2,17 +2,16 @@
use super::actions::Action;
use super::keybinds::get_default_keybinds;
-use crate::common::{update_state, AppInstruction, AppState, SenderWithContext, OPENCALLS};
+use crate::common::{AppInstruction, SenderWithContext, OPENCALLS};
use crate::errors::ContextType;
use crate::os_input_output::OsApi;
use crate::pty_bus::PtyInstruction;
use crate::screen::ScreenInstruction;
-use crate::wasm_vm::{EventType, PluginInputType, PluginInstruction};
+use crate::wasm_vm::PluginInstruction;
use crate::CommandIsExecuting;
-use serde::{Deserialize, Serialize};
-use strum_macros::EnumIter;
-use termion::input::TermReadEventsAndRaw;
+use termion::input::{TermRead, TermReadEventsAndRaw};
+use zellij_tile::data::{Event, InputMode, Key, ModeInfo};
use super::keybinds::key_to_actions;
@@ -62,27 +61,21 @@ impl InputHandler {
'input_loop: loop {
//@@@ I think this should actually just iterate over stdin directly
let stdin_buffer = self.os_input.read_from_stdin();
- drop(
- self.send_plugin_instructions
- .send(PluginInstruction::GlobalInput(stdin_buffer.clone())),
- );
for key_result in stdin_buffer.events_and_raw() {
match key_result {
Ok((event, raw_bytes)) => match event {
termion::event::Event::Key(key) => {
+ let key = cast_termion_key(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
// been revised. Sorry about this (@categorille)
- if {
- let mut should_break = false;
- for action in
- key_to_actions(&key, raw_bytes, &self.mode, &keybinds)
- {
- should_break |= self.dispatch_action(action);
- }
- should_break
- } {
+ let mut should_break = false;
+ for action in key_to_actions(&key, raw_bytes, &self.mode, &keybinds)
+ {
+ should_break |= self.dispatch_action(action);
+ }
+ if should_break {
break 'input_loop;
}
}
@@ -130,11 +123,14 @@ impl InputHandler {
}
Action::SwitchToMode(mode) => {
self.mode = mode;
- update_state(&self.send_app_instructions, |_| AppState {
- input_mode: self.mode,
- });
+ self.send_plugin_instructions
+ .send(PluginInstruction::Update(
+ None,
+ Event::ModeUpdate(get_mode_info(mode)),
+ ))
+ .unwrap();
self.send_screen_instructions
- .send(ScreenInstruction::ChangeInputMode(self.mode))
+ .send(ScreenInstruction::ChangeInputMode(mode))
.unwrap();
self.send_screen_instructions
.send(ScreenInstruction::Render)
@@ -236,27 +232,10 @@ impl InputHandler {
.unwrap();
}
Action::TabNameInput(c) => {
- self.send_plugin_instructions
- .send(PluginInstruction::Input(
- PluginInputType::Event(EventType::Tab),
- c.clone(),
- ))
- .unwrap();
self.send_screen_instructions
.send(ScreenInstruction::UpdateTabName(c))
.unwrap();
}
- Action::SaveTabName => {
- self.send_plugin_instructions
- .send(PluginInstruction::Input(
- PluginInputType::Event(EventType::Tab),
- vec![b'\n'],
- ))
- .unwrap();
- self.send_screen_instructions
- .send(ScreenInstruction::UpdateTabName(vec![b'\n']))
- .unwrap();
- }
Action::NoOp => {}
}
@@ -272,45 +251,10 @@ impl InputHandler {
}
}
-/// Describes the different input modes, which change the way that keystrokes will be interpreted.
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter, Serialize, Deserialize)]
-pub enum InputMode {
- /// In `Normal` mode, input is always written to the terminal, except for the shortcuts leading
- /// to other modes
- Normal,
- /// In `Locked` mode, input is always written to the terminal and all shortcuts are disabled
- /// except the one leading back to normal mode
- Locked,
- /// `Resize` mode allows resizing the different existing panes.
- Resize,
- /// `Pane` mode allows creating and closing panes, as well as moving between them.
- Pane,
- /// `Tab` mode allows creating and closing tabs, as well as moving between them.
- Tab,
- /// `Scroll` mode allows scrolling up and down within a pane.
- Scroll,
- RenameTab,
-}
-
-/// 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)]
-pub struct Help {
- pub mode: InputMode,
- pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description>
-}
-
-impl Default for InputMode {
- fn default() -> InputMode {
- InputMode::Normal
- }
-}
-
/// Creates a [`Help`] struct indicating the current [`InputMode`] and its keybinds
/// (as pairs of [`String`]s).
// TODO this should probably be automatically generated in some way
-pub fn get_help(mode: InputMode) -> Help {
+pub fn get_mode_info(mode: InputMode) -> ModeInfo {
let mut keybinds: Vec<(String, String)> = vec![];
match mode {
InputMode::Normal | InputMode::Locked => {}
@@ -339,7 +283,7 @@ pub fn get_help(mode: InputMode) -> Help {
keybinds.push(("Enter".to_string(), "when done".to_string()));
}
}
- Help { mode, keybinds }
+ ModeInfo { mode, keybinds }
}
/// Entry point to the module. Instantiates an [`InputHandler`] and starts
@@ -362,3 +306,35 @@ pub fn input_loop(
)
.handle_input();
}
+
+pub fn parse_keys(input_bytes: &[u8]) -> Vec<Key> {
+ input_bytes.keys().flatten().map(cast_termion_key).collect()
+}
+
+// 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!")
+ }
+ }
+}
diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs
index 4b676037..7b1e8779 100644
--- a/src/common/input/keybinds.rs
+++ b/src/common/input/keybinds.rs
@@ -1,12 +1,11 @@
//! Mapping of inputs to sequences of actions.
use super::actions::{Action, Direction};
-use super::handler::InputMode;
use std::collections::HashMap;
use strum::IntoEnumIterator;
-use termion::event::Key;
+use zellij_tile::data::*;
type Keybinds = HashMap<InputMode, ModeKeybinds>;
type ModeKeybinds = HashMap<Key, Vec<Action>>;
@@ -17,14 +16,14 @@ pub fn get_default_keybinds() -> Result<Keybinds, String> {
let mut defaults = Keybinds::new();
for mode in InputMode::iter() {
- defaults.insert(mode, get_defaults_for_mode(&mode)?);
+ defaults.insert(mode, get_defaults_for_mode(&mode));
}
Ok(defaults)
}
/// Returns the default keybinds for a givent [`InputMode`].
-fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> {
+fn get_defaults_for_mode(mode: &InputMode) -> ModeKeybinds {
let mut defaults = ModeKeybinds::new();
match *mode {
@@ -227,10 +226,7 @@ fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> {
defaults.insert(Key::Up, vec![Action::ScrollUp]);
}
InputMode::RenameTab => {
- defaults.insert(
- Key::Char('\n'),
- vec![Action::SaveTabName, Action::SwitchToMode(InputMode::Tab)],
- );
+ defaults.insert(Key::Char('\n'), vec![Action::SwitchToMode(InputMode::Tab)]);
defaults.insert(
Key::Ctrl('g'),
vec![Action::SwitchToMode(InputMode::Normal)],
@@ -245,7 +241,7 @@ fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> {
}
}
- Ok(defaults)
+ defaults
}
/// Converts a [`Key`] terminal event to a sequence of [`Action`]s according to the current
diff --git a/src/common/ipc.rs b/src/common/ipc.rs
index 77d57df3..81576b86 100644
--- a/src/common/ipc.rs
+++ b/src/common/ipc.rs
@@ -3,12 +3,12 @@
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
-type SessionID = u64;
+type SessionId = u64;
#[derive(PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct Session {
// Unique ID for this session
- id: SessionID,
+ id: SessionId,
// Identifier for the underlying IPC primitive (socket, pipe)
conn_name: String,
// User configured alias for the session
@@ -30,9 +30,9 @@ pub enum ClientToServerMsg {
// Create a new session
CreateSession,
// Attach to a running session
- AttachToSession(SessionID, ClientType),
+ AttachToSession(SessionId, ClientType),
// Force detach
- DetachSession(SessionID),
+ DetachSession(SessionId),
// Disconnect from the session we're connected to
DisconnectFromSession,
}
diff --git a/src/common/mod.rs b/src/common/mod.rs
index 7e52dde7..e895fcc0 100644
--- a/src/common/mod.rs
+++ b/src/common/mod.rs
@@ -9,34 +9,35 @@ pub mod screen;
pub mod utils;
pub mod wasm_vm;
-use std::io::Write;
-use std::path::{Path, PathBuf};
+use std::cell::RefCell;
+use std::path::PathBuf;
use std::sync::mpsc;
use std::thread;
-use std::{cell::RefCell, sync::mpsc::TrySendError};
use std::{collections::HashMap, fs};
-
-use crate::panes::PaneId;
-use directories_next::ProjectDirs;
-use input::handler::InputMode;
-use serde::{Deserialize, Serialize};
-use termion::input::TermRead;
-use wasm_vm::PluginEnv;
-use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
-use wasmer_wasi::{Pipe, WasiState};
+use std::{
+ collections::HashSet,
+ io::Write,
+ str::FromStr,
+ sync::{Arc, Mutex},
+};
use crate::cli::CliArgs;
use crate::layout::Layout;
+use crate::panes::PaneId;
use command_is_executing::CommandIsExecuting;
+use directories_next::ProjectDirs;
use errors::{AppContext, ContextType, ErrorContext, PluginContext, PtyContext, ScreenContext};
use input::handler::input_loop;
use os_input_output::OsApi;
use pty_bus::{PtyBus, PtyInstruction};
use screen::{Screen, ScreenInstruction};
-use utils::consts::{ZELLIJ_IPC_PIPE, ZELLIJ_ROOT_PLUGIN_DIR};
-use wasm_vm::{
- wasi_stdout, wasi_write_string, zellij_imports, EventType, PluginInputType, PluginInstruction,
-};
+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 wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
+use wasmer_wasi::{Pipe, WasiState};
+use zellij_tile::data::{EventType, InputMode};
#[derive(Serialize, Deserialize, Debug)]
pub enum ApiCommand {
@@ -45,25 +46,6 @@ pub enum ApiCommand {
SplitVertically,
MoveFocus,
}
-// FIXME: It would be good to add some more things to this over time
-#[derive(Debug, Clone, Default)]
-pub struct AppState {
- pub input_mode: InputMode,
-}
-
-// FIXME: Make this a method on the big `Communication` struct, so that app_tx can be extracted
-// from self instead of being explicitly passed here
-pub fn update_state(
- app_tx: &SenderWithContext<AppInstruction>,
- update_fn: impl FnOnce(AppState) -> AppState,
-) {
- let (state_tx, state_rx) = mpsc::channel();
-
- drop(app_tx.send(AppInstruction::GetState(state_tx)));
- let state = state_rx.recv().unwrap();
-
- drop(app_tx.send(AppInstruction::SetState(update_fn(state))))
-}
/// An [MPSC](mpsc) asynchronous channel with added error context.
pub type ChannelWithContext<T> = (
@@ -107,19 +89,6 @@ impl<T: Clone> SenderWithContext<T> {
}
}
- /// Attempts to send an event on this sender's channel, terminating instead of blocking
- /// if the event could not be sent (buffer full or connection closed).
- ///
- /// This can only be called on [`SyncSender`](SenderType::SyncSender)s, and will
- /// panic if called on an asynchronous [`Sender`](SenderType::Sender).
- pub fn try_send(&self, event: T) -> Result<(), TrySendError<(T, ErrorContext)>> {
- if let SenderType::SyncSender(ref s) = self.sender {
- s.try_send((event, self.err_ctx))
- } else {
- panic!("try_send can only be called on SyncSenders!")
- }
- }
-
/// Updates this [`SenderWithContext`]'s [`ErrorContext`]. This is the way one adds
/// a call to the error context.
///
@@ -142,8 +111,6 @@ thread_local!(
/// Instructions related to the entire application.
#[derive(Clone)]
pub enum AppInstruction {
- GetState(mpsc::Sender<AppState>),
- SetState(AppState),
Exit,
Error(String),
}
@@ -157,7 +124,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
.get_stdout_writer()
.write(take_snapshot.as_bytes())
.unwrap();
- let mut app_state = AppState::default();
let command_is_executing = CommandIsExecuting::new();
@@ -382,8 +348,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
.get_active_tab_mut()
.unwrap()
.set_pane_selectable(id, selectable);
- // FIXME: Is this needed?
- screen.render();
}
ScreenInstruction::SetMaxHeight(id, max_height) => {
screen
@@ -447,12 +411,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
let store = Store::default();
let mut plugin_id = 0;
let mut plugin_map = HashMap::new();
- let handler_map: HashMap<EventType, String> =
- [(EventType::Tab, "handle_tab_rename_keypress".to_string())]
- .iter()
- .cloned()
- .collect();
-
move || loop {
let (event, mut err_ctx) = receive_plugin_instructions
.recv()
@@ -462,18 +420,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
send_pty_instructions.update(err_ctx);
send_app_instructions.update(err_ctx);
match event {
- PluginInstruction::Load(pid_tx, path, events) => {
+ PluginInstruction::Load(pid_tx, path) => {
let project_dirs =
ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
let plugin_dir = project_dirs.data_dir().join("plugins/");
- // FIXME: This really shouldn't need to exist anymore, let's get rid of it!
- let root_plugin_dir = Path::new(ZELLIJ_ROOT_PLUGIN_DIR);
let wasm_bytes = fs::read(&path)
.or_else(|_| fs::read(&path.with_extension("wasm")))
.or_else(|_| fs::read(&plugin_dir.join(&path).with_extension("wasm")))
- .or_else(|_| {
- fs::read(&root_plugin_dir.join(&path).with_extension("wasm"))
- })
.unwrap_or_else(|_| panic!("cannot find plugin {}", &path.display()));
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
@@ -504,7 +457,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
send_screen_instructions: send_screen_instructions.clone(),
send_app_instructions: send_app_instructions.clone(),
wasi_env,
- events,
+ subscriptions: Arc::new(Mutex::new(HashSet::new())),
};
let zellij = zellij_imports(&store, &plugin_env);
@@ -519,88 +472,33 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
pid_tx.send(plugin_id).unwrap();
plugin_id += 1;
}
- PluginInstruction::Draw(buf_tx, pid, rows, cols) => {
+ PluginInstruction::Update(pid, event) => {
+ for (&i, (instance, plugin_env)) in &plugin_map {
+ let subs = plugin_env.subscriptions.lock().unwrap();
+ // FIXME: This is very janky... Maybe I should write my own macro for Event -> EventType?
+ 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(),
+ );
+ update.call(&[]).unwrap();
+ }
+ }
+ drop(send_screen_instructions.send(ScreenInstruction::Render));
+ }
+ PluginInstruction::Render(buf_tx, pid, rows, cols) => {
let (instance, plugin_env) = plugin_map.get(&pid).unwrap();
- let draw = instance.exports.get_function("draw").unwrap();
+ let render = instance.exports.get_function("render").unwrap();
- draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)])
+ render
+ .call(&[Value::I32(rows as i32), Value::I32(cols as i32)])
.unwrap();
buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap();
}
- PluginInstruction::UpdateTabs(mut tabs) => {
- for (instance, plugin_env) in plugin_map.values() {
- if !plugin_env.events.contains(&EventType::Tab) {
- continue;
- }
- let handler = instance.exports.get_function("update_tabs").unwrap();
- tabs.sort_by(|a, b| a.position.cmp(&b.position));
- wasi_write_string(
- &plugin_env.wasi_env,
- &serde_json::to_string(&tabs).unwrap(),
- );
- handler.call(&[]).unwrap();
- }
- }
- // FIXME: Deduplicate this with the callback below!
- PluginInstruction::Input(input_type, input_bytes) => {
- match input_type {
- PluginInputType::Normal(pid) => {
- let (instance, plugin_env) = plugin_map.get(&pid).unwrap();
- let handle_key =
- instance.exports.get_function("handle_key").unwrap();
- for key in input_bytes.keys() {
- if let Ok(key) = key {
- wasi_write_string(
- &plugin_env.wasi_env,
- &serde_json::to_string(&key).unwrap(),
- );
- handle_key.call(&[]).unwrap();
- }
- }
- }
- PluginInputType::Event(event) => {
- for (instance, plugin_env) in plugin_map.values() {
- if !plugin_env.events.contains(&event) {
- continue;
- }
- let handle_key = instance
- .exports
- .get_function(handler_map.get(&event).unwrap())
- .unwrap();
- for key in input_bytes.keys() {
- if let Ok(key) = key {
- wasi_write_string(
- &plugin_env.wasi_env,
- &serde_json::to_string(&key).unwrap(),
- );
- handle_key.call(&[]).unwrap();
- }
- }
- }
- }
- }
- drop(send_screen_instructions.send(ScreenInstruction::Render));
- }
- PluginInstruction::GlobalInput(input_bytes) => {
- // FIXME: Set up an event subscription system, and timed callbacks
- for (instance, plugin_env) in plugin_map.values() {
- let handler =
- instance.exports.get_function("handle_global_key").unwrap();
- for key in input_bytes.keys() {
- if let Ok(key) = key {
- wasi_write_string(
- &plugin_env.wasi_env,
- &serde_json::to_string(&key).unwrap(),
- );
- handler.call(&[]).unwrap();
- }
- }
- }
-
- drop(send_screen_instructions.send(ScreenInstruction::Render));
- }
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
PluginInstruction::Quit => break,
}
@@ -623,7 +521,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
let listener = std::os::unix::net::UnixListener::bind(ZELLIJ_IPC_PIPE)
.expect("could not listen on ipc socket");
let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow());
- err_ctx.add_call(ContextType::IPCServer);
+ err_ctx.add_call(ContextType::IpcServer);
send_pty_instructions.update(err_ctx);
send_screen_instructions.update(err_ctx);
@@ -698,8 +596,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
send_screen_instructions.update(err_ctx);
send_pty_instructions.update(err_ctx);
match app_instruction {
- AppInstruction::GetState(state_tx) => drop(state_tx.send(app_state.clone())),
- AppInstruction::SetState(state) => app_state = state,
AppInstruction::Exit => {
break;
}
diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs
index 26a7d497..043a9aea 100644
--- a/src/common/os_input_output.rs
+++ b/src/common/os_input_output.rs
@@ -82,15 +82,10 @@ fn handle_command_exit(mut child: Child) {
}
for signal in signals.pending() {
- // FIXME: We need to handle more signals here!
- #[allow(clippy::single_match)]
- match signal {
- signal_hook::SIGINT => {
- child.kill().unwrap();
- child.wait().unwrap();
- break 'handle_exit;
- }
- _ => {}
+ if signal == signal_hook::SIGINT {
+ child.kill().unwrap();
+ child.wait().unwrap();
+ break 'handle_exit;
}
}
}
diff --git a/src/common/screen.rs b/src/common/screen.rs
index bb77ab85..5208834a 100644
--- a/src/common/screen.rs
+++ b/src/common/screen.rs
@@ -5,14 +5,16 @@ use std::os::unix::io::RawFd;
use std::str;
use std::sync::mpsc::Receiver;
-use super::{input::handler::InputMode, AppInstruction, SenderWithContext};
+use super::{AppInstruction, SenderWithContext};
use crate::os_input_output::OsApi;
use crate::panes::PositionAndSize;
use crate::pty_bus::{PtyInstruction, VteEvent};
-use crate::tab::{Tab, TabData};
+use crate::tab::Tab;
use crate::{errors::ErrorContext, wasm_vm::PluginInstruction};
use crate::{layout::Layout, panes::PaneId};
+use zellij_tile::data::{Event, InputMode, TabInfo};
+
/// Instructions that can be sent to the [`Screen`].
#[derive(Debug, Clone)]
pub enum ScreenInstruction {
@@ -72,7 +74,6 @@ pub struct Screen {
active_tab_index: Option<usize>,
/// The [`OsApi`] this [`Screen`] uses.
os_api: Box<dyn OsApi>,
- tabname_buf: String,
input_mode: InputMode,
}
@@ -98,7 +99,6 @@ impl Screen {
active_tab_index: None,
tabs: BTreeMap::new(),
os_api,
- tabname_buf: String::new(),
input_mode,
}
}
@@ -174,15 +174,12 @@ impl Screen {
pub fn go_to_tab(&mut self, mut tab_index: usize) {
tab_index -= 1;
let active_tab = self.get_active_tab().unwrap();
- match self.tabs.values().find(|t| t.position == tab_index) {
- Some(t) => {
- if t.index != active_tab.index {
- self.active_tab_index = Some(t.index);
- self.update_tabs();
- self.render();
- }
+ if let Some(t) = self.tabs.values().find(|t| t.position == tab_index) {
+ if t.index != active_tab.index {
+ self.active_tab_index = Some(t.index);
+ self.update_tabs();
+ self.render();
}
- None => {}
}
}
@@ -276,38 +273,33 @@ impl Screen {
let mut tab_data = vec![];
let active_tab_index = self.active_tab_index.unwrap();
for tab in self.tabs.values() {
- tab_data.push(TabData {
+ tab_data.push(TabInfo {
position: tab.position,
name: tab.name.clone(),
active: active_tab_index == tab.index,
});
}
self.send_plugin_instructions
- .send(PluginInstruction::UpdateTabs(tab_data))
+ .send(PluginInstruction::Update(None, Event::TabUpdate(tab_data)))
.unwrap();
}
pub fn update_active_tab_name(&mut self, buf: Vec<u8>) {
let s = str::from_utf8(&buf).unwrap();
+ let active_tab = self.get_active_tab_mut().unwrap();
match s {
"\0" => {
- self.tabname_buf = String::new();
- }
- "\n" => {
- let new_name = self.tabname_buf.clone();
- let active_tab = self.get_active_tab_mut().unwrap();
- active_tab.name = new_name;
- self.update_tabs();
- self.render();
+ active_tab.name = String::new();
}
"\u{007F}" | "\u{0008}" => {
//delete and backspace keys
- self.tabname_buf.pop();
+ active_tab.name.pop();
}
c => {
- self.tabname_buf.push_str(c);
+ active_tab.name.push_str(c);
}
}
+ self.update_tabs();
}
pub fn change_input_mode(&mut self, input_mode: InputMode) {
self.input_mode = input_mode;
diff --git a/src/common/utils/consts.rs b/src/common/utils/consts.rs
index fa9eee0d..663a545d 100644
--- a/src/common/utils/consts.rs
+++ b/src/common/utils/consts.rs
@@ -4,5 +4,3 @@ pub const ZELLIJ_TMP_DIR: &str = "/tmp/zellij";
pub const ZELLIJ_TMP_LOG_DIR: &str = "/tmp/zellij/zellij-log";
pub const ZELLIJ_TMP_LOG_FILE: &str = "/tmp/zellij/zellij-log/log.txt";
pub const ZELLIJ_IPC_PIPE: &str = "/tmp/zellij/ipc";
-pub const ZELLIJ_ROOT_PLUGIN_DIR: &str = "/usr/share/zellij/plugins";
-pub const ZELLIJ_ROOT_LAYOUT_DIR: &str = "/usr/share/zellij/layouts";
diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs
index 15b920ad..29b110ae 100644
--- a/src/common/wasm_vm.rs
+++ b/src/common/wasm_vm.rs
@@ -1,36 +1,22 @@
-use crate::tab::TabData;
-use serde::{Deserialize, Serialize};
use std::{
+ collections::HashSet,
path::PathBuf,
- sync::mpsc::{channel, Sender},
+ sync::{mpsc::Sender, Arc, Mutex},
};
use wasmer::{imports, Function, ImportObject, Store, WasmerEnv};
use wasmer_wasi::WasiEnv;
+use zellij_tile::data::{Event, EventType};
use super::{
- input::handler::get_help, pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction,
- PaneId, SenderWithContext,
+ pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext,
};
-#[derive(Clone, Debug, PartialEq, Hash, Eq, Serialize, Deserialize)]
-pub enum EventType {
- Tab,
-}
-
-#[derive(Clone, Debug)]
-pub enum PluginInputType {
- Normal(u32),
- Event(EventType),
-}
-
#[derive(Clone, Debug)]
pub enum PluginInstruction {
- Load(Sender<u32>, PathBuf, Vec<EventType>),
- Draw(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
- Input(PluginInputType, Vec<u8>), // plugin id, input bytes
- GlobalInput(Vec<u8>), // input bytes
+ Load(Sender<u32>, PathBuf),
+ Update(Option<u32>, Event), // Focused plugin / broadcast, event data
+ Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
Unload(u32),
- UpdateTabs(Vec<TabData>), // num tabs, active tab
Quit,
}
@@ -41,7 +27,7 @@ pub struct PluginEnv {
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 wasi_env: WasiEnv,
- pub events: Vec<EventType>,
+ pub subscriptions: Arc<Mutex<HashSet<EventType>>>,
}
// Plugin API ---------------------------------------------------------------------------------------------------------
@@ -49,16 +35,28 @@ pub struct PluginEnv {
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),
- "host_get_help" => Function::new_native_with_env(store, plugin_env.clone(), host_get_help),
}
}
}
-// FIXME: Bundle up all of the channels! Pair that with WasiEnv?
+fn host_subscribe(plugin_env: &PluginEnv) {
+ let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
+ let new: HashSet<EventType> = serde_json::from_str(&wasi_stdout(&plugin_env.wasi_env)).unwrap();
+ subscriptions.extend(new);
+}
+
+fn host_unsubscribe(plugin_env: &PluginEnv) {
+ let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
+ let old: HashSet<EventType> = serde_json::from_str(&wasi_stdout(&plugin_env.wasi_env)).unwrap();
+ 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
@@ -67,7 +65,6 @@ fn host_open_file(plugin_env: &PluginEnv) {
.unwrap();
}
-// FIXME: Think about these naming conventions – should everything be prefixed by 'host'?
fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
let selectable = selectable != 0;
plugin_env
@@ -101,21 +98,6 @@ fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) {
.unwrap()
}
-fn host_get_help(plugin_env: &PluginEnv) {
- let (state_tx, state_rx) = channel();
- // FIXME: If I changed the application so that threads were sent the termination
- // signal and joined one at a time, there would be an order to shutdown, so I
- // could get rid of this .is_ok() check and the .try_send()
- if plugin_env
- .send_app_instructions
- .try_send(AppInstruction::GetState(state_tx))
- .is_ok()
- {
- let help = get_help(state_rx.recv().unwrap().input_mode);
- wasi_write_string(&plugin_env.wasi_env, &serde_json::to_string(&help).unwrap());
- }
-}
-
// Helper Functions ---------------------------------------------------------------------------------------------------
// FIXME: Unwrap city
diff --git a/zellij-tile/Cargo.toml b/zellij-tile/Cargo.toml
index bdabb175..eb9a2d59 100644
--- a/zellij-tile/Cargo.toml
+++ b/zellij-tile/Cargo.toml
@@ -8,4 +8,6 @@ license = "MIT"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0" \ No newline at end of file
+serde_json = "1.0"
+strum = "0.20.0"
+strum_macros = "0.20.0" \ No newline at end of file
diff --git a/zellij-tile/src/data.rs b/zellij-tile/src/data.rs
new file mode 100644
index 00000000..9576285a
--- /dev/null
+++ b/zellij-tile/src/data.rs
@@ -0,0 +1,77 @@
+use serde::{Deserialize, Serialize};
+use strum_macros::{EnumDiscriminants, EnumIter, EnumString, ToString};
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub enum Key {
+ Backspace,
+ Left,
+ Right,
+ Up,
+ Down,
+ Home,
+ End,
+ PageUp,
+ PageDown,
+ BackTab,
+ Delete,
+ Insert,
+ F(u8),
+ Char(char),
+ Alt(char),
+ Ctrl(char),
+ Null,
+ Esc,
+}
+
+#[derive(Debug, Clone, EnumDiscriminants, ToString, Serialize, Deserialize)]
+#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))]
+#[strum_discriminants(name(EventType))]
+pub enum Event {
+ ModeUpdate(ModeInfo),
+ TabUpdate(Vec<TabInfo>),
+ KeyPress(Key),
+}
+
+/// Describes the different input modes, which change the way that keystrokes will be interpreted.
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter, Serialize, Deserialize)]
+pub enum InputMode {
+ /// In `Normal` mode, input is always written to the terminal, except for the shortcuts leading
+ /// to other modes
+ Normal,
+ /// In `Locked` mode, input is always written to the terminal and all shortcuts are disabled
+ /// except the one leading back to normal mode
+ Locked,
+ /// `Resize` mode allows resizing the different existing panes.
+ Resize,
+ /// `Pane` mode allows creating and closing panes, as well as moving between them.
+ Pane,
+ /// `Tab` mode allows creating and closing tabs, as well as moving between them.
+ Tab,
+ /// `Scroll` mode allows scrolling up and down within a pane.
+ Scroll,
+ RenameTab,
+}
+
+impl Default for InputMode {
+ fn default() -> InputMode {
+ InputMode::Normal
+ }
+}
+
+/// 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)]
+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)]
+pub struct TabInfo {
+ /* subset of fields to publish to plugins */
+ pub position: usize,
+ pub name: String,
+ pub active: bool,
+}
diff --git a/zellij-tile/src/lib.rs b/zellij-tile/src/lib.rs
index de87ee9c..72211764 100644
--- a/zellij-tile/src/lib.rs
+++ b/zellij-tile/src/lib.rs
@@ -1,14 +1,14 @@
-mod shim;
+pub mod data;
+pub mod prelude;
+pub mod shim;
+
+use data::*;
-pub use shim::*;
#[allow(unused_variables)]
pub trait ZellijTile {
- fn init(&mut self) {}
- fn draw(&mut self, rows: usize, cols: usize) {}
- fn handle_key(&mut self, key: Key) {}
- fn handle_global_key(&mut self, key: Key) {}
- fn update_tabs(&mut self) {}
- fn handle_tab_rename_keypress(&mut self, key: Key) {}
+ fn load(&mut self) {}
+ fn update(&mut self, event: Event) {}
+ fn render(&mut self, rows: usize, cols: usize) {}
}
#[macro_export]
@@ -20,45 +20,22 @@ macro_rules! register_tile {
fn main() {
STATE.with(|state| {
- state.borrow_mut().init();
+ state.borrow_mut().load();
});
}
#[no_mangle]
- pub fn draw(rows: i32, cols: i32) {
+ pub fn update() {
STATE.with(|state| {
- state.borrow_mut().draw(rows as usize, cols as usize);
+ state.borrow_mut().update($crate::shim::object_from_stdin());
});
}
#[no_mangle]
- pub fn handle_key() {
+ pub fn render(rows: i32, cols: i32) {
STATE.with(|state| {
- state.borrow_mut().handle_key($crate::get_key());
+ state.borrow_mut().render(rows as usize, cols as usize);
});
}
-
- #[no_mangle]
- pub fn handle_global_key() {
- STATE.with(|state| {
- state.borrow_mut().handle_global_key($crate::get_key());
- });
- }
-
- #[no_mangle]
- pub fn update_tabs() {
- STATE.with(|state| {
- state.borrow_mut().update_tabs();
- })
- }
-
- #[no_mangle]
- pub fn handle_tab_rename_keypress() {
- STATE.with(|state| {
- state
- .borrow_mut()
- .handle_tab_rename_keypress($crate::get_key());
- })
- }
};
}
diff --git a/zellij-tile/src/prelude.rs b/zellij-tile/src/prelude.rs
new file mode 100644
index 00000000..2dd24a47
--- /dev/null
+++ b/zellij-tile/src/prelude.rs
@@ -0,0 +1,3 @@
+pub use crate::data::*;
+pub use crate::shim::*;
+pub use crate::*;
diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs
index b7beb7af..42a646a1 100644
--- a/zellij-tile/src/shim.rs
+++ b/zellij-tile/src/shim.rs
@@ -1,105 +1,56 @@
-use serde::{de::DeserializeOwned, Deserialize, Serialize};
+use serde::de::DeserializeOwned;
use std::{io, path::Path};
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
-pub enum Key {
- Backspace,
- Left,
- Right,
- Up,
- Down,
- Home,
- End,
- PageUp,
- PageDown,
- BackTab,
- Delete,
- Insert,
- F(u8),
- Char(char),
- Alt(char),
- Ctrl(char),
- Null,
- Esc,
-}
-
-// TODO: use same struct from main crate?
-#[derive(Default, Debug, Clone, Serialize, Deserialize)]
-pub struct Help {
- pub mode: InputMode,
- pub keybinds: Vec<(String, String)>,
-}
+use crate::data::*;
-// TODO: use same struct from main crate?
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub enum InputMode {
- Normal,
- Locked,
- Resize,
- Pane,
- Tab,
- RenameTab,
- Scroll,
- Exiting,
-}
+// Subscription Handling
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub struct TabData {
- /* subset of fields to publish to plugins */
- pub position: usize,
- pub name: String,
- pub active: bool,
+pub fn subscribe(event_types: &[EventType]) {
+ println!("{}", serde_json::to_string(event_types).unwrap());
+ unsafe { host_subscribe() };
}
-impl Default for InputMode {
- fn default() -> InputMode {
- InputMode::Normal
- }
+pub fn unsubscribe(event_types: &[EventType]) {
+ println!("{}", serde_json::to_string(event_types).unwrap());
+ unsafe { host_unsubscribe() };
}
-pub fn get_key() -> Key {
- deserialize_from_stdin().unwrap()
-}
-
-pub fn open_file(path: &Path) {
- println!("{}", path.to_string_lossy());
- unsafe { host_open_file() };
-}
+// Plugin Settings
pub fn set_max_height(max_height: i32) {
unsafe { host_set_max_height(max_height) };
}
pub fn set_invisible_borders(invisible_borders: bool) {
- let invisible_borders = if invisible_borders { 1 } else { 0 };
- unsafe { host_set_invisible_borders(invisible_borders) };
+ unsafe { host_set_invisible_borders(if invisible_borders { 1 } else { 0 }) };
}
pub fn set_selectable(selectable: bool) {
- let selectable = if selectable { 1 } else { 0 };
- unsafe { host_set_selectable(selectable) };
+ unsafe { host_set_selectable(if selectable { 1 } else { 0 }) };
}
-pub fn get_help() -> Help {
- unsafe { host_get_help() };
- deserialize_from_stdin().unwrap_or_default()
-}
+// Host Functions
-pub fn get_tabs() -> Vec<TabData> {
- deserialize_from_stdin().unwrap_or_default()
+pub fn open_file(path: &Path) {
+ println!("{}", path.to_string_lossy());
+ unsafe { host_open_file() };
}
-fn deserialize_from_stdin<T: DeserializeOwned>() -> Option<T> {
+// Internal Functions
+
+#[doc(hidden)]
+pub fn object_from_stdin<T: DeserializeOwned>() -> T {
let mut json = String::new();
io::stdin().read_line(&mut json).unwrap();
- serde_json::from_str(&json).ok()
+ serde_json::from_str(&json).unwrap()
}
#[link(wasm_import_module = "zellij")]
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_help();
}