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

image

Опять что-то конфигурировать?


Без паники, если у вас всё и так уже прекрасно работает, ничего менять не нужно. Если же что-то из приведённого ниже списка давно томится в запылённом туду-списочке, но времени засучить рукава как обычно не хватает, то вам будет интересно взглянуть. Итак, что же предлагает вам ECFG:

  • Хранение всей конфигурации в гит-репозитории.
  • Автоматическая загрузка свежих версий всех сторонних пакетов по сети во время первого запуска.
  • Оптимизированная скорость загрузки редактора: подключенные модули автоматически загружаются только в момент использования.
  • Легковесный фреймворк практически не вмешивается в код конфигурации, позволяя включать найденные в сети сниппеты и по-прежнему пользуясь всеми вышеперечисленными преимуществами.
  • Добавлять или изменять конфигурацию легко и интуитивно — даже когда вы успели позабыть всё elisp-кунг-фу (автор убеждался неоднократно)

Исходный код размещен в открытом доступе на гитхабе: github.com/maslennikov/emacs-config.

Emacs Config. Начало


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

По мере накопления опыта и различных хотелок все более объёмные плагины начали перемещаться в ~/.emacs.d/. Всё это, однако, требовало все больше склеивающей логики и управления зависимостями, и одного ~/.emacs становилось очевидно недостаточно.

Со временем код инициализации был разбит на раздельные модули, и достаточно долгое время ~/.emacs.d/ с этими модулями и вручную собранными с просторов интернета плагинами синхронизировалась через Dropbox со всеми моими рабочими станциями.

В этот период я начал остро ощущать проблему контроля версий плагинов. Примерно в это же время начал набирать популярность package.el и идея автоматического управления установкой пакетов уже перестала казаться утопией. Ещё одной из причин для автоматизации установки плагинов было желание перейти от простой синхронизации через Dropbox к полноценному репозиторию на гитхабе: конфигурационного кода было уже неприлично много для того, чтобы позволять себе не пользоваться системой контроля версий, а файрвол на новом рабочем месте блокировал к тому же мой дропбокс. Хранить же скачанные с интернета и неуправляемые исходники и бинарные файлы плагинов на гитхабе принципиально не хотелось.

Переломный момент наступил тогда, когда мной был обнаружен конфигурационный фреймворк Oh My Emacs, представлявший собой практически идеальное решение для всех моих нужд. За исключением одного момента: он был медленным. Очень. Это и послужило толчком для создания проекта ECFG.

Установка


На данный момент ECFG не использует ни ~/.emacs, ни ~/.emacs.d/. Это сделано намеренно для того, чтобы исключить возможность автоматического изменения библиотеки редактором или подключенными плагинами. С другой стороны, все артефакты различных модулей (например файлы истории recentf) найдут своё изначально задуманное место в ~/.emacs.d, а настройки, уникальные для каждого пользователя (например, custom-set-variables и пр.) могут быть свободно размещены в ~/.emacs.

Информацию для более тонкого контроля над этим процессом вы найдёте в справке к переменным user-emacs-directory и custom-file.

Для установки ECFG сохраните копию репозитория на свою рабочую станцию в любую директорию:
git clone https://github.com/maslennikov/emacs-config.git ~/.emacs.config

