Ich gehe davon aus, dass Sie die neueste matchit
Plugin-Version 1.13.3 verwenden, die ich derzeit im Github-Repository von Vim finden kann.
[%
Die meiste Zeit springt man zum function!
, springt gelegentlich (uneinheitlich abhängig von der Cursorposition) zum if
und ignoriert (
s völlig .
Wenn Sie drücken [%
, wird die s:MultiMatch()
Funktion aufgerufen. Am Ende des letzteren befindet sich eine while
Schleife, deren Anzahl von Iterationen ist v:count1
. Diese Variable speichert die Anzahl für den letzten normalen Befehl. Hier sollte es sein 1
, weil Sie vorher keine Nummer getroffen haben [%
. In der Mitte der Funktion werden jedoch einige :normal
Befehle ausgeführt, um die Bildschirm- und Cursorposition zu speichern. Diese normalen Befehle ändern den Wert von v:count1
.
Sie können dies folgendermaßen überprüfen:
nno cd :<c-u>call Func()<cr>
fu! Func()
echom v:count1
endfu
Geben Sie diesen Code ein und drücken Sie cd
, lesen Sie Ihre Nachrichten ( :messages
): Sie sollten sehen 1
, weil Sie zuvor keine Nummer getroffen haben cd
. Geben Sie nun diesen Code ein:
nno cd :<c-u>call Func()<cr>
fu! Func()
norm! 3G
echom v:count1
endfu
Und machen Sie das gleiche Experiment, drücken Sie cd
eine Datei mit mehr als 3 Zeilen ein. Diesmal sollten Sie in den Nachrichten 3
nicht sehen 1
.
Aus diesem Grund wird die searchpair()
Funktion in der Schleife zu oft aufgerufen, was, wie ich vermute, das von Ihnen beschriebene Verhalten erklärt. Zumindest auf meinem Computer (Linux, Vim- 8.0
Patches 1-134
).
Um dies zu beheben, können Sie die Zeile 729 löschen :
let level = v:count1
Und verschieben Sie es am Anfang der Funktion (bevor andere Befehle, einschließlich :normal
Befehle, geändert werden können v:count1
):
fun! s:MultiMatch(spflag, mode)
if !exists("b:match_words") || b:match_words == ""
return ""
end
let level = v:count1
Ich habe gerade Neovims Matchit in Vim ausprobiert (überraschenderweise ist es anders als das von Vim) und es scheint zu funktionieren ... komisch
Dies liegt wahrscheinlich an der Pull-Anfrage Nr. 5124 , die neovim vor einem Jahr zusammengeführt hat. Laut matchit
der Festschreibungsnachricht sollte verhindert werden , dass ein unerwünschter Eintrag in die Jumplist eingefügt wird. Um dies zu lösen, wurde durch das Festschreiben geändert, wie die Bildschirm- und Cursorpositionen gespeichert wurden. Es werden keine :normal
Befehle mehr verwendet, sondern die Funktion winsaveview()
und aufgerufen winrestview()
. Indem sie sie :normal
für einen anderen Zweck loswerden , haben sie auch das zuvor beschriebene Problem behoben, da v:count1
es nicht mehr geändert wird. Obwohl es in Zukunft sein könnte, wenn einige Befehle in der Mitte der Funktion hinzugefügt werden.
]%
springt zu )
s und sonst nichts.
Gegen Ende der s:MultiMatch()
Funktion, Zeile 722 , wird das Muster, das den Endteil einer Gruppe von Token beschreibt, wie folgt definiert:
let closepat = substitute(closepat, ',', '\\|', 'g')
Der Zweck der Ersetzung besteht darin, jedes Komma, das zwei aufeinanderfolgende Gruppen von Token trennt, durch einen doppelt maskierten Balken zu ersetzen, der von Vims Regex-Engine als Wechsel (Trennung zwischen zwei Zweigen) interpretiert wird. Ich denke, dass die Substitution auch die Doppelpunkte ersetzen sollte, die :
die Token in jeder Gruppe trennen. Sie können die Ersetzung also folgendermaßen umschreiben:
let closepat = substitute(closepat, '[,:]', '\\|', 'g')
]%
Bewegen Sie mit dieser Änderung den Cursor auf die verschiedenen Token, die in b:match_words
und &l:matchpairs
nicht nur beschrieben sind )
. Zumindest auf meiner Maschine.
va%
verhält sich [%
in diesem Beispiel identisch und wählt nichts aus.
Bei den vorherigen Änderungen, insbesondere bei der zweiten, va%
sollte der Text zwischen den beiden umgebenden Token ausgewählt werden. Obwohl das Plugin einen mittleren Teil einer Gruppe von Token (wie else
in if|else|endif
) als Endteil zu behandeln scheint (es wird searchpair()
durch sein drittes Argument übergeben, nicht durch sein zweites). Was Sie als umgebende Token betrachten, kann Sie manchmal überraschen.
Neovims va%
((( )))
"expandieren" jedoch nicht nach wiederholten a%
. Ich bin mir nicht sicher, ob Vim es jemals getan hat, aber imo sollte es. genau wie a(
.
Derzeit ist die visuelle Zuordnung a%
in Zeile 71 wie folgt definiert :
vmap a% <Esc>[%v]%
Wenn ich o
am Anfang von hinzufüge {rhs}
, um den Cursor an den Anfang der Auswahl zu bewegen ( :h v_o
), erhalte ich das gewünschte Verhalten:
vmap a% o<Esc>[%v]%
Hier ist eine Version des matchit
Plugins mit den 3 kleinen Änderungen, die bisher beschrieben wurden.
Und hier ist noch eine, bei der ich versucht habe, auch die PR # 5124 von Neovim aufzunehmen.
Wenn Sie den Code auf Ihrem Computer testen möchten, aber nicht die Rechte haben, das Standard- matchit
Plugin zu ändern (oder nicht möchten), können Sie die Datei erstellen ~/.vim/plugin/matchit.vim
und dort Ihr experimentelles matchit
Plugin schreiben .
Da in der runtimepath, ~/.vim
bevor kommt $VIMRUNTIME
, soll Vim Ihre benutzerdefinierte Version vor einer Standard beziehen. Und da hat das Standard-Plugin den Schutz:
if exists("loaded_matchit") || &cp
finish
endif
let loaded_matchit = 1
... nur Ihre Version sollte vollständig bezogen sein.
]%
macht fast nichts. Ich muss mir den Code ansehen.