Comment afficher les résultats de recherche pour tous les tampons ouverts

17

Une chose que je fais souvent (mais je me fie à la ligne de commande pour le faire) est la recherche / l'accueil dans plusieurs fichiers.

Existe-t-il un moyen d'afficher les résultats de recherche pour tous les tampons ouverts?

Idéalement, j'aimerais avoir un nouveau tampon fractionné contenant l'emplacement des résultats et un extrait tout comme le grepfait. Par exemple ( /statistics):

models/statistics.php: /*! \file   statistics.php
controllers/stats.php: $this->load->model('statistics');
controllers/stats.php: // Query statistics...
controllers/stats.php: $num_exams = $this->statistics->countExams();

En prime, j'aimerais pouvoir rechercher le terme sous le curseur, un peu comme le gdfait.

Roflo
la source
2
stackoverflow.com/questions/11975174/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Réponses:

15

Vous pouvez utiliser :vimgrep /pattern/ {files}pour remplir la liste de correctifs rapides avec des modèles correspondants. Le problème est que l' :vimgrepoption fichiers ne permet pas directement les tampons. Vous pouvez utiliser:

%   Is replaced with the current file name.       *:_%* *c_%*
#   Is replaced with the alternate file name.     *:_#* *c_#*
#n  (where n is a number) is replaced with        *:_#0* *:_#n*
    the file name of buffer n.  "#0" is the same as "#".     *c_#n*
##  Is replaced with all names in the argument list   *:_##* *c_##*
    concatenated, separated by spaces.  Each space in a name
    is preceded with a backslash.
#<n (where n is a number > 0) is replaced with old    *:_#<* *c_#<*
    file name n.  See |:oldfiles| or |v:oldfiles| to get the
    number.                         *E809*
    {only when compiled with the |+eval| and |+viminfo| features}

Une autre option consiste à écrire un script qui génère une liste de fichiers à partir de :buffers. Par ce poste SO avec un léger tweek nous obtenons:

function! BuffersList()
  let all = range(0, bufnr('$'))
  let res = []
  for b in all
    if buflisted(b)
      call add(res, bufname(b))
    endif
  endfor
  return res
endfunction

function! GrepBuffers (expression)
  exec 'vimgrep/'.a:expression.'/ '.join(BuffersList())
endfunction

command! -nargs=+ GrepBufs call GrepBuffers(<q-args>)

Vous pouvez maintenant appeler :GrepBufs <expression>et obtenir la :vimgrepsortie standard mais en utilisant les tampons à la place.

Mettre à jour Si vous souhaitez appeler en GrepBuffersutilisant la valeur sous le curseur, ajoutez ce nouveau mappage.

nnoremap <leader>z :call GrepBuffers("<C-R><C-W>")<CR>

Lorsque vous êtes en mode normal, <leader>zvous passez :vimgreple curseur sur vos tampons ouverts.

jecxjo
la source
2
Sous forme d'une seule ligne: command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' '). Utilisation::Bufgrep/foo/
Peter Rincker
8

La recherche dans les tampons ouverts uniquement est agréable, mais il peut arriver un moment où vous souhaitez rechercher dans un projet entier. Cela peut être plus rapide et plus facile que vous ne le pensez!

Recherche dans un projet

  • grepest l'outil de recherche standard Unix. Il convient de le mentionner en raison de son omniprésence. Déjà intégré dans Vim via la :grepcommande. par exemple :grep -r 'foo'. Tu vois :h :grep.
  • Ack est plus rapide que grep normal car il ignore les répertoires VCS, les fichiers binaires et peut rechercher des types de fichiers spécifiques comme --perl. Pour l'intégration de Vim, voir Ack.vim
  • Ag the Silver Surfer est un outil de recherche de code similaire à ack, mais plus rapide. Plugin Vim: Ag.vim
  • git greprecherche un référentiel très rapidement. Fugitive.vim fournit :Ggrep.
  • Ripgrep est encore plus rapide que Ag et git grep. Peut également être utilisé avec :grep.

Je recommande à la fois ripgrep, Ag et git grepcomme ils sont tous super rapides. J'ai cherché plus de 4700+ en moins d'une seconde. Il est assez difficile de battre ripgrep.

Pour tester l'une de ces alternatives sans plugin ou si vous ne voulez tout simplement pas de plugin, vous pouvez définir votre 'grepprg'option en conséquence. par exemple set grepprg=ag\ --vimgrepou set grepprg=rg\ --vimgrep. Voir :h 'grepprg'et :h 'grepformat'pour plus d'informations. Vous pouvez maintenant rechercher via :grep. par exemple :grep 'foo'.

Comme solution de rechange finale, vous pouvez l'utiliser :vimgrepcar elle est disponible sur tous les systèmes disponibles sur Vim. Voir :h :vimgpour plus d'aide.

Liste QuickFix

Comme la plupart de ces options utilisent la liste quickfix, je vous suggère d'utiliser des mappages plus conviviaux pour traverser la liste quickfix. J'utilise le plugin intact de Tim Pope qui utilise ]qet [qpour :cnextet :cprevrespectivement. Certaines personnes aiment le quickfix d'ouvrir après une recherche est effectuée , puis ajouter ce qui suit à votre ~/.vimrcfichier: autocmd QuickFixCmdPost *grep* cwindow. Vous pouvez également ouvrir manuellement la liste QuickFix via :copen.

Vous voulez des "recherches" encore plus rapides?

Vous allez avoir besoin d'utiliser un outil qui utilise des index prédéfinis comme ctags , cscope ou GNU global .

  • Vim a construit à l' appui CTAG via :tag, <c-]>et beaucoup d' autres commandes et options. Tu vois :h tags. Vous pouvez également vouloir lire les Ctags sans effort avec Git ou regarder le plugin Gutentags
  • La prise en charge de Cscope est également intégrée et peut être utilisée via une :cscopecommande. Voir:h cscope

Plus d'aide

Je commencerais par ce bel épisode de Vimcast : Rechercher plusieurs fichiers avec:vimgrep .

Pour plus d'aide sur Vim, consultez la documentation:

:h grep
:h :vimgrep
:h :grep
:h 'grepprg'
:h 'grepformat'
:h quickfix
:h :cnext
:h tags
:h cscope
Peter Rincker
la source
6

Mon plugin GrepCommands définit des variantes de la :vimgrepcommande intégrée qui ciblent tous les arguments, les tampons répertoriés, les fenêtres de la page à onglet actuelle ou toutes les pages à onglet pour sa recherche. Fondamentalement, une implémentation de plugin robuste de la réponse de @ jecxjo.

Ingo Karkat
la source
1

Commandes :bufdoet:vimgrepadd

Cette réponse est basée sur /programming//a/11976158/1057593 .

Cependant, je voulais ajouter quelques bits. Encore une fois, la commande de base est

:bufdo vimgrepadd pattern %

Si votre liste de correctifs rapides n'est pas vide, vous souhaiterez probablement la supprimer en premier (voir /programming//q/27385970/1057593 ). Cela peut être fait avec

:cexpr []

vim-unimpaired fournit les mappages ]qet fait [qdéfiler les correspondances.

cmdline-history

C'est un bon flux de travail pour entrer le modèle de recherche séparément avec /pattern. Cela vous permet d'utiliser une commande générique de votre historique de ligne de commande en utilisant le modèle de recherche actuel. Cela ressemblerait à

/pattern
:bufdo vimgrepadd // %

Une nouvelle recherche typique à l’échelle du tampon serait

/pattern2
:bufdo<up><up>...

J'ai ajouté les mappages suivants à mon vimrc à utiliser <C-N>et <C-P>au lieu des touches fléchées

cmap <C-P> <Up>
cmap <C-N> <Down>

Pour rechercher l'historique des commandes q:, utilisez , puis /bufdo<CR>et appelez une commande avec <CR>. Pour plus de détails, voir https://vim.fandom.com/wiki/Using_command-line_history et les pages d'aide :h historyet :h cmdline-window.

Vous pouvez ajouter à la commande réutilisable :copenpour voir immédiatement la liste de correctifs de la manière suivante:

:execute "bufdo vimgrepadd // %" | copen

La proposition de stackoverflow a :bufdo vimgrepadd // % | copenouvert plusieurs fenêtres involontaires dans mon cas.

Hotschke
la source