Ich arbeite an einem Plugin, mit dem Benutzer benutzerdefinierte Operatoren erstellen können. Die Operatoren würden einen VimL-Ausdruck auf das Bewegungs- oder Textobjekt anwenden, über das sich der Operator bewegt.
Saubere Benutzeroberfläche
Ich denke, die sauberste Schnittstelle zum Definieren der benutzerdefinierten Operatoren wäre die Verwendung eines Befehls. Ich habe einen Befehl definiert :MapExpress
, der ungefähr so aufgerufen wird:
:MapExpress cd '/* ' . v:val . ' */'
Dies würde einen Operator für den Normalmodus erstellen und eine Zuordnung für den visuellen Modus cd
, die die Bewegung oder Auswahl in Kommentarbegrenzern im C-Stil umgibt.
Hier liegt natürlich ein Problem. Sie können keinen Befehl, der in einem Plugin definiert ist, aus Ihrer .vimrc
Datei aufrufen .
Weniger als zufriedenstellende Problemumgehungen
Ich habe ein paar Problemumgehungen gefunden, mit denen ich nicht ganz zufrieden bin.
Der Benutzer autocmd VimEnter *
ruft den Befehl auf
Während dies funktionieren würde, fügt es viel "mentalen Overhead" hinzu. Ich würde vermuten, dass viele Vim-Benutzer nicht genau wissen, wie das autocmd
funktioniert.
Der Benutzer erstellt eine Datei, in ~/.vim/after/plugin/
der der Befehl aufgerufen wird
Auch dies würde funktionieren, hat jedoch den Nachteil, dass diese Konfiguration in einer eigenen Datei deaktiviert ist und leicht verloren geht und vergessen wird.
Ich verschiebe die Befehlsdefinitionen in das autoload/
Verzeichnis meines Plugins , und der Benutzer ruft eine Methode auf, die das Laden der Datei und damit die zu definierenden Befehle auslöst
Das würde so aussehen:
call express#init()
MapExpress cd '/* ' . v:val . ' */'
Etwas besser, aber dies würde zu Verwirrung darüber führen, ob die express#init()
Methode erforderlich ist, damit das Plugin überhaupt funktioniert.
Alternativen zur Verwendung eines Befehls
Ich habe auch einige Alternativen zur Verwendung eines Befehls zum Definieren des Operators in Betracht gezogen, aber jeder hat seine Vorbehalte.
Der Benutzer ruft eine Funktion zum Definieren der Operatoren auf
Das würde ungefähr so aussehen:
call express#operator('cd', '"/* ".v:val." */"')
Dies ist nicht schrecklich, hat aber den Nachteil, dass ein zitierter Ausdruck erforderlich ist. Das kann ärgerlich sein, wenn Sie Anführungszeichen in Ihrem Ausdruck verwenden möchten.
Benutzer verwendet eine <expr>
Zuordnung
So was:
nmap <expr> cd express#nmap('"/* ".v:val." */"')
xmap <expr> cd express#xmap('"/* ".v:val." */"')
Dies hat die gleiche mühsame Anforderung an zitierte Ausdrücke und verstößt auch gegen DRY, sofern Sie keine Variable einführen (nicht ideal).
Okay, na und?
Hier sind alle meine Ideen und warum ich keine davon mag. Bin ich zu pingelig? Gibt es eine bessere Lösung, an die ich nicht gedacht habe?
quelle
call express#initMapCommands()
? Alles, was zusätzliche Zitate erfordert, ist eine super schlechte Idee.<q-args>
wirklich funktioniert. DankeAntworten:
Mir scheint, Sie suchen
:runtime
. Sie können Befehle, die in Plugins definiert sind, perfekt von Ihrer .vimrc ausführen, aber Sie müssen vorher den Plugin-Namen (der ihn definiert) kennen.Hinweis: Im Gegensatz zur Autoload-Lösung stürzt bei diesem Ansatz die .vimrc-Beschaffung nicht ab. Wenn ein Autoload-Plugin nicht gefunden werden kann (durch Ausführung einer Funktion), gibt vim einen Fehler aus.
:runtime
bleibt stumm, wenn kein Plugin geladen werden kann.quelle
:runtime
. Verwenden Sie andernfalls eine Option, wie von romainl vorgeschlagen.plugin/
.plugin/
- wenn Sie Ihr "Projekt" / Repository auf diese Weise organisieren. Plugin-Manager aktualisieren die'runtimepath'
Option automatisch .Eine Liste wäre IMO die einfachste Lösung:
Überprüfen
g:pluginname_my_operators
Sie, wann Sie Ihr Plugin initialisieren und:MapExpress
ggf. für jedes Element ausführen, während Ihre Benutzer den Befehl für die On-the-Fly-Definition weiterhin verwenden können.quelle
v:val
muss Teil der Zeichenfolge sein, da es ausgewertet wird, wenn die Map-Interna aufgerufen werden. Ich denke, jede Lösung mit Zitaten ist weniger als ideal.