Wie aktualisiere ich eine Nebenmodusdefinition, während ich sie entwickle?

13

Ich fing an, einen Nebenmodus zu programmieren, um einige Tastenkombinationen bereitzustellen. Mein erster Versuch hatte einen Tippfehler:

(define-minor-mode borked-mode
  "A mode defined with a broken key binding"
  nil nil
  '(([b] . 'previous-line)))

Ich hatte die Absicht , die verwenden bSchlüssel, und sofort erkennen , dass ich verwendet habe , sollte "b"statt [b]. Also habe ich den Nebenmodus neu definiert:

(define-minor-mode borked-mode
  "A mode defined with a broken key binding"
  nil nil
  '(("b" . 'previous-line)))

Dies hat jedoch nicht funktioniert. Dies brachte mich auf eine wilde Gänsejagd durch die verschiedenen Arten des Bindens von Schlüsseln (dh (kbd ...), [...] usw.). Schließlich wurde mir klar, dass eine einfache Neubewertung des (define-minor-mode ...)Formulars nichts an der ursprünglichen, kaputten Tastaturbelegung ändern würde. Ich habe dann versucht, die Tastaturbelegung direkt über zu ändern (define-key borked-mode-map ...)und konnte die korrigierte Tastaturbelegung immer noch nicht laden. Schließlich habe ich Emacs neu gestartet und mein Nebenmodus wurde korrekt geladen.

Meine Frage ist: Wie aktualisieren Sie eine Nebenmodusdefinition, während Sie sie entwickeln? Gibt es eine Möglichkeit, eine defekte Definition zu löschen, oder müssen Sie Emacs neu starten, um defekte Bits zu löschen?

Tyler
quelle

Antworten:

11

Bei der ersten Auswertung define-minor-modewird eine Variable borked-mode-mapmit den von Ihnen angegebenen Tastenkombinationen definiert . Sobald dieses Symbol definiert wurde, wird es durch eine erneute Bewertung define-minor-modenicht mehr geändert.

Sie können die verschiedenen borked-mode-xxxSymbole mit löschen uninternund dann Ihren Code neu bewerten. Versuchen:

(unintern 'borked-mode-map)

Sie könnten daran interessiert sein, das define-minor-modeMakro zu erweitern, um zu sehen, was es tatsächlich tut. Punkt ans Ende setzen und callen M-x pp-macroexpand-last-sexp. Dadurch wird ein neuer Puffer geöffnet, in dem das erweiterte Makro angezeigt wird. Dort sehen Sie die defvarAufrufe zum Einrichten Ihrer Modusvariablen. Wenn Sie die Hilfe lesen, werden defvarSie feststellen, dass der Anfangswert nur verwendet wird, wenn das zu definierende Symbol ungültig ist. Sobald es existiert, defvarändern nachfolgende Aufrufe seinen Wert nicht.

Glucas
quelle
13

Ich denke, die beste Antwort, die ich Ihnen geben kann, ist, sich von der "Inline-Tastenkombination" von fernzuhalten define-minor-mode. Verwenden

(defvar borked-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [b] 'previous-line)
    ...
    map))

(define-minor-mode borked-mode
  "A mode defined with a broken key binding"
  :global nil
  ...)

Stattdessen. Anschließend können Sie C-M-xdiese Definitionen erneut auswerten.

Stefan
quelle
1
defvarwird den Wert nach C-M-x:) nicht mehr auswerten. Benötigen Sie defparameteroder eine separate setf.
wvxvw
Wie @wvxvw hervorhebt, wird das Problem dadurch nicht behoben. Ihr Beispielcode macht dasselbe wie das define-minor-modeMakro: Aufrufen defvar, um die Karte zu definieren. Das zweite Auswerten dieser Defvar hat keine Auswirkung.
Glucas
7
@wvxvw Wenn Sie C-M-x( eval-defun) verwenden, um defvardie Variable neu zu bewerten , wird sie aktualisiert. Dies ist ein Sonderfall in eval-defun; Wenn Sie eval-bufferoder aufrufen, eval-regionwird der vorhandene Wert nicht geändert.
Gilles 'SO- hör auf böse zu sein'
Ah - das scheint der entscheidende Punkt zu sein.
glucas
1
Beachten Sie, dass C-M-xim defvarFormular nur die Moduszuordnungsvariable selbst aktualisiert wird. Sie müssen sich auch C-M-xauf dem define-minor-modeFormular befinden, um die geänderte Karte in den Nebenmodus zu "installieren". Ich habe versucht, durch Erweitern der Makros herauszufinden, warum, aber es ist mir ein Rätsel.
Tyler