24.2.9 Примеры основных режимов

Режим текста, возможно, является самым простым режимом наряду с Основным режимом. Вот выдержки из text-mode.el, иллюстрирующие многие из вышеупомянутых соглашений:

;; Создать таблицу синтаксиса для этого режима.
(defvar text-mode-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?\" ".   " st)
    (modify-syntax-entry ?\\ ".   " st)
    ;; Добавить 'p', чтобы M-c на 'hello' приводил к 'Hello', а не к 'hello'.
    (modify-syntax-entry ?' "w p" st)
    …
    st)
  "Таблица синтаксиса, используемая в режиме `text-mode'.")

Вот как теперь определяется фактическая команда режима:

(define-derived-mode text-mode nil "Text"
  "Основной режим для редактирования текста, предназначенного для чтения человеком.
В этом режиме абзацы разделяются только пустыми или белыми строками.
Таким образом, вы можете получить всю выгоду от адаптивного заполнения
(см. переменную `adaptive-fill-mode').
\\{text-mode-map}
Включение режима Text запускает обычный хук `text-mode-hook'."
  (setq-local require-final-newline mode-require-final-newline))

Три режима Lisp (режим Lisp, режим Emacs Lisp и режим взаимодействия Lisp) имеют больше функций, чем режим Text, и код соответственно более сложен. Вот выдержки из lisp-mode.el, иллюстрирующие, как эти режимы написаны.

Вот как определяются синтаксис и таблицы сокращений для режима Lisp:

;; Создать переменные таблиц, специфичные для режима.
(define-abbrev-table 'lisp-mode-abbrev-table ()
  "Таблица сокращений для режима Lisp.")

(defvar lisp-mode-syntax-table
  (let ((table (make-syntax-table lisp--mode-syntax-table)))
    (modify-syntax-entry ?\[ "_   " table)
    (modify-syntax-entry ?\] "_   " table)
    (modify-syntax-entry ?# "' 14" table)
    (modify-syntax-entry ?| "\" 23bn" table)
    table)
  "Таблица синтаксиса, используемая в `lisp-mode'.")

Три режима для Lisp имеют много общего в своем коде. Например, режим Lisp и режим Emacs Lisp наследуются от режима Lisp Data, а режим Lisp Interaction наследуется от режима Emacs Lisp.

Среди прочего, режим Lisp Data настраивает переменную comment-start для обработки комментариев Lisp:

  (setq-local comment-start ";")
  …

Каждый из различных режимов Lisp имеет немного отличающуюся карту клавиш. Например, режим Lisp привязывает C-c C-z к run-lisp, но другие режимы Lisp — нет. Однако все режимы Lisp имеют некоторые общие команды. Следующий код настраивает общие команды:

(defvar-keymap lisp-mode-shared-map
  :parent prog-mode-map
  :doc "Карта клавиш для команд, общих для всех типов режимов Lisp."
  "C-M-q" #'indent-sexp
  "DEL" #'backward-delete-char-untabify)

И вот код для настройки карты клавиш для режима Lisp:

(defvar-keymap lisp-mode-map
  :doc "Карта клавиш для обычного режима Lisp.
Все команды в `lisp-mode-shared-map' наследуются этой картой."
  :parent lisp-mode-shared-map
  "C-M-x" #'lisp-eval-defun
  "C-c C-z" #'run-lisp)

Наконец, вот команда основного режима для режима Lisp:

(define-derived-mode lisp-mode lisp-data-mode "Lisp"
  "Основной режим для редактирования кода Lisp для Lisps, отличных от GNU Emacs Lisp.
Команды:
Delete преобразует табуляции в пробелы при движении назад.
Пустые строки разделяют абзацы. Точки с запятой начинаются комментарии.

\\{lisp-mode-map}
Обратите внимание, что `run-lisp' может использоваться как для запуска вспомогательной задачи Lisp,
так и для переключения на существующую.")
  (setq-local find-tag-default-function 'lisp-find-tag-default)
  (setq-local comment-start-skip
              "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *")
  (setq imenu-case-fold-search t))