Tauschen Sie das Standardverhalten des Befehls gegen das Cu-Verhalten aus

7

Viele Emacs-Befehle ändern ihr Verhalten, wenn sie mit einem oder mehreren C-uPräfixen aufgerufen werden. In einigen Fällen ist das Standardverhalten eines Befehls für mich weniger nützlich als das Verhalten, das ich beim Präfixieren erhalte C-u. Gleichzeitig möchte ich das Standardverhalten nicht vollständig beseitigen.

Um ein konkretes Beispiel zu geben, beendet der quit-windowBefehl (an qin gebunden help-mode) das aktuelle Fenster und vergräbt den darin standardmäßig angezeigten Puffer. Wenn es damit aufgerufen wird, wird C-ustattdessen der Puffer gelöscht. Ich möchte, dass der Befehl den Puffer standardmäßig beendet und ihn vergräbt, wenn er mit einem C-uPräfix aufgerufen wird .

F: Wie kann ich Emacs anweisen, dass sich ein Befehl so verhält, als würde er C-u standardmäßig mit einem Präfix aufgerufen, während das Standardverhalten in das C-u Präfix verschoben wird ?

Ich weiß, dass ich dies beheben kann, indem ich den ursprünglichen Befehl neu definiere oder ihn in einen benutzerdefinierten Befehl einbinde, der Präfixargumente gemäß meinen Einstellungen übergibt. Aber ich würde lieber so etwas machen:

(swap-args 'quit-window)
itsjeyd
quelle

Antworten:

4

Etwas wie das:

(defun swap-args (fun)
  (if (not (equal (interactive-form fun)
                  '(interactive "P")))
      (error "Unexpected")
    (advice-add
     fun
     :around
     (lambda (x &rest args)
       "Swap the meaning the universal prefix argument"
       (if (called-interactively-p 'any)
           (apply x (cons (not (car args)) (cdr args)))
         (apply x args))))))

Funktioniert natürlich nur für (interactive "P"). Für andere Arten ist interactivees möglicherweise nicht sinnvoll, das erste Argument zu negieren.

abo-abo
quelle
1
Könnte ein bisschen einfacher sein mit :filter-argsstatt :around, denke ich.
Npostavs
Danke, swap-argsfunktioniert so, dass das C-uVerhalten zum Standard wird, wenn es auf einen Befehl angewendet wird. Wenn ich jedoch den Befehl mit C-uaufrufe, erhalte ich nicht das ursprüngliche Verhalten. Vielleicht called-interactively-pist schuld? Nach meinem Verständnis wird 'anydiese Funktion mit einem Argument von nur zurückgegeben, nilwenn der enthaltende Befehl von Lisp aufgerufen wird. Wenn Sie also den empfohlenen Befehl über eine Schlüsselbindung aufrufen, kann der Zweig else nicht erreicht werden.
Itsjeyd
'anywar in Ordnung, ich habe funcallstatt applyversehentlich verwendet.
Abo-Abo
2
Sie sollten auch etwas zur Dokumentzeichenfolge hinzufügen, da dies sonst verwirrend sein kann.
Gilles 'SO - hör auf böse zu sein'
1
Ärgerlicherweise suchen einige Funktionen (z. B. org-insert-subheading) buchstäblich nach dem rohen universellen Argument (anscheinend (4)) anstelle einer Wahrheitsüberprüfung.
Olejorgenb
1

Eine andere Methode, die auf der Tatsache basiert, dass eine interactive-formEigenschaft in der Liste der Funktion die im Code angegebene Form überschreibt: ( ref )

(put 'org-insert-subheading
     'interactive-form
     '(interactive (progn (if current-prefix-arg
                              '(nil)
                            '((4))))))

Mit (interactive-form 'function), um die aktuelle Spezifikation abzurufen, können auch komplexere Spezifikationen verarbeitet werden.

Ich denke , die beste Lösung (wenn möglich) ist die Funktion wickeln mit (let ((prefix-arg (not current-prefix-arg)))obwohl

olejorgenb
quelle
0

Nicht so einfach wie gedacht. Da es jedoch trivial ist, den getauschten Befehl zu haben:

(defun my-quit-window-args-swapped (&optional bury window)
"Adapted docstring blah, blah "
  (interactive "P")
  (quit-restore-window window (if bury 'bury 'kill)))
Andreas Röhler
quelle
Vielen Dank, aber wie ich in meiner Frage erwähnt habe, suche ich nach einer generischen Lösung, die ich auf verschiedene Befehle anwenden kann, nicht nach einem für den quit-windowBefehl spezifischen Wrapper .
Itsjeyd
@itsjeyd Es gibt keine endliche Einschränkung WRT für das Ergebnis und die Verwendung eines Arguments. Es geht nicht um "(Swap-Args ...", sondern um die Verwendung und Bedeutung von Args - was endlich kostenlos ist.
Andreas Röhler
1
Ich hätte meine Worte sorgfältiger wählen sollen. Ich wollte nicht vorschlagen, dass Ihre Lösung nicht für andere Befehle angepasst werden kann. Es ist eine perfekte Lösung, um Standard und C-uVerhalten auszutauschen , und ich bin sicher, dass andere, die auf Ihren Beitrag stoßen, davon unterstützt werden! Persönlich werde ich es nicht verwenden, da ich mehrere Befehle habe, deren Verhalten ich ändern möchte, und ich möchte vermeiden, dass mehrere Wrapper definiert werden müssen.
Itsjeyd
@itsjeyd AFAIU Das einzige, was hier definiert wird, ist die Art und Weise, wie der Körper Cu erhält. Es gibt keinen Standard, an welchem ​​Punkt im Körper das Argument verwendet wird, und es gibt viele Möglichkeiten, es zu verwenden - hier im booleschen Sinne. Sicher, Sie könnten eine Art KI einsetzen, um all diese Möglichkeiten abzudecken und zu bewältigen. :)
Andreas Röhler