Como pesquisar a palavra atual em todas as guias abertas no Vim?


16

Comecei a aprender a pesquisa de palavras no Vim usando *e #enquanto o cursor estiver sobre a palavra atual. Mas essa pesquisa é limitada ao buffer de arquivo atual.

Existe um comando ou um atalho para estender esta pesquisa para:

  1. todas as guias abertas?
  2. todos os buffers abertos?

11
Você pode achar interessante e útil essa explicação sobre guias versus buffers .
Curinga

Respostas:


4

Não tenho uma solução exata para o seu problema, espero que uma resposta melhor que a minha seja apresentada. Mas foi assim que lidei com o problema de encontrar uma palavra em todos os buffers.

" enables to search in all open buffers with :Search <pattern>
command! -nargs=1 Search call setqflist([]) | silent bufdo grepadd! <args> %

nnoremap <left>  :cprev<cr>zvzz
nnoremap <right> :cnext<cr>zvzz

A primeira linha cria um comando Searchcom o padrão de pesquisa como argumento, que grava os resultados em uma lista de correções rápidas. As duas outras linhas mapeiam as (pelo menos para mim) teclas de seta inúteis para algo útil; eles são mapeados para ir para a próxima / anterior pesquisa ou para o próximo / anterior erro de compilação, etc., eles simplesmente avançam na lista de correções rápidas. Você pode usar isso da seguinte maneira:

:Search foobar
<right>
<right>
…

Adoro esse comando, mas adicionei algumas coisas para que ele escape melhor dos termos de pesquisa e force um redesenho. (o uso silencioso com divisões pode causar erros no vim ui). comando! -nargs = 1 Chamada de pesquisa setqflist ([]) | silencioso execute "bufdo grepadd! '<args>'%" | redesenhar!
Igorio 21/07

você também pode digitar :cnou :cpalternar para o próximo documento.
Phyatt #

7

Na verdade, é o comportamento padrão, embora possa ser difícil perceber: tente *mudar para outra guia e use nans Nno modo de comando para avançar e retroceder entre os hits da pesquisa.

Isso pode fazer mais sentido se primeiro você ativar o destaque para todos os hits:

:set hlsearch

11
+1 apenas por hlsearchisso eu não sabia e que eu teria pesquisado um dia ou outro :-). No entanto, por padrão Eu tentei * #, n e N, e não saltar para outros buffers de arquivo ...
Stephane Rolland

Não, ne Nnão salte os buffers (eles se abrem), mas o termo que eles segmentam é pesquisado em todas as guias; clique *com o destaque em e percorra as guias - todas serão destacadas com o mesmo termo, para que você possa usá n-lo Nlocalmente sem uma nova pesquisa.
Goldilocks

2
A questão toda é NÃO ter que percorrer suas guias para encontrar todas as correspondências.
Magnus

11
@ Magnus Embora isso possa ser preferível, na verdade não é explicitamente indicado na pergunta, que pergunta como "estender essa pesquisa a ... todos os buffers" -> ela é estendida a todos os buffers. O objetivo da minha resposta foi deixar isso claro, pois pode não ser, especialmente se você não tiver hlsearchdefinido.
Goldilocks


1

Como me encontrei fazendo isso com frequência, misturei um script (improvável).

Você ou outra pessoa pode achar útil.


Breve explicação:

Basicamente, ele pesquisa a lista de buffers e mostra o resultado na janela de correção rápida.

Dois comandos básicos são adicionados.

  1. Search <pattern> : Pesquise todos os buffers <pattern>.
  2. Search1 <pattern>: Pesquise todos os buffers <pattern>, mas mostre apenas o primeiro resultado para cada buffer. Normalmente útil para listar todos os buffers em que a função, variável fooé usada (ou o que for).

Use bang ( :Search! foo) para acrescentar aos resultados.

Além disso GSearche GSearch1é adicionado onde a diferença é que, com Searcho delimitador regex roteiro add, por exemplo:

foo -> /foo/

Onde, como GSearchespera, seja fechado.

A jbandeira é sempre adicionada para impedir o salto.


Código:

Existem alguns hacks para impedir a listagem de erros e, ao mesmo tempo, manter o código curto. try / catchera um pouco complicado bufdo.

let s:not_idents = split("/!#$%&\"`´¨'¯()*+,-.:;<=>?¿@[\]^{|}µ¶·¸~±×÷®©«»¬­ª°º¹²³¼½¾", '\zs')
" Create a delimited pattern. "
fun! s:Parse_pat(pat)
    for c in s:not_idents
        if stridx(a:pat, c) == -1
            return c . a:pat . c
        endif
    endfor
    echohl Error
    echom "Could not delimit pattern '". a:pat ."'"
    echohl None
    return ''
endfun

fun! s:AllBufSearch(pat, bang, uno, isg)
    if a:isg
        let pat = a:pat
    else
        let pat = s:Parse_pat(a:pat)
    endif
    if pat == ''
        return
    endif
    cclose
    let [_buf, _view] = [bufnr("%"), winsaveview()]
    let _foldenable = &foldenable
    set nofoldenable

    " Copy of current qflist. "
    let qfc = getqflist()
    " Hack to prevent error if no matches. "
    call setqflist([{}])
    silent execute "bufdo vimgrepadd! " . pat . "j %"
    " Restore "
    exec "buffer " . _buf
    let &foldenable = _foldenable
    call winrestview(_view)
    " Fix "
    let qf = getqflist()
    call remove(qf, 0)
    " Only one listing per buffer. "
    if a:uno
        let bn = {}
        let i  = 0
        for m in qf
            if has_key(bn, m["bufnr"])
                call remove(qf, i)
            else
                let bn[m["bufnr"]] = 1
                call remove(qf[i], "valid")
                let i += 1
            endif
        endfor
    endif
    if a:bang == "!"
        let qf = qfc + qf
    endif
    " If any matches, copen. "
    if len(qf)
        call setqflist(qf)
        copen
    endif
endfun

command! -nargs=1 -bang Search   call s:AllBufSearch(<q-args>, "<bang>", 0, 0)
command! -nargs=1 -bang Search1  call s:AllBufSearch(<q-args>, "<bang>", 1, 0)
command! -nargs=1 -bang GSearch  call s:AllBufSearch(<q-args>, "<bang>", 0, 1)
command! -nargs=1 -bang GSearch1 call s:AllBufSearch(<q-args>, "<bang>", 1, 1)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.