Comment mettez-vous à jour une définition de mode mineur pendant que vous la développez?

13

J'ai commencé à coder un mode mineur pour fournir des raccourcis clavier. Ma tentative initiale avait une faute de frappe:

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

J'avais l'intention d'utiliser la bclé et j'ai immédiatement réalisé que j'aurais dû utiliser à la "b"place de [b]. J'ai donc redéfini le mode mineur:

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

Cependant, cela n'a pas fonctionné. Cela m'a lancé sur une chasse aux oies sauvages à travers toutes les différentes façons de lier les clés (c'est-à-dire, (kbd ...), [...], etc.). Finalement, je me suis rendu compte que la simple réévaluation du (define-minor-mode ...)formulaire ne changeait rien, j'étais coincé avec la carte des touches originale et cassée. J'ai ensuite essayé de changer le clavier directement via (define-key borked-mode-map ...)et je n'ai toujours pas pu charger le clavier corrigé. Enfin, j'ai redémarré Emacs et mon mode mineur était correctement chargé.

Ma question est: comment mettre à jour une définition de mode mineur pendant que vous la développez? Existe-t-il un moyen de vider une définition cassée, ou devez-vous redémarrer emacs pour effacer les bits cassés?

Tyler
la source

Réponses:

11

La première fois que vous évaluez votre, define-minor-modeil définit une variable borked-mode-mapavec les raccourcis clavier que vous avez spécifiés. Cependant, une fois ce symbole défini, réévaluer votre define-minor-modene le modifiera pas.

Vous pouvez supprimer les différents borked-mode-xxxsymboles à l'aide unintern, puis réévaluer votre code. Essayer:

(unintern 'borked-mode-map)

Vous pourriez être intéressé à développer la define-minor-modemacro pour voir ce qu'elle fait réellement. Mettez le point à la fin et appelez M-x pp-macroexpand-last-sexp. Cela ouvrira un nouveau tampon montrant la macro développée. Vous y verrez les defvarappels utilisés pour configurer vos variables de mode. Si vous lisez l'aide, defvarvous verrez que la valeur initiale n'est utilisée que si le symbole défini est nul - une fois qu'il existe, les defvarappels suivants ne changeront pas sa valeur.

glucas
la source
13

Je pense que la meilleure réponse que je puisse vous donner est de rester à l'écart de la "fonction de raccourcis clavier en ligne" de define-minor-mode. Utilisation

(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
  ...)

Au lieu. Ensuite, vous pouvez utiliser C-M-xpour réévaluer ces définitions.

Stefan
la source
1
defvarn'évaluera pas sa valeur à nouveau après C-M-x:) Vous auriez besoin defparameterou d'un séparé setf.
wvxvw
Comme le souligne @wvxvw, cela ne résout pas réellement le problème. Votre exemple de code fait la même chose que la define-minor-modemacro: appeler defvarpour définir la carte. Évaluer ce defvar une deuxième fois n'a aucun effet.
glucas
7
@wvxvw Si vous utilisez C-M-x( eval-defun) pour réévaluer la defvaralors la variable est mise à jour. Ceci est un cas spécial dans eval-defun; si vous appelez eval-bufferou eval-regionalors la valeur existante n'est pas modifiée.
Gilles 'SO- arrête d'être méchant'
Ah - cela semble être le point clé.
glucas
1
Notez que C-M-xsur le defvarformulaire ne met à jour que la variable mode-map elle-même. Vous devez également C-M-xsur le define-minor-modeformulaire pour obtenir la carte modifiée «installée» dans le mode mineur. J'ai essayé de comprendre pourquoi en étendant les macros, mais ça me dépasse.
Tyler