alexghergh / nvim-tmux-navigation

Easy Neovim-Tmux navigation, completely written in Lua
MIT License
304 stars 22 forks source link

Bindings only work between tmux and nvim #28

Open madhat2r opened 1 month ago

madhat2r commented 1 month ago

Is it possible to have this navigate all splits and not just between nvim and tmux?

Take the following: There are three panes, 2 are nvim windows in a tmux split and the right most is the 2nd tmux split.

Screenshot 2024-07-30 at 1 54 55 PM

If I navigate using any on the NvimTmuxNaviate[xxx] commands they only switch from nvim to tmux and vice-versa. It would be nice if I could start on the left pane and navigate across it in order (or the reverse) going from nvim window to nvim window, then tmux split.

This would ease the workflow as one keybinding would work across all splits and I wouldn't have to switch to C-w commands for vim windows.

alexghergh commented 1 month ago

Hello,

Yes, that should be the case by default! This means you probably didn't configure the plugin correctly, so make sure that is first properly configured, before continuing debugging.

I might be able to help if you reproduce a minimal working environment and paste the configuration here.

Best

madhat2r commented 1 month ago

Thanks @alexghergh .

lazy spec for plugin:

{ 'alexghergh/nvim-tmux-navigation', config = function()

    local nvim_tmux_nav = require('nvim-tmux-navigation')

    nvim_tmux_nav.setup {
        disable_when_zoomed = true -- defaults to false
    }

    vim.keymap.set('n', "<C-h>", nvim_tmux_nav.NvimTmuxNavigateLeft)
    vim.keymap.set('n', "<C-j>", nvim_tmux_nav.NvimTmuxNavigateDown)
    vim.keymap.set('n', "<C-k>", nvim_tmux_nav.NvimTmuxNavigateUp)
    vim.keymap.set('n', "<C-l>", nvim_tmux_nav.NvimTmuxNavigateRight)
    vim.keymap.set('n', "<C-\\>", nvim_tmux_nav.NvimTmuxNavigateLastActive)
    vim.keymap.set('n', "<C-Space>", nvim_tmux_nav.NvimTmuxNavigateNext)

end
}

relevant tmux:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n C-h if-shell "$is_vim" 'send-keys C-h'  'select-pane -L'
bind-key -n C-j if-shell "$is_vim" 'send-keys C-j'  'select-pane -D'
bind-key -n C-k if-shell "$is_vim" 'send-keys C-k'  'select-pane -U'
bind-key -n C-l if-shell "$is_vim" 'send-keys C-l'  'select-pane -R'

# bind-key -n M-h if-shell "$is_vim" 'send-keys M-h' 'resize-pane -L 3'
# bind-key -n M-j if-shell "$is_vim" 'send-keys M-j' 'resize-pane -D 3'
# bind-key -n M-k if-shell "$is_vim" 'send-keys M-k' 'resize-pane -U 3'
# bind-key -n M-l if-shell "$is_vim" 'send-keys M-l' 'resize-pane -R 3'

tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'

if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"

if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"
alexghergh commented 1 month ago

Hmm, I'm not too sure about lazy, but I think you have to specify lazy = false somewhere in the plugin spec, i.e.:

{ 'alexghergh/nvim-tmux-navigation', lazy = false, config = function()

    local nvim_tmux_nav = require('nvim-tmux-navigation')

    nvim_tmux_nav.setup {
        disable_when_zoomed = true -- defaults to false
    }

    vim.keymap.set('n', "<C-h>", nvim_tmux_nav.NvimTmuxNavigateLeft)
    vim.keymap.set('n', "<C-j>", nvim_tmux_nav.NvimTmuxNavigateDown)
    vim.keymap.set('n', "<C-k>", nvim_tmux_nav.NvimTmuxNavigateUp)
    vim.keymap.set('n', "<C-l>", nvim_tmux_nav.NvimTmuxNavigateRight)
    vim.keymap.set('n', "<C-\\>", nvim_tmux_nav.NvimTmuxNavigateLastActive)
    vim.keymap.set('n', "<C-Space>", nvim_tmux_nav.NvimTmuxNavigateNext)

end
}

You can even go as far as:

    {
        'alexghergh/nvim-tmux-navigation',
        opts = {
            disable_when_zoomed = true,
            keybindings = {
                left = '<C-h>',
                down = '<C-j>',
                up = '<C-k>',
                right = '<C-l>',
                last_active = '<C-\\>',
                next = '<C-Space>',
            },
        },
        lazy = false,
    },

or something like this. Let me know if it works for you!

madhat2r commented 1 month ago

I tried both approaches neither changed the behavior.

I don't think it is a problem loading the plugin as it does work, it just doesn't work on the vim splits, but it does happily change to the tmux and back again.

madhat2r commented 1 month ago

Also, it does not work on vim splits if I only have one tmux split with nvim running in it, if that makes this any clearer.

madhat2r commented 1 month ago

I have been looking at this a bit more and it looks like this is an issue with the tmux side.

The command to check if it is in vim (ps -o state= -o comm= -t '#{pane_tty}' \ | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$')

returns ps: /dev/tty#{pane_tty} and /dev/#{pane_tty}: No such file or directory and therefore the is_vim var is not getting set and thereby not getting the keystrokes to activate the plugin.

Thanks for your help in this. Hopefully I will find a fix for this.

madhat2r commented 1 month ago

Found current issue in "christoomey/vim-tmux-navigator`

https://github.com/christoomey/vim-tmux-navigator/issues/391

madhat2r commented 1 month ago

It seems that changing the is_vim test in tmux is the answer at least for me.

For anyone else facing this issue, see https://github.com/christoomey/vim-tmux-navigator/issues/295#issuecomment-1021591011

alexghergh commented 1 month ago

So the issue seems solved, at least on our side, right? Great! Please close the issue unless there's anything else you need assistance with!

madhat2r commented 1 month ago

It is solved, but other users of your awesome plugin will most likely experience this issue if they follow the instructions on the README. Would you consider adding a comment about the tmux flag if nvim is running in a subshell or accept a PR doing so?

Bjorn-Eric-Abr commented 1 month ago

I don't think the examples work with lazyvim (anymore?)?

For anyone else running in to keymaps not registering, this might point you in the right direction:https://www.reddit.com/r/neovim/comments/14yer8w/neovimtmux_navigation_plugin_with_lazyvim_not/

For me, the LazyVim keymappings overwrote the Navigator ones. Kinda hard to spot since it worked from tmux in to NeoVim then inside NeoVim but not back out again.

Solved the keybindings by also adding this to my config/mappings.lua

local map = LazyVim.safe_keymap_set

map("n", "<C-l>", "<Cmd>NvimTmuxNavigateRight<CR>")
map("n", "<C-h>", "<Cmd>NvimTmuxNavigateLeft<CR>")
map("n", "<C-k>", "<Cmd>NvimTmuxNavigateUp<CR>")
map("n", "<C-j>", "<Cmd>NvimTmuxNavigateDown<CR>")