vimscript bedingt basierend auf grep auf aktuellem puffer

7

Ich suche nach einer Möglichkeit, Code innerhalb einer Funktion abhängig vom Vorhandensein von Text in der bearbeiteten Datei unter bestimmten Bedingungen auszuführen. Ich habe einen Weg gefunden, der funktioniert, sich aber nicht sehr "sauber" anfühlt.

Folgendes habe ich:

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

Die Frage ist: Kann das gleiche Ergebnis irgendwie ohne die umständliche Verwendung von v: errmsg erzielt werden ?

Was ich vorhabe, ist etwas von der Form

function! foo()
   (...)
   if GrepInCurrentBuffer(l:pattern)
      (... do stuff ...)
   (...etc...)
Dalker
quelle
6
Verwenden Sie search()- siehe:h search()
VanLaser
1
@ VanLaser: Das hat einwandfrei funktioniert und ist genau das, wonach ich gesucht habe. Vielen Dank!
Dalker
2
Bitte! Beginnen Sie im Allgemeinen damit, um :h function-list
herauszufinden

Antworten:

6

Die Funktion, die Sie suchen, ist search(). Diese Funktion sucht ab der Cursorposition und wenn eine Übereinstimmung gefunden wird, wird die Zeilennummer zurückgegeben. Wird keine Übereinstimmung gefunden, wird 0 zurückgegeben. Die 'ignorecase', 'smartcase'und 'magic'Optionen sind auf dem Suchmuster verwendet. Beachten Sie, dass Sie, wenn Sie auswählen möchten, wo die Suche beginnen soll, mit cursor()der setpos()Funktion oder die Cursorposition festlegen und mit der getcurpos()Funktion die Cursorposition speichern können.

Hier ist ein Beispiel dafür in Aktion:

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

Weitere Informationen zu den in dieser Antwort genannten Dingen finden Sie in den folgenden Hilfethemen:

  • :help search()
  • :help 'ignorecase'
  • :help 'smartcase'
  • :help 'magic'
  • :help cursor()
  • :help setpos()
  • :help getcurpos()
Immergrüner Baum
quelle
1
Wie wäre es nur :echo search('pattern', 'nw') ? 1 : 0stattdessen? :)
VanLaser
Denn wenn sich vor dem Cursor ein Hallo befindet, wird es nicht erkannt.
EvergreenTree
Das 'w'-Flag umschließt die Suche jedoch um das Ende der Datei. So wird jedes Vorkommen erkannt.
VanLaser
1
Das ist eine sehr schöne Lösung! Ich habe versucht, die Einstellung der Cursorposition für die Suche innerhalb von Bereichen zu demonstrieren, aber ich glaube, ich habe nicht das beste Beispiel ausgewählt. Ich habe das Beispiel aktualisiert.
EvergreenTree
1
Unterstützt es die Regex-Suche?
Sergio Abreu
3

Als Referenz für alle, die sich in Zukunft mit dieser Frage befassen, finden Sie hier eine funktionierende Lösung, die dem gleichen Muster wie der Pseudocode in der Frage folgt. Es basiert vollständig auf VanLasers Kommentaren sowohl zur ursprünglichen Frage als auch zur Antwort von EvergreenTree.

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

In dem speziellen Fall der eigentlichen Funktion, aus der diese Frage hervorging, erforderte die Lösung nicht wirklich die 'nw'-Flags. Diese Flags sollten die Lösung jedoch im Allgemeinen sicherer machen, basierend auf ihrer Beschreibung in der Hilfe von vim:

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

(aus :help searchVim 7.4)

Dalker
quelle
Dies ist der beste Weg, um einfach zu überprüfen, ob etwas im Puffer vorhanden ist.
EvergreenTree