Введение в Emacs

Сначала позволю себе небольшое введение в историю возникновения и развития Emacs. Думается, будущий emacs'ер должен хотя бы в общих чертах представлять откуда растут уши у его любимого текстового редактора. Если же это не совпадает с действительностью, спокойно пропустите раздел, и пусть по ночам вас мучает совесть.

В 70-х годах XX века парня по имени Ричард Столлман занесло в Standford AI Lab, где он познакомился с чудесным редактором E, умеющим осуществлять редактирование в реальном времени. Будучи под впечатлением, Ричард бросился реализовывать возможности E в другом редакторе — TECO. Собственно, последний и послужил прототипом для создания Emacs.

Вообще, первым из Emacs'ов для UNIX был Gosling Emacs. Сам Gosling написан на языке C, а расширения к нему на одном из диалектов языка Lisp.

Но Gosling был проприетарной программой, и в 1984 Столлман начал разработку его новой, свободной реализации: GNU Emacs. Так появился герой сегодняшнего рассказа, выдержавший уже более двадцати релизов и являющийся одним из старейших текстовых редакторов.

Впрочем, это не просто редактор. Emacs не придерживается философии UNIX (одна задача — одна программа), он разработан в качестве среды «всё в одном». Как иногда шутят пользователи «Emacs — отличная операционная система, которой не хватает лишь хорошего текстового редактора».

Например, Emacs сумеет организовать вашу жизнь, вовремя доставить почту и даже сварить кофе.

emacs

Необыкновенная гибкость Emacs «компенсируется» его сложностью. По-началу сочетания горячих клавиш кажутся неудобными (да что там, попросту варварскими!), но привыкаешь к ним достаточно быстро, а дальше уже просто не представляешь жизнь в каком-то отличном от Emacs редакторе. Даже если изначально вам будет сложно приспособить свои пальцы, переборите искушение вернуться в редкатор, используемый ранее — просто работайте в Emacs и вскоре лёгкий ветер перемен ворвётся в ваше рабочее пространство. Странно признавать это, но пока Emacs лучший из мира свободных редакторов, которых автору довелось увидеть немало.

Начало работы

Кому не следует читать этот пост?

Если вы чувствуете, что не готовы потратить несколько вечеров на освоение и небольшую доводку редактора (Emacs можно доводить до идеального состояния очень много лет, но это под силу лишь опытным пользователям, на которых материал не рассчитан), остановитесь. Emacs «из коробки» не принесёт вам много пользы. Те, кто предпочитает usef-friendly редакторы, могут обратить свой взор на SublimeText. Он не обладает всеми возможностями Emacs, он распространяется не под свободной лицензией, но имеет одно несомненное достоинство (третье НЕ): не требует усилий при доводке под себя.

Если читатель ещё здесь

При наличии желания освоить редактор, но без знания Lisp тоже можно жить, поэтому расстраиваться нет причин: в конце поста будут даны ссылки, призванные оказать посильную помощь в освоении объёмного материала, а вместе с ними места´, где можно добыть готовую конфигурацию, дабы не приходилось тянуться за напильником с первых же дней работы.

Пожалуй, лучшее, с чего можно начать, это интерактивный учебник, встроенный в сам Emacs. Последовательно наберите команды C-u + C-h + t для выбора языка учебника.

Здесь будет лишь приведена графическая шпаргалка по использованию наиболее часто употребляющихся команд. Всё остальное вы найдёте в упомянутом интерактивном учебнике, документации по Emacs или иных многочисленных руководствах. Мы остановимся на наиболее интересных моментах, которые должны быть понятны новичку и не займут много времени для описания. Разумеется, такие вещи как знаменитый org-mode не будут влючены в это начальное руководство.

Условимся:

  • M — клавиша модификатор (по-умолчанию Alt)
  • Ctrl — клавиша Control
  • предполагаемая версия GNU Emacs 24

Шпаргалка по командам Emacs, подготовленная специально для этого поста (может, кому пригодится в начале пути):

Emacs Help

Настройка Emacs

За основу взят пакет emacs.d от purcell.

Переопределение сочетаний клавиш

