Самый быстрый способ переключиться на буфер в Vim?


43

Одним из способов выбора буфера в vim может быть просмотр списка буферов с использованием стандартных команд as :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-^>.

Но это, кажется, не работает для меня (я использую vim 7.4 на Ubuntu Box, от гостя Windows, с итальянской клавиатурой ). Я подозреваю, что это потому, что ^символ находится в верхнем регистре клавиши на итальянской клавиатуре, так что на самом деле, чтобы получить ^мне нужно нажатьSHIFT-^

Любые идеи?


2
Можешь нажать <c-6>вместо <c-^>?
Питер Ринкер

Вы имеете в виду Ctrl-1, чтобы перейти к буферу № 1? К сожалению, не работает. ничего не происходит
Джорджио Робино

1
Нет. Некоторые терминалы могут понимать Ctrl-6, который совпадает с Ctrl- ^ на клавиатуре США.
Питер Ринкер

2
+1 Отлично, это работает! Я использую итальянскую раскладку клавиатуры (используя эмулятор терминала замазки). Итак: 1<C-6>переключается на буфер №1. Спасибо!
Джорджио Робино,

Вы можете попробовать использовать CtrlSpace .
Хунбо Лю

Ответы:


52

Команда :bтакже может взять подстроку имени файла буфера, к которому вы хотите перейти, что очень удобно.

Например, если у вас есть три буфера foo, barи baz, затем

  • :b barпереключится на barфайл.

  • :b oпереключится на fooфайл.

  • :b aдаст вам ошибку, потому что это может означать либо barили baz, но вы можете исправить имя, чтобы быть более конкретным, например, с : r Enter.

Это может быть очень полезно, потому что вместо

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

вы можете сделать что-то вроде

:b LongFileName

что намного короче и проще.

Эта команда также может принимать число, если вы хотите использовать это:

:b 5

8
Предостережение об использовании частичных имен буферов: если частичное имя буфера появляется в начале границы слова в пути некоторого буфера, :bкоманда не сможет использовать буфер с частичным именем в середине слова . Например, если у вас есть два буфера path/to/fooи path/to/tofu, команда :b f<Tab>никогда не будет соответствовать path/to/tofu, так как она совпадает в начале слова в path/to/foo.
Tommcdo

2
:5bнемного короче :b 5 ;-)
joeytwiddle

16

Это то, что я использую:

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

Теперь нажатие \bбудет список доступных буферов и подготовить :bдля вас.

Затем вы можете просто ввести номер буфера и нажать Enter.

Или вы можете ввести часть имени файла и нажать Enter. (Однако я обычно нажимаю клавишу Tab, прежде чем нажимать Enter, чтобы проверить, что я получил правильный буфер. Если нет, я продолжаю ездить на велосипеде с Tab, пока не получу тот, который хотел.)


На самом деле, я использую слегка подправленную версию выше:

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

Это предотвратит появление -- More --запроса, когда у вас будет больше буферов, чем доступных строк для их отображения.

Но если у вас 'more'все равно отключена опция, это отображение действительно вас раздражает, потому что 'more'после этого она снова включается ls!


1
По правде говоря, я на самом деле не использую ни одного из них, я использую свой собственный маленький плагин , но функциональность очень похожа. С помощью плагина я также могу выполнить Tab-complete для имен файлов неоткрытых буферов.
Joeytwiddle

1
Хотя этот метод не такой быстрый, как при использовании, [count]<C-^>когда вы знаете номер буфера, он довольно полезен, когда вы не знаете.
Joeytwiddle

2
спасибо joeytwiddle за ваши заметки. Я проверю ваш плагин как можно скорее. В моем случае (см. Проблему с клавиатурой выше) [count]<C-6>мне представляется самый быстрый способ переключения на известный буфер
Джорджио Робино

Да, я также использую [count]<C-^>эти дни. Но это означает, что мне нужно запустить MiniBufExplorer или что-то подобное, чтобы знать, что такое номера буфера!
Joeytwiddle

зачем вам <CR> и <SPACE>? Сначала мне кажется, что без них все работает нормально ...
Феликс Краззолара

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>для переключения режима окна Ctrl.

Я лично пользуюсь 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 и статью Дрю Нейла «О заточке пилы» .


да Хотшке, признаюсь, я часто использую: CtrlPBuffer
Джорджио

Я использую, map <leader>a <ESC>:CtrlPBuffer<CR><CR>чтобы перейти к ранее открытому буферу с <leader>a(пока <leader>bпросто открывает список буферов для меня)
Rolf

@ Рольф: ты знаешь <C-^>(= <C-6>)? см :h CTRL-^. Афаик, это просто делает то, что, <leader>aкажется, делает твое отображение . Поэтому я думаю, что вы только что привели пример, почему люди говорят, что использование плагинов может привести к пользователю vim, который не знает, что vim уже может делать сам по себе.
Хотчке

@Hotschke: Нет, я этого не знал. Узнал что-то знал, спасибо! Я собираюсь переназначить <C - ^> хотя.
Рольф

1
Отличная ссылка на <Cd> с ванильным vim. Я не видел эту ссылку нигде.
Радке

8

В дополнение к действительно полезным ответам от joeytwiddle и Doorknob не забывайте о том :b#, что переключается на последний использованный буфер. Это также можно сделать просто <C-^>. Когда у вас много буферов и вы постоянно переключаетесь между ними, самый последний буфер обычно является наиболее распространенным местом назначения.

Лично я использую сочетание многих методов. Когда я работаю в основном с двумя буферами, а остальные открываются просто для случайного обращения, я склонен переключаться между ними с помощью :b#или <C-^>. Когда мне приходится работать с большим количеством из них и переключаться чаще, я использую либо цифры (как в подсказке joeytwiddle), либо часть имен (как в подсказке ручки двери) с TAB для их завершения. Когда имена сбивают с толку, и открыто много буферов (обычно более 10), я чаще использую плагин Ctrl-P ( https://github.com/kien/ctrlp.vim ) С двумя быстрыми нажатиями клавиш я получил список их всех, и я могу использовать мощный нечеткий поиск по ним, чтобы быстро найти то, что я хочу.


2
<C - ^> один (<C-6> в моем случае, как предположил Питер Ринкер) является хорошим трюком в случае только двух буферов :-)
Джорджио Робино

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-Airlines, чтобы показать буфер 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>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.