condicional vimscript baseado em grep no buffer atual

7

Estou procurando uma maneira de executar algum código dentro de uma função condicionalmente, dependendo da presença de algum texto no arquivo editado. Eu encontrei uma maneira de fazer isso que funciona, mas não parece muito "limpo".

Aqui está o que eu tenho:

function! foo()
    (...)
    let v:errmsg = 'ok'
    execute "silent! normal! :/" . l:pattern . "\r"
    if v:errmsg == 'ok'
        (... do stuff ...)
    else
        (... do other stuff ...)
    endif
 endfunction

A questão é: o mesmo resultado pode ser alcançado de alguma maneira sem o uso desajeitado de v: errmsg ?

O que eu tenho em mente é algo da forma

function! foo()
   (...)
   if GrepInCurrentBuffer(l:pattern)
      (... do stuff ...)
   (...etc...)
Dalker
fonte
6
Use search()- Veja:h search()
VanLaser
11
@ VanLaser: funcionou perfeitamente e é exatamente o que eu estava procurando. Muito obrigado!
Dalker
2
De nada! Em geral, comece com isso para descobrir o que está disponível::h function-list
VanLaser 07/11

Respostas:

6

A função que você está procurando é search(). Esta função pesquisará começando na posição do cursor e, quando uma correspondência for encontrada, seu número de linha será retornado. Se nenhuma correspondência for encontrada, 0 será retornado. A 'ignorecase', 'smartcase'e 'magic'as opções são usados no padrão de pesquisa. Observe que, se quiser escolher onde a pesquisa começa, você pode usar cursor()a setpos()função ou para definir a posição do cursor e a getcurpos()função para salvar a localização do cursor.

Aqui está um exemplo disso em ação:

function! SearchInRange(pattern, start_line, end_line)
    " Save cursor position.
    let save_cursor = getcurpos()

    " Set cursor position to beginning of file.
    call cursor(a:start_line, 0)

    " Search for the string 'hello' with a flag c.  The c flag means that a
    " match at the cursor position will be accepted.
    let search_result = search(pattern, "c", a:end_line)

    " Set the cursor back at the saved position.  The setpos function was
    " used here because the return value of getcurpos can be used directly
    " with it, unlike the cursor function.
    call setpos('.', save_cursor)

    " If the search function didn't find the pattern, it will have
    " returned 0, thus it wasn't found.  Any other number means that an instance
    " has been found.
    return search_result ? 1 : 0
endfunction

Para mais informações sobre as coisas mencionadas nesta resposta, consulte os seguintes tópicos de ajuda:

  • :help search()
  • :help 'ignorecase'
  • :help 'smartcase'
  • :help 'magic'
  • :help cursor()
  • :help setpos()
  • :help getcurpos()
EvergreenTree
fonte
11
Que tal apenas em :echo search('pattern', 'nw') ? 1 : 0vez disso? :)
VanLaser
Porque se uma ocorrência de olá estiver antes do cursor, ela não será detectada.
EvergreenTree
O sinalizador 'w' envolverá a pesquisa no final do arquivo. Portanto, qualquer ocorrência será detectada.
VanLaser
11
Essa é uma solução muito boa! Eu estava tentando demonstrar a configuração da posição do cursor para pesquisar dentro dos intervalos, mas acho que não escolhi o melhor exemplo. Eu atualizei o exemplo.
EvergreenTree
11
suporta pesquisa regex?
Sergio Abreu
3

Para referência a qualquer pessoa que olhe para essa pergunta no futuro, aqui está uma solução funcional que segue o mesmo padrão que o pseudocódigo na pergunta. É completamente baseado nos comentários de VanLaser , tanto na pergunta original quanto na resposta da EvergreenTree.

function! foo()
    (... do stuff that defines l:pattern ...)
    if search(l:pattern,'nw')
        (... do stuff ...)
    else
        (... do other stuff ...)
    endif
endfunction

No caso específico da função real que originou essa pergunta, a solução não exigiu realmente os sinalizadores 'nw'. Essas sinalizações devem, no entanto, tornar a solução mais segura em geral, com base em sua descrição na ajuda do vim:

'n'     do Not move the cursor
'w'     wrap around the end of the file

(a partir :help searchdo Vim 7.4)

Dalker
fonte
Para simplesmente verificar se existe algo no buffer, esta é a melhor maneira de fazê-lo.
EvergreenTree