Клавиши

При работе с GNU Emacs следует по максимуму использовать клавиатуру и по минимуму — мышь. Обозначения клавиш в GNU Emacs несут на себе груз наследия 1970-х годов и смущают многих новичков.

GNU Emacs разрабатывался как набор сценариев, упрощающих работу с так называемыми LISP-машинами — специализированными компьютерами, предназначенными для работы с кодом на языке Lisp. Клавиатуры этих компьютеров отличались от современных, и некоторые клавиши там были на других местах. Также там были клавиши, которые на современных клавиатурах вы не найдёте.

Однако, в GNU Emacs по-прежнему используются обозначения клавиш, соответствующих клавиатурам LISP-машин.

  1. Обозначения клавиш

Обозначение LISP-машина Совр. клавиатура

C

Control

Ctrl

M

Meta

Alt

A

Alt

 — 

S

Super

Shift или Windows

H

Hyper

 — 

RET

Return

Enter

<up>

<down>

<left>

<right>

<backspace>

Backspace

Backspace

<del>

Del

Del

<prior>

PgUp

PgUp

<next>

PgDn

PgDn

Обратите внимание на то, что на клавиатурах LISP-машин была клавиша Alt, но этот не тот Alt, к которому вы привыкли.

Вы часто встретите в документации GNU Emacs или пакетов обозначения сочетаний, использующие клавишу S. Как правило, следует интерпретировать её как Shift, поскольку клавиша Super в современных операционных системах зарезервирована для более важных действий, и обычно называется Windows.

Сочетания и последовательности

В подавляющем случае в современном программном обеспечении используются сочетания клавиш (keyboard shortcut) — это набор из нескольких клавиш, которые нужно нажать одновременно. Например, Ctrl+Alt+Del, или Windows+E.

В GNU Emacs всё немного сложнее.

  • Регистр символов имеет значение.

  • Действующая раскладка имеет значение.

  • Клавиши называются ключами (keys).

  • Вместо сочетаний клавиш используются последовательности клавиш (keys sequences). Слово «последовательность» в данном случае означает, что клавиши нужно нажимать в определённом порядке.

    Если вы любите видеоигры, то знаете, что во многих из них есть комбо — последовательность нажатий кнопок, дающая особые возможности. Вот это они и есть.

    Самый простой пример последовательности — это C-x C-c. Такую запись нужно интерпретировать следующим образом:

    1. Нажмите Ctrl+x.

    2. Нажмите Ctrl+c.

Использование последовательностей позволяет связать с ними все нужные команды[1]. Далее для краткости вместо «нажмите сочетание клавиш» или «нажмите последовательность клавиш» будет использоваться сокращённая форма «нажмите».

Карты клавиш

Приведённая выше последовательность C-x C-c действует в GNU Emacs независимо от того, какие режимы активны в буфере. Однако, некоторые последовательности клавиш действуют только при активации определённых режимов. Более того, одна и та же последовательность в разных режимах может делать разные вещи.

Такое поведение достигается за счёт использования карт клавиш (keymaps).

Карты клавиш делятся на глобальную и локальные.

Последовательности из глобальной карты всегда и везде действуют одинаково. Последовательности из локальных карт действуют только если активен соответствующий режим.

Кроме этого, режим может определять собственные последовательности. В этом случае говорят, что у него собственная карта клавиш. Однако, для запуска этих последовательностей нужно использовать сочетание, называемое префиксом.

Допустим, некий режим определяет команды, привязанные к последовательностям C-a и C-c. Эти последовательности могут конфликтовать с другими режимами, и вместо нужных функций будут вызываться ненужные.

Чтобы этого не происходило, добавим в настройках карты клавиш режима префикс, например, C-t. Это значит, что для вызова нужных функций теперь нужно использовать последовательности C-t C-a и C-t C-c соответственно.

Привязки

В большинстве случаев вам нужно будет привязывать команды к глобальной карте клавиш.

Порядок привязки последовательностей следующий:

  1. Очистить существующие связи последовательности с командами с помощью функции keymap-global-unset.

  2. Связать нужную последовательность с нужной командой с помощью функции keymap-global-set.

Рассмотрим на примере из реальной жизни. По умолчанию в GNU Emacs последовательность C-z не отменяет последнюю сделанную правку, а сворачивает редактор на панель (при работе в графическом режиме) или в фон (при работе в терминале). Разумеется, такое поведение не только сбивает с толку, но и крайне неудобно.

Добавьте в init.el код, исправляющий поведение GNU Emacs при нажатии последовательность C-z:

(keymap-global-unset "C-z")
(keymap-global-set "C-z" 'undo)

Если у вас старая версия GNU Emacs и приведённый выше код не работает, перепишите его следующим образом:

(global-unset-key (kbd "C-z"))
(global-set-key (kbd "C-z") 'undo)

В старых версиях GNU Emacs функции global-set-key и global-unset-key принимают на вход код последовательности и название команды. Для определения кода последовательности нужно использовать функцию kbd. Функции keymap-global-set и keymap-global-unset определяют код последовательности автоматически.

Локализация

Если вы используете GNU Emacs с системной раскладкой, то наверняка обратили внимание, что все последовательности и сочетания работают в раскладке EN и не работают в раскладке RU.

Существует несколько способов решения этой проблемы, но я рекомендую следующие два.

Смена метода ввода

Для смены метода ввода нажмите kbd:[C-\]. Внутри GNU Emacs раскладка изменится, а сочетания и последовательности клавиш начнут работать.

Хотя этот метод решения проблемы является рекомендуемым, у него есть несколько недостатков.

  • Для фреймов GNU Emacs вам нужно будет всегда использовать раскладку EN. Впрочем, это не такая уж большая проблема в большинстве операционных систем. Достаточно включить настройку Отдельная раскладка для каждого окна.

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

Сторонний пакет reverse-im

Используйте пакет reverse-im, и тогда GNU Emacs начнёт «понимать» сочетания и последовательности клавиш в указанных раскладках и методах ввода.

Установка и настройка reverse-im.el
;; 📦 REVERSE-IM
;; https://github.com/a13/reverse-im.el
;; Чтобы сочетания клавиш работали в любой раскладке.
(use-package reverse-im
  :ensure t
  :custom
  (reverse-im-input-methods '("russian-computer"))
  :config
  (reverse-im-mode 1))

1. Вопрос удобства использования длинных последовательностей оставим за скобками.