Im Anschluss an eine Antwort auf eine andere Frage zum neuen Beratungssystem :
Im alten Stil advice.el
war es möglich, einzelne Mitglieder der Argumentliste einer empfohlenen Funktion zu manipulieren, ohne Aussagen zu denjenigen Mitgliedern zu machen, die nicht so manipuliert wurden. Zum Beispiel die folgenden Ratschläge:
(defadvice ansi-term (around prompt-for-name last)
(let ((name (read-from-minibuffer "Tag: ")))
(and (not (string= name ""))
(ad-set-arg 1 (concat "Term: " name)))
ad-do-it))
Ermöglicht die (optionale) Bereitstellung eines Puffernamen-Arguments für einen ansi-term
Aufruf, wobei ansi-term
das erste Argument weiterhin durch Aufforderung gemäß seiner eigenen interaktiven Form erhalten wird.
(Zum späteren Nachschlagen ansi-term
lautet die Signatur (PROGRAM &optional BUFFER-NAME)
und das interaktive Formular fordert zur Eingabe von PROGRAM mit mehreren möglichen Standardwerten auf, hat jedoch keine Auswirkungen auf BUFFER-NAME.)
Ich bin mir nicht sicher, ob dies möglich ist oder nicht nadvice.el
. Wenn es so ist, bin ich mir nicht sicher, wie es gemacht werden kann. Ich habe verschiedene Möglichkeiten gefunden, um die Argumentliste einer empfohlenen Funktion zu ersetzen .
Zum Beispiel von * info * (elisp) Hinweiskombinatoren :
`:filter-args' Call FUNCTION first and use the result (which should be a list) as the new arguments to pass to the old function. More specifically, the composition of the two functions behaves like: (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
Andere Kombinatoren bieten ähnliche Funktionen, und der gemeinsame Nenner besteht darin, dass die Argumentliste einer Funktion zwar ersetzt, abgeschnitten, erweitert usw. werden kann, es jedoch keine offensichtliche Möglichkeit für Funktionsempfehlungen gibt, das Argument an einer bestimmten Position in der Liste ohne zu ändern etwas über den Rest davon zu behaupten .
Im vorliegenden Fall scheint es dem Ratgeber unmöglich zu sein, ansi-term
nur einen Puffernamen zu übergeben, da es nicht möglich ist, eine Liste zu erstellen, die einen Wert an Position 1 hat, aber nichts, nicht einmal nil
an Position 0. Im allgemeinen Fall Es erscheint dem Ratgeber unmöglich, Argumente über Position 0 hinaus willkürlich zu ändern.
Dies scheint insofern bedauerlich, als es zum Erzeugen eines ähnlichen Effekts notwendig ist, Code zu kopieren und einzufügen: Konkret kann ich entweder die ansi-term
interaktive Form kopieren und nach meinem Geschmack erweitern, oder ich kann sie ansi-term
insgesamt kopieren und ebenfalls erweitern. In beiden Fällen muss ich jetzt einen Teil der Emacs-Lisp-Distribution in meiner Init-Datei neu definieren, was mir sowohl hinsichtlich der Haltbarkeit als auch der Ästhetik als unerwünscht erscheint.
Meine Frage ist also: Kann man mit einer solchen Liste von Argumenten fertig werden nadvice.el
? Wenn das so ist, wie?
Antworten:
Im Gegenteil, ich halte es für eine gute Idee, die interaktive Form der empfohlenen Funktion zu kopieren und einzufügen, obwohl Sie dies hier eigentlich nicht tun müssen.
Ich habe deine Frage von oben bis unten gelesen. Als ich zum Code-Block kam, vermutete ich , dass Ihr Rat wahrscheinlich den Puffernamen ändert. Aber ich wusste es nicht , bis Sie später die Unterschrift als Kommentar zur Verfügung stellten.
In der Tat ist nichts weniger als nichts. :-) Aber das ist hier kaum relevant.
Wie Sie in der von Ihnen zitierten Dokumentation sehen können, wird der vom Hinweis zurückgegebene Wert als Argument für die empfohlene Funktion verwendet. Der Rückgabewert muss eine Liste aller Argumente sein, nicht nur derjenigen, die geändert wurden.
Bleiben Sie so nah wie möglich am alten Rat, und verwenden Sie dabei Folgendes
nadvice
:Aber ich empfehle Ihnen, den Rat wie folgt zu definieren:
Diese Variante ist eigentlich selbsterklärend.
quelle
args
Liste im Falle eines Aufrufs wie erweitern(ansi-term "foo")
, sonst(setf (nth 1 args)...
würde ein Fehler ausgelöst.buffer-name
obligatorisch ist.:filter-args
Hinweis erhält ein einziges Argument, das eine Liste von Argumenten für die empfohlene Funktion darstellt. Daher sollte die erste Variante wegfallen&rest
und die zweite Variante müsste eine Art destrukturierendes Konstrukt verwenden, um schöne Namen zu erhalten.So würde ich es machen:
während ich derjenige war, der
:filter-args
mich vorstellte, finde ich es persönlich selten bequem.quelle