Tampilkan hanya garis yang cocok?

31

Dalam file yang panjang, saya ingin mencari pola yang akan cocok dengan sekitar 200 baris atau lebih. Baris yang cocok berada di tempat acak dalam file.
Ketika sebuah baris cocok, hanya baris itu sendiri yang relevan, tidak ada konteks di atas atau di bawah.

Biasanya, saya akan mencari /dan melompati pertandingan dengan n.
Tetapi itu berarti hanya ada satu atau dua garis yang relevan pada layar sekaligus.

Apakah ada cara untuk menyembunyikan semua baris yang tidak cocok, saat menelusuri daftar baris hasil?


Pendekatan brute force akan menghapus semua garis yang tidak cocok, dan membatalkan penghapusan itu nanti. Tapi itu jelek dalam berbagai cara, bahkan jika itu tidak akan berakhir dengan gigih ...

Volker Siegel
sumber

Jawaban:

34
:vimgrep pattern %
:cwin

vimgrepakan mencari pola Anda di file saat ini ( %), atau file apa pun yang Anda tentukan.

cwinkemudian akan membuka buffer di jendela Anda yang hanya akan menampilkan garis yang diinginkan. Anda dapat menggunakan hampir semua perintah navigasi / pencarian di dalam cwinbuffer. Tekan kembali untuk melompat ke garis di bawah kursor Anda di file sumber.

Zach Ingbretsen
sumber
1
:vimgrepdapat disingkat menjadi:vim
D. Ben Knoble
bagaimana saya kembali ke buffer lagi?
pasha
juga bagaimana cara menutup buffer? terima kasih sebelumnya
pasha
Dari buffer perbaikan cepat (cwindow) Anda dapat menekan return pada baris apa saja untuk melompat ke lokasi itu di buffer asli. Anda dapat menutup buffer cwindow dari mana saja dengan :ccl[ose]atau namun Anda biasanya menutup buffer (mis., Beralih ke sana dan :bd). Anda dapat membuka kembali penyangga perbaikan cepat dengan menjalankannya :cw[indow]lagi, dan itu akan menggunakan hasil vimgrep terakhir Anda.
Zach Ingbretsen
15

Anda dapat membuat daftar semua baris yang cocok dengan

:g/{pattern}

( :printPerintah dapat dihilangkan; ini adalah default untuk :g.)

Ingo Karkat
sumber
1
Ini adalah "grep asli" ( g/REgexp/p) ... Masalahnya adalah Anda tidak dapat dengan mudah melompat ke salah satu pertandingan, ...
Martin Tournoij
@Carpetsmoker: Anda benar; untuk itu, saya punya plugin, lihat jawaban saya yang lain.
Ingo Karkat
Itu bisa berguna untuk banyak kasus. Bisakah output diarahkan ke buffer baru? Itu akan memungkinkan untuk tetap memiliki penyorotan sintaks pada baris. (Hmm ... itu menimbulkan pertanyaan lain, tunggu sebentar ...)
Volker Siegel
@IngoKarkat apa artinya itu g. Saya berasumsi bahwa ini adalah pola global. Saya biasanya melakukan pencarian VI dengan garis miring /patterndan ini akan menemukan semua kejadian. Orang dapat menavigasi ke mereka dengan menekan surat itun
Alexander Cska
@AlexanderCska: Tidak, ini bukan pengubah untuk pencarian, tetapi perintah terpisah :g[lobal]yang mengambil pola sebagai argumen. Anda akan menemukan semua detail di :help :global.
Ingo Karkat
12

Anda dapat menggunakan opsi foldmethoddan foldexpruntuk melipat garis yang tidak relevan.

Setelah mencari, pencarian terakhir disimpan dalam @/register. Jadi, Anda dapat dengan mudah melipat semua yang tidak cocok dengan ini (hanya untuk satu baris):

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

Metode yang lebih maju, seperti menambahkan beberapa tingkat lipat untuk garis konteks yang dapat Anda tampilkan atau sembunyikan, atau cocokkan beberapa baris, dapat ditemukan di Vim Tips Wiki .

Ben
sumber
Sepertinya ada yang set foldlevel=0dibutuhkan? Tapi mungkin itu standar.
Volker Siegel
1
Ya defaultnya adalah nol, tetapi jika tidak berfungsi tanpanya, menambahkannya tidak ada salahnya. :-)
Ben
Tapi sekarang ... bagaimana cara mengembalikannya kembali, tanpa jejak?
Volker Siegel
dalam mode normal, Anda dapat menggunakan 'zi' untuk mematikan dan mematikannya.
John O'M.
Sebagian besar waktu ketika saya melakukan ini, saya pertama kali :tab spmendapatkan tampilan membuang baru pada file. Lalu kembali sesederhana :closeatau cara lain untuk membunuh tab.
Ben
6

Jika pesanan tidak masalah maka hanya memindahkan garis.

:g/pat/m0

Untuk bantuan lebih lanjut lihat:

:h :g
:h :m
Peter Rincker
sumber
1
Dan :g/pat/m$(pindahkan garis yang cocok ke akhir) juga OK,
Lerner Zhang
6

[d] hapus semua garis yang bukan (!) yang cocok dengan pola:

:g!/pattern/d

atau bahkan lebih sederhana (terima kasih atas komentar oleh 'B Layer'):

:v/pattern/d
Kevin Liu
sumber
Ya, tapi itu lebih konvensional untuk menggunakan yang setara :vdaripada :g!. (Saya tidak ingat kapan terakhir kali saya melihat yang terakhir digunakan, TBH!)
B Layer
2

Jika Anda ingin membuat daftar semua baris yang cocok (seperti pada jawaban saya yang lain), dan kemudian beralih ke satu pasangan tertentu, plugin FindOccurrence saya menyediakan [/pemetaan untuk itu (dan [nuntuk pola pencarian terakhir, alih-alih menanyakan satu). [/patterndaftar suka :g/pattern, tetapi kemudian meminta jumlah pertandingan untuk melompat ke.

Ingo Karkat
sumber
0

Cara lain adalah menggunakan :h :ilist, saya menggunakannya untuk mendapatkan gambaran umum halaman manual. hasilnya terlihat seperti ini:

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

Ini adalah fungsi kecil yang memungkinkan Anda memilih untuk pergi ke baris hasil dengan indeks:

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

Dapat digunakan seperti ini:

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