Emacs: переключаем раскладку одинаково с ОС
Наверное, первое, что неприятно поражает новичка в Emacs — невозможность использовать системные средства для переключения языка ввода. Не в том смысле, что оно не работает. А в том, что переключение на любой отличный от английского язык средствами ОС превращает Emacs в Notepad. Перестают работать все клавиатурные комбинации! Паника!
К счастью, Emacs, как и всякая уважающая себя ОС, имеет собственный механизм переключения языков, кодировок и прочего. И все это даже работает. Одна беда — нельзя повесить переключение и в системе, и в Emacs на одну и ту же клавишу, потому что система в таком случае тоже будет переключаться. А пользоваться разными сочетаниями в Emacs и вне него… Что ж, я долгое время так и поступал. Неудобно.
Итак, задача:
- Хотим переключаться везде по одной и той же клавише. Причем, чтобы если мы нажимаем эту клавишу в Emacs, использовался его внутренний механизм, в остальных случаях пусть этим занимается ОС.
- Хотим, чтобы п. 1 работал и в Windows, и в Linux. И желательно чтобы сценарий загрузки был общим.
Первый пункт, исходя из общечеловеческой логики, может быть разрешен двумя путями:
- убедить ОС не переключаться, пока активен Emacs;
- после одновременного переключения и в ОС, и в Emacs, переключить ОС обратно.
Оказывается, первый вариант реализуем в Linux, а второй в Windows. Дальнейшее изложение предполагает, что в качестве универсальной клавиши переключения выбран Caps Lock.
Для Linux палочкой-выручалочкой оказывается сочетание SCIM/iBus и xmodmap. С помощью xmodmap можно переназначить Caps Lock на какое-нибудь неиспользуемое действие, например, F13. Для этого в файл ~/.Xmodmap вписываем строку:
keycode 66 = F13
Число 66 — это код соответствующей клавиши. Скорее всего, у вас будет такой же, но лучше в этом убедиться с помощью утилиты xev.
Дальше убиваем системную переключалку раскладок (без особых зверств), и настраиваем SCIM/iBus на переключение по F13, а затем отключаем переключение для Emacs, вписывая в ~/.Xdefaults строку:
Emacs*useXIM:false
Теперь остается только подправить стартовый сценарий Emacs (.emacs или init.el), вставив туда:
(global-set-key [f13] 'toggle-input-method)
Выходим из сеанса, входим обратно, тратим еще пару часов на доработку напильником, и все заработает. Для Linux это все. Я намеренно опустил некоторые подробности про настройку SCIM/iBus, поскольку времена меняются, и старые инструкции становятся устаревшими. А тут я как бы не причем: «настройте iBus на переключение по F13» еще долго не устареет. В конце концов, гугл никто не отменял. Идея использовать SCIM и его аналоги не новая, об этом много где можно прочитать.
В Windows такой фокус не пройдет, но зато один вдумчивый камрад предложил очень изящное решение (ссылка не работает?..), которое упомянуто выше: после переключения вернуть системную раскладку обратно. (Для установки Caps Lock в качестве клавиши переключения системной раскладкой нужно воспользоваться чем-то вроде lswitch или лезть в реестр.)
Теперь остается только вооружиться переменной system-type, и получим сценарий, который кроссплатформенно решает нашу задачу:
(if (eq system-type 'windows-nt) ((defvar safe-language-change-flag nil) (defun safe-language-change () (interactive) (setq safe-language-change-flag (not safe-language-change-flag)) (when safe-language-change-flag (toggle-input-method) (w32-toggle-lock-key 'capslock))) (global-set-key (kbd "<language-change>") 'safe-language-change)) (global-set-key [f13] 'toggle-input-method))
Правда, в случае запуска в натуральной консоли проблема все еще остается.