Вряд ли вам хватит тех команд, что приведены в учебнике Emacs. Возможно, некоторые из них вы захотите переопределить. Например, у автора сочетание команд Alt+Shift по-привычке связано с переключением раскладки клавиатуры, а в Emacs сочетание клавиш Ctrl+Alt+Shift+1 открывает своеобразный shell, куда можно вписать консольную команду, дабы затем её исполнить.

Как пример: вы пишете документ в LaTeX и через какое-то время у вас возникает непреодолимое желание взглянуть на результат своих трудов. Что же, это не проблема. Указанное выше сочетание клавиш позволит вам запустить команду для сборки pdf-документа из tex-файла и насладиться просмотром.

Но как использовать эту команду, если часть её просто совпадает с командой переключения раскладки? Не беда, сейчас мы исправим это.

Для переопределения клавиш заведите себе отдельный файл .emacs. В случае, если вы желаете подключать дополнительные пакеты, вносить многочисленные правки или даже писать свои расширения, лучше складывать конфигурационные файлы в директорию ~/.emacs.d/, откуда Emacs будет читать настройки при запуске.

Например, файл наших настроек мы назовём init-key-bindings.el, там определим клавиши, которые следует изменить. А в другом файле (Emacs будет читать его и инициализировать команды) init.el подключим наше, скажем так, расширение. Например:

;; init-key-bindings.el
;;----------------------------------------------------------------------------
;; Key bindings
;;----------------------------------------------------------------------------

