Code Monkey home page Code Monkey logo

tmux.nvim's Introduction

tmux.nvim

As my workflow has changed over time, I no longer use tmux. This means that while I will continue to maintain this plugin, I will no longer implement fixes, features, or maintenance. PRs are always welcome and will be merged upon review.

dependabot ci coverage

features

copy from nvim to nvim to tmux

tmux-copy.mp4

navigating from nvim into tmux panes

tmux-navigate.mp4

resizing nvim splits like tmux panes

tmux-resize.mp4

requirements

  • neovim >= 0.5

The plugin and .tmux.conf scripts are battle tested with

  • tmux 3.2a

installation

Install tmux.nvim with e.g. packer.nvim and run the setup function:

use({
    "aserowy/tmux.nvim",
    config = function() return require("tmux").setup() end
})

configuration

The config step is only necessary to overwrite configuration defaults.

The following defaults are given:

{
    copy_sync = {
        -- enables copy sync. by default, all registers are synchronized.
        -- to control which registers are synced, see the `sync_*` options.
        enable = true,

        -- ignore specific tmux buffers e.g. buffer0 = true to ignore the
        -- first buffer or named_buffer_name = true to ignore a named tmux
        -- buffer with name named_buffer_name :)
        ignore_buffers = { empty = false },

        -- TMUX >= 3.2: all yanks (and deletes) will get redirected to system
        -- clipboard by tmux
        redirect_to_clipboard = false,

        -- offset controls where register sync starts
        -- e.g. offset 2 lets registers 0 and 1 untouched
        register_offset = 0,

        -- overwrites vim.g.clipboard to redirect * and + to the system
        -- clipboard using tmux. If you sync your system clipboard without tmux,
        -- disable this option!
        sync_clipboard = true,

        -- synchronizes registers *, +, unnamed, and 0 till 9 with tmux buffers.
        sync_registers = true,

        -- synchronizes registers when pressing p and P.
        sync_registers_keymap_put = true,

        -- synchronizes registers when pressing (C-r) and ".
        sync_registers_keymap_reg = true,

        -- syncs deletes with tmux clipboard as well, it is adviced to
        -- do so. Nvim does not allow syncing registers 0 and 1 without
        -- overwriting the unnamed register. Thus, ddp would not be possible.
        sync_deletes = true,

        -- syncs the unnamed register with the first buffer entry from tmux.
        sync_unnamed = true,
    },
    navigation = {
        -- cycles to opposite pane while navigating into the border
        cycle_navigation = true,

        -- enables default keybindings (C-hjkl) for normal mode
        enable_default_keybindings = true,

        -- prevents unzoom tmux when navigating beyond vim border
        persist_zoom = false,
    },
    resize = {
        -- enables default keybindings (A-hjkl) for normal mode
        enable_default_keybindings = true,

        -- sets resize steps for x axis
        resize_step_x = 1,

        -- sets resize steps for y axis
        resize_step_y = 1,
    }
}

usage

Tmux.nvim uses only lua API. If you are not running the default keybindings, you can bind the following functions to your liking. Besides the bindings in nvim you need to add configuration to tmux.

copy sync

Copy sync uses tmux buffers as master clipboard for *, +, unnamed, and 0 - 9 registers. The sync does NOT rely on temporary files and works just with the given tmux API. Thus, making it less insecure :). The feature enables a nvim instace overarching copy/paste process! dd in one nvim instance, switch to the second and p your deletes.

If you sync your clipboard not with a standalone tmux, disable sync_clipboard to ensure nvim handles yanks and deletes alone.

This has some downsites, on really slow machines, calling registers or pasting will eventually produce minimal input lag by syncing registers in advance to ensure the correctness of state. To avoid this, disabling sync_registers will only redirect the * and + registers.

To redirect copies (and deletes) to clipboard, tmux must have the capability to do so. The plugin will just set -w on set-buffer. If your tmux need more configuration check out tmux-yank for an easy setup.

Ignoring buffers must have the form of buffer_name = true to enable an unsorted list in lua. This enhances the performance of checks - if a buffer is ignored or not - meaningfull.

navigation

To enable cycle-free navigation beyond nvim, add the following to your ~/.tmux.conf:

It is important to note, that your bindings in nvim must match the defined bindings in tmux! Otherwise the pass through will not have the seamless effect!

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?\.?(view|n?vim?x?)(-wrapped)?(diff)?$'"

bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' { if -F '#{pane_at_left}' '' 'select-pane -L' }
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' { if -F '#{pane_at_bottom}' '' 'select-pane -D' }
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' { if -F '#{pane_at_top}' '' 'select-pane -U' }
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' { if -F '#{pane_at_right}' '' 'select-pane -R' }

bind-key -T copy-mode-vi 'C-h' if -F '#{pane_at_left}' '' 'select-pane -L'
bind-key -T copy-mode-vi 'C-j' if -F '#{pane_at_bottom}' '' 'select-pane -D'
bind-key -T copy-mode-vi 'C-k' if -F '#{pane_at_top}' '' 'select-pane -U'
bind-key -T copy-mode-vi 'C-l' if -F '#{pane_at_right}' '' 'select-pane -R'

Otherwise you can add:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?\.?(view|n?vim?x?)(-wrapped)?(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 -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R

To run custom bindings in nvim, make sure to set enable_default_keybindings to false. The following functions are used to navigate around windows and panes:

{
    [[<cmd>lua require("tmux").move_left()<cr>]],
    [[<cmd>lua require("tmux").move_bottom()<cr>]],
    [[<cmd>lua require("tmux").move_top()<cr>]],
    [[<cmd>lua require("tmux").move_right()<cr>]],
}

resize

Add the following bindings to your ~/.tmux.conf:

It is important to note, that your bindings in nvim must match the defined bindings in tmux! Otherwise the pass through will not have the seamless effect!

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

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

bind-key -T copy-mode-vi M-h resize-pane -L 1
bind-key -T copy-mode-vi M-j resize-pane -D 1
bind-key -T copy-mode-vi M-k resize-pane -U 1
bind-key -T copy-mode-vi M-l resize-pane -R 1

To run custom bindings in nvim, make sure to not set enable_default_keybindings to true. The following functions are used to resize windows:

{
    [[<cmd>lua require("tmux").resize_left()<cr>]],
    [[<cmd>lua require("tmux").resize_bottom()<cr>]],
    [[<cmd>lua require("tmux").resize_top()<cr>]],
    [[<cmd>lua require("tmux").resize_right()<cr>]],
}

tpm

If you are using tmux plugin manager, you can add the following plugin.

set -g @plugin 'aserowy/tmux.nvim'

run '~/.tmux/plugins/tpm/tpm'

Available options for the plugin and their defaults are:

set -g @plugin 'aserowy/tmux.nvim'

# navigation
set -g @tmux-nvim-navigation true
set -g @tmux-nvim-navigation-cycle true
set -g @tmux-nvim-navigation-keybinding-left 'C-h'
set -g @tmux-nvim-navigation-keybinding-down 'C-j'
set -g @tmux-nvim-navigation-keybinding-up 'C-k'
set -g @tmux-nvim-navigation-keybinding-right 'C-l'

# resize
set -g @tmux-nvim-resize true
set -g @tmux-nvim-resize-step-x 1
set -g @tmux-nvim-resize-step-y 1
set -g @tmux-nvim-resize-keybinding-left 'M-h'
set -g @tmux-nvim-resize-keybinding-down 'M-j'
set -g @tmux-nvim-resize-keybinding-up 'M-k'
set -g @tmux-nvim-resize-keybinding-right 'M-l'

run '~/.tmux/plugins/tpm/tpm'

troubleshoot

Window switching stops working in python virtual environment

christoomey/vim-tmux-navigator#295

To enable searching for nvim in subshells, you need to change the 'is_vim' part in the tmux plugin. This will make searching for nested nvim instances result in positive resolutions.

Found by @duongapollo

Compatibility with vim-yoink or other yank-related tmux-plugins

aserowy/tmux.nvim#88

The configuration in the given issue integrates tmux.nvim with yanky.nvim and which-key.nvim so we get the benefits of all yank-related plugins.

Found by @kiyoon

contribute

Contributed code must pass luacheck and be formatted with stylua. Besides formatting, all tests have to pass. Tests are written for busted.

If you are using nix-shell, you can start a nix-shell and run fac (format and check).

stylua lua/ && luacheck lua/ && busted --verbose

inspiration

clipboard harmonization

navigation & resizing

tmux.nvim's People

Contributors

aca avatar alex23rodriguez avatar aserowy avatar bekaboo avatar blakejc94 avatar dependabot[bot] avatar jdsutherland avatar joeveiga avatar kevintraver avatar kjubybot avatar moetayuko avatar mojasp avatar pedro757 avatar pinbraerts avatar sigasigasiga avatar surmish avatar thenyeguy avatar tusqasi avatar zhengpd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tmux.nvim's Issues

Enhancement: Not jump to other tmux pane if current pane is in fullscreen

When there are a few windows in neovim, and also a few pane in tmux window, and current pane is in fullscreen, I use C-hjkl to jump to other window in neovim, but it jumped to other tmux pane, which is not what I wanted, If we can disable jump tmux panes in fullscreen, it would be useful.

Fail to map `<C-S-HJKL>` to resize splits

Here is my configuration

return {
  "aserowy/tmux.nvim",
  event = "VeryLazy",
  opts = {
    resize = {
      enable_default_keybindings = false,
    }
  },
  config = function(_, opts)
    local tmux = require("tmux")
    tmux.setup(opts)
    map("n", "<C-S-H>", "<cmd>lua require('tmux').resize_left()<cr>", "resize")
  end
}

But nothing happen when I press <C-S-H>. Is it a limitation of tmux to bind <C-S-*> keys?

Request to use a fork of vim-tmux-navigator tpm with resize support

Hello!

Have you considered forking vim-tmux-navigator (the tmux config, not the vim plugin) so that we could push the resize config into that repo? Main motivation is I'd rather have the tmux conf snippet for resizing moved into the tpm plugin, rather than copy pasting it into my own (and everyone else's) tmux.conf.

I could create the tpm plugin for myself, but I think it'd be beneficial for everyone to be able to do just:

set -g @plugin 'aserowy/tmux.nvim'

I can submit a PR if you'r open to it.
Thanks!

Disable Keybindings in insert mode

Hi, thanks for this great plugin. As the title state I'm looking for a way to enable navigation from nvim to tmux only when i'm in normal mode and not insert mode. Currently when I type to delete the previous char it switches to the next tmux panel from nvim.
Is there any option to do that ?
Thanks in advance.

Can not navigate between 2 Vim panel

tmux-bug.mov

The bug detail is in the video.

My tmux config:

# Pane navigation
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' { if -F '#{pane_at_left}' '' 'select-pane -L' }
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' { if -F '#{pane_at_bottom}' '' 'select-pane -D' }
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' { if -F '#{pane_at_top}' '' 'select-pane -U' }
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' { if -F '#{pane_at_right}' '' 'select-pane -R' }

My vim config

  local status_ok, tmux = pcall(require, "tmux")
  if not status_ok then
    return
  end

  tmux.setup {
    copy_sync = {
      enable = false,
      redirect_to_clipboard = false,
      sync_clipboard = false,
      sync_deletes = false,
    },
    navigation = {
      -- Enables default keybindings (C-hjkl) for normal mode
      enable_default_keybindings = true,
    },
    resize = {
      -- Enables default keybindings (A-hjkl) for normal mode
      enable_default_keybindings = true,
      resize_step_x = 3,
      resize_step_y = 3,
    },
  }

Compatibility with vim-yoink or other yank-related plugins

Hi, thanks for the wonderful plugin.

I may not be aware of the details of this implementation so my apologies if this is impossible.

There are some plugins that overrides y and p to perform custom yanking, like
vim-cutlass and vim-yoink.
I found a problem that in this way you can't use these plugins together.

I saw that there is an autocmd for text yanking.
Here's the minimal example:

vim.api.nvim_create_autocmd({ "TextYankPost" }, {
	callback = function()
		vim.highlight.on_yank({ higroup = "Visual", timeout = 200 })
	end,
})

Perhaps you can use such autocmds to perform buffer syncing rather than remapping y key, and if all plugin developers do that it should be possible to override multiple functionalities related to yanks.

What do you think?

EDIT:

Sorry, it seems like you're already doing this. I don't know why vim-yoink stopped working with this plugin installed, then. Any idea to make both work together?

copy sync

enables syncing of registers in tmux and nvim

Custom movement mappings freeze neovim

This happens every time I want to navigate from neovim to another tmux pane using those mappings.

This is a recent behaviour that didn't happen on older versions.

Configuration used

local packer = require("packer")
local use = packer.use
packer.startup(function()
  use "wbthomason/packer.nvim"
  use { "aserowy/tmux.nvim", config = function()
      require"tmux".setup {navigation = {enable_default_keybindings = false}}
      vim.cmd [[nnoremap <C-w>h <cmd>lua require('tmux').move_left()<cr>]]
      vim.cmd [[nnoremap <C-w>j <cmd>lua require('tmux').move_bottom()<cr>]]
      vim.cmd [[nnoremap <C-w>k <cmd>lua require('tmux').move_top()<cr>]]
      vim.cmd [[nnoremap <C-w>l <cmd>lua require('tmux').move_right()<cr>]]
    end
  }
end)

Neovim version

foo@bar:~$ nvim --version
NVIM v0.6.0-dev+181-g5d633546b
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by datwaft@dguevara

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "
/home/linuxbrew/.linuxbrew/Cellar/neovim/HEAD-5d63354/share/nvim"

Run :checkhealth for more info

Revelevant tmux configuration

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

bind-key -n 'C-w' if-shell "$is_vim" 'send-keys C-w' 'switch-client -Ttable1'

bind-key -Ttable1 'h' { if -F '#{pane_at_left}' '' 'select-pane -L' }
bind-key -Ttable1 'j' { if -F '#{pane_at_bottom}' '' 'select-pane -D' }
bind-key -Ttable1 'k' { if -F '#{pane_at_top}' '' 'select-pane -U' }
bind-key -Ttable1 'l' { if -F '#{pane_at_right}' '' 'select-pane -R' }
bind-key -Ttable1 '\' select-pane -l
bind-key -Ttable1 's' split-window -v -c "#{pane_current_path}"
bind-key -Ttable1 'v' split-window -h -c "#{pane_current_path}"
bind-key -Ttable1 'C-w' send-keys C-w

TMUX version

foo@bar:~$ tmux -V
tmux 3.0a

add option to change resize step

Cool plugin,
Maybe add a way to increase the resize step
It could be confired like this

{
    navigation = {
      ...
    },
    resize = {
        enable_default_keybindings = true,
        resize_step = 3,m
    }
}

Navigating out of lazy.nvim window results in Error: WinLeave Autocommands ...

I am using https://github.com/folke/lazy.nvim as my package manager and when I open it via :Lazy it opens a floating window in nvim.

Trying to then navigate using tmux.nvim results in:

E5108: Error executing lua ...are/nvim/lazy/tmux.nvim/lua/tmux/navigation/
navigate.lua:37: WinLeave Autocommands for "*": Vim(substitute):E21: Cannot make changes, 'modifiable' is off
stack traceback:
        [C]: in function 'wincmd'
        ...are/nvim/lazy/tmux.nvim/lua/tmux/navigation/navigate.lua:37: in
 function 'to'
        ...l/share/nvim/lazy/tmux.nvim/lua/tmux/navigation/init.lua:30: in
 function 'move_right'
        [string ":lua"]:1: in main chunk

My config

return {
  "aserowy/tmux.nvim",
  keys = { "<C-h>", "<C-j>", "<C-k>", "<C-l>" },
  config = function()
    require("tmux").setup({
      copy_sync = { enable = false },
      navigation = { cycle_navigation = true, enable_default_keybindings = true },
      resize = { enable_default_keybindings = true, resize_step_x = 1, resize_step_y = 1 },
    })
  end,
}

My best guess is that I am missing some config flag for floating windows, but I also feel that it was happening only since my upgrade from nvim 0.9.2 to 0.9.4. I'm suspecting that maybe neovim/neovim#25523 introduced an issue (it did for other plugins using auto_cmd

How can I clear the screen with C-l

This may be a stupid question, but aside from remapping the navigation to use ALT+key instead of CTRL+key how can I keep the bash behaviour of CTRL-l to clear the screen.

I use ALT+{h,l} to cycle bufferline, and I would like to keep it

execute selected line in tmux pane

send the current selected line in nvim to tmux pane and execute it

configuration should enable

  • keybinding
  • pane priority (which bordered pane should get targeted)

a further feature could be sending multi line selects

Searching for neovim process on Nix

If you have installed neovim via Nix, the recommended grep expression won't match the process name that ps returns. In most cases, nix users are installing a wrapped version of neovim that shows up as .nvim-wrapped. This line is working for me as of now in my tmux.conf:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?\.nvim-wrapped$'"

The wrapped version runs under this process name for diff mode as well, so no need to worry about the name changing for other modes (in my case, at least)

May want to add this to the README :)

Window switching stops working in python virtual environment

Hi @aserowy thanks for this great plugin!

I'm running into some unexpected behavior currently. If I have a tmux session and open nvim, <c-j> et all. works. However, if I first run poetry shell it no longer works. The mapping is set, but now nothing happens.

It must have something to do with poetry since if I activate the environment manually with source .venv/bin/activate it does work.

Any ideas? I believe poetry shell spawns a subshell, (though $TMUX remains set) and that might have something to do with it.

Debounce resize command

Long pressing M-h or other arrow commands continue to resize even when they keys are released.
Seems like the event listener for the key stcks all the keypresses.
Ideally it would stop once the keys are released
This could be implemented using a debounce on the keypress event.
Not sure how feasble it is in lua or with the limitations of the neovim api.

Use default key bindings

I want to use vim's default keybindings (Ctrl-w + hjkl) to move between vim and tmux
So I set it as follows:

init.lua (NVIM v0.6.0-dev+bec7f47ce)

local map = vim.api.nvim_set_keymap
local map_opts = {noremap = true, silent = true}

map("", "<C-w>h", ":lua require'tmux'.move_left()<cr>", map_opts)
map("", "<C-w>j", ":lua require'tmux'.move_bottom()<cr>", map_opts)
map("", "<C-w>k", ":lua require'tmux'.move_top()<cr>", map_opts)
map("", "<C-w>l", ":lua require'tmux'.move_right()<cr>", map_opts)

tmux.conf (tmux 3.2a)

bind -n C-w switch-client -T NAVIGATOR

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

bind -T NAVIGATOR h if-shell "$is_vim" "send-keys C-w h"  "select-pane -L"
bind -T NAVIGATOR j if-shell "$is_vim" "send-keys C-w j"  "select-pane -D"
bind -T NAVIGATOR k if-shell "$is_vim" "send-keys C-w k"  "select-pane -U"
bind -T NAVIGATOR l if-shell "$is_vim" "send-keys C-w l"  "select-pane -R"

bind -T NAVIGATOR C-w send-keys C-w

It was possible, but it stopped responding from a certain version
What's wrong?
Could the plugin support the default key bindings as well?

" keymap intersects normal workflow

I wanted to yank and paste from the system clipboard to neovim with "+y and "+p, it works fine until I enter tmux. So I dug in and found this key bind from the plugin intersects it.

['"'] = [[v:lua.tmux.sync_registers('"')]],

Can you change this or let me customize the key bindings?
For now, I will use vim.api.nvim_del_keymap('n', '"') as a workaround.

Slows down commands

I was trying this plugin out but realized that this plugin adds significant lag to commands. I had some remaps that used commands and it made them unusable.

e.g.

vim.api.nvim_set_keymap("n", "}", [[:keepjumps normal! }<cr>]], { noremap = true })
vim.api.nvim_set_keymap("n", "{", [[:keepjumps normal! {<cr>]], { noremap = true })

Can not navigate between tmux panes when in vim insert mode

Problem

Say I open multiple Tmux panes, the pane under focus is running Neovim in insert mode. I am not able to navigate to other panes using keyboard shortcuts. I have to switch to normal mode in Neovim and only then can I navigate from the pane running Neovim to another pane.

Expected behavior

With proper settings, I hope that I can navigate between Tmux panes freely using keyboard shortcuts, even when the pane is running Neovim/Vim in insert mode.

Screenshots

image

Versions

Tmux 3.3a
tmux.nvim commit 673782b (2023 Sept 6)

My settings

Tmux settings:

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' { if -F '#{pane_at_left}'   '' 'select-pane -L' }
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' { if -F '#{pane_at_bottom}' '' 'select-pane -D' }
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' { if -F '#{pane_at_top}'    '' 'select-pane -U' }
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' { if -F '#{pane_at_right}'  '' 'select-pane -R' }
bind-key -T copy-mode-vi 'C-h' if -F '#{pane_at_left}'   '' 'select-pane -L'
bind-key -T copy-mode-vi 'C-j' if -F '#{pane_at_bottom}' '' 'select-pane -D'
bind-key -T copy-mode-vi 'C-k' if -F '#{pane_at_top}'    '' 'select-pane -U'
bind-key -T copy-mode-vi 'C-l' if -F '#{pane_at_right}'  '' 'select-pane -R'

Neovim settings:

local status_ok, tmux = pcall(require, "tmux")
if not status_ok then
	return
end

tmux.setup {
  navigation = {
    cycle_navigation = false,
    enable_default_keybindings = true,
    persist_zoom = false,
  },
  resize = {
    enable_default_keybindings = false,
  },
}

Question

Is there any way in which I can navigate between Tmux panes freely using keyboard shortcuts, even when the pane is running Neovim/Vim in insert mode? If so, how? Thanks!

[Bug report] Cycle-free navigation in tmux panes could not be enabled?

Hello there. Hope you're doing well. Thank you for creating this unifying plugin; it makes switching between nvim buffers and tmux panes less cognitively demanding.

Please see the following video:

simplescreenrecorder-2022-06-27_14.08.58.mp4

As you can see, pressing Alt-h cycles the tmux panes.

Inside my .tmux.conf:

# navigation
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

bind-key -n 'M-h' if-shell "$is_vim" 'send-keys M-h' { if -F '#{pane_at_left}' '' 'select-pane -L' }
bind-key -n 'M-j' if-shell "$is_vim" 'send-keys M-j' { if -F '#{pane_at_bottom}' '' 'select-pane -D' }
bind-key -n 'M-k' if-shell "$is_vim" 'send-keys M-k' { if -F '#{pane_at_top}' '' 'select-pane -U' }
bind-key -n 'M-l' if-shell "$is_vim" 'send-keys M-l' { if -F '#{pane_at_right}' '' 'select-pane -R' }

bind-key -T copy-mode-vi 'M-h' if -F '#{pane_at_left}' '' 'select-pane -L'
bind-key -T copy-mode-vi 'M-j' if -F '#{pane_at_bottom}' '' 'select-pane -D'
bind-key -T copy-mode-vi 'M-k' if -F '#{pane_at_top}' '' 'select-pane -U'
bind-key -T copy-mode-vi 'M-l' if -F '#{pane_at_right}' '' 'select-pane -R'

tmux.lua:

require("tmux").setup({
  navigation = {
    -- C-hjkl
    enable_default_keybindings = false,
    cycle_navigation = false,
  },
})

local function map(mode, lhs, rhs, opts)
  local options = { noremap = true, silent = true }
  if opts then
    options = vim.tbl_extend("force", options, opts)
  end
  vim.api.nvim_set_keymap(mode, lhs, rhs, options)
end

map("n", "<A-h>", '<cmd>lua require("tmux").move_left()<cr>')
map("n", "<A-l>", '<cmd>lua require("tmux").move_right()<cr>')
map("n", "<A-k>", '<cmd>lua require("tmux").move_top()<cr>')
map("n", "<A-j>", '<cmd>lua require("tmux").move_bottom()<cr>')

As per instructed, "bindings in nvim must match the defined bindings in tmux". In nvim buffers, cycling navigation is indeed disabled:

simplescreenrecorder-2022-06-27_14.24.13.mp4

My question is, what went wrong and how do I disable cycling navigation in tmux panes as well?

Any input is much appreciated. Thank you:)

