如何创建在Vim窗口之间移动的快捷方式?

18
假设我有一个显示了9个缓冲区的单个Vim标签页(等距分布,如3×3表格)。 目前,要从左上角的窗口转到右下角的窗口,我需要按 3, Ctrl+W, J,然后再按 3, Ctrl+W, L。这很麻烦,我想只需按Ctrl+9即可转到第9个窗口,按Ctrl+3即可转到第3个窗口等等。 在Vim中,有没有一种简单的方法可以映射这样的操作?
6个回答

40

有一个比使用鼠标或硬编码移动映射更简单的解决方案; 如果窗口编号与你想要的3x3矩阵不同,或者你决定使用少于9个窗口,它们将会出错。这里是如何做到的:

在你的.vimrc中加入以下内容:

let i = 1
while i <= 9
    execute 'nnoremap <Leader>' . i . ' :' . i . 'wincmd w<CR>'
    let i = i + 1
endwhile

现在你只需要按下<Leader><number>,就能快速进入你想要的窗口。我不建议超过9个窗口,因为在我的看法中,多窗口视图的效用遵循瑞利分布,当窗口数量过多时会很快变得毫无意义。

如果你在statusline中显示窗口编号,将有助于你快速确定当前所在窗口和想要去的窗口。为此,请使用以下小函数,并相应地添加到你的statusline中。

function! WindowNumber()
    let str=tabpagewinnr(tabpagenr())
    return str
endfunction

在你的statusline中看它的表现:

set laststatus=2
set statusline=win:%{WindowNumber()}
请注意,上述行将替换您的statusline。 它只是用于说明目的,以展示如何调用函数。 您应该在您认为适当的statusline中放置它。 这是我的样子:

enter image description here


更新

romainl在评论中要求我的状态栏,所以这里是:

"statusline
hi StatusLine term=bold cterm=bold ctermfg=White ctermbg=235
hi StatusHostname term=bold cterm=bold ctermfg=107 ctermbg=235 guifg=#799d6a
hi StatusGitBranch term=bold cterm=bold ctermfg=215 ctermbg=235 guifg=#ffb964

function! MyGitBranchStyle()
    let branch = GitBranch()
    if branch == ''
        let branchStyle = ''
    else
        let branchStyle = 'git:' . branch
    end
    return branchStyle
endfunction

function! WindowNumber()
    let str=tabpagewinnr(tabpagenr())
    return str
endfunction

set laststatus=2
set statusline=%#StatusLine#%F%h%m%r\ %h%w%y\ col:%c\ lin:%l\,%L\ buf:%n\ win:%{WindowNumber()}\ reg:%{v:register}\ %#StatusGitBranch#%{MyGitBranchStyle()}\ \%=%#StatusLine#%{strftime(\"%d/%m/%Y-%H:%M\")}\ %#StatusHostname#%{hostname()}
最后一行应该只有一行(如果您的设置会自动将其分成多行,请小心)。我知道有方法可以在每个步骤中使用递增的字符串连接来保持它有组织,但我懒得改变它。:) GitBranch() 函数(与其他 git 功能一起)由 git.vim 插件 提供。如此处所述,其中存在一个错误,我使用了修复了该错误的衍生工具包 。但是,我在这里保留两个链接和博客以表彰所有人。同时请注意,我使用深色背景,因此如果您使用明亮的主题(也要根据您的喜好),可能需要调整一下颜色。

@yoda,我知道我们不在Arch论坛的每月截图帖子上,但是...你介意分享一下你的状态栏吗? - romainl
@yoda,以下内容将进入第三个屏幕 nnoremap <c-a> :3wincmd w<CR> 但是,<c-3> 不起作用 nnoremap <c-3> :3wincmd w<CR> 因此,由于某种原因,数字键无法正常工作,有什么办法可以修复吗? - Kamilski81
1
@Kamilski81:昨天我试着使用ctrl键,但是我也无法让它起作用,这就是为什么我提供了使用<Leader>的解决方案。当我尝试使用ctrl时,我以为自己犯了一些愚蠢的错误,但既然你也遇到了同样的错误,也许我有空的时候会再看看它。顺便说一下,我将我的<Leader>设置为" "(或空格键),所以按下空格和数字比按下ctrl+数字要容易得多... - user616736

10

更好,更通用的答案:

使用countCtrl+wCtrl+w跳转到当前窗口下方/右侧的count窗口。

例如,如果您在3x3网格的左上角,并想要跳转到左下角,则可以使用7Ctrl+wCtrl+w

特定的3x3网格答案:

如果您总是使用3x3布局,则可以尝试使用数字键盘的以下映射,它们始终跳转到左上角,然后从那里移动适当的数量,键位在数字键盘上的位置会跳转到屏幕上“等效”的位置:

noremap <k7> 1<c-w><c-w>
noremap <k8> 2<c-w><c-w>
noremap <k9> 3<c-w><c-w>
noremap <k4> 4<c-w><c-w>
noremap <k5> 5<c-w><c-w>
noremap <k6> 6<c-w><c-w>
noremap <k1> 7<c-w><c-w>
noremap <k2> 8<c-w><c-w>
noremap <k3> <c-w>b
编辑:原来c-w c-w会自动跳转到左上角。第一个映射需要明确地指定1,因为没有计数的c-w c-w会在当前窗口和之前选择的窗口之间切换。

(Ctrl-W t 映射始终跳转到左上角最上面的窗口,Ctrl-W b 映射始终跳转到右下角最下面的窗口)。

或者您可以将每个数字映射到第N个窗口,例如k6将是6个c-w c-w,而不是尝试按屏幕布局键。


5

我更喜欢使用标准的vim按键(jkhl)。

noremap <C-J> <C-W>w
noremap <C-K> <C-W>W
noremap <C-L> <C-W>l
noremap <C-H> <C-W>h

如果你注意到前两个地图可以顺时针或逆时针跳转,而不仅仅是上下跳转,那么有一个技巧。

你还可以使用 <数字><C-J> 直接切换到任何窗口,例如,2<C-J> 将转到第2个窗口。


3

也许不完全符合您的要求,但如果您使用支持此功能的终端,可以设置以下选项:

:set mouse+=a
:set ttymouse=xterm2

点击缓冲区以切换到它。是的,用鼠标。

还有很多其他的鼠标行为也可以使用 - 您可以单击以移动插入点,拖动以选择文本或调整分割线大小,并使用滚轮。


我知道这对 Vim 文化来说是异端的,但实际上这确实是最好的方法。 - webdevguy

1

嗯... 我相当确定这不会保持窗口布局,但我仍然使用它

:buf sys

前往system.h文件,

:buf Sing

前往 MyLargeNamedClassSingleton.cpp

buf 将执行自动完成(如果配置了,则可能为菜单完成),因此您可以执行

:buf part<Tab>

列出与您输入的part可能匹配的文件。这要比在各个缓冲区中导航要好很多。
但我明白,这当然并没有回答您具体的问题 :)

1

我喜欢用箭头键移动。
我将 ctr+方向 键映射到在该方向上移动到下一个窗口分区。

map <C-UP> <C-W><C-UP>
map <C-DOWN> <C-W><C-DOWN>
map <C-LEFT> <C-W><C-LEFT>
map <C-RIGHT> <C-W><C-RIGHT>

你不能直接从一个窗口跳转到另一个窗口,但我发现这样可以非常方便地在窗口之间移动


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接