Чтобы научить Emacs загружать ECFG, достаточно разместить следующие строки в ваш ~/.emacs
;; in case you use windows, teach it the utf8
(prefer-coding-system 'utf-8)
(load-file "~/.emacs.config/init.el")

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

Как это работает


Как указано в вашем ~/.emacs, точкой входа для ECFG является файл init.el, который управляет последовательностью загрузки всех остальных модулей.

Файлы конфигурации (как раз то, ради чего это всё и затевалось), сгруппированы в двух директориях:
  • init.d: содержит базовую конфигурацию редактора, независимую от типа файла или режима в текущем буфере;
  • modules: содержит конфигурацию, применимую к файлам или режимам определенного типа.


Базовая конфигурация из директории init.d/ загружается синхронно во время запуска редактора, отчего особое внимание было уделено оптимизации скорости исполнения этого кода (более подробную информацию об оптимизации подключаемых модулей вы можете получить здесь).

Конфигурация основных режимов из директории modules подготавливает ленивую загрузку модулей с помощью механизма autoloads. Для этого достаточно определить в файле модуля функцию инициализации с именем ecfg-NAME-module-init и зарегистрировать ее с помощью макроса ecfg-auto-module. Например, подключение нового модуля для конфигурации режима cmake осуществляется следующим образом:
;;;###autoload (ecfg-auto-module "CMakeLists\\.txt$" cmake)

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


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

Комментарии (15)


  1. BelBES
    05.10.2015 21:20
    +2

    Мне кажется, что со временем у всех Emacs-пользователей конфиг приходит примерно к такому модульному виду :-)


    1. geeqie
      05.10.2015 21:46
      +1

      Да, со временем наступает просветление, что конфиг твой это уже не просто список простых настроек, а более-менее взрослое приложение, к которому и относиться нужно соответствующе :)


  1. D_Bushenko
    05.10.2015 22:53
    +1

    Отличный пример организации конфигов! Остается надеяться, что идея фреймворка не заглохнет через пару месяцев.
    Ваш emacs-config стоит рекомендовать всем, кто всерьез осваивает Emacs.


    1. monah_tuk
      06.10.2015 08:29

      Я бы порекомендовал ещё: github.com/alexott/emacs-configs

      ну и я тоже пришёл к подобной схеме и хранению конфигов в git.


    1. geeqie
      06.10.2015 08:55

      Спасибо! Идею я специально не спешил выкатывать на всеобщее обозрение, решив испытать её предварительно в бою. И был очень приятно удивлен тем, как всё просто и предсказуемо работает. Поэтому покуда не перевелись ещё буквы в алфавите, будем набирать их в emacs.


  1. loz
    05.10.2015 23:40
    +1

    Вобще в последнее время копировать какие-то сниппеты elisp-кода не приходится, все более-менее нужные пакеты уже в elpa и настраиваются через M-x customize-group. Но все равно спасибо за статью :)


    1. abatyuk
      06.10.2015 07:36

      Черт, я понял, что что-то забыл. После пятнадцатилетнего перерыва настроил себе emacs для работы с clojure, так ни разу в customize-group и не сходил.


    1. geeqie
      06.10.2015 09:01

      Так и есть, сниппеты это было давно, когда деревья были большими :) Сейчас основное внимание уделено автоматизации деплоя конфига и оптимизации скорости загрузки модулей. Я из тех олдфагов, которые не пользуются emacs-server, и предпочитают держать по пять окон редактора открытыми для различных контекстов.


      1. loz
        06.10.2015 09:41

        Да вроде нет причин не использовать emacs-server, это как тот же tmux, нет опасности закрыть его как-то, не сохранив все что было. Правда, в таком случае, бывает под 500+ открытых буферов, но в общем случае это неважно)


        1. PerlPower
          06.10.2015 11:42

          Я стараюсь не держать все в одном окне, потому что иногда бывает запускаешь в eshell неубиваемый процесс, или процесс с большим выхлопом, или открываем большой файл в НЕ-fundamental-mode и все может повиснуть. Emacs-server от такого спасает?


          1. mkpankov
            06.10.2015 12:27

            Не спасает. Фундаментальная проблема сервера Emacs для меня в том, что он слишком жёстко связан с окружающим миром. Изоляция процессов плохая. Заглючило sudo в tramp-mode и всё повисло? Убивай сервер. Запустил что-то слишком прожорливое или медленное? Сервер висит вместе с процессом. Короче, не 21-й век: асинхронности мало.


          1. loz
            06.10.2015 13:32

            От этого спасает desktop-mode, в какой-то степени. Хотя у меня емакс редко прям виснет, обычно можно по C-g что-то сделать.


  1. mkpankov
    07.10.2015 10:35

    А вы пробовали Emacs Prelude?


    1. geeqie
      07.10.2015 16:14
      +1

      Нет, но я знаю о существовании такого рода стартер-китов: spacemacs, prelude, oh-my-emacs, emacs24-starter-kit… это все хорошо, когда ты начинаешь знакомиться с редактором и хочешь быстро получить более-менее налаженную систему. Но когда ты годами собираешь по крупицам свой собственный конфиг и максимально контролируешь свои любимые режимы, то перепиливать под себя что-то существующее может оказаться затратнее, чем навелосипедить решение для своих нужд.


  1. BelBES
    10.10.2015 18:23

    Кстати, заметил, что вы пользуетесь semantic для C++… у вас как-то получилось заставить его работать в фоне и не подвешивать время от времени редактор для индексации хедеров?