Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bindings only work between tmux and nvim #28

Open
madhat2r opened this issue Jul 30, 2024 · 14 comments
Open

Bindings only work between tmux and nvim #28

madhat2r opened this issue Jul 30, 2024 · 14 comments

Comments

@madhat2r
Copy link

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
Copy link
Owner

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
Copy link
Author

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
Copy link
Owner

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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

christoomey/vim-tmux-navigator#391

@madhat2r
Copy link
Author

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

For anyone else facing this issue, see christoomey/vim-tmux-navigator#295 (comment)

@alexghergh
Copy link
Owner

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
Copy link
Author

madhat2r commented Aug 3, 2024

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
Copy link

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>")

@aSapien
Copy link

aSapien commented Oct 12, 2024

There seems to be a rather elegant solution suggested in christoomey/vim-tmux-navigator/issues/295#issuecomment-1123455337

Porting the following to lua could alleviate the dependency on the tmux-side plugin altogether, only requiring the short Tmux snippet attached under.

function! s:set_is_vim()
  call s:TmuxCommand("set-option -p @is_vim yes")
endfunction

function! s:unset_is_vim()
  call s:TmuxCommand("set-option -p -u @is_vim")
endfunction

augroup tmux_navigator_is_vim
  au!
  autocmd VimEnter * call s:set_is_vim()
  autocmd VimLeave * call s:unset_is_vim()
  if exists('##VimSuspend')
    autocmd VimSuspend * call s:unset_is_vim()
    autocmd VimResume * call s:set_is_vim()
  endif
augroup END

Tmux snippet:

bind -n C-h if-shell -F "#{@is_vim}" "send-keys C-h"  "select-pane -L"
bind -n C-j if-shell -F "#{@is_vim}" "send-keys C-j"  "select-pane -D"
bind -n C-k if-shell -F "#{@is_vim}" "send-keys C-k"  "select-pane -U"
bind -n C-l if-shell -F "#{@is_vim}" "send-keys C-l"  "select-pane -R"
bind -n C-\\ if-shell -F "#{@is_vim}" "send-keys C-\\" "select-pane -l"

@alexghergh would you consider such a change?

@aSapien
Copy link

aSapien commented Oct 12, 2024

Following up on my suggestion above, currently this lazy.nvim setup works for me:

Plugin:

return {
  "alexghergh/nvim-tmux-navigation",
  config = function()
    require("nvim-tmux-navigation").setup({
      disable_when_zoomed = true, -- defaults to false
      keybindings = {
        left = "<C-h>",
        down = "<C-j>",
        up = "<C-k>",
        right = "<C-l>",
        last_active = "<C-\\>",
        next = "<C-Space>",
      },
    })

    local function tmux_command(command)
      local tmux_socket = vim.fn.split(vim.env.TMUX, ",")[1]
      return vim.fn.system("tmux -S " .. tmux_socket .. " " .. command)
    end

    local nvim_tmux_nav_group = vim.api.nvim_create_augroup("NvimTmuxNavigation", {})

    vim.api.nvim_create_autocmd({ "VimEnter", "VimResume" }, {
      group = nvim_tmux_nav_group,
      callback = function()
        tmux_command("set-option -p @is_vim yes")
      end,
    })

    vim.api.nvim_create_autocmd({ "VimLeave", "VimSuspend" }, {
      group = nvim_tmux_nav_group,
      callback = function()
        tmux_command("set-option -p -u @is_vim")
      end,
    })
  end,
}

.tmux.conf:

bind -n C-h if-shell -F "#{@is_vim}" "send-keys C-h"  "select-pane -L"
bind -n C-j if-shell -F "#{@is_vim}" "send-keys C-j"  "select-pane -D"
bind -n C-k if-shell -F "#{@is_vim}" "send-keys C-k"  "select-pane -U"
bind -n C-l if-shell -F "#{@is_vim}" "send-keys C-l"  "select-pane -R"
bind -n C-\\ if-shell -F "#{@is_vim}" "send-keys C-\\" "select-pane -l"

@radek-sprta
Copy link

For whoever ends up here, to get this working with LazyVim, I combined
#28 (comment) & #28 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants