如何让 tmux 在 neovim 窗格内忽略命令?

如何让 tmux 在 neovim 窗格内忽略命令?

我正在尝试让 tmux 和 neovim 尽可能无缝地协同工作。不过我遇到了一个问题。每当我在 tmux 中的 neovim 窗格中时,我都想使用默认的所需绑定将 neovim 拆分为水平/垂直窗口...

C-w v垂直

C-w nC-w s水平。

它只是简单地命中或未命中。它的反应不是很灵敏... 编辑: 现在注意到它有响应,但我必须按C-w两次才能s在 neovim 中激活它。为什么?我不想要这种行为

每当我用 for 执行该C-w s操作并且只点击C-w一次 then 时s,它就会触发 tmux 命令在任何可用会话之间切换。我只希望它在 tmux 窗格中执行该操作。在 neovim 中时,我希望它拆分。我的 tmux 前缀是C-w,我想保留原样,但是当我在 neovim 窗格中时,如何让 tmux 忽略命令。我不想再更改默认绑定了。

**2020 年 4 月 4 日更新:**

# eliminates delay when switching out of mode in vim/nvim
set -sg escape-time 0

# remap prefix from 'C-b' to 'C-a'
unbind C-b
set-option -g prefix C-w
bind C-w send-prefix

# Easy config reload
bind R source-file ~/.tmux.conf \; display-message "tmux.conf reloaded."

unbind '"'
unbind %

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

bind 'v' if-shell "$is_vim" 'send-keys C-w v'  'split-window -h'
bind 's' if-shell "$is_vim" 'send-keys C-w n'  'split-window -v'
bind 'n' if-shell "$is_vim" 'send-keys C-w n' 'split-window -v'

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

bind 'S-h' if-shell "$is_vim" 'send-keys C-w S-h'
bind 'S-j' if-shell "$is_vim" 'send-keys C-w S-j'
bind 'S-k' if-shell "$is_vim" 'send-keys C-w S-k'
bind 'S-l' if-shell "$is_vim" 'send-keys C-w S-l'

决定使用vim-tmux-navigator plugin,但我还有最后一个问题……我不太确定如何编写 neovim 的窗口移位绑定脚本。绑定C-w然后进行。我尝试了Shift-<direction>最后 4 个命令,但它不起作用.tmux.conf

答案1

目前尚不清楚您是否已尝试配置 tmux 来执行此操作并且它不起作用,或者您是否正在询问如何执行此操作。

无论如何,通常这是通过改变所需的键绑定以仅在某些条件下执行来完成的,例如您可以检查 neovim:

bind v if -F '#{!=:#{pane_current_command},neovim}' 'splitw -v' 'send v'

或者对于选择树:

bind s if -F '#{!=:#{pane_current_command},neovim}' 'choose-tree -Zs' 'send s'

如果你希望检查一些与pane_current_command查看不同的内容,可以使用不同的条件https://github.com/tmux/tmux/wiki/Formats以及FORMATS手册页中的部分。

当 neovim 在活动窗格中运行时,您需要对要传递给 neovim 的每个键绑定执行此操作。

您可以使用键表一次性完成所有操作,这样虽然更短,但配置起来更麻烦。

答案2

vim/neovim 默认使用前缀C-w来移动和旋转窗口,我也将 tmux 的前缀更改为C-w。考虑到这一点,为了让 tmux 识别出我在 neovim 窗格中,我必须点击C-w两次才能忽略 tmux 并在 vim/neovim 中执行我的命令。

然而,这对于我来说,开销太大了……

在...的帮助下vim-tmux-导航器经过一些细微的更改,我能够使用默认的C-w窗口移动。该插件允许您无缝地从 vim/neovim 窗口(窗格)移动到 tmux 窗格。默认情况下,该插件会映射窗格移动,而无需使用C-wC-<hjkl>我太习惯于点击了,所以C-w我将其改回了默认设置... 在我的.vimrcinit.vim如果您使用的是 neovim,我为插件添加了这个...

let g:tmux_navigator_no_mappings = 1

nnoremap <silent> <c-w>h :TmuxNavigateLeft<cr>
nnoremap <silent> <c-w>j :TmuxNavigateDown<cr>
nnoremap <silent> <c-w>k :TmuxNavigateUp<cr>
nnoremap <silent> <c-w>l :TmuxNavigateRight<cr>
nnoremap <silent> <c-w>\ :TmuxNavigatePrevious<cr>

在我的.tmux.conf我添加了这个

unbind C-b
set-option -g prefix C-w
bind C-w send-prefix

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

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

检查您是否在要拆分的 vim/neovim 窗格中,否则在 tmux 中拆分。我这样做了...

bind 'v' if-shell "$is_vim" 'send-keys C-w v'  'split-window -h'
bind 's' if-shell "$is_vim" 'send-keys C-w n'  'split-window -v'
bind 'n' if-shell "$is_vim" 'send-keys C-w n' 'split-window -v'

对于使用 Shift 键切换窗格,我错误地认为我应该使用S-<hjkl>,而实际上 S 所做的只是将字母大写。考虑到这一点,C-w S-h我没有这样做,而是这样做了...

bind 'H' if-shell "$is_vim" 'send-keys C-w H'
bind 'J' if-shell "$is_vim" 'send-keys C-w J' 
bind 'K' if-shell "$is_vim" 'send-keys C-w K' 
bind 'L' if-shell "$is_vim" 'send-keys C-w L' 

如果你想知道为什么我C-w在脚本中省略了,那是因为默认情况下前缀是需要的,除非我使用bind -n

相关内容