zellij-org / zellij

A terminal workspace with batteries included
https://zellij.dev
MIT License
21.64k stars 654 forks source link

Dispatching keybound actions into plugins #662

Open arefem-project opened 3 years ago

arefem-project commented 3 years ago

It would be nice if plugins could handle actions dispatched from keybindings. This would enable plugins to customize Zellij's default behavior for actions.

An example use case might be a plugin that wants to keep the current directory when creating a new pane. This plugin would need a way to handle "NewPane" actions dispatched from Zellij. The API for handling dispatched actions from inside plugins might look like this:

use zellij_tile::prelude::*;

#[derive(Default)]
struct StickyCWD {
 // ...
}

register_plugin!(StickyCWD);

impl ZellijPlugin for StickyCWD {
    fn load(&mut self) {
        subscribe(&[ EventType::Action ]);
    }

    fn update(&mut self, event: Event) {
        match event {
            Event::Action(Action::NewPane(direction)) => {
                 // TODO: Open terminal with pane direction and current directory
            }
            _ => {}
        }
}

While the config file would look like this:

keybinds:
    plugins:
        sticky-cwd:
            pane:
                - action: [ NewPane: Right, ]
                  key: [ Char: 'm', ]

This above config would dispatch an Action::NewPane(Direction::Right) enum into the plugin when the "m" key is pressed inside the pane mode. The above presupposes that we have a way to associate the "sticky-cwd" tag with the running StickyCWD plugin.

a-kenji commented 3 years ago

Thanks @arefem-project for taking the time writing this issue down! I have to agree that would be a great feature to have.

The plugin side looks good to me personally, but I am not that familiar with it. I think it is a lot of configuration for just changing potentially one action here, but I am not sure how to make it possibly less verbose. Maybe somehow look at #661 and put these together.

spacemaison commented 3 years ago

Ah yeah I realize now that I was logged into the wrong account while posting this issue @a-kenji. Both #661 and #662 are me.

I think it is a lot of configuration for just changing potentially one action here, but I am not sure how to make it possibly less verbose.

It could be reworked to go into the plugin configuration:

plugins:
  - path: sticky-cwd.wasm
    tag: sticky-cwd
    keybinds:
       pane:
         - action: [ NewPane: Right, ]
           key: [ Char: 'm', ]

Honestly that pull request is already large enough that I was trying to break things into smaller chunks!

a-kenji commented 3 years ago

Honestly that pull request is already large enough that I was trying to break things into smaller chunks!

Oh no, I like that it is split up, I was actually suggesting you two to communicate with each other about it - which you seem to be in a unique position in to do ;-).

I thought briefly about binding the invocation of the plugin actions in the normal keybind config with an action, for example: PluginAction: {tag: sticky-cwd, action: NewPane: }, this would maybe make it clearer which action should have precedence? But I am not convinced that it would make it easy to add and remove plugins as well as make it any less verbose.

I would like to get input from more people on here preferably.

I like the 2nd option you proposed more personally, because then the configuration for the plugin would all be in one place.