Afficher uniquement les lignes correspondantes?

31

Dans un long fichier, je voudrais rechercher un modèle qui correspondra à environ 200 lignes. Les lignes correspondantes se trouvent à des emplacements aléatoires dans le fichier.
Lorsqu'une ligne correspond, seule la ligne elle-même est pertinente, pas de contexte au-dessus ou en dessous.

Normalement, je cherchais /et sautais les matchs avec n.
Mais cela signifie qu'il n'y a qu'une ou deux lignes pertinentes à l'écran à la fois.

Existe-t-il un moyen de masquer toutes les lignes qui ne correspondent pas, tout en parcourant la liste des lignes de résultat?


Une approche par force brute serait de supprimer toutes les lignes qui ne correspondent pas et d'annuler cette suppression plus tard. Mais c'est moche à bien des égards, même si cela ne finirait pas par une annulation persistante ...

Volker Siegel
la source

Réponses:

34
:vimgrep pattern %
:cwin

vimgreprecherchera votre modèle dans le fichier actuel ( %) ou dans les fichiers que vous spécifiez.

cwinouvrira alors un tampon dans votre fenêtre qui n'affichera que les lignes souhaitées. Vous pouvez utiliser à peu près n'importe quelle commande de navigation / recherche dans le cwintampon. Appuyez sur Retour pour passer à la ligne sous votre curseur dans le fichier source.

Zach Ingbretsen
la source
1
:vimgreppeut être abrégé en:vim
D. Ben Knoble
comment puis-je revenir au tampon?
pasha
aussi comment fermer le tampon? merci d'avance
pasha
À partir du tampon quickfix (cwindow), vous pouvez appuyer sur retour sur n'importe quelle ligne pour accéder à cet emplacement dans le tampon d'origine. Vous pouvez fermer le tampon cwindow de n'importe où avec :ccl[ose]ou comme vous le fermez normalement (par exemple, basculez dessus et :bd). Vous pouvez rouvrir le tampon quickfix en exécutant à :cw[indow]nouveau, et il utilisera vos derniers résultats vimgrep.
Zach Ingbretsen
15

Vous pouvez répertorier toutes les lignes correspondantes avec

:g/{pattern}

(La :printcommande peut être omise; c'est la valeur par défaut pour :g.)

Ingo Karkat
la source
1
Ceci est le "grep original" ( g/REgexp/p) ... Le problème est que vous ne pouvez pas facilement accéder à l'un des matchs, cependant ...
Martin Tournoij
@Carpetsmoker: Vous avez raison; pour cela, j'ai un plugin, voir mon autre réponse.
Ingo Karkat du
Cela pourrait être utile dans de nombreux cas. La sortie peut-elle être redirigée vers un nouveau tampon? Cela permettrait d'avoir encore une coloration syntaxique sur les lignes. (Hmm ... cela soulève une autre question, attendez une seconde ...)
Volker Siegel
@IngoKarkat quel est le sens du g. Je suppose que c'est un modèle global. Je fais habituellement une recherche VI avec une barre oblique /patternet cela trouverait toutes les occurrences. On peut y accéder en appuyant sur la lettren
Alexander Cska
@AlexanderCska: Non, ce n'est pas un modificateur pour la recherche, mais une commande distincte :g[lobal]qui prend un modèle comme argument. Vous trouverez tous les détails sur :help :global.
Ingo Karkat
12

Vous pouvez utiliser les options foldmethodet foldexprpour replier les lignes non pertinentes.

Après la recherche, la dernière recherche est enregistrée dans le @/registre. Ainsi, vous pouvez facilement replier tout ce qui ne correspond pas comme ceci (pour les correspondances sur une seule ligne):

:setlocal foldexpr=getline(v:lnum)=~@/?0:1 foldmethod=expr

Des méthodes plus avancées, comme l'ajout de plusieurs niveaux de pliage pour les lignes de contexte que vous pouvez afficher ou masquer, ou la mise en correspondance de plusieurs lignes, peuvent être trouvées sur le wiki Vim Tips .

Ben
la source
On dirait qu'il y a un set foldlevel=0besoin? Mais c'est peut-être par défaut.
Volker Siegel
1
Oui, la valeur par défaut est zéro, mais si cela ne fonctionne pas sans, l'ajout ne peut pas faire de mal. :-)
Ben
Mais maintenant ... comment le réactiver, sans aucune trace?
Volker Siegel
en mode normal, vous pouvez utiliser «zi» pour activer et désactiver le pliage.
John O'M.
La plupart du temps, lorsque je fais cela, je commence :tab sppar obtenir une nouvelle vue jetable sur le fichier. Revenir en arrière est aussi simple que :closen'importe quelle autre façon de tuer l'onglet.
Ben
6

Si l'ordre n'a pas d'importance, déplacez simplement les lignes.

:g/pat/m0

Pour plus d'aide, voir:

:h :g
:h :m
Peter Rincker
la source
1
Et :g/pat/m$(déplacer les lignes correspondantes à la fin) est également OK,
Lerner Zhang
6

[d] supprime toutes les lignes qui ne correspondent pas (!) aux motifs:

:g!/pattern/d

ou encore plus simple (merci pour les commentaires de 'B Layer'):

:v/pattern/d
Kevin Liu
la source
Oui, mais c'est plus conventionnel d'utiliser l'équivalent :vplutôt que :g!. (Je ne me souviens pas de la dernière fois où j'ai vu ce dernier utilisé, TBH!)
B Layer
2

Si vous souhaitez répertorier toutes les lignes correspondantes (comme dans mon autre réponse), puis passer à une correspondance particulière, mon plug-in FindOccurrence fournit un [/mappage pour cela (et [npour le dernier modèle de recherche, au lieu d'en demander une). [/patternliste comme :g/pattern, mais demande ensuite le numéro du match auquel aller.

Ingo Karkat
la source
0

Une autre façon consiste à utiliser :h :ilist, je l'utilise pour obtenir un aperçu de la page de manuel. son résultat ressemble à ceci:

~/find.~
  1:    3 NAME
  2:    6 SYNOPSIS
  3:    9 DESCRIPTION
  4:   18 OPTIONS
  5:   93 EXPRESSION
  6:  779 EXAMPLES
  7:  877 HISTORY
  8:  931 BUGS

Voici une petite fonction qui vous permet de choisir d'aller à la ligne de résultat par index:

function! s:select_ilist(ilist_result)
  if empty(a:ilist_result) || a:ilist_result =~# '^\_s*Error'
    return
  endif

  let select = input(a:ilist_result . "\ngoto : ")
  if empty(select) | return | endif

  " ilist result starts with '\nfilename\n', filename can be empty
  let lines = split(a:ilist_result[stridx(a:ilist_result, "\n", 1) : ], "\n")
  if select <= 0 || select > len(lines) | return | endif

  exec matchstr(lines[select-1], '^\v\s*\d+\:\s+\zs\d+')
endfunction

Il peut être utilisé comme ceci:

command! -buffer Section call s:select_ilist(execute('silent! ilist /\v\C^[A-Z][^a-z]+$/'))
dedowsdi
la source