在vim中切换到缓冲区的最快方法?


43

在vim中选择缓冲区的一种方法是浏览缓冲区列表,使用标准命令:ls,或者使用一些外部插件/ vimscript代码在窗口中浏览列表

假设我想尽可能快地直接跳转到缓冲区。

为了在顺序模式下遍历缓冲区列表,我现在使用<C-J> <C-K>快捷方式,在.vimrc中进行设置:

" move among buffers with CTRL
map <C-J> :bnext<CR>
map <C-K> :bprev<CR>

另一种方式(直接访问)可能是通过数字切换:知道缓冲区号,可以通过输入缓冲区号后接来直接进行切换<C-^>。因此,如果要切换到5号缓冲区,请按5<C-^>

但这似乎对我不起作用(我在Windows客户机上使用意大利语键盘在ubuntu盒上使用vim 7.4 )。我怀疑这是因为该^字符位于意大利语键盘的大写字母中,所以实际上^我需要按SHIFT-^

有任何想法吗?


2
您可以按<c-6>代替<c-^>吗?
彼得·林克

您是说Ctrl-1转到1号缓冲区吗?不幸的是行不通。什么都没发生
Giorgio Robino

1
否。某些终端机可以理解Ctrl-6,与美国键盘上的Ctrl- ^相同。
彼得·林克

2
+1好极了!我使用意大利语键盘布局(使用腻子终端模拟器)。因此:1<C-6>切换到1号缓冲区。谢谢!
乔治·罗宾诺

您可以尝试使用CtrlSpace
刘洪波

Answers:


51

:b命令还可以获取您要移动到的缓冲区文件名的子字符串,这非常方便。

举例来说,如果你有三个缓冲区foobarbaz,然后

  • :b bar将切换到该bar文件。

  • :b o将切换到该foo文件。

  • :b a会给您一个错误,因为它可能表示barbaz,但是您可以使用来更正该名称,例如: r Enter

这可能非常有用,因为它意味着

:buffer very/very/long/path/to/a/veryVeryLongFileName.txt

你可以做类似的事情

:b LongFileName

它更短,更容易。

如果要使用此命令,也可以使用一个数字:

:b 5

8
关于使用部分缓冲区名称的警告:如果部分缓冲区名称出现在某个缓冲区路径的单词边界的开头,则该:b命令将无法访问部分名称在单词中间的缓冲区。例如,如果您有两个缓冲区path/to/foopath/to/tofu,则该命令:b f<Tab>将永远不会匹配path/to/tofu,因为它在中的单词开头匹配path/to/foo
tommcdo

2
:5b则稍短一些:b 5 ;-)
joeytwiddle

15

这是我用的:

nnoremap <Leader>b :ls<CR>:b<Space>

现在按\b列出可用的缓冲区:b为您准备。

然后,您只需键入缓冲区编号,然后按Enter。

或者,您可以键入文件名的一部分,然后按Enter。(但是,我通常在按Enter键之前先按Tab键,以检查是否获得了正确的缓冲区。否则,我将继续使用Tab键直到获得所需的缓冲区。)


实际上,我使用了上面的略微调整的版本:

nnoremap <C-e> :set nomore <Bar> :ls <Bar> :set more <CR>:b<Space>

-- More --当您的缓冲区多于可用行以显示缓冲区时,这将防止出现提示。

但是,如果您通常'more'无论如何都禁用了该选项,则此映射确实会让您感到烦恼,因为'more'这样做之后它会重新启用该选项ls


1
实话实说,我实际上并没有使用任何一个,而是使用了自己的小插件,但是功能非常相似。使用该插件,我还可以对未打开的缓冲区的文件名执行Tab补全。
joeytwiddle

1
尽管此技术不如[count]<C-^>您知道缓冲区号时使用的速度快,但当您不知道时它很有用。
joeytwiddle

2
谢谢joeytwiddle的笔记。我将尽快检查您的插件。就我而言(请参阅上面的键盘问题)[count]<C-6>在我看来是切换到已知缓冲区的最快方法
Giorgio Robino 2015年

