Je souhaite rechercher du texte dans tous les fichiers actuellement ouverts dans vim et afficher tous les résultats au même endroit. Il y a deux problèmes, je suppose:
:grep
/:vim
, en particulier les noms des fichiers qui ne sont pas sur le disque;:grep -C 1 text
ne semble pas bon dans la fenêtre de correction rapide.Voici un bel exemple de recherche de fichiers multiples dans Sublime Text 2:
Des idées?
Ou
:bufdo vimgrepadd threading % | copen
La fenêtre de correction rapide ne vous convient peut-être pas, mais elle est beaucoup plus fonctionnelle que le "panneau de résultats" de ST2, ne serait-ce que parce que vous pouvez la garder ouverte et visible lorsque vous vous déplacez et que vous pouvez interagir avec elle si elle n'y est pas.
Comme la réponse de Waz, j’ai écrit pour cela des commandes personnalisées, publiées dans mon plugin GrepCommands . Il permet de rechercher dans les tampons (:BufGrep
), les fenêtres visibles (:WinGrep
), les onglets et les arguments.
(Mais comme toutes les autres réponses, il ne gère pas encore les tampons non nommés.)
J'ai créé cette fonction il y a longtemps, et j'imagine que ce n'est probablement pas la solution la plus propre, mais elle m'a été utile:
" 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')
Une version améliorée (sur les stéroïdes) de la réponse de Waz, avec une meilleure recherche dans la mémoire tampon et un traitement spécial des cas, se trouve ci-dessous (les modérateurs ne me permettraient plus de mettre à jour la réponse de Waz: D). Une version plus détaillée. avec des liens pour les touches de direction pour naviguer dans la liste de corrections rapides et F3 pour fermer la fenêtre de corrections rapides peut être trouvé ici: https://Pastebin.com/5AfbY8sm (Quand j’ai envie de trouver comment faire un plugin je vais mettre à jour cette réponse. Je voulais accélérer le partage pour le moment)
" 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