Как показать результаты поиска для всех открытых буферов


17

Одна вещь, которую я часто делаю (но полагаюсь на командную строку), это поиск / поиск в нескольких файлах.

Есть ли способ отобразить результаты поиска для всех открытых буферов?

В идеале, я хотел бы иметь новый разделенный буфер, содержащий местоположение результата и фрагмент так же, как это grepделает. Например ( /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();

В качестве бонуса я хотел бы иметь возможность искать термин под курсором, во многом как gdделает.


Ответы:


15

Вы можете использовать :vimgrep /pattern/ {files}для заполнения списка быстрых исправлений соответствующими шаблонами. Проблема в том, что :vimgrepопция файлов напрямую не разрешает буферы. Ты можешь использовать:

%   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}

Другой вариант - написать скрипт, который генерирует список файлов из :buffers. По такому посту с небольшим изменением мы получаем:

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>)

Теперь вы можете вызывать :GrepBufs <expression>и получать стандартный :vimgrepвывод, но вместо этого используя буферы.

Обновить Если вы хотите позвонить, GrepBuffersиспользуя значение под курсором, добавьте это новое отображение.

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

Когда вы находитесь в нормальном режиме типа , <leader>zи вы будете :vimgrepкурсор слово над открытыми буферами.


2
В виде одной строки: command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' '). Использование::Bufgrep/foo/
Питер Ринкер

8

Поиск только в открытых буферах - это хорошо, но может наступить момент, когда вы захотите выполнить поиск по всему проекту. Это может быть быстрее и проще, чем вы думаете!

Поиск по проекту

  • grepстандартный поисковый инструмент Unix Стоит упомянуть из-за его повсеместности. Уже интегрированы в Vim через :grepкоманду. например :grep -r 'foo'. См :h :grep.
  • Ack работает быстрее, чем обычный grep, потому что он пропускает каталоги VCS, двоичные файлы и может искать определенный тип файлов, например --perl. Для интеграции Vim см. Ack.vim
  • Ag the Silver Surfer - это инструмент для поиска кода, похожий на ack, но более быстрый. Плагин Vim: Ag.vim
  • git grepочень быстро ищет репозиторий Fugitive.vim предоставляет :Ggrep.
  • Ripgrep даже быстрее, чем Ag и git grep. Можно использовать и с :grep.

Я рекомендую оба ripgrep, Ag, и так git grepкак они все очень быстрые. Я искал более 4700+ менее чем за 1 секунду. Это довольно сложно победить ripgrep.

Чтобы протестировать один из этих вариантов без плагина, или вы просто не хотите плагин, вы можете соответственно настроить свой 'grepprg'вариант. например set grepprg=ag\ --vimgrepили set grepprg=rg\ --vimgrep. Смотрите :h 'grepprg'и :h 'grepformat'для получения дополнительной информации. Теперь вы можете искать через :grep. например :grep 'foo'.

В качестве последнего запасного варианта вы можете использовать :vimgrepего, так как он доступен на всех системах, в которых доступен Vim. Смотрите :h :vimgдля получения дополнительной помощи.

Список быстрых исправлений

Поскольку большинство этих опций используют список быстрых исправлений, я предлагаю вам использовать более удобные сопоставления для пересечения списка быстрых исправлений. Я использую неповрежденный плагин Тима Поупа, который использует ]qи [qдля :cnextи :cprevсоответственно. Некоторые люди , как QuickFix открыть после поиска выполняется , то добавьте следующие строки в ~/.vimrcфайл: autocmd QuickFixCmdPost *grep* cwindow. Вы также можете вручную открыть список QuickFix через :copen.

Хотите еще более быстрых «поисков»?

Вам нужно будет использовать какой-то инструмент, который использует готовые индексы, такие как ctags , cscope или GNU global .

  • Vim имеет встроенную поддержку ГКДА через :tag, <c-]>и многие другие команды и опции. См :h tags. Также может захотеть прочитать Effortless Ctags с Git или заглянуть в плагин Gutentags
  • Поддержка Cscope также встроена и может использоваться через :cscopeкоманду. Видеть:h cscope

Больше помощи

Я хотел бы начать с этого хорошего эпизода Vimcast : поиск нескольких файлов с:vimgrep .

Для получения дополнительной помощи Vim см. Документацию:

:h grep
:h :vimgrep
:h :grep
:h 'grepprg'
:h 'grepformat'
:h quickfix
:h :cnext
:h tags
:h cscope

6

Мой плагин GrepCommands определяет варианты встроенной :vimgrepкоманды, которые нацелены на поиск всех аргументов, перечисленных буферов, окон на текущей вкладке или на всех вкладках. По сути, надежная реализация плагина ответа @ jecxjo.


1

Команды :bufdoи:vimgrepadd

Этот ответ основан на /programming//a/11976158/1057593 .

Однако я хотел добавить несколько битов. Опять основная команда

:bufdo vimgrepadd pattern %

Если ваш список быстрых исправлений не пуст, вы, вероятно, хотите сначала очистить его (см. Https://stackoverflow.com/q/27385970/1057593 ). Это может быть сделано с

:cexpr []

vim-unimpaired предоставляет сопоставления ]qи [qциклически проходит матчи.

CmdLine-история

Это хороший рабочий процесс для ввода шаблона поиска отдельно /pattern. Это позволяет вам использовать общую команду из истории командной строки, используя текущий шаблон поиска. Это будет выглядеть как

/pattern
:bufdo vimgrepadd // %

Типичный новый поиск по всему буферу будет

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

Я добавил следующие отображения в мой vimrc для использования <C-N>и <C-P>вместо клавиш со стрелками

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

Для поиска в истории команд используйте q:, затем /bufdo<CR>и вызовите команду с помощью <CR>. Для получения дополнительной информации см. Https://vim.fandom.com/wiki/Using_command-line_history и страницы справки :h historyи :h cmdline-window.

Вы можете добавить в команду многоразового использования, :copenчтобы сразу увидеть список исправлений следующим образом:

:execute "bufdo vimgrepadd // %" | copen

Предложение от stackoverflow :bufdo vimgrepadd // % | copenоткрыло несколько непреднамеренных окон в моем случае.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.