(global-set-key (kbd "C-x /") 'shell-command) ;; run shell
; или вообще применить клавишу super как meta
; (setq x-super-keysym 'meta) ;; set meta key

(provide 'init-key-bindings)

Дальше идём править init.el:

; init.el
(require 'init-key-bindings)

Как становится понятно, самый главный файл — это init.el. Он загружает пакетный менеджер ELPA и при первом запуске доустанавливает из сети указанные пакеты. Это весьма полезно, поскольку при большом количестве сторонних пакетов позволит не тратить время на их повторный поиск, установку и настройку: настройки будут записаны вами в init-* файлы, пакеты подключены в init.el и при переносе конфигурации на другую машину от вас ровным счётом ничего больше не потребуется. Автоматизация — отличная штука.

Конечно, подгружаемые файлы могут носить любое название и необязательно должны начинаться с init.

Управление пакетами

Emacs может включать множество пакетов на все случаи жизни. Для управления пакетами используется менеджер этих самых пакетов: ELPA, позволяющий с лёгкостью находить доступные для загрузки пакеты, инсталлировать и обновлять их.

Для указания репозитория пакетов добавьте в ваш файл init.el следующие строки:

(when (>= emacs-major-version 24)
  (require 'package)
  (package-initialize)
  (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
)

Перезапустите Emacs.

Чтобы просмотреть список доступных для установки пакетов, введите команду C-x list-packages. Поиск по пакетной базе осуществляется точно так же как в обычном файле: командой C-s.

Для установки пакета следует перевести на него курсор и нажать i (install). Это пометка, сигнализирующая о том, что пакет должен быть установлен. В свою очередь отметка d (delete) укажет на то, что пакет следует удалить; отметка u снимет эти флаги. Непосредственная установка начнётся после того, как вы выберете все пакеты и нажмёте x.

Существует несколько источников, откуда можно невозбранно утащить пакеты для установки. Вот они:

Шрифт

Пользователям Emacs 23 и выше несказанно повезло: все проблемы с юникодом решены в этой версии. Отставить бубен! Просто укажите шрифт, который должен использовать Emacs.

Для поддержки TTF шрифтов редактор должен быть собран с флагом xft.

# ~/.Xdefaults

# любимый шрифт
Emacs.font: Consolas:size=11:antialise:true
Emacs.FontBackend: xft

# запуск редактора с определённой геометрией
Emacs.geometry: 160x43

Темы

Emacs, как и любой уважающий себя редактор, поддерживает смену тем оформления. На данный момент любимой темой автора является Github, стиль которой можно наблюдать на скринах ниже.

Темы можно установить при помощи пакетного менеджера, но для примера мы установим github вручную.

Для этого следует перейти на страницу проекта и загрузить репозиторий, после чего распаковать файл github-theme.el в каталог .emacs.d/themes и указать Emacs'у использовать эту директорию для подгрузки тем.

; init.el
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/")

Чтобы быстро выбрать/сменить тему введите сочетание клавиша-модификатор+x(вспоминаем: по-умолчанию модификатором является Alt). Начните набирать команду load-theme, затем выбирайте из списка доступных тем ту, что нравится вам больше всего.

Смена темы происходит очень быстро, Emacs может спросить вас применить ли тему и использовать ли её без вопросов в будущем. Дабы вручную указать «дефолтную» тему добавьте ещё одну строку:

; init.el
(setq-default custom-enabled-themes '(github))

Мы не коснулись ещё одного важного файла, присутствующего в Emacs: custom.el. Он содержит настройки внешнего вида редактора и может быть заполнен автоматически в том случае, когда вы кастомизируете настройки при помощи графического интерфейса.

emacs customize

Вам могут пригодиться команды M-x customize или M-x customize-group, предоставляющие упомянутый интерфейс для настроек. Воспользуйтесь ими.

Кроме того, некоторые настройки поведения удобнее описать всё в том же init.el:

;;-----------------------
;; Emacs appearance setup
;;-----------------------

(setq display-time-day-and-date t ; display day and date
      display-time-24hr-format t ; use 24hr format
      display-time-interval 10 ; redisplay every ten seconds
      display-time-default-load-average nil) ; don't display the system load average
(display-time)
(display-battery-mode 1)

Подобные настройки заставят Emacs отображать дату и время в 24-часовом формате и заряд батареи ноутбука, обновляя данные каждые 10 секунд.

Проверка орфографии

Для проверки орфографии имеется встроенная интерактивная система Ispell. Чтобы проверять орфографию «на лету» (подробности о словарях и настройке имеются на соответствующей вики-странице) следует дать команду Alt+x и ввести flyspell-mode. Чтобы включить проверку раз и навсегда в комментариях к коду или же в обычном тексте (plain text) откройте файл init.el и допишите:

;;----------------------------------------------------------------------------
;; Enable automatic spell checking
;;----------------------------------------------------------------------------

(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'prog-mode-hook 'flyspell-mode)

Выглядит это так:

emacs flyspell

Проблемы могут возникнуть при проверке текста, в котором есть как английские, так и русские слова.

Поддержка синтаксиса языков программирования

В основном осуществляется при помощи сторонних плагинов. Для примера установим python-django.

Дабы не приходилось искать и загружать пакет снова при работе на другой машине, как уже оговаривалось выше, будем фиксировать планируемые изменения в соответствующих файлах.

; init-python-django

(require-package 'python-django)
(global-set-key (kbd "C-x j") 'python-django-open-project)
((python-mode
  (python-shell-interpreter . "python")
  (python-shell-interpreter-args . "~/workspace/python/site/manage.py shell")
  (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
  (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
  (python-shell-completion-setup-code . "from IPython.core.completerlib import module_completion")
  (python-shell-completion-module-string-code . "';'.join(module_completion('''%s'''))\n")
  (python-shell-completion-string-code . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
  (python-shell-extra-pythonpaths . "~/workspace/python/site/apps/")
  (python-shell-virtualenv-path . "~/.virtualenvs/site")))

(provide 'init-python-django)

не забываем загрузить и инициализировать сам пакет

; init.el

(require 'init-python-django)

Внимание!

Рассмотренный пакет нуждается в дополнительных настройках как то: указание путей к директории виртуального окружения, каталогу с проектом и приложениями:  подробнее.

Примерно так следует поступать и с остальными языками.

Разные языки программирования имеют разные требования при написании кода. Прежде всего это относится к отступам: их количеству, использованию пробелов или же табуляции. Emacs позволит подстроиться под каждый язык. К примеру, укажем никогда не использовать табуляцию и настроим ширину отступа для нескольких языков.

; init.el

;;--------------------
;; Indentation setup
;;-------------------

(setq-default indent-tabs-mode nil) ; never use tab characters for indentation
(setq tab-width 2 ; set tab-width
      c-default-style "stroustrup" ; indent style in CC mode
      js-indent-level 2 ; indentation level in JS mode
      css-indent-offset 2) ; indentation level in CSS mode
(add-hook 'python-mode-hook
          (lambda ()
            (setq tab-width 4)
            ))

(add-hook 'ruby-mode-hook
          (lambda ()
            (setq tab-width 2)
            ))

Также может оказаться полезной команда untabify, которая переведёт все отступы в пробелы (что бывает полезно при работе с чужим кодом, когда встречается мешанина из пробелов и табуляции).

Разное

Emacs может служить проводником в мире файлов. Рассмотрим несколько часто встречающихся ситуаций:

Вам хотелось бы удалить файл, но не хотелось бы при этом покидать уютный буфер текстового редактора. Не проблема! Заветное сочетание клавиш M+x, ввод команды delete-file и — вуаля! — файл уничтожен! Будьте аккуратны с этой командой, вас не станут переспрашивать действительно ли вам нужно удалить именно этот файл.

Или, к примеру, хочется посмотреть сколько строк кода уже написано. Как отобразить количество строк кода слева от основного текста?

И снова на выручку приходит M-x. Впишите linum-mode, эффект не заставит себя ждать.

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

Вы можете включить режим автозаполнения, набрав M-x auto-fill-mode<Return>. Когда этот режим включен, его можно выключить с помощью той же команды. Граница разбиения обычно равна 70-ти символам, но вы можете изменить ее используя команду C-x f. Вы должны задать границу в виде числового аргумента для этой команды.

Но что делать, если этот режим хочется держать включенным всегда? При выходе из Emacs подобные настройки будут сброшены. Что ж, мы снова пойдём править init.el:

;;----------------------------------------------------------------------------
;; Enable auto-fill (80 lines)
;;----------------------------------------------------------------------------

(add-hook 'text-mode-hook 'turn-on-auto-fill)
(add-hook 'text-mode-hook
  '(lambda() (set-fill-column 80)))
(add-hook 'prog-mode-hook 'turn-on-auto-fill)
(add-hook 'prog-mode-hook
  '(lambda() (set-fill-column 80)))

Невероятно удобной вещью являются закладки. Если вы часто обращаетесь к какому-то файлу (это может быть ваш todo-лист в org-mode ;), есть возможность добавить его в закладки. Для управления закладками служат команды:

  • C-x r m — установить закладку
  • C-x r l — отобразить все закладки
  • C-x r b — перейти к закладке
  • M-x bookmark-delete удалить закладку

Весьма радует умное расположение буферов/окон. Но об этом нечего говорить, лучше один раз увидеть:

Emacs Buffer

Автор очень любит редактировать markdown-текст, и после SublimeText не хватало такой приятной мелочи как предварительный просмотр этого самого текста в браузере. В частности такой подход относится к тем, кто использует Jekyll, Pelican или иные движки для ведения блога. Не будешь ведь каждый раз запускать веб-сервер для генерации страниц только лишь для того, чтобы явно увидеть результат?

Вы не проградаете и здесь: Emacs выручит нас, если использовать markdown-mode.

После установки плагина введите уже частично знакомую комбинацию M-x markdown-preview. Разумеется, сам markdown должен быть установлен и доступен по указанному в настройках пути. Мы условились использовать для настроек init-* файлы, поэтому пример будет выглядеть следующим образом:

; init-markdown.el

(require-package 'markdown-mode)

;;; Markdown mode
(autoload 'markdown-mode "markdown-mode"
"Major mode for editing Markdown files" t)
; Ассоциировать файлы с расширением
; .markdown и .md с markdown-mode
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
; с markdown2 можно включать дополнительные плюшки
; такие как fenced-code-blocks
(setq markdown-command "/usr/local/bin/markdown2 -x fenced-code-blocks")

(provide 'init-markdown)

При подключении новых пакетов не нужно ничего выдумывать: все доступные опции и примеры подключения как правило описаны в репозитории пакета. Просто не забудьте дать Emacs'у указание на его (пакета) загрузку:

; init.el

(require 'init-markdown)

Вместо заключения

Как было обещано в начале этого небольшого обзора, приводятся ссылки для быстрого приготовления текстового редактора. Автор искренне считает, что товарищам, не сведующим в программировании вообще и Lisp в частности, изначально лучше воспользоваться готовой конфигурацией.

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

  1. EmacsWiki (увы, русская версия оставляет желать лучшего)
  2. Руководство по GNU Emacs. Ричард Столлман
  3. Для быстрого старта можно воспользоваться Emacs Starter Kit (подготовит основу) или emacs.d/ имени purcell
  4. Программирование на Emacs Lisp
  5. GNU Emacs Manuals Online