作为一名软件开发人员,我将 tmux 与 Neovim 结合使用(在 Debian 10 上)。
我遇到了以下两个问题,经过大量调查后仍然找不到适合我的解决方案:
- 我想无限循环切换分屏(就像浏览器上的标签一样)。假设我在 Neovim 上打开了 3 个垂直分屏,从最后一个分屏转到第一个分屏的唯一方法是向后循环,我想从最后一个分屏向右导航到第一个分屏。
- 当我“越过边界”时,tmux 会退出全屏,我想防止这种情况发生。所以我通常将 Neovim 放在顶部,占据屏幕的 70% 到 80%,并在底部放置一个终端(如上图所示),但有时我需要使用 tmux 进入全屏 Neovim。假设我在 Neovim 中打开了 2 个垂直分割,会发生什么情况是,当我在右侧分割中时,我不小心导航到右侧(由于右侧没有其他分割,我想像上面所述那样循环它们),tmux 会退出 Neovim 全屏,我不想发生这种情况,我只希望在我向下移动(即终端所在的位置)时发生这种情况,或者也许我只是使用我用于全屏的相同组合键(在我的情况下是 Ctrl-s + z)。
这是我的.tmux.conf:
# tmux display things in 256 colors
set -g default-terminal "screen-256color"
# Automatically renumber tmux windows
set -g renumber-windows on
# Unbind default prefix and set it to Ctrl+s
unbind C-b
set -g prefix C-s
bind C-s send-prefix
# Split window and fix path for tmux
bind / split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# Pane movement shortcuts
# bind -n C-h select-pane -L
# bind -n C-j select-pane -D
# bind -n C-k select-pane -U
# bind -n C-l select-pane -R
# Smart pane switching with awareness of Vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
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'
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'"
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
bind-key -T copy-mode-vi 'C-\' select-pane -l
# Resize pane shortcuts
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# Enable mouse support for switching panes/windows
setw -g mouse on
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
set-option -g history-limit 10000
set-option -sg escape-time 10
答案1
如果您使用“christoomey/vim-tmux-navigator”,我认为这对您有用:
首要问题:
在我的系统中(在 Ubuntu 18.04 上使用 tmux 2.6,在 Debian Buster 上使用 tmux 2.7),我可以像您描述的那样循环浏览窗格。例如,如果我在最右侧的窗格中,并且我使用ctrl-l
“向右”键,我最终会进入最左侧的窗格。将其放入您的 tmux conf 中应该可以解决问题:
# Smart pane switching with awareness of Vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
由于我在 vim 中使用 fzf,并已设置ctrl+j/k
为在列表中上下移动,因此我有一个额外的检查 ( is_fzf
) 来触发该行为,而不是导航拆分。如果您想执行相同的操作,代码如下:
# Smart pane switching with awareness of Vim splits and fzf windows.
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
# See: https://github.com/keeganlow/dotfiles/blob/master/.tmux.conf
is_fzf="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?fzf$'"
bind-key -n 'C-k' if-shell "($is_vim || $is_fzf)" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-j' if-shell "($is_vim || $is_fzf)" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
第二个问题:
在你的 vimrc 中,你可以使用:
let g:tmux_navigator_disable_when_zoomed = 1
在 vim 中移动时不要脱离缩放。
编辑-我的整个.tmux.conf
# reload the tmux.conf and display a message to that effect
bind r source-file ~/.tmux.conf \; display "Reloaded .tmux.conf"
# source colorscheme
set -g default-terminal 'screen-256color'
# source-file ~/.tmux_light.conf
# remap prefix from CTRL-B to CTRL+Spacebar {{{
set -g prefix C-Space
unbind C-b
# }}}
# configure default limits/times {{{
# Set scrollback buffer to 10000
set -g history-limit 10000
# No delay for escape key press
set -sg escape-time 0
# When using repeatable commands (like resizing) repeat-time is the duration of
# the window (in milliseconds) for which a repeat can be made (default is 500)
set -g repeat-time 1000
# If I want to switch to another pane while in a fzf list, I can do prefix+q,
# then hit the number of the pane I want. Make those numbers last a bit longer.
# (I can always press escape to make them turn off immediately)
set -g display-panes-time 3000
# }}}
# pane and window indexing {{{
# Set the base index for windows to 1 instead of 0
set -g base-index 1
# Set the base index for panes to 1 instead of 0
set-window-option -g pane-base-index 1
# }}}
# pane navigation {{{
# allow the vim pluging 'tmux-plugins/vim-tmux-focus-events' to work
set -g focus-events on
# split panes using | and - {{{
%if "#{==:#{host},office}"
# ubuntu 20.04
bind '\' split-window -h
%endif
%if "#{!=:#{host},office}"
# ubuntu 18.04 and debian buster
bind \ split-window -h
%endif
bind - split-window -v
unbind '"'
unbind %
# }}}
# Pane resizing with prefix + H/J/K/L: {{{
bind -r H resize-pane -L 5
bind -r L resize-pane -R 5
bind -r K resize-pane -U 3
bind -r J resize-pane -D 3
# }}}
# Smart pane switching with awareness of Vim splits and fzf windows. {{{
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
# See: https://github.com/keeganlow/dotfiles/blob/master/.tmux.conf
is_fzf="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?fzf$'"
bind-key -n 'C-k' if-shell "($is_vim || $is_fzf)" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-j' if-shell "($is_vim || $is_fzf)" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
# go to last pane (like b# in vim)
bind '#' select-pane -l
# }}}
# }}}
# visually select and yank to system clipboard {{{
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -sel clip -i'
# like visual block mode
bind-key -T copy-mode-vi r send-keys -X rectangle-toggle
# I think I might overwrite the lower case p for 'previous window', since I
# can just use next/numbers to swtich
bind P paste-buffer
# }}}