是的,[count]<C-^>这些天我也在用。但这意味着我需要运行MiniBufExplorer或类似的东西,才能知道缓冲区号是多少!
joeytwiddle

为什么需要<CR>和<SPACE>?一开始,对我来说,好像没有它们就可以正常工作...
Felix Crazzolara

9

:CtrlPBuffer从插件CtrlP(4k★)

该插件的主要功能是提供模糊匹配,以方便地通过视觉反馈打开其他缓冲区。

打开模糊缓冲区上市:CtrlPBuffer或按<C-p>,然后<C-b>改变模式buffer

输入足够数量的字符以指定要打开的缓冲区。
您也可以使用<C-j><C-k>循环浏览列表并手动选择缓冲区。

在此处输入图片说明

客制化

如果您希望立即使用打开缓冲区列表<C-p>,请在vimrc中添加以下行:

let g:ctrlp_cmd = 'CtrlPBuffer'

您可以<C-f/b>用来切换ctrlp窗口的模式。

我个人使用let g:ctrlp_cmd = 'CtrlPMRU'。最近使用的(mru)列表还包含打开的缓冲区。如果您使用不同的ctrlp模式并希望坚持使用上一个模式,则可以设置let g:ctrlp_cmd = 'CtrlPLastMode [--dir]'

类似的插件

还有更多的插件可以提供带有模糊匹配的交互式提示的缓冲区列表,例如

黑暗的一面与光明的一面

(即插件繁重的vim设置与vim方式)

在决定使用这些更复杂的插件之前请先通过@Doorknob@joeytwiddle研究答案。特别是,检查其中一根衬垫是否已满足您的需求。

  1. nnoremap <Leader>b :b <C-d>
  2. nnoremap <Leader>b :ls<Cr>:b<Space>

仅为了切换缓冲区而安装插件可能是一个过大的杀伤力。另请参见https://www.vi-improved.org/recommendations上的评论以及Drew Neil的“锐化锯子”一文


是的,Hotschke,我承认我经常使用:CtrlPBuffer
Giorgio Robino

map <leader>a <ESC>:CtrlPBuffer<CR><CR>用来跳到以前打开的缓冲区<leader>a(而<leader>b只是为我打开缓冲区列表)
Rolf

@Rolf:您知道<C-^>(= <C-6>)吗?见:h CTRL-^。Afaik,这确实<leader>a可以完成您的映射似乎要做的事情。因此,我想您只是举了一个例子,为什么人们说使用插件可能导致不知道vim已经可以自己做什么的vim用户。
Hotschke

@Hotschke:不,我不知道。知道了些什么,谢谢!我要重新映射<C-^>。
罗尔夫(Rolf)'18

很好的参考<Cd>与香草vim。我在其他任何地方都没有看到该参考。
radke

8

除了joeytwiddle和Doorknob提供的真正有用的答案外,别忘了:b#,它会切换到最近使用的缓冲区。也可以用just完成<C-^>。当您有很多缓冲区并且经常在它们之间切换时,最近的缓冲区通常是最常见的目的地。

我个人使用多种方法的组合。当我主要使用两个缓冲区,而其余缓冲区只是为了偶尔参考而打开时,我倾向于使用:b#或在它们之间切换<C-^>。当我不得不使用更多的它们并更频繁地切换时,我可以使用带有TAB的数字(如joeytwiddle提示)或部分名称(如Doorknob提示)使用它们。当名称混乱时,并且打开了许多缓冲区(通常超过10个),我更频繁地使用Ctrl-P插件(https://github.com/kien/ctrlp.vim)通过两次快速按键,我得到了它们都可以,并且我能够对它们使用强大的模糊搜索来快速找到我想要的东西。


2
仅使用2个缓冲区时,单独使用<C-^>(在我的情况下为<C-6>,正如Peter Rincker所建议的那样)是一个好技巧:-)
Giorgio Robino 2015年

5

[b]b从插件vim-unimpaired(> 2k★)

如果碰巧已经安装了vim-unimpaired,可以使用

  • [b:bp[revious]
  • ]b:bn[ext]

