Ist es möglich, dass ein Hotkey mit numerischem Präfix eine Funktion so oft ausführt?

7

Ich finde, wenn Sie ein numerisches Präfix eingeben, bevor Sie einen ex-Befehl ausführen, gilt die Konvention, den Befehl einzurichten, um eine Operation über einen Zeilenbereich vorzubereiten. Es wird in der Dokumentation erklärt,

Eine Anzahl von Zeilen

Wenn Sie wissen, wie viele Zeilen Sie ändern möchten, können Sie die Nummer und dann ":" eingeben. Wenn Sie beispielsweise "5:" eingeben, erhalten Sie:

    :.,.+4

Jetzt können Sie den Befehl eingeben, den Sie verwenden möchten. Es wird der Bereich "." (aktuelle Zeile) bis ". + 4" (vier Zeilen nach unten). Somit umfasst es fünf Zeilen.

Ich habe es jetzt mit einer benutzerdefinierten Funktion von mir zu tun, dieser:

function! MyAmazingEnhancedDot()
    if v:hlsearch == 1
        :normal! .n
    else
        :normal! .j
    endif
endfun

Dies ist nur eine Möglichkeit, sich wiederholende Aufgaben zu optimieren, einschließlich des Wiederholens einer Operation in einem Zeilenbereich oder über eine Reihe von Suchübereinstimmungen.

Diese Funktion ist an einen Hotkey gebunden. Wie Alt+ .oder was auch immer.

Mein Ziel ist es, etwas sehr Mächtiges tun zu können: Ich sollte tippen können /varName<CR>ciwnew-var<ESC>n9<Alt+.>, um 10 Instanzen von varNameto umzubenennen new-var.

Was tatsächlich passiert, wenn ich dies tue, ist, dass es das Umbenennen nicht durchführt und die 9 Zeilen mit meiner .gespeicherten Bearbeitungsoperation aus Spalte 0 bearbeitet werden.

Ich kann nur davon ausgehen, dass Vim meine Tastenanschläge folgendermaßen interpretiert : :.,.+8 normal! .n.

Auf der halb vollen :normal! .jGlasseite funktioniert der Fall der Bindung tatsächlich, da die jBewegung, die keine Wirkung hat, in dieser Situation keine Konsequenz hat. (Ich brauche immer noch das j, damit es in einem interaktiven Anwendungsfall mit nicht numerischen Präfixen funktioniert.)

Meine Frage ist also, wie ich das Zeilenerweiterungsverhalten überschreiben kann, das Vim auf meine Bindung anwendet. Was fantastisch wäre, wäre, wenn ich das numerische Präfix als Argument oder so etwas einlesen könnte.

Steven Lu
quelle

Antworten:

6

Standardmäßig behandelt vim alle Funktionen so, als wären sie Standard-Ex-Befehle, dh alle vorangestellten Zahlen werden als verwendet {range}. Um dies zu ändern, müssen Sie Ihre Funktion und Ihre Karte ändern, um eine Zählung zu verwenden.

Karte mit Zählung

Karten können gezählt werden und werden über v:countund zur Verfügung gestellt v:count1. Die erste enthält 0, wenn keine Zählung angegeben ist, und die spätere enthält standardmäßig 1. Sie können eine Karte für Ihre Funktion erstellen:

nnoremap <M-.> :<C-u>call MyAmazingEnhancedDot(v:count1)<cr>

Für mehr Information :h v:count

Befehle mit count

Befehle können entweder a {range}oder a countals Präfix haben. Beim Erstellen des Befehls -countdeaktiviert das Flag die Bereichsoption und setzt die <count>Variable standardmäßig auf 0. Optional kann ein Standardwert angegeben werden -count=N. Der Präfixwert ist dann über die Variable countin Ihrer Funktion verfügbar .

Ein Befehl mit count würde folgendermaßen aussehen:

:command -count=1 EDot call MyAmazingEnhancedDot(<count>)

Wenn Sie jetzt 9EDotIhre Funktion aufrufen , wird sie mit der Anzahl 9anstelle eines Bereichs aufgerufen .

Weitere Informationen finden Sie unter :h command-count

Beide Beispiele

Hier ist dein Code:

function MyAmazingEnhancedDot(count)
  let c = a:count
  while c > 0
    if v:hlsearch == 1
      :normal! .n
    else
      :normal! .j
    endif
    let c -= 1
  endwhile
endfunction

command -count=1 EDot call MyAmazingEnhancedDot(<count>)

nnoremap <M-.> :<C-u>exe v:count1 . "EDot"<CR>

Jetzt können Sie Ihr Beispiel machen

/varName<CR>ciwvar-name<esc>n9<M-.>
jecxjo
quelle
1
Cool. Jetzt scheint es zu viele Möglichkeiten zu geben, mein Problem zu lösen! Ich verstehe, dass Sie beide Mechanismen in dem von Ihnen angegebenen Beispiel kombiniert haben, um zu veranschaulichen, wie sie verwendet werden. Aber ich frage mich, ob es nicht ausreicht, nur das zu verwenden nnoremap <M-.> :<C-u>call MyAmazingEnhancedDot(v:count1)<cr>und zu überspringen command -count=1 EDot call MyAmazingEnhancedDot(<count>)?
Steven Lu
Das Überspringen der Befehlsoption ist in Ordnung. Der einzige Vorteil der Befehlsoption besteht darin, dass Sie sie über ex-Befehle wie z :9EDot. Wenn Sie nicht häufig Ex-Befehle verwenden, überspringen Sie diese.
Jecxjo
Genial. Jetzt ist Ihre perfekte Antwort vollständig!
Steven Lu