Показывать только совпадающие строки?

31

В длинном файле я хотел бы найти шаблон, который будет соответствовать примерно 200 строкам или около того. Соответствующие строки находятся в случайных местах в файле.
Когда строка соответствует, релевантна только сама строка, без контекста выше или ниже.

Обычно я искал /и прыгал через совпадения n.
Но это означает, что на экране одновременно может быть только одна или две соответствующие строки.

Есть ли способ скрыть все строки, которые не совпадают, при просмотре списка строк результатов?


Подход грубой силы должен был бы удалить все несоответствующие линии, и отменить это удаление позже. Но это безобразно по-разному, даже если это не приведет к постоянному уничтожению ...

Volker Siegel
источник

Ответы:

34
:vimgrep pattern %
:cwin

vimgrepбудет искать ваш шаблон в текущем файле ( %) или в любых других файлах, которые вы укажете.

cwinоткроет в вашем окне буфер, который покажет только нужные строки. Вы можете использовать практически любую команду навигации / поиска в cwinбуфере. Нажмите return, чтобы перейти к строке под вашим курсором в исходном файле.

Зак Ингбретсен
источник
1
:vimgrepможет быть сокращено до:vim
Д. Бен Нобл
как мне снова вернуться в буфер?
Паша
также, как я могу закрыть буфер? заранее спасибо
паша
Из буфера quickfix (cwindow) вы можете нажать return в любой строке, чтобы перейти к этому месту в исходном буфере. Вы можете закрыть буфер cwindow из любого места :ccl[ose]или, как обычно, закрыть буфер (например, переключиться на него и :bd). Вы можете снова открыть буфер быстрого исправления, запустив его :cw[indow]снова, и он будет использовать ваши последние результаты vimgrep.
Зак Ингбретсен
15

Вы можете перечислить все соответствующие строки с

:g/{pattern}

(Команда :printможет быть опущена; это значение по умолчанию для :g.)

Инго Каркат
источник
1
Это «оригинальный grep» ( g/REgexp/p) ... Проблема в том, что вы не можете легко перейти к одному из матчей, хотя ...
Мартин Турной
@Carpetsmoker: Ты прав; для этого у меня есть плагин, см. мой другой ответ.
Инго Каркат
Это может быть полезно во многих случаях. Можно ли перенаправить вывод в новый буфер? Это позволило бы по-прежнему выделять синтаксис в строках. (Хм ... это поднимает другой вопрос, подожди секунду ...)
Фолькер Зигель
@IngoKarkat в чем смысл g. Я предполагаю, что это глобальная модель. Я обычно делаю VI поиск с косой чертой, /patternи это будет найти все вхождения. К ним можно перейти, нажав на буквуn
Александр Цка
@AlexanderCska: Нет, это не модификатор поиска, а отдельная команда, :g[lobal]которая принимает шаблон в качестве аргумента. Вы найдете все детали на :help :global.
Инго Каркат
12

Вы можете использовать опции foldmethodи foldexpr, чтобы сложить ненужные строки.

После поиска последний поиск сохраняется в @/реестре. Таким образом, вы можете легко сложить все, что не соответствует так (только для однострочных совпадений):

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

Более сложные методы, такие как добавление нескольких уровней свертывания для строк контекста, которые вы можете показать или скрыть, или сопоставление нескольких строк, можно найти в Vim Tips Wiki .

Бен
источник
Кажется, есть set foldlevel=0необходимость? Но, возможно, это по умолчанию.
Фолькер Сигел
1
Да, по умолчанию это ноль, но если он не работает без добавления, это не повредит. :-)
Бен,
Но теперь ... как переключить его снова, без следов?
Фолькер Сигел
в обычном режиме вы можете использовать 'zi' для включения и выключения складывания.
Джон ОМ.
Большую часть времени, когда я делаю это, я сначала :tab spполучаю новый одноразовый вид на файл. Тогда вернуться так же просто, как :closeи любой другой способ убить вкладку.
Бен
6

Если порядок не имеет значения, просто переместите линии.

:g/pat/m0

Для получения дополнительной помощи см .:

:h :g
:h :m
Питер Ринкер
источник
1
И :g/pat/m$(переместите совпавшие строки до конца) также все в порядке,
Лернер Чжан
6

[d] удаляет все строки, не соответствующие (!) шаблонам:

:g!/pattern/d

или даже проще (спасибо за комментарии «B Layer»):

:v/pattern/d
Кевин Лю
источник
Да, но более привычно использовать эквивалент :v, чем :g!. (Я не помню, когда в последний раз видел последний использованный, TBH!)
B Layer
2

Если вы хотите перечислить все совпадающие строки (как в моем другом ответе), а затем перейти к одному конкретному совпадению, мой плагин FindOccurrence обеспечивает [/сопоставление для этого (и [nдля последнего шаблона поиска вместо запроса одной). [/patternсписки, как :g/pattern, но затем просит номер матча, чтобы перейти к.

Инго Каркат
источник
0

Другой способ заключается в использовании :h :ilist, я использую его, чтобы получить обзор справочной страницы. результат выглядит так:

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

Вот небольшая функция, которая позволяет вам перейти к строке результата по индексу:

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

Это можно использовать так:

command! -buffer Section call s:select_ilist(execute('silent! ilist /\v\C^[A-Z][^a-z]+$/'))
dedowsdi
источник