用于循环打开缓冲区。无需为相同的命令定义更宝贵的映射。此外,跳转到第一个和最后一个缓冲区可以通过

  • [B:bf[irst])和
  • ]B:bl[ast])。

还有很多更支架的映射中包含vim-unimpaired,你可能会发现有用。它们都遵循相同的方案,因此容易记住它们。

黑暗的一面与光明的一面

这个插件可以被认为是轻量级的和“ vimish”的。#vim社区将其表示为“不伤害”插件。


+1还值得注意,您可以提供一个计数。3[b向后跳三个缓冲区。
joeytwiddle

1

目前,我正在使用<Leader>+ number键进行切换。领导者钥匙是我的<space>钥匙。我还使用vim-airline在窗口顶部显示缓冲区nr。

" airline settings
let g:airline#extensions#tabline#buffer_nr_show = 1
let g:airline#extensions#tabline#enabled = 1

尽管bufnr通常超过10,所以我调整了自己的映射,如果number唯一匹配,则立即切换缓冲区,否则等待更多数字输入或<space>键确认:

nnoremap <expr> <Leader>1 tweak#wtb_switch#key_leader_bufnum(1)
nnoremap <expr> <Leader>2 tweak#wtb_switch#key_leader_bufnum(2)
nnoremap <expr> <Leader>3 tweak#wtb_switch#key_leader_bufnum(3)
nnoremap <expr> <Leader>4 tweak#wtb_switch#key_leader_bufnum(4)
nnoremap <expr> <Leader>5 tweak#wtb_switch#key_leader_bufnum(5)
nnoremap <expr> <Leader>6 tweak#wtb_switch#key_leader_bufnum(6)
nnoremap <expr> <Leader>7 tweak#wtb_switch#key_leader_bufnum(7)
nnoremap <expr> <Leader>8 tweak#wtb_switch#key_leader_bufnum(8)
nnoremap <expr> <Leader>9 tweak#wtb_switch#key_leader_bufnum(9)




func! tweak#wtb_switch#key_leader_bufnum(num)
    let l:buffers = tweak#wtb_switch#buflisted()
    let l:input = a:num . ""

    while 1

        let l:cnt = 0
        let l:i=0
        " count matches
        while l:i<len(l:buffers)
            let l:bn = l:buffers[l:i] . ""
            if l:input==l:bn[0:len(l:input)-1]
                let l:cnt+=1
            endif
            let l:i+=1
        endwhile

        " no matches
        if l:cnt==0 && len(l:input)>0
            echo "no buffer [" . l:input . "]"
            return ''
        elseif l:cnt==1
            return ":b " . l:input . "\<CR>"
        endif

        echo ":b " . l:input

        let l:n = getchar()

        if l:n==char2nr("\<BS>") ||  l:n==char2nr("\<C-h>")
            " delete one word
            if len(l:input)>=2
                let l:input = l:input[0:len(l:input)-2]
            else
                let l:input = ""
            endif
        elseif l:n==char2nr("\<CR>") || (l:n<char2nr('0') || l:n>char2nr('9'))
            return ":b " . l:input . "\<CR>"
        else
            let l:input = l:input . nr2char(l:n)
        endif

        let g:n = l:n

    endwhile
endfunc

func! tweak#wtb_switch#buflisted()
  return filter(range(1, bufnr('$')), 'buflisted(v:val)')
endfunc

代码从这里粘贴

顺便说一句,我也用<S-h>,并<S-l>:bp:bn,或:tabp:tabn如果不止一个标签页是当前打开。对我来说很直观。


1

这些天,我一直[buffer_number]<Ctrl-^>在切换缓冲区,因为它非常快。

但是如何知道缓冲区编号?我使用MiniBufExplorer,所以我总是可以在Vim的顶部看到缓冲区号。

我还使用以下映射,因为<C-^>用一只手很难够到。

:nmap <C-E> <C-^>

在没有配置的新机器上,我回退到 :b [part_of_filename]<Tab><Enter>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.