我正在尝试让 tmux 和 neovim 尽可能无缝地协同工作。不过我遇到了一个问题。每当我在 tmux 中的 neovim 窗格中时,我都想使用默认的所需绑定将 neovim 拆分为水平/垂直窗口...
C-w v
垂直
C-w n
或C-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-w
。C-<hjkl>
我太习惯于点击了,所以C-w
我将其改回了默认设置... 在我的.vimrc
或init.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