Clipboard selection

Hey @aserowy,

I am using this plugin as alternative to https://github.com/christoomey/vim-tmux-navigator.
Moving around and reszing works.
Although I needed to PackerCompile everything first, this wasn't necessary for other plugins so I was confused at first why it wasn't working.

A different issue that I stumbled on is that yanking from nvim it seems that the selection is yanked into PRIMARY.
I can paste this selection into a different tmux window with middle mouse click just fine and also paasting between nvim sessions works.

However would it be possible that the yanked text to be synced to CLIPBOARD instead?
For multiple use-cases:

  1. Yank something from nvim and paste it somewhere else that isn't tmux e.g. browser
  2. Yank text from a remote nvim/tmux session and have it synced to local clipboard using X11 forwarding.

[FR] Omit setup step if use default settings

Some plugins allow us to omit setup call if we use default setting. Please only force user to setup call if they wanna change default behavior. This will help remove boilerplate code in our config. Thank you

Opening neovim outside tmux session throws an error

I get the following error when I start neovim outside a tmux session:

line  442:
E5108: Error executing lua vim/shared.lua:64: s: expected string, got nil
stack traceback:
        vim/shared.lua:64: in function 'gsplit'
        vim/shared.lua:111: in function 'split'
        ...leon/.config/nvim/plugged/tmux.nvim/lua/tmux/wrapper.lua:26: in function 'get_socket'
        ...leon/.config/nvim/plugged/tmux.nvim/lua/tmux/wrapper.lua:30: in function 'execute'
        ...leon/.config/nvim/plugged/tmux.nvim/lua/tmux/wrapper.lua:40: in function 'get_version'
        ...leon/.config/nvim/plugged/tmux.nvim/lua/tmux/wrapper.lua:52: in function 'setup'
        /home/leon/.config/nvim/plugged/tmux.nvim/lua/tmux/init.lua:25: in function 'setup'
        /home/leon/.config/nvim/lua/init.lua:47: in main chunk
        [C]: in function 'require'
        [string ":lua"]:1: in main chunk
Press ENTER or type command to continue

Can be fixed by not calling get_version() in setup() in tmux.nvim/lua/tmux/wrapper.lua:

local M = {}
function M.setup()
	M.is_tmux = get_tmux() ~= nil
+       if not M.is_tmux then
+           return
+       end
	M.version = get_version()
end

vim buffers only cycle when zoomed

The feature described in #7 seems to only work in zoom now. I see there were some issues and changes since I implemented it but I haven't looked closely at the details to follow everything.

Did you intend to revert the cycling vim buffers feature or is this a bug?

Error: next3.4 could not get parsed

Starting in the latest commit (cb1f401), I get the following error on startup:

Error detected while processing $XDG_CONFIG_HOME/nvim/init.lua:
next3.4 could not get parsed!

next3.4 is my tmux version:

$ tmux -V
tmux next-3.4

I'm using tmux-git from the AUR.

Using the previous commit (6e9597a) works without issue.

Resizing fails in a specific scenario

Resizing works fine except for one specific scenario:
When there is tmux pane on the left, and a vim pane on the right that has a horizontal split, resizing from the vim pane(from either split) will not work:
grafik

When there is no horizontal split it will work; resizing from the tmux pane will work, if the vim instance is on the left instead it will work, etc...

Only this specific scenario just does nothing

Stopped working across nvim to nvim in tmux pane split

If I split tmux window in two panes side by side and run nvim on each split, the mappings won't move from one split to another, it only works in:

  • nvim window to nvim window
  • nvim window to tmux pane
  • tmux pane to nvim window
  • tmux pane to tmux pane

