Open DanCardin opened 2 years ago
Hi! I also like to use neovim with Zellij. but, currently, the Zellij does not provide that feature. I personally think this feature should be processed in vim/neovim (using plugin). Of course, we can add the feature for vim/nvim, but i don't know if that's the right direction.
There does need to be some level of zellij (or zellij plugin) specific behavior, since it needs to only conditionally forward the original binding to vim in the even the pane's running process is vim
Re the vim side, I'm willing to fork the (n)vim plugin i reference for myself for that side, what's unclear to me is how such a plugin would work. i.e. whether zellij supports the external control required for support it.
@DanCardin Thanks for the explanation!
First, I looked at how vim-tmux-navigator
works. As you already know, the core of this plugin is the if-shell
conditions statement in tmux.conf
. Unfortunately, Zellij does not yet provide such an extensible config. So I think you are curious about plugins.
So, I thought about whether the above function can be implemented using the current Zellij plugin system. The conclusion seems to be impossible at present.
Because by default the Zellij plugin has an isolated environment using WASM. In plugin, there are some convenience function that can communicate with the Host (Zellij Server). For examples, hook the keyboard event.
But, the problem is, there is still no function to trigger a specific event of Zellij inside the plugin. For example, the navigation of the pane, etc.
Also, it seems difficult to confirm that vim/nvim is currently running. Because the inside of the plugin is a WASM VM, it is isolated from the host's environment variables.
Therefore, further development related to WASM is required to implement the seamless navigation
function through the Zellij Plugin.
You can check which functions the plugin can use through the zellij-server/src/wasm_vm.rs
file.
I'm not super tuned into how the plugin interface works, but it seems like a PaneProgramChanged
(or somesuch name) event could be emitted? my brief lookings into how this is done in tmux basically that they pipe the pane's tty to pgrep -t
. Perhaps there's a better, more cross platform way of doing that.
being able to subscribe to an event like this seems like it would be useful elsewhere. For example, I dont know if this is default, but my tmux's tabs automatically display "nvim" or "zsh" as the tab name depending on which is focused in the currently active tab.
I am also very interested for something like christoomey/vim-tmux-navigator. I think this might be the last thing that keeps me from going completely to zellij.
I've spent some time looking into this issue to try to create a neovim plugin to mirror the same features as above mentioned plugin.
Reading Chris' code, it effectively uses the following cli command to navigate to another frame: tmux shell-pane -t $TMUX_PANE -<direction>
. Where <direction>
is either LUDR
(left, up, down, right). It take the command and runs it in vim's system
-function. Which spawns a non-interactive shell and runs the command.
:echo system("tmux select-pane $TMUX_PANE -R")
It works!
Luckily for us, zellij has as an action argument where you can navigate using zellij action move-focus-or-tab <direction>
. So let's try to use it. I'm using neovim, but it's mostly the same for vim.
:echo system("zellij action move-focus-or-tab right")
ENODEV: No such device
What gives?! An error! I've opened up #1861 which tries to debug the issue. However, due to how zellij tries to access tty information in a non-interactive terminal, it panics and fails.
So, unless this bug is fixed which I believe will need some internal refactors of zellij and how it handles communication between client and server, this is blocked.
@Lilja Thank you for your interest in this feature.
I am also constantly interested in this feature, and did some testing after a new version was released. I don't know if this could be a fundamental solution, but you can use lua from the nvim side to run a zellij action like this:
local pipe = io.popen("zellij action move-focus down")
pipe:close() -- necessary
I hope this will help you with your work.
Thanks @jaeheonji! That worked.
I created a neovim plugin to solve this problem, Lilja/zellij.nvim which has vim-tmux-navigator compatible keybindings. Feel free to try it out.
Thank you for making a awesome plugin Lilja/zellij.nvim!
But, for natural navigation like tmux-nvigator, there seems to be more to be implemented in zellij side. Therefore, I will keep this issue as it is now.
Here is something that is getting close. I just need some help sending ctrl + w h
etc.
bind "h" {
SwitchToMode "Normal";
Run "bash" "-c" "[ ! -z $VIMRUNTIME ] && zellij action close-pane & zellij action move-focus left || zellij action close-pane & zellij action write 7f 68";
}
It would be nice to be able to send-keys
that way I could so something like
bind "h" {
SwitchToMode "Normal";
Run "bash" "-c" "[ ! -z $VIMRUNTIME ] && zellij action close-pane & zellij action move-focus left || zellij action close-pane & zellij action send-keys ctrl+w h";
}
From @casonadams find above. I was able to make it work, with a small adjustment. But it's not working well.
If you disregard sending ctrl+w h
and instead using my zellij.nvim
neovim plugin, you can actually send :ZellijNavigate(Right|Left|Down|Up)<Cr>
like this:
Run "bash" "-c" "[ -z $VIMRUNTIME ] && zellij action move-focus left || zellij action write-chars \":ZellijNavigateLeft \"";
☝️ note the newline. It's important as we need something to press
This doesn't work fully as the run command will open a pane, because it's expected to be used for running certain long running commands like tail
or some sort of compile-watcher tool.
So we probably need a flag for Run
to run inside of a subprocess and not display the contents like it does right now.
It would be awesome if we could implement this not only for vim but also for helix (or other programs)
In order to achieve this zellij can follow tmux like approach: create a custom "vim locked mode", then use plugin provided by https://github.com/zellij-org/zellij/issues/967#issuecomment-1295806553.
@Dzordzu I believe your last point might be already addressed (in nvim at least) by this the zellij-nav.nvim plugin.
It might be obvious to some, but maybe not. If such a partial lock mode existed, it should probably be named something more generic. Maybe "Partial Lock" or "Subprocess Lock"
But maybe those two features should be separated?
If the features get separated then "Partial Lock" would make sense
If they are joined as a single feature then "Subprocess Lock" might make more sense.
The recent patch version (0.40.1) adds the ability to:
Ctrl j
zellij action list-clients
Sample output:
$ zellij action list-clients
CLIENT_ID ZELLIJ_PANE_ID RUNNING_COMMAND 1 plugin_2 zellij:session-manager 2 terminal_3 vim /tmp/my-file.txt
I think this should give anyone wishing to implement this sort of navigation all the tools they need (more info here: https://github.com/zellij-org/zellij/issues/2434#issuecomment-2089950065)
I have created a plugin which solves this issue! See vim-zellij-navigator as the Zellij version of vim-tmux-navigator! Currently, it relies on an additional plugin in Neovim to know whether Neovim is running, I will change this to use list-clients once that command becomes available to plugins.
@hiasr - if you want, until this command is directly available to plugins, you can invoke zellij action list-clients
from plugins using the run_command
API call and parsing its output.
Also @hiasr - if I may offer another suggestion: could be cool if you make the plugin generic: a sort of discrete piece of logic that you can bind to a key and does: "move <direction>
unless I am focused on <config_app_string>
in which case send the key to the focused pane". I think this will also help out @mrjones2014 in implementing support in their plugin.
Good idea! I am currently working on migrating towards zellij action list-clients
such that the additional neovim plugin is not necessary and multiple clients work as expected. Once that is finished I will look into configurability, maybe a regex you can add as an argument would cover most of the potential usecases.
And also, while I'm at it: another piece of advice - I'd recommend not using latest
in the keybinding https
url but using the version number explicitly. The reason for this is that Zellij caches the plugins on successful load by their URL - and so when someone would want to upgrade, if using latest
they'd have to explicitly clear the cache.
Idea
In order to achieve this zellij can follow tmux like approach: create a custom "vim locked mode", then use plugin provided by #967 (comment).
How it would work
* During vim startup zellij enters "vim locked mode" (command send by vim) * Zellij plugin detects that pane is using vim * Zellij triggers "vim locked mode" * Some of the keybindings are disabled * When VIM plugin detects edge of the vim, the disable mode command is sent to zellij. Afterwards, the command changing the pane/tab is sent
I think this sort of approach is the solution to this problem. I referenced vim-zellij-navigator and built a plugin to support this approach, in pursuit of seamless navigation for Vim and other programs that benefit from Ctrl+h/j/k/l
nav, like Helix, FZF, Zoxide, Atuin, etc.
The result: fresh2dev/zellij-autolock
I just published v0.2 of zellij-autolock which makes use of Zellij v0.41's API enhancements. The result is a much more responsive and reliable auto-locking mechanism. Thanks @imsnif!
Any way of the autolock work with the new colliding keybinding solution? For now I've managed to configure the vim-zellij-navigator – with a bit of trouble.
Any way of the autolock work with the new colliding keybinding solution?
For now I've managed to configure the vim-zellij-navigator – with a bit of trouble.
If you have a specific issue, please file an issue in the repo with more details.
(originally commented about this on reddit and was directed to suggest it here.
The relevant tmux plugin is christoomey/vim-tmux-navigator and the corresponding vim plugin (which i use, there are a few) is aserowy/tmux.nvim.
At a high level, the idea is to bind the same tmux and vim keybinds and for both navigation and pane resize to work contextually to whether vim is focused or not (ideally interacting with vim splits seamlessly also.
The comment on reddit suggested that zellij might be able to get away without a vim plugin. Because of vim split navigation, im skeptical this can be done (fully) without a vim plugin, but I'm personally happy to fork the plugin, so long as the hooks necessary for the vim plugin to function correctly exist (relevant portion of the vim plugin i use)
But in order to be fully specified, i'll lay out the expected behavior in the event it can all be done in zellij, but being aware that if that's not possible, some of the behaviors laid out will be handled by the vim plugin
Given some layout
Suppose keybind of C-h, C-j, C-k, C-l for navigation and M-h, M-j, M-k, M-l resizing: navigation
resizing
With a similar table for vertical naviation.
I notice that zoom is not currently implemented today. but the above plugins (really just the vim one) have the option to only navigate vim splits when zommed. I.e. disable pane navigation if zoomed. Personally, that's the behavior i have enabled (right now), but just to be aware that this (and i suppose normal pane navigation keybinds) interact with a theoretical zoom feature