Mostrar apenas linhas correspondentes?

31

Em um arquivo longo, eu gostaria de procurar um padrão que corresponda aproximadamente a 200 linhas. As linhas correspondentes estão em locais aleatórios no arquivo.
Quando uma linha corresponde, apenas a própria linha é relevante, sem contexto acima ou abaixo.

Normalmente, eu pesquisava /e pularia as correspondências com n.
Mas isso significa que há apenas uma ou duas linhas relevantes na tela por vez.

Existe uma maneira de ocultar todas as linhas que não correspondem, enquanto percorre a lista de linhas de resultados?


Uma abordagem de força bruta seria excluir todas as linhas não correspondentes e desfazer essa exclusão posteriormente. Mas isso é feio de várias maneiras, mesmo que não acabe em desfazer persistente ...

Volker Siegel
fonte

Respostas:

34
:vimgrep pattern %
:cwin

vimgrepprocurará seu padrão no arquivo atual ( %) ou nos arquivos que você especificar.

cwinirá abrir um buffer na sua janela que mostrará apenas as linhas desejadas. Você pode usar praticamente qualquer comando de navegação / pesquisa no cwinbuffer. Pressione return para pular para a linha abaixo do cursor no arquivo de origem.

Zach Ingbretsen
fonte
1
:vimgreppode ser abreviado para:vim
D. Ben Knoble
como faço para voltar ao buffer novamente?
pasha
Também como fecho o buffer? agradece antecipadamente #
pasha
No buffer do quickfix (cwindow), você pode pressionar return em qualquer linha para ir para esse local no buffer original. Você pode fechar o buffer do cwindow de qualquer lugar :ccl[ose]ou normalmente fecha um buffer (por exemplo, alterne para ele e :bd). Você pode reabrir o buffer do quickfix executando :cw[indow]novamente e ele usará seus últimos resultados do vimgrep.
Zach Ingbretsen 23/03
15

Você pode listar todas as linhas correspondentes com

:g/{pattern}

(O :printcomando pode ser omitido; é o padrão para :g.)

Ingo Karkat
fonte
1
Este é o "grep original" ( g/REgexp/p) ... O problema é que você não pode pular facilmente para uma das partidas ...
Martin Tournoij
@Carpetsmoker: Você está certo; por isso, eu tenho um plugin, veja minha outra resposta.
Ingo Karkat 28/02
Isso pode ser útil para muitos casos. A saída pode ser redirecionada para um novo buffer? Isso permitiria ainda ter destaque de sintaxe nas linhas. (Hmm ... que levanta outra questão, espere um segundo ...)
Volker Siegel
@IngoKarkat qual é o significado de g. Presumo que seja um padrão global. Eu costumo fazer uma pesquisa VI com uma barra /patterne isso encontraria todas as ocorrências. Pode-se navegar até eles pressionando a letran
Alexander Cska
@AlexanderCska: Não, não é um modificador para pesquisa, mas um comando separado :g[lobal]que assume um padrão como argumento. Você encontrará todos os detalhes em :help :global.
Ingo Karkat 13/06
12

Você pode usar as opções foldmethode foldexprpara dobrar linhas irrelevantes.

Após a pesquisa, a última pesquisa é armazenada no @/registro. Portanto, você pode facilmente dobrar tudo o que não corresponde dessa maneira (apenas para correspondências de uma linha):

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

Métodos mais avançados, como adicionar vários níveis de dobra para linhas de contexto que você pode mostrar ou ocultar ou combinar várias linhas, podem ser encontrados no Wiki de dicas do Vim .

Ben
fonte
Parece que é set foldlevel=0necessário? Mas talvez seja o padrão.
Volker Siegel
1
Sim, o padrão é zero, mas se não funcionar sem, adicioná-lo não será prejudicial. :-)
Ben
Mas agora ... como mudar novamente, sem deixar vestígios?
Volker Siegel
no modo normal, você pode usar 'zi' para ativar e desativar a dobra.
John O'M.
Na maioria das vezes, quando faço isso, primeiro :tab spobtenho uma nova exibição descartável no arquivo. Então, voltar é tão simples quanto :closeou qualquer outra maneira de eliminar a guia.
28415 Ben
6

Se a ordem não importa, basta mover as linhas.

:g/pat/m0

Para obter mais ajuda, consulte:

:h :g
:h :m
Peter Rincker
fonte
1
E :g/pat/m$(mover as linhas adaptado à extremidade) também é OK,
Lerner Zhang
6

[d] elimina todas as linhas que não (!) correspondem aos padrões:

:g!/pattern/d

ou ainda mais simples (obrigado pelos comentários de 'Camada B'):

:v/pattern/d
Kevin Liu
fonte
Sim, mas é mais convencional usar o equivalente :vdo que :g!. (Não me lembro a última vez que eu vi o último utilizado, TBH!)
B Camada
2

Se você deseja listar todas as linhas correspondentes (como na minha outra resposta) e pular para uma correspondência específica, meu plug-in FindOccurrence fornece um [/mapeamento para isso (e [npara o último padrão de pesquisa, em vez de procurar por uma). [/patternlista como :g/pattern, mas depois pede o número da correspondência para a qual saltar.

Ingo Karkat
fonte
0

Outra maneira é usar :h :ilist, eu uso para obter uma visão geral da página de manual. seu resultado fica assim:

~/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

Aqui está uma pequena função que permite escolher ir para a linha de resultado por índice:

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

Pode ser usado assim:

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