Jak wyświetlić wyniki wyszukiwania dla wszystkich otwartych buforów

17

Jedną rzeczą, którą często robię (ale polegam na linii poleceń) jest wyszukiwanie / grepowanie w wielu plikach.

Czy istnieje sposób wyświetlania wyników wyszukiwania dla wszystkich otwartych buforów?

Idealnie chciałbym mieć nowy bufor podzielony zawierający lokalizację wyniku i fragment kodu podobnie jak greprobi. Na przykład ( /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();

Jako bonus chciałbym móc wyszukać termin pod kursorem, podobnie jak gdrobi.

Roflo
źródło
2
stackoverflow.com/questions/11975174/...
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Odpowiedzi:

15

Możesz użyć :vimgrep /pattern/ {files}do wypełnienia listy szybkich pasujących wzorców. Problem polega na tym, że :vimgrepopcja plików nie zezwala bezpośrednio na bufory. Możesz użyć:

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

Inną opcją jest napisanie skryptu, który generuje listę plików :buffers. Za ten post SO z niewielkim poprawką otrzymujemy:

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

Możesz teraz zadzwonić :GrepBufs <expression>i uzyskać standardowe :vimgrepwyjście, ale zamiast tego użyć buforów.

Aktualizacja Jeśli chcesz zadzwonić, GrepBuffersużywając wartości pod kursorem, dodaj nowe mapowanie.

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

Gdy jesteś w trybie normalnym typu <leader>zi będziesz :vimgrepsłowo kursor otwartych buforów.

jecxjo
źródło
2
W postaci pojedynczej linii: command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' '). Zastosowanie::Bufgrep/foo/
Peter Rincker
8

Przeszukiwanie tylko otwartych buforów jest przyjemne, ale może nadejść czas, kiedy będziesz chciał przeszukać cały projekt. To może być szybsze i łatwiejsze niż myślisz!

Wyszukiwanie w projekcie

  • grepjest standardowym narzędziem wyszukiwania w systemie Unix. Warto wspomnieć ze względu na jego wszechobecność. Już zintegrowany z Vimem za pomocą :greppolecenia. np :grep -r 'foo'. Zobaczyć :h :grep.
  • Ack jest szybszy niż zwykłe grep, ponieważ pomija katalogi VCS, pliki binarne i może wyszukiwać określone typy plików, takie jak --perl. Aby zapoznać się z integracją Vima, zobacz Ack.vim
  • Ag Silver Surfer to narzędzie do wyszukiwania kodu podobne do ack, ale szybsze. Wtyczka Vima: Ag.vim
  • git grepbardzo szybko przeszukuje repozytorium. Fugitive.vim zapewnia :Ggrep.
  • Ripgrep jest jeszcze szybszy niż Ag i git grep. Może być również używany z :grep.

Polecam zarówno ripgrep, Ag, git grepjak i wszystkie są super szybkie. Przeszukałem ponad 4700+ w mniej niż 1 sekundę. Trudno jest pokonać ripgrep.

Aby przetestować jedną z tych alternatyw bez wtyczki lub po prostu nie chcesz wtyczki, możesz odpowiednio ustawić swoją 'grepprg'opcję. np . set grepprg=ag\ --vimgreplub set grepprg=rg\ --vimgrep. Zobacz :h 'grepprg'i :h 'grepformat'więcej informacji. Teraz możesz wyszukiwać za pośrednictwem :grep. np :grep 'foo'.

Jako ostatnią rezerwę możesz użyć, :vimgrepponieważ jest ona dostępna we wszystkich systemach, w których Vim jest dostępny. Zobacz :h :vimgwięcej pomocy.

Lista QuickFix

Ponieważ większość z tych opcji korzysta z listy szybkich poprawek, sugeruję użycie bardziej przyjaznych mapowań do przekreślenia listy szybkich poprawek. Używam Tim papieża nienagannej wtyczki, które wykorzystuje ]qi [qna :cnexti :cprevodpowiednio. Niektórzy ludzie lubią QuickFix otworzyć po Wyszukiwanie odbywa się następnie dodać następujące wpisy do ~/.vimrcpliku: autocmd QuickFixCmdPost *grep* cwindow. Możesz także ręcznie otworzyć listę QuickFix za pośrednictwem :copen.

Chcesz jeszcze szybszych „wyszukiwań”?

Będziesz musiał użyć jakiegoś narzędzia, które korzysta z gotowych indeksów, takich jak ctags , cscope lub GNU global .

  • Vim ma wbudowane CTAG wsparcia poprzez :tag, <c-]>i wiele innych poleceń i opcji. Zobaczyć :h tags. Może także chcesz przeczytać Effitless Ctags w Git lub zajrzeć do wtyczki Gutentags
  • Obsługa Cscope jest również wbudowana i może być używana za pomocą :cscopepolecenia. Widzieć:h cscope

Więcej pomocy

Zacznę od tego miłego odcinka Vimcast : Przeszukaj wiele plików za pomocą:vimgrep .

Więcej pomocy Vima w dokumentacji:

:h grep
:h :vimgrep
:h :grep
:h 'grepprg'
:h 'grepformat'
:h quickfix
:h :cnext
:h tags
:h cscope
Peter Rincker
źródło
6

Moja wtyczka GrepCommands definiuje warianty wbudowanego :vimgreppolecenia, które ma na celu wyszukiwanie wszystkich argumentów, wymienionych buforów, okien na bieżącej stronie kart lub wszystkich stron kart. Zasadniczo solidna implementacja wtyczki odpowiedzi @ jecxjo.

Ingo Karkat
źródło
1

Polecenia :bufdoi:vimgrepadd

Ta odpowiedź jest oparta na /programming//a/11976158/1057593 .

Chciałem jednak dodać kilka bitów. Ponownie podstawowym poleceniem jest

:bufdo vimgrepadd pattern %

Jeśli lista szybkich poprawek nie jest pusta, prawdopodobnie najpierw chcesz ją wyczyścić (patrz /programming//q/27385970/1057593 ). Można to zrobić za pomocą

:cexpr []

vim-unimpaired zapewnia odwzorowania ]qi [qprzełącza mecze.

cmdline-history

Dobrym przepływem pracy jest oddzielne wprowadzanie wzorca wyszukiwania /pattern. Pozwala to na użycie polecenia ogólnego z historii wiersza poleceń przy użyciu bieżącego wzorca wyszukiwania. To by wyglądało

/pattern
:bufdo vimgrepadd // %

Typowe byłoby wyszukiwanie w całym buforze

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

Dodałem następujące mapowania do mojego vimrc do użycia <C-N>i <C-P>zamiast klawiszy strzałek

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

Aby przeszukać historię poleceń, użyj q:, a następnie /bufdo<CR>wywołaj polecenie za pomocą <CR>. Aby uzyskać więcej informacji, zobacz https://vim.fandom.com/wiki/Using_command-line_history oraz strony pomocy :h historyi :h cmdline-window.

Możesz dodać do polecenia wielokrotnego użytku, :copenaby natychmiast zobaczyć listę poprawek w następujący sposób:

:execute "bufdo vimgrepadd // %" | copen

Propozycja z przepełnienia stosu :bufdo vimgrepadd // % | copenotworzyła w moim przypadku kilka niezamierzonych okien.

Hotschke
źródło