Как искать открытые буферы в Vim?
Я бы хотел найти текст во всех файлах, открытых в настоящее время в vim, и отображать все результаты в одном месте. Я думаю, есть две проблемы:
- Я не могу передать список открытых файлов в
:grep
/:vim
, особенно имена файлов, которые не находятся на диске;
- Результат
:grep -C 1 text
выглядит не очень хорошо в окне quickfix.
Вот хороший пример поиска нескольких файлов в Sublime Text 2: ![enter image description here]()
Любые идеи?
Ответы
Ответ 1
или
:bufdo vimgrepadd threading % | copen
Окно quickfix может показаться вам нехорошо, но оно намного более функционально, чем панель результатов "ST2", хотя бы потому, что вы можете держать ее открытой и видимой при переходе к местоположениям и взаимодействовать с ней, если она там отсутствует.
Ответ 2
ack и Ack.vim обрабатывать эту проблему красиво, Вы также можете использовать :help :vimgrep
. Например:
:bufdo AckAdd -n threading
создаст хорошее окно быстрого нажатия, которое позволит вам перейти к позиции курсора.
Ответ 3
Я сделал эту функцию давным-давно, и я предполагаю, что это, вероятно, не самый чистый из решений, но это было полезно для меня:
" Looks for a pattern in the open buffers.
" If list == 'c' then put results in the quickfix list.
" If list == 'l' then put results in the location list.
function! GrepBuffers(pattern, list)
let str = ''
if (a:list == 'l')
let str = 'l'
endif
let str = str . 'vimgrep /' . a:pattern . '/'
for i in range(1, bufnr('$'))
let str = str . ' ' . fnameescape(bufname(i))
endfor
execute str
execute a:list . 'w'
endfunction
" :GrepBuffers('pattern') puts results into the quickfix list
command! -nargs=1 GrepBuffers call GrepBuffers(<args>, 'c')
" :GrepBuffersL('pattern') puts results into the location list
command! -nargs=1 GrepBuffersL call GrepBuffers(<args>, 'l')
Ответ 4
Как и ответ Waz, я написал для этого специальные команды, опубликованные в моем плагине GrepCommands. Он позволяет искать буферы (:BufGrep
), видимые окна (:WinGrep
), вкладки и аргументы.
(Но, как и все другие ответы, он еще не обрабатывает неназванные буферы.)
Ответ 5
Улучшенная версия (по стероидам) ответа Waz, с лучшим поиском буфера и обработкой особых случаев, может быть найдена ниже (модераторы не позволят мне обновить Waz-ответ больше: D).
Более сложная версия с привязками для клавиш со стрелками для навигации по списку QuickFix и F3 для закрытия окна QuickFix можно найти здесь: https://pastebin.com/5AfbY8sm
(Когда мне хочется выяснить, как сделать плагин, я обновлю этот ответ. Я хотел бы ускорить его совместное использование)
" Looks for a pattern in the buffers.
" Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]
" If pattern is not specified then usage instructions will get printed.
" If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
" If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
function! s:GrepBuffers(...)
if a:0 > 4
throw "Too many arguments"
endif
if a:0 >= 1
let l:pattern = a:1
else
echo 'Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]'
return
endif
let l:matchCase = 0
if a:0 >= 2
if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
endif
let l:matchCase = a:2
endif
let l:matchWholeWord = 0
if a:0 >= 3
if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
endif
let l:matchWholeWord = a:3
endif
let l:prefix = 'c'
if a:0 >= 4
if a:4 != 'c' && a:4 != 'l'
throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
endif
let l:prefix = a:4
endif
let ignorecase = &ignorecase
let &ignorecase = l:matchCase == 0
try
if l:prefix == 'c'
let l:vimgrep = 'vimgrep'
elseif l:prefix == 'l'
let l:vimgrep = 'lvimgrep'
endif
if l:matchWholeWord
let l:pattern = '\<' . l:pattern . '\>'
endif
let str = 'silent ' . l:vimgrep . ' /' . l:pattern . '/'
for buf in getbufinfo()
if buflisted(buf.bufnr) " Skips unlisted buffers because they are not used for normal editing
if !bufexists(buf.bufnr)
throw 'Buffer does not exist: "' . buf.bufnr . '"'
elseif empty(bufname(buf.bufnr)) && getbufvar(buf.bufnr, '&buftype') != 'quickfix'
if len(getbufline(buf.bufnr, '2')) != 0 || strlen(getbufline(buf.bufnr, '1')[0]) != 0
echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . buf.bufnr . ']' | echohl normal
endif
else
let str = str . ' ' . fnameescape(bufname(buf.bufnr))
endif
endif
endfor
try
execute str
catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
" How do you want to handle this exception?
echoerr v:exception
return
endtry
execute l:prefix . 'window'
"catch /.*/
finally
let &ignorecase = ignorecase
endtry
endfunction