diff --git a/Cargo.lock b/Cargo.lock index 4ff46b0..df0c5c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "zj-quit" -version = "0.1.0" +version = "0.2.0" dependencies = [ "zellij-tile", ] diff --git a/README.md b/README.md index d0908cf..20201b3 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,36 @@ -## About +# zj-quit -This is an example [Zellij][zellij] plugin in Rust. It can be used as a template to start developing your own plugins. +A [zellij](https://zellij.dev/) plugin that prompts for confirmation before killing the current session. -More about Zellij plugins: [Zellij Documentation][docs] +![image](https://github.com/cristiand391/zj-quit/assets/6853656/0b2537c4-6872-402b-aa5d-f0713c46c32b) -[zellij]: https://github.com/zellij-org/zellij -[docs]: https://zellij.dev/documentation/plugins.html +This has been requested multiple times by users: +* https://github.com/zellij-org/zellij/issues/467 +* https://github.com/zellij-org/zellij/issues/1229 +* https://github.com/zellij-org/zellij/issues/3147 -## Development +so I decided go the *zellij way* ™️ and made a plugin for this :) -*Note*: you will need to have `wasm32-wasi` added to rust as a target to build the plugin. This can be done with `rustup target add wasm32-wasi`. +## Usage -## Inside Zellij -![img-2023-06-14-143355](https://github.com/zellij-org/rust-plugin-example/assets/795598/d9e563dc-5d71-4e10-af5b-190365bdca3b) - -You can load the `./plugin-dev-workspace.kdl` file as a Zellij layout to get a terminal development environment: - -Either when starting Zellij: -``` -zellij --layout ./plugin-dev-workspace.kdl +Download the last release available at https://github.com/cristiand391/zj-quit/releases/ and set up an alias for it: +```kdl +plugins { + zj-quit location="file:/path/to/zj-quit.wasm" +} ``` -*Note that in this case there's a small bug where the plugin is opened twice, it can be remedied by closing the oldest instance or loading with the new-tab action as secified below - this will be addressed in the near future* -Or from a running Zellij session: -```bash -zellij action new-tab --layout ./plugin-dev-workspace.kdl -``` +https://zellij.dev/documentation/plugin-aliases -## Otherwise +then set a keybind to launch it in a floating window: -1. Build the project: `cargo build` -2. Load it inside a running Zellij session: `zellij action start-or-reload-plugin file:target/wasm32-wasi/debug/rust-plugin-example.wasm` -3. Repeat on changes (perhaps with a `watchexec` or similar command to run on fs changes). +```kdl +keybinds clear-defaults=true { + shared_except "locked" { + bind "Ctrl q" { + LaunchOrFocusPlugin "zj-quit" { + floating true + } + } +} +``` diff --git a/scripts/check.js b/scripts/check.js new file mode 100644 index 0000000..49dff00 --- /dev/null +++ b/scripts/check.js @@ -0,0 +1,6 @@ +const util = require('node:util'); +const exec = util.promisify(require('node:child_process').exec); + +exports.preCommit = async () => { + await exec('cargo check') +}; diff --git a/src/main.rs b/src/main.rs index 934ab8d..aed67a7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,50 +3,55 @@ use zellij_tile::prelude::*; use std::collections::BTreeMap; #[derive(Default)] -struct State { - current_session_name: String, -} +struct State {} register_plugin!(State); impl ZellijPlugin for State { fn load(&mut self, _configuration: BTreeMap) { - request_permission(&[ - PermissionType::ReadApplicationState, - PermissionType::ChangeApplicationState, - ]); - subscribe(&[EventType::SessionUpdate, EventType::Key]); + request_permission(&[PermissionType::ChangeApplicationState]); + subscribe(&[EventType::Key]); } fn update(&mut self, event: Event) -> bool { - let mut should_render = false; match event { - Event::SessionUpdate(session_infos, _) => { - if let Some(current_session) = session_infos.iter().find(|s| s.is_current_session) { - self.current_session_name = current_session.name.clone(); - should_render = true; - } - } Event::Key(key) => { if let Key::Char('\n') = key { - kill_sessions(&[self.current_session_name.clone()]) + quit_zellij() } else if let Key::Esc = key { hide_self(); } } _ => (), }; - should_render + false } - fn render(&mut self, _rows: usize, _cols: usize) { - if !self.current_session_name.is_empty() { - println!( - "Are you sure you want to kill the current session ({})?", - self.current_session_name - ); - println!("Press Enter to confirm."); - println!("Press Esc to close this pane."); - } + fn render(&mut self, rows: usize, cols: usize) { + let confirmation_text = "Are you sure you want to kill the current session?".to_string(); + let confirmation_y_location = (rows / 2) - 2; + let confirmation_x_location = cols.saturating_sub(confirmation_text.chars().count()) / 2; + + print_text_with_coordinates( + Text::new(confirmation_text), + confirmation_x_location, + confirmation_y_location, + None, + None, + ); + + let help_text = "Help: - Confirm, - Hide"; + let help_text_y_location = rows - 1; + let help_text_x_location = cols.saturating_sub(help_text.chars().count()) / 2; + + print_text_with_coordinates( + Text::new(help_text) + .color_range(3, 6..13) + .color_range(3, 25..30), + help_text_x_location, + help_text_y_location, + None, + None, + ); } }