Was machen matchit.vims [%,]%, a%?

7

matchits %/ g%sind einfach genug zu verwenden, aber ich habe Probleme, die anderen Zuordnungen zu verstehen, die möglicherweise nützlich klingen, aber nicht verständlich zu funktionieren scheinen.

]%  Go to [count] next unmatched group, as specified by
    |b:match_words|.  Similar to |]}|.

Ich würde erwarten , dass dies mir vielleicht damit springen endif, endfunctionusw. Nehmen Sie das folgende vimscript Beispiel des eingebauten in vim ftplugin mit ( b:match_wordserscheint Set zu sein.)

function! SuperTab()
  let l:part = strpart(getline('.'),col('.')-2,1)
  if (l:part=~'^\W\?$')
      return "\<Tab>"
  else
      return "\<C-n>"
  endif
endfunction

[%Die meiste Zeit springt man zum function!, springt gelegentlich (uneinheitlich abhängig von der Cursorposition) zum ifund ignoriert (s völlig . ]%springt zu )s und sonst nichts. va%verhält sich [%in diesem Beispiel identisch und wählt nichts aus. Ist das normales Verhalten? Gibt es ein Beispiel, in dem diese Zuordnungen sinnvoll sind?

Masse
quelle
1
Gute Frage! Ich dachte, ich würde es aktivieren und eine Antwort finden, aber ich bin genauso ratlos wie Sie. Soweit ich sehen kann ]%macht fast nichts. Ich muss mir den Code ansehen.
B-Schicht
Ich denke, es könnte nur ein Buggy sein. Soweit ich aus der Dokumentation und den Kommentaren im Code ersehen kann, sollte es so funktionieren, wie Sie es vorgeschlagen haben. Möglicherweise wird sich jemand (@BLayer? Oder vielleicht ich!) Den aktuellen Code ansehen und Ihnen sagen, warum / wie es schief geht.
Rich
Ich werde versuchen, dieses Wochenende zu antworten. Ich habe vor einiger Zeit ein wenig gestochert und bin mir sicher, dass es stark abgehört hat, aber ich habe es in keiner Tiefe debuggt.
B-Schicht
Ich habe gerade versucht neovim die matchit in vim ( überraschend anders ist als die vim) und es scheint zu funktionieren .. seltsam github.com/neovim/neovim/blob/master/runtime/plugin/matchit.vim
Messe
1
Neovims va% ((( )))"expandieren" jedoch nicht nach wiederholten a%. Ich bin mir nicht sicher, ob Vim es jemals getan hat, aber imo sollte es a(.
Messe

Antworten:

6

Ich gehe davon aus, dass Sie die neueste matchitPlugin-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 ifund ignoriert (s völlig .

Wenn Sie drücken [%, wird die s:MultiMatch()Funktion aufgerufen. Am Ende des letzteren befindet sich eine whileSchleife, 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 :normalBefehle 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 cdeine Datei mit mehr als 3 Zeilen ein. Diesmal sollten Sie in den Nachrichten 3nicht 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.0Patches 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 :normalBefehle, 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

Geben Sie hier die Bildbeschreibung ein


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 matchitder 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 :normalBefehle mehr verwendet, sondern die Funktion winsaveview()und aufgerufen winrestview(). Indem sie sie :normalfür einen anderen Zweck loswerden , haben sie auch das zuvor beschriebene Problem behoben, da v:count1es 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_wordsund &l:matchpairsnicht nur beschrieben sind ). Zumindest auf meiner Maschine.

Geben Sie hier die Bildbeschreibung ein


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 elsein 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 oam 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]%

Geben Sie hier die Bildbeschreibung ein


Hier ist eine Version des matchitPlugins 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- matchitPlugin zu ändern (oder nicht möchten), können Sie die Datei erstellen ~/.vim/plugin/matchit.vimund dort Ihr experimentelles matchitPlugin schreiben .

Da in der runtimepath, ~/.vimbevor 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.

user852573
quelle
Bitte öffnen Sie Probleme für die verschiedenen Probleme, die Sie unter github.com/chrisbra/matchit
Christian Brabandt
@ChristianBrabandt Ok, ich habe 2 Ausgaben geöffnet, um die ]%und v_a%Zuordnungen zu diskutieren, die ein wenig geändert werden könnten.
user852573
Erstaunliche Antwort! Ich bin ein bisschen überrascht, wie anscheinend nur wenige Leute diese Funktionen nutzen, aber ich bin froh, dass wir verstehen können, was jetzt los ist.
Messe