Привязка клавиш Emacs не работает в пользовательском основном режиме

Я нахожусь на ранней стадии создания основного режима для Emacs для просмотра и взаимодействия со стеком. Обменная сеть.

В нем задействовано несколько основных режимов, все с одноклавишными сочетаниями клавиш, похожими на dired. Я просмотрел исходный код dired и извлек то, что, по моему мнению, сработает:

(defvar stack-network-mode-map
  (let ((map (make-keymap)))
    (define-key map "n"     'stack-network-next-site)
    (define-key map "p"     'stack-network-previous-site)
    (define-key map ","     'stack-network-move-site-up)
    (define-key map "."     'stack-network-move-site-down)
    (define-key map "j"     'stack-network-jump-to-bookmarks)
    (define-key map "\C-m"  'stack-network-do-enter-site) ; ret
    (define-key map "o"     'stack-network-do-enter-site)
    (define-key map "u"     'stack-network-do-profile-summary)
    (define-key map "\C-uu" 'stack-network-do-profile-summary-for-user)
    (define-key map "i"     'stack-network-do-inbox)
    (define-key map "b"     'stack-network-toggle-bookmark)
    (define-key map "?"     'stack-network-list-functions) ; [1]
    (define-key map "\C-i"  'stack-network-display-details) ; tab
    map)
  "Keymap for Stack Exchange: Network Browser major mode")

но, к сожалению, это, кажется, не имеет абсолютно никакого эффекта; буфер просто редактируется, как и любой другой обычный буфер. Как я могу добиться привязки клавиш с одним ключом, если это не так? (Кстати, я в этом уверен. Здесь должно быть что-то еще.)


person Sean Allred    schedule 27.02.2013    source источник
comment
Нужны подробности... Я загружаю пакет, на который вы ссылаетесь, и он отлично работает. Доступны все привязки основных режимов (хотя они и не определены).   -  person Trey Jackson    schedule 28.02.2013
comment
Не определяйте основные режимы с помощью defun. Используйте define-derived-mode, который обрабатывает за вас весь шаблон, включая уничтожение локальных переменных, переключение карты клавиш, установку переменных основного режима, запуск хуков и т. д.   -  person lunaryorn    schedule 28.02.2013


Ответы (3)


Вы хотите определить stack-network-mode с помощью define-derived-mode (и сделать его производным от special-mode, например).

Другие комментарии к вашему коду:

  • используйте () вместо nil для пустых списков аргументов.
  • stack-network-next-site должен иметь (interactive) сразу после строки документации, чтобы сделать его интерактивной командой, иначе он не будет работать как привязка клавиш.

Если вы не хотите использовать special-mode, вы можете вызвать supress-keymap сразу после создания make-keymap.

person Stefan    schedule 28.02.2013
comment
Это предотвращает редактирование буфера (полагаю, благодаря special-mode), но ключи по-прежнему не привязаны :( (Кроме того, насколько мне известно, () === nil.) - person Sean Allred; 28.02.2013
comment
Если вы хотите увидеть код в его нынешнем виде, это здесь (конкретная фиксация связана, чтобы сохранить использование для дальнейшего использования) - person Sean Allred; 28.02.2013
comment
@vermiculus () === nil имеет место, но принято использовать () для пустых списков аргументов. nil в этом месте большинству программистов Emacs Lisp кажется тревожным. - person lunaryorn; 28.02.2013
comment
@lunaryorn Я буду иметь это в виду - я в основном использовал его, потому что мне гораздо быстрее печатать, и идея «нулевых аргументов» по-прежнему имеет смысл. Но если нам нужна конвенция, полагаю, я соглашусь. Я все еще застрял; смотри первые два комментария. - person Sean Allred; 28.02.2013
comment
Переместите определение stack-network-mode-map перед формой define-derived-mode. В противном случае define-derived-mode неявно определяет stack-network-mode-map с вновь созданной раскладкой. defvar однако не изменяет значения переменных, которые уже установлены. - person lunaryorn; 28.02.2013
comment
@lunaryorn, не могли бы вы отредактировать это в ответе? Вот что исправило это навсегда! - person Sean Allred; 28.02.2013
comment
@vermiculus Я добавил это как новый ответ. - person lunaryorn; 01.03.2013
comment
К сожалению, все, что я могу вам дать, это голосование. - person Sean Allred; 01.03.2013
comment
@vermiculus Меня не волнуют голоса и репутация моих ответов. - person lunaryorn; 01.03.2013
comment
@lunarorn это справедливо. Это такая же часть решения, как и принятый ответ - мне было бы нелегко понять тот факт, что defvar немного глупо, а define-derived-mode ведет себя так. По своей сути голосование — это способ сказать «спасибо». - person Sean Allred; 01.03.2013

Переместите определение stack-network-mode-map перед определением режима. В противном случае define-derived-mode неявно определяет эту переменную, а defvar не изменяет значение переменных, отличных от nil, поэтому карта фактически будет пустой.

См. Производные режимы:

Новый режим имеет собственную разреженную раскладку под названием variant-map. define-derived-mode делает раскладку клавиатуры родительского режима родительской для новой карты, если вариант-map уже не установлен и уже имеет родителя.

person lunaryorn    schedule 01.03.2013

Вы определили раскладку клавиатуры, но не использовали ее. Переменная существует, но не фиксирует никаких ключевых событий.

(use-local-map stack-network-mode-map)
person John Andrews    schedule 28.02.2013