mrjones2014 / smart-splits.nvim

🧠 Smart, seamless, directional navigation and resizing of Neovim + terminal multiplexer splits. Supports tmux, Wezterm, and Kitty. Think about splits in terms of "up/down/left/right".
MIT License
904 stars 38 forks source link

[Feature]: Support zellij #111

Open linux-cultist opened 1 year ago

linux-cultist commented 1 year ago

Similar Issues

Description

Since this plugin has tmux support, could it also support zellij (https://zellij.dev/documentation)?

It's a popular and newer alternative to tmux and maybe it's easy to support it? Just posting this so you can see if it would be easy or hard.

mrjones2014 commented 1 year ago

Took a look at the docs to see if the CLI can implement our mux interface:

Lua method Zellij CLI support
is_in_session() Maybe possible with zellij list-sessions?
current_pane_id() No CLI command I could find. Is there an environment variable, maybe?
current_pane_at_edge(direction) No CLI command I could find. Can possibly be worked around with zellij cli move-focus back and forth.
current_pane_is_zoomed() zellij cli toggle-fullscreen exists, but no way to check if it is fullscreen. Not a critical component for the plugin, options may not work completely correctly.
next_pane(direction) zellij action move-focus [direction]
resize_pane(direction) zellij action resize [direction]
split_pane(direction) zellij action new-pane --direction [direction]

Unfortunately its not possible without current_pane_id(). Let me know if you know of a way to implement that I may have missed. is_in_session() could be shimmed by just checking if current_pane_id() returns nil or error.

linux-cultist commented 1 year ago

Thank you for checking! Maybe the author of zellij can add command line arguments for these things. I can check on their github page and ask, and point to this feature request above.

towry commented 10 months ago

Can we just implement partially? Thanks.

mrjones2014 commented 10 months ago

Unfortunately it's not possible without the ability to retrieve current pane ID, and it looks like the PR linked above has not merged yet to Zellij.

mrjones2014 commented 4 months ago

This is now unblocked!

mrjones2014 commented 4 months ago

Actually this is still blocked by Zellij not having conditional mappings. See https://github.com/zellij-org/zellij/issues/967

imsnif commented 4 months ago

Actually this is still blocked by Zellij not having conditional mappings. See zellij-org/zellij#967

If I may - you can do this either with the Run keybinding and then insert conditionals in your favorite shell, or use a Zellij plugin (I think someone did this in the linked issue comment).

mrjones2014 commented 4 months ago

From the linked plugin README:

Currently, I have not found a way to accomplish this, even through the zellij plugin system.

However, a Run keybind might work; do you know how that could be used to determine the foreground process name of the pane?

imsnif commented 4 months ago

I was referring to: https://github.com/zellij-org/zellij/issues/967#issuecomment-2091833356

mrjones2014 commented 4 months ago

Ah okay, I haven't tried that but maybe it will work.

hiasr commented 4 months ago

@mrjones2014 If I can help by making part of vim-zellij-navigator more generic, let me know!

mrjones2014 commented 4 months ago

Thanks @hiasr ! Looking at the code, the only thing that jumps out at me is this:

https://github.com/hiasr/vim-zellij-navigator/blob/6dfb8c634de4478f9a1952700bce984ead3c8e5d/src/main.rs#L126-L132

Does this mean the user can't configure the keymaps? This is something all the other mux backends support.

hiasr commented 4 months ago

@mrjones2014 I just added configurable modifiers and the resize command in release 0.2.1, I think it now supports all the features necessary.

mrjones2014 commented 4 months ago

Would someone be willing to contribute a simple Zellij config that sets up the required keymaps? Since I don't use Zellij, that will be quite a bit of work for me. If someone could help me with that, I can help with the Lua plugin changes.

Ideally the setup would be that we have a config stored in a directory like ./zellij/config.kdl, then I can update flake.nix to pull in zellij and in the flake's shellHook I can do alias zellij="zellij --config ./zellij/config.kdl"; that will make local development really easy

mrjones2014 commented 4 months ago

also @hiasr does your plugin support resizing Zellij panes?

hbiel commented 4 months ago

I have never used these kind of plugins before so i don't know exactly what details may be needed in the configuration especially for the neovim integration.

The following configuration lets you

Just put it in your config.kdl. Hope this helps!

keybinds {
    shared_except "locked" {
        bind "Ctrl h" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "move_focus_or_tab";
                payload "left";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Ctrl j" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "move_focus";
                payload "down";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Ctrl k" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "move_focus";
                payload "up";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Ctrl l" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "move_focus_or_tab";
                payload "right";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Alt h" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "resize";
                payload "left";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Alt j" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "resize";
                payload "down";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Alt k" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "resize";
                payload "up";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
        bind "Alt l" {
            MessagePlugin "https://github.com/hiasr/vim-zellij-navigator/releases/download/0.2.1/vim-zellij-navigator.wasm" {
                name "resize";
                payload "right";
                move_mod "ctrl";
                resize_mod "alt";
            };
        }
    }
}
mrjones2014 commented 4 months ago

Thanks @hbiel this helps a lot!

nosduco commented 2 months ago

Any updates on this integration or how I may be able to help? Would love to be able to use Zellij instead of tmux with smart-splits

GrizzlT commented 2 months ago

I like how this neovim plugin tells wezterm that neovim is active through a user variable. This brings a lot of robustness (no dependency on binary names, it's all in the application's behavior).

The latest version of zellij should make it possible to send something similar to a zellij plugin through pipes. I was thinking of creating a small plugin almost similar to https://github.com/hiasr/vim-zellij-navigator that would be specialized for this plugin but I haven't found the time yet to assess if a small contribution to vim-zellij-navigator would suffice to support all functionality featured by this neovim plugin.

Other than that I'm not entirely sure how to implement current_pane_at_edge(direction), is moving and checking if the pane stays the same enough? @mrjones2014 what does this function require exactly?

mrjones2014 commented 2 months ago

Sorry yall, it’s been crazy at my day job, haven’t had time to dedicate to open source lately.

Other than that I'm not entirely sure how to implement current_pane_at_edge(direction), is moving and checking if the pane stays the same enough?

yeah, there’s another backend that does the same, with the caveat that the cursor should not have moved by the time the function returns (e.g. you can move to check, but then move it back to the original pane)