F: Wie kann ich yasnippet
eine Textzeichenfolge innerhalb des Elisp-Codes korrekt erweitern (Snippet-Felder erkennen)?
Ein sehr einfaches Snippet ist nur eine Zeichenfolge, in der sich einige Steuerzeichen vermischen. Wir können auch Elisp-Formulare verwenden, um umfangreichere Snippets zu erstellen, aber mir ist nicht klar, wie ich sie angemessen erweitern kann.
Hier ist ein einfaches Beispiel, das das Problem erfasst. Ich erstelle ein org-mode
Snippet, um ein Link-Skelett einzufügen, das aussieht [[source][description]]
. Das folgende einfache Snippet erzeugt das gewünschte Verhalten von "Start im Quellfeld, Ende im Beschreibungsfeld":
[[$1][$0]]
Wir können Elisp-Code in Snippets (in `s eingeschlossen) mischen. Ich hätte gedacht, dass das Folgende genau das gleiche Verhalten wie die einfachere Version erzeugen würde, da das if
einfach [[$1][$0]]
als String ausgewertet wird :
`(if t "[[$1][$0]]")`
Dies ist jedoch nicht der Fall. Stattdessen verhält es sich so, als wären die Felder $0
und $1
keine Felder, beendet das Snippet und platziert einen Punkt nach dem Finale ]
. Also: Wie erhält man das gewünschte Verhalten, wenn ein elisp-Formular zu einer Textzeichenfolge mit yasnippet
in diese Zeichenfolge eingebetteten Feldern ausgewertet wird ?
BEARBEITEN: Wie gewünscht, hier ist der spezielle Anwendungsfall, der die Frage inspiriert hat. Wenn die X-Zwischenablage einen URL-Link enthält, möchte ich, dass das Quellfeld im Organisationslink ([[ Quelle ] [Beschreibung]] ausgefüllt und im Zielfeld belassen wird. Es verwendet eine Hilfsfunktion ( dan-xclipboard-link-p
), die die URL zurückgibt, falls vorhanden, oder sonst nil
. Es scheint mir, dass ich in der Lage sein sollte, so etwas zu tun:
`(let ((link (dan-xclipboard-link-p)))
(if link
(concat "[[" link "][$0]]")
"[[$1][$0]]"))`
Tatsächlich funktionierte mit einer früheren Version von yasnippet eine Version dieses Codes so, wie ich es beabsichtigt hatte.
EDIT 2: Interessanterweise funktioniert dieses Snippet, wenn sich ein Link in der X-Zwischenablage befindet, schlägt jedoch fehl, wenn dies nicht der Fall ist (dh es wird nicht $1
als Feld erkannt :
[[`(or (dan-xclipboard-link-p) "$1")`][$0]]
(if t (yas-insert-snippet))
? Können Sie eine realistischere Bedingung angeben, damit wir den tatsächlichen Anwendungsfall verstehen können? Dies könnte ein XY-Problem mit eleganteren Lösungen sein.yas-insert-snippet
das hier zutrifft. Auf jeden Fall kommt jetzt ein tatsächlicher Anwendungsfall (der früher funktioniert hat) in Frage.Antworten:
KURZE LÖSUNG
Wenn Ihnen ein zusätzlicher
TAB
Tastendruck nichts ausmacht , sollte die Definition Ihres Snippets wie folgt funktionieren.Das eingebettete Lisp gibt die URL aus der Zwischenablage zurück, falls vorhanden, und legt sie als Standardtext im Feld fest
$1
. Sie können über den Link tippen, um ihn zu ändern oder nurTAB (yas-next-field)
um einen Punkt zu verschieben$0
.LÄNGERE VOLLSTÄNDIGE LÖSUNG
Ich kam auf die Idee, die auf dem Kommentar von @ IqbalAnsari basiert, nachdem ich die kürzere Lösung geschrieben hatte. Sie können das Bedingungsprädikat verwenden, um auszuwählen, welches Snippet erweitert werden soll. Definieren Sie beispielsweise zwei Snippets mit demselben Trigger
SNIPPET 1
SNIPPET 2
Beide Snippets haben den gleichen Trigger, aber invertierte Prädikate, die mit dem gekennzeichnet sind
condition:
. Daher wird nur eines der Snippets in Abhängigkeit von dem von zurückgegebenen Wert erweitert(dan-xclipboard-link-p)
. Auf diese Weise können Sie den Punkt$0
direkt positionieren .Um die allgemeine Frage zu beantworten: Nein, es ist yasnippet nicht möglich, Felder innerhalb von elisp zu erkennen, da eingebettete elisp-Blöcke separat analysiert werden, ohne dass die normale Vorlagensyntax berücksichtigt wird. Ich bin mir jedoch nicht sicher, wie die vorherigen Versionen funktioniert haben.
quelle