Як дізнатися, що насправді робить ключова послідовність


14

Час від часу спостерігаю несподівану поведінку під час редагування тексту. Моє перше звернення, як правило, використовувати C-h kдля з'ясування, які функції викликаються заданою послідовністю клавіш. Однак іноді документація суперечить спостережуваній поведінці. У цих випадках я зазвичай припускаю, що якийсь інший пакет приєднався до цієї функції або послідовності ключів і змінює свою поведінку.

Як я можу дізнатися, які функції залучаються до моєї послідовності ключів?

Один із прикладів, з якими я стикався нещодавно, - це те, що я натиснув "клавішу, а лапки було вставлено на початку та в кінці активної області. У мене була підозра, що це не поведінка Emacs за замовчуванням, тому я C-h k "з'ясовував, яка функція насправді викликається.

У describe-keyдокументації мені сказано, що self-insert-commandвикликається функція , яка є вбудованою функцією. Якщо коротко розповісти, після деякої кількості спроб і помилок я зміг визначити, що поведінка викликана electric-pair-mode. В майбутньому, чи є більш швидкий спосіб дійти до цього висновку, ніж відключати підозрювані пакети один за одним, поки не знайдуть винуватця?


Чи можливо, що electric-pair-modeактивовано тільки в деяких основних режимах? Ви все ще бачите self-insert-commandдля "коли ви робите в C-h kтой час як electric-pair-modeактивний?
Каушал Моді

@kaushalmodi: Виявляється, це electric-pair-modeпрацює, підключившись post-self-insert-hook, а не змінюючи прив'язку клавіш.
nispio

C-h kточно розповідає, що відбувається з натисканням клавіші. Якщо ви подивитеся на документацію для self-insert-command, вона дуже чітко говорить про те post-self-insert-hook, що виконується після завершення команди.
shosti

@shosti: У цьому простому прикладі так. Але що робити, що робити, якщо розширення використовує так, after-change-functionsяк згадує Джордон у своїй відповіді? Документація для функції, ймовірно, не буде конкретно згадувати про цей гачок, чи не так?
nispio

Вибачте, я повинен був бути більш конкретним. C-h k+ стандартні гачки == повна поведінка (більш-менш). Звичайно, це іноді залишає багато можливостей, але це все-таки набагато прозоріше, ніж будь-яка інша складна програмна система, про яку я знаю.
shosti

Відповіді:


13

Немає простого способу точно знати, що робитиме одна клавіша.

Якщо ви бачите додаткову поведінку, завжди перевіряйте загальні гачки. Перегляньте список тут: http://www.gnu.org/software/emacs/manual/html_node/elisp/Standard-Hooks.html

У більшості випадків важливими є:

  • функції після зміни
  • функції перед зміною
  • гачок першої зміни
  • пост-команда-гачок
  • попередньо командна гачка
  • пост-самовставлення-гачок

Вам потрібно буде оглянути ці гачки і вивчити функції, які вони містять, щоб побачити, яка з них модифікує вашу поведінку.

Якщо функції в цих гачках не повністю описують спостережувану поведінку, перевірте функції, поради, які з’являться в їхній документації від describe-function.


Редагувати: Я написав деякі функції, щоб допомогти описати гачок краще, ніж переходити по черзі через функції: https://gist.github.com/jordonbiondo/bad03e44bb053db0f1eb Ви можете використовувати describe-hookвизначені там, як інші функції опису. Ось зразок його результату:

А ось і весь код на випадок, якщо суть зникає:

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

Чи означає це, що коли функція отримує інформацію, документація автоматично оновлюється, щоб відобразити зміни?
nispio

Я не знаю, чи актуалізуються фактичні властивості, але значення, що повертається, documentationоновлюється для відображення.
Джордон Біондо

1
@nispio так, так і є.
Малабарба

1
Код / функція в gist.github.com/jordonbiondo/bad03e44bb053db0f1eb могла, і на мою думку, повинна бути включена у відповідь. Я думаю, що відповідь SE має обмеження в 30000 символів.
Faheem Mitha

4

Можливо, не на повну відповідь на ваше запитання, але пакет helm-descbindsдопомагає вам шукати всі визначені прив'язки клавіатури з представлення клавіш ascii. Для кожного удару, він показує вам інтерактивну функцію , пов'язану з клавіші швидкого доступу, і ви можете попросити , helm-descbindsщоб описати його, або виконати його безпосередньо з результатів пошуку.

введіть тут опис зображення

Ось опис пакета з сайту GitHub:

Helm Descbinds надає інтерфейс для опису прив’язок emacs, що робить активні в даний час прив'язки клавіш до інтерактивного пошуку за допомогою керма.

Крім того, у вас є такі дії

  • Виконай команду
  • Опишіть команду
  • Знайдіть команду

І C-zдасть вам стійкий опис поточної команди.


2
Це чудово. Я обов'язково це пов'язую C-h b. Єдине бажання - я можу перейти до пункту у списку, ввівши фактичну послідовність клавіш замість того, щоб набрати текстC - c _ C - p
nispio
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.