Як оновлювати визначення другорядного режиму під час його розробки?


13

Я почав кодувати другорядний режим, щоб надати деякі клавіші. Моя початкова спроба мала друк:

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

Я мав намір скористатися bключем і одразу зрозумів, що я повинен був використовувати його "b"замість [b]. Тому я переосмислив другорядний режим:

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

Однак це не спрацювало. Це підняло мене на погоню за дикими гусками через усі різні способи прив'язки ключів (тобто (kbd ...), [...] тощо). Нарешті я зрозумів, що просто переоцінка (define-minor-mode ...)форми нічого не змінила, я застряг у оригінальній, зламаній ключовій карті. Потім я спробував змінити мапу клавіатури безпосередньо через (define-key borked-mode-map ...)і досі не міг завантажити виправлену мапу клавіш. Нарешті я перезапустив Emacs, і мій незначний режим був коректно завантажений.

Моє запитання: як ви оновлюєте визначення другорядного режиму під час його розробки? Чи є спосіб очистити зламане визначення, або вам доведеться перезапустити emacs, щоб очистити зламані біти?

Відповіді:


11

Перший раз, коли ви оцінюєте свій, define-minor-modeвін визначає змінну borked-mode-mapз вказаними вами ключами. Після того, як цей символ буде визначений, проте, повторна оцінка його define-minor-modeне змінить.

Ви можете видалити різні borked-mode-xxxсимволи за допомогою, uninternа потім переоцінити свій код. Спробуйте:

(unintern 'borked-mode-map)

Можливо, вам буде цікаво розширити define-minor-modeмакрос, щоб побачити, що він насправді робить. Поставте крапку в кінці і зателефонуйте M-x pp-macroexpand-last-sexp. Це відкриє новий буфер із відображенням розширеного макросу. Там ви побачите defvarдзвінки, які використовуються для налаштування змінних вашого режиму. Якщо ви прочитаєте довідку, defvarто побачите, що початкове значення використовується лише у випадку, якщо визначений символ недійсний - як тільки він існує, наступні defvarдзвінки не змінять його значення.


13

Я думаю, що найкраща відповідь, яку я можу дати вам, - це триматися подалі від "функції вкладених клавіатур" define-minor-mode. Використовуйте

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

Натомість. Потім ви можете використовувати C-M-xдля повторної оцінки цих визначень.


1
defvarне буде оцінювати свою цінність знову після C-M-x:) Вам знадобиться defparameterабо окремо setf.
wvxvw

Як зазначає @wvxvw, це фактично не вирішує проблему. Ваш приклад код робить те саме, що define-minor-modeробить макрос: виклик defvarдля визначення карти. Оцінка того, що дефвара вдруге не має ефекту.
glucas

7
@wvxvw Якщо ви використовуєте C-M-x( eval-defun) для переоцінки, defvarзмінна оновлюється. Це особливий випадок у Росії eval-defun; якщо ви зателефонували eval-bufferабо eval-regionтоді існуюче значення не зміниться.
Жил "ТАК - перестань бути злим"

Ага - це здається ключовим моментом.
глюкас

1
Зверніть увагу, що C-M-xу defvarформі оновляється лише сама змінна карта-карта режиму. Потрібно також C-M-xна define-minor-modeформі, щоб змінити карту "встановлено" в другорядний режим. Я спробував з’ясувати, чому розширюючи макроси, але це поза мною.
Тайлер

0

Ви можете визначити карту свого режиму так:

(defvar dnd-mode-map
  (let ((map (make-sparse-keymap)))
    (prog1 map
      (define-key map "q" 'dnd-quit)
      (when (eq this-command 'eval-defun)
        (let ((mmap (assq 'dnd-mode minor-mode-map-alist)))
          (when mmap
            (setcdr mmap map)))))))

Тепер ви можете переоцінити визначення карти за допомогою, eval-defunі воно автоматично оновить збережену карту всередині minor-mode-map-alist.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.