我在 tmux 中使用 Vim,最近将以下内容添加到我的.vimrc
文件中:
" easy navigation
nnoremap <C-Left> :tabprevious
nnoremap <C-Right> :tabnext
但这似乎没有效果(我按下CTRL+l
或CTRL+Right
,我的光标只是移动,就像我CTRL
根本没有按下一样)。我猜 tmux 在某种程度上对此负责。
我尝试将以下每一行(而不是同时)添加到我的代码中,但.tmux.conf
无济于事:
set -g default-terminal "xterm"
set-window-option -g xterm-keys on
肯定有一种简单的方法可以将这些命令传递给 vim?
我读了这篇文章:
如何让 tmux 中的 Vim 中的 shift+箭头和 ctrl+箭头起作用?
并尝试将以下内容添加到我的.vimrc
,但也没有明显的效果:
if &term =~ '^screen'
" tmux will send xterm-style keys when its xterm-keys option is on
execute "set <xUp>=\e[1;*A"
execute "set <xDown>=\e[1;*B"
execute "set <xRight>=\e[1;*C"
execute "set <xLeft>=\e[1;*D"
endif
我正在运行 vim 版本 7.4
答案1
TERM
tmux 的推荐设置是screen-256color
,并且您添加到作品中的代码片段vimrc
仅适用于以TERM
开头的,screen
因此您可以确保如果您的代码块TERM
是,那么该代码块将永远不会被执行xterm
。
我之前在这台机器上成功使用过这个代码片段,没有set-window-option -g xterm-keys on
,但不知为何,它似乎不再对我有用了(过去三个月我都没有使用 tmux)。我想知道发生了什么。iTerm 升级?tmux 升级?
添加set-window-option -g xterm-keys on
到我的~/.tmux.conf
修复程序中即可解决问题。
<C-Left>
无论如何,您可以直接映射由和生成的原始序列<C-Right>
作为临时解决方法。
nnoremap <C-v><C-Left> :tabprevious<CR>
应该会给你类似这样的结果:
nnoremap ^[[D :tabprevious<CR>
答案2
除非你看到你使用的代码(例如<C-Left>
)在“终端键”部分:set termcap
,您不能立即使用它。
这文档列出了映射特殊键的 3 种方法。第一种方法是插入或者命令行模式按下Ctrl-K
,然后按下要映射的键序列(例如Ctrl-K Ctrl-Left
)。如果它打印<...>
,则可以将其用作映射的左侧。否则,在其前面加上<Esc>
( Ctrl-V Esc
) ,或使用Ctrl-V Ctrl-Left
。例如,在 下,tmux
我得到[1;5D
,Ctrl-Left
并且<Left>
。Left
这意味着对于Left
我可以使用<Left>
,并且对于Ctrl-Left
我需要^[[1;5D
(^[
应该是一个字符,,Ctrl-V Esc
请注意后面的<CR>
):
nnoremap ^[[1;5D <Cmd>tabprevious<CR>
或者 (:h :set-termcap
):
set <C-Left>=^[[1;5D
nnoremap <C-Left> <Cmd>tabprevious<CR>
如果您在不同的终端下工作,您可能需要第二种方法:
if &term =~ '^screen'
set <C-Left>=...
elseif &term =~ '^tmux'
set <C-Left>=...
endif
nnoremap <C-Left> <Cmd>tabprevious<CR>
某些键适用于某些终端,但不能适用于其他终端(当它们在相应的 terminfo 条目中没有字段时)。让我们<S-Left>
以 为例。从( ):set termcap
下的 not中,我可以看到它位于字段中:tmux
TERM=rxvt-unicode-256color
t_#4
termcap
t_#4 <S-Left> ^[[d
key_sleft kLFT #4 shifted left-arrow
key
这意味着名称terminfo
是。现在让我们看看(not under )、(under ) 和(我们稍后可能需要)kLFT
的此字段的值:TERM=rxvt-unicode-256color
tmux
TERM=screen
tmux
TERM=tmux
$ infocmp rxvt-unicode-256color | grep kLFT
kLFT=\E[d, kNXT=\E[6$, kPRV=\E[5$, kRIT=\E[c, ka1=\EOw,
$ infocmp screen | grep kLFT
$ infocmp tmux | grep kLFT
kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~,
条目中缺少该screen
terminfo
内容。要解决此问题:
if &term =~ '^screen'
set <S-Left>=...
endif
nnoremap <S-Left> <Cmd>tabprevious<CR>
或者(vim
我们必须使用termcap
名称):
if &term =~ '^screen'
set t_#4=...
endif
nnoremap <S-Left> <Cmd>tabprevious<CR>
或者你可以告诉tmux
使用它自己的 terminfo
入口:
set -g default-terminal tmux
附注:<Esc>
如果可能,请避免在配置中(或通常在文本文件中)使用该字符。它是一个看起来像 2 的字符。如果您使用鼠标复制它,它^[
会变成 2 个字符,这样它就不起作用了。特别是在文档中,您可以找到^[
2 个字符的示例,您不能直接复制。这种事情很容易被忽视。
如果仍然不起作用,请告诉我您按下了什么以及它产生的转义序列(使用Ctrl-V
)。
答案3
另一种解决方案如下:
" Note: Move to the next tab! By Questor
nnoremap <silent> <C-Up> :tabnext<cr>
inoremap <silent> <C-Up> <C-O>:tabnext<cr>
vnoremap <silent> <C-Up> :<C-U>tabnext<cr>v
" Note: Move to the previous tab! By Questor
nnoremap <silent> <C-Down> :tabprevious<cr>
inoremap <silent> <C-Down> <C-O>:tabprevious<cr>
vnoremap <silent> <C-Down> :<C-U>tabprevious<cr>v
对我来说非常有用!
参见使用示例https://github.com/eduardolucioac/groovim/blob/master/.vimrc