It not working in:

  • nvim window in tmux pane to nvim window in another tmux pane

I'm not sure whether it used to work, I suspect it did because I've been using it for quite a while and only noticed this problem lately.

keep zoom in vim panes

At first sight I thoght persist_zoom option was about keeping the vim pane zoom when re-enter that pane, instead is about preventing switching to other pane when zoomed in.

So It would be cool to keep the zoom in the vim panes, because I found myself constantly typing prefix + z to recover the zoom when switching to the vim panes

e.g.

image

When switching to vim pane

image

Maybe we can create this feature keep_zoom or something like that to achieve this behavior

Add wezterm support as a new backend beside tmux

Hey there. I had been a long neovim + tmux Ctrl[j,jk,h,l] user for long time. And recently found another alternative setup which satisfies all my needs. It's wezterm + its built-in multiplexer, which gives me:

  • a multiplexer ability to split panes and create a new tab instance
  • use copy mode with vim like keybinding
  • built-in ssh support
  • and finally, as a bonus, to preview images and having terminal multiplexing at the same time! Which is awesome!

The only missing part is make it works with the Ctrl[j,jk,h,l] nav workflow: to switch back and forth between panes and neovim windows seamlessly (resize panes as well, which I do not use). The solution for emacs + evil (vim binds) is already implemented. And perhaps, it is time to make it work for neovim as well.
The trick is to ask wezterm about the available panes at the interested side and use these ids to direct navigation like:

wezterm cli get-pane-direction right # capture id number as stdout output
wezterm cli activate-pane --pane-id 46 # use the id

What about to create a new backend (lets say wezterm) and make the plugin work for wezterm also? Thank you for any input.

Misconception of #{pane_at_top}

Recently I migrate from vim-tmux-navigator but I encounter this bug, when the vim pane is zoomed in, it does not cycle, no matter what persist_zoom you've set

After some debugging I found that #{pane_at_top} means if the pane is at the top at the specific moment you ask.

That's why when we run this in a zoomed in pane we get 1 and when we run that in a zoomed out pane we get 0
tmux -S <YOUR-SESSION-SOCKET> display-message -p '#{pane_at_top}'

That variable is not appropiate to find out if it has a neighbor in X direction, nor to find if it's the very last pane, so basically it's useless for that purpose

So my recommendation is to go back to the behavior of the plugin vim-tmux-navigator, What do you think?

Default keybindings work within tmux panes but not nvim panes using Lazy

Hi!

I recently installed the plugin, however looks like there is no way I can make <C-hjlk> work.

I'm using the default configuration as mentioned in the readme, navigation within tmux panes works good but never across neovim splits.

Neovim config

  use({
      "aserowy/tmux.nvim",
      config = function() return require("tmux").setup({
          sync_clipboard = false,
          sync_unnamed = false,
      }) end
  })

tmux config

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 -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R

Curiously enough executing :lua require('tmux').move_right() (or any of the other variants) works well. I've tried to set up the keymaps manually with no success. I also tried binding the actions to a different set of bindings:

vim.keymap.set({'n', 't'}, '<leader>wj', function () tmux.move_bottom() end)
vim.keymap.set({'n', 't'}, '<leader>wk', function () tmux.move_top() end)
vim.keymap.set({'n', 't'}, '<leader>wl', function() tmux.move_right() end)
vim.keymap.set({'n', 't'}, '<leader>wh', function() tmux.move_left() end)

This works as expected, and is what I'm using now as a fallback while trying to solve this since ideally I prefer tmux bindings and nvim bindings to be the same

I tried to deactivate other plugins just in case they might be overwriting the specific default bindings but I had no luck with that either.

Any Idea on how to troubleshoot this one?
Thanks!

Make vim split navigation wrap consistent with tmux panes

image (yes, a screenshot because github markdown table defeated me)

From A, move_left() does nothing (it doesn't wrap around, moving to C). But this is inconsistent from tmux, where the same scenario using panes does wrap around for navigation.

What do you think about making vim wrap as well?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.