Comment savoir ce que fait réellement une séquence de touches

14

De temps en temps, j'observe un comportement inattendu lors de l'édition de texte. Mon premier recours consiste généralement à utiliser C-h kpour savoir quelles fonctions sont appelées par une séquence de touches donnée. Cependant, la documentation est parfois en contradiction avec le comportement observé. Dans ces cas, je suppose généralement qu'un autre package s'est accroché à cette fonction ou séquence de touches et modifie son comportement.

Comment savoir quelles fonctions sont liées à ma séquence de touches?

Un exemple que j'ai rencontré récemment est que j'ai appuyé sur la "touche et que des guillemets ont été insérés au début et à la fin de la région active. Je soupçonnais que ce n'était pas le comportement par défaut d'Emacs, j'ai donc l'habitude C-h k "de savoir quelle fonction était réellement appelée.

La describe-keydocumentation m'a dit que la fonction self-insert-commandétait appelée, qui est une fonction intégrée. Pour faire court, après quelques essais et erreurs, j'ai pu déterminer que le comportement était dû à electric-pair-mode. À l'avenir, y a-t-il un moyen plus rapide d'arriver à cette conclusion que de désactiver les colis suspects un par un jusqu'à trouver le coupable?

nispio
la source
Est-il possible que le ait electric-pair-modeété activé uniquement dans certains modes majeurs? Ne voyez - vous encore self-insert-commandpour "quand vous faites C-h ktout electric-pair-modeest actif?
Kaushal Modi,
@kaushalmodi: Il s'avère que cela electric-pair-modefonctionne en se connectant à post-self-insert-hook, et non en modifiant le raccourci clavier.
nispio
C-h kvous indique exactement ce qui se passe pour une touche. Si vous regardez la documentation de self-insert-command, il est très clairement indiqué post-self-insert-hookque la commande est exécutée une fois la commande terminée.
shosti
@shosti: Dans cet exemple simple, oui. Mais que se passe-t-il si et si une extension utilise after-change-functionscomme Jordon le mentionne dans sa réponse? La documentation d'une fonction ne mentionnera probablement pas spécifiquement ce crochet, n'est-ce pas?
nispio
Désolé, j'aurais dû être plus précis. C-h k+ les hooks standards == le comportement complet (plus ou moins). Bien sûr, cela laisse parfois beaucoup de possibilités, mais il est toujours beaucoup plus transparent que tout autre système logiciel complexe que je connaisse.
shosti

Réponses:

13

Il n'y a pas de moyen facile de savoir exactement ce que fera une seule pression sur une touche.

Si vous voyez un comportement supplémentaire, vérifiez toujours les crochets communs. Voir la liste ici: http://www.gnu.org/software/emacs/manual/html_node/elisp/Standard-Hooks.html

Dans la plupart des cas, les plus importants sont:

  • fonctions après changement
  • fonctions avant changement
  • premier crochet de changement
  • hook post-commande
  • pré-commande-hook
  • crochet post-auto-inséré

Vous devrez inspecter ces crochets et examiner les fonctions qu'ils contiennent pour voir lequel modifie votre comportement.

Si les fonctions de ces hooks ne décrivent pas entièrement le comportement observé, consultez les fonctions pour obtenir des conseils qui apparaîtront dans leur documentation à partir de describe-function.


Edit: J'ai écrit quelques fonctions pour aider à décrire un crochet mieux que de passer par les fonctions une par une: https://gist.github.com/jordonbiondo/bad03e44bb053db0f1eb Vous pouvez utiliser describe-hookdéfini ici comme les autres fonctions de description. Voici un échantillon de sa sortie:

Et voici tout le code, au cas où l'essentiel disparaîtrait:

(defun guess-all-hooks ()
  "Return a list of all variables that are probably hook lists."
  (let ((syms '()))
    (mapatoms
     (lambda (sym)
       (if (ignore-errors (symbol-value sym))
           (let ((name (symbol-name sym)))
             (when (string-match "-\\(hook[s]?\\|functions\\)$" name)
               (push sym syms))))))
    syms))

(defun face-it (str face)
  "Apply FACE to STR and return."
  (propertize str 'face face))

(defun describe-hook (hook)
  "Display documentation about a hook variable and the
functions it contains."
  (interactive
   (list (completing-read
          "Hook: " (mapcar (lambda (x) (cons x nil)) (guess-all-hooks)))))
  (let* ((sym (intern hook))
         (sym-doc (documentation-property sym 'variable-documentation))
         (hook-docs (mapcar
                     (lambda (func)
                       (cons func (ignore-errors (documentation func))))
                     (symbol-value sym))))
    (switch-to-buffer
     (with-current-buffer (get-buffer-create "*describe-hook*")
       (let ((inhibit-read-only t))
         (delete-region (point-min) (point-max))
         (insert (face-it "Hook: " 'font-lock-constant-face) "\n\n")
         (insert (face-it (concat "`" hook "'") 'font-lock-variable-name-face))
         (replace-string "\n" "\n\t" nil
                         (point)
                         (save-excursion
                           (insert "\n" sym-doc "\n\n")
                           (1- (point))))
         (goto-char (point-max))
         (insert (face-it "Hook Functions: " 'font-lock-constant-face) "\n\n")
         (dolist (hd hook-docs)
           (insert (face-it (concat "`" (symbol-name (car hd)) "'")
                            'font-lock-function-name-face)
                   ": \n\t")
           (replace-string "\n" "\n\t" nil
                           (point)
                           (save-excursion
                             (insert (or (cdr hd) "No Documentation") "\n\n")
                             (1- (point))))
           (goto-char (point-max))))
       (help-mode)
       (help-make-xrefs)
       (read-only-mode t)
       (setq truncate-lines nil)
       (current-buffer)))))
Jordon Biondo
la source
Est-ce à dire que lorsqu'une fonction est conseillée, la documentation est automatiquement mise à jour pour refléter le changement?
nispio
Je ne sais pas si les propriétés réelles sont mises à jour, mais la valeur renvoyée par documentationest mise à jour pour refléter.
Jordon Biondo
1
@nispio oui, ça l'est.
Malabarba
1
Le code / la fonction dans gist.github.com/jordonbiondo/bad03e44bb053db0f1eb pourrait, et à mon avis, devrait être inclus dans la réponse. Je pense qu'une réponse SE a une limite de 30 000 caractères.
Faheem Mitha
4

Peut-être pas une réponse complète à votre question, mais le package helm-descbindsvous aide à rechercher toutes les liaisons de clavier définies à partir de la représentation ascii du raccourci. Pour chaque hit, il vous montre la fonction interactive associée au raccourci clavier, et vous pouvez demander helm-descbindsà le décrire ou à l' exécuter directement à partir des résultats de la recherche.

entrez la description de l'image ici

Voici la description du package sur le site GitHub:

Helm Descbinds fournit une interface pour les liaisons de description d'emacs, ce qui rend les liaisons de touches actuellement actives consultables de manière interactive avec helm.

De plus, vous avez les actions suivantes

  • Exécutez la commande
  • Décrivez la commande
  • Trouvez la commande

Et C-zvous donnera une description persistante de la commande actuelle.

Amelio Vazquez-Reina
la source
2
C'est bien. Je vais certainement lier cela à C-h b. Mon seul souhait est que je puisse passer à l'élément de la liste en entrant la séquence de touches réelle au lieu de taperC - c _ C - p
nispio