Как модулировать конфигурацию Emacs? - PullRequest
43 голосов
/ 17 января 2010

Я решил переписать мой .emacs с нуля, и я хочу настроить что-то модульное, чтобы избежать страшного файла 1k + LoC init.el ...

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

  • глобальные опции
  • функции редактирования
  • навигация (кадры и буферы)
  • 1012 * комбинации клавиш *
  • Настройки режимов

Пока я все еще пытаюсь продумать структуру, я ищу несколько указателей о том, как этого добиться.
Я посмотрел на некоторые .emacs на github и тому подобное, и, похоже, есть разные подходы, и нет предпочтительного способа пойти с этим, что немного сбивает с толку.
Мне было бы интересно прочитать некоторые идеи относительно того, как структурировать такую ​​установку, и особенно некоторый связанный код elisp.


edit: Догнали вещи, и у них еще не было времени поиграть с этим. Через несколько дней опробую предложенные методы и посмотрим, что лучше, а между тем спасибо за все рекомендации!


edit2: я использовал грамотный файл инициализации с org-mode , и это абсолютно потрясающе!
Я еще не настроен на конкретный механизм загрузки, я использую этот код для рекурсивной загрузки моего каталога elisp, а затем требую или как там говорится в инструкциях по установке.

  (if (fboundp 'normal-top-level-add-subdirs-to-load-path)
  (let* ((my-lisp-dir "~/.emacs.d/elisp/")
  (default-directory my-lisp-dir))
  (setq load-path (cons my-lisp-dir load-path))
  (normal-top-level-add-subdirs-to-load-path)))

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

Ответы [ 10 ]

43 голосов
/ 17 января 2010

Мой .emacs файл загружает ~ / .emacs.d / init.el , который определяет следующие функции, написанные сначала для XEmacs, но работающие достаточно хорошо для Emacs в наши дни :

(defconst user-init-dir
  (cond ((boundp 'user-emacs-directory)
         user-emacs-directory)
        ((boundp 'user-init-directory)
         user-init-directory)
        (t "~/.emacs.d/")))


(defun load-user-file (file)
  (interactive "f")
  "Load a file in current user's configuration directory"
  (load-file (expand-file-name file user-init-dir)))

Затем идет остальная часть файла и загружает множество отдельных файлов с такими формами:

(load-user-file "personal.el")

Мой текущий набор файлов выглядит следующим образом:

  • personal.el
  • platform.el
  • cygwin.el
  • variables.el
  • paths.el
  • почта-news.el
  • различ-funcs.el
  • bbdb.el
  • calendar.el
  • гну-funcs.el
  • с-и-java.el
  • lisp.el
  • clojure.el
  • go.el
  • markdown.el
  • SGML-xml.el
  • tex.el
  • spelling.el
  • packages.el
  • fonts.el
  • цвет-theme.el
  • frame.el
  • server.el
  • keys.el
  • aquamacs.el

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

6 голосов
/ 17 января 2010

Чтобы разделить настройки на разные файлы, вы можете использовать initsplit.el . Кроме того, в вики есть страница о модульном макете .emacs .

2 голосов
/ 11 июня 2012

Если вы хотите разделить ваш custom-set-variables, но хотите что-то легче, чем initsplit.el, тогда попробуйте это:

(defmacro custom-set-variable (var value)
  "Call `custom-set-variables' with a warning shown
when customizing using the customize GUI.

XXX: does not support setting the optional NOW and
REQUEST (dependency) fields."
  (custom-set-variables
    ;; `load-file-name' is set by `load-file':
    ;; http://stackoverflow.com/a/1971376/470844
    `(,var ,value nil nil
      ,(format "!!! CAREFUL: CUSTOM-SET IN %s !!!" load-file-name))))

Теперь поместите ваши конфигурационные модули в отдельные файлы и загрузите их с load-file в вашем ~/.emacs, как предлагали другие. В каждом модуль конфигурации, используйте

(custom-set-variable var value)

вместо

(custom-set-variables '(var value))

или

(setq-default var value)

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

"!!! CAREFUL: CUSTOM-SET IN <path to module file> !!!"

Если вы управляете файлами конфигурации, тогда diff скажет, какой линия вашего ~/.emacs для перехода в пользовательский модуль.

Обсуждение вопросов с наивным использованием нескольких custom-set-variables звонки: http://www.dotemacs.de/custbuffer.html

Редактировать: Ответ на вопросы Алана

Проблема, решаемая вышеупомянутым макросом custom-set-variable, решает

Интерфейс настройки в Emacs сохраняет все настраиваемые переменные в ваш ~/.emacs всякий раз, когда вы редактируете любую пользовательскую переменную набора. если ты модулировать ваши пользовательские переменные, распределяя их по несколько файлов, тогда вам нужно понять, когда Emacs вставляет дубликаты настройки в вашем .emacs, и удалите их. custom-set-variable макрос выше поможет вам сделать это.

Реальный пример из моих конфигурационных файлов

Я настраиваю переменные, связанные с пробелами в ~/.emacs.d/extensions/whitespace.el файл, который загружается моим ~/.emacs. Например, я установил свой search-whitespace-regexp переменная, как это:

(nc:custom-set-variable search-whitespace-regexp "[ \t\r\n]+")

Теперь происходят две вещи. Во-первых, когда я сталкиваюсь с этой переменной в В интерфейсе настройки я получаю предупреждение:

Generated warning in Emacs' customization dialog

Во-вторых, если я изменю какие-либо переменные с помощью интерфейса настройки, мой ~/.emacs делает очень очевидным, что я скрыл некоторые определения. Например, после изменения search-whitespace-regexp и global-whitespace-mode в интерфейсе настройки получаю:

$ svn di --diff-cmd "diff" -x "-U0" ~/v/conf
Index: /home/collins/v/conf/dot.emacs
===================================================================
--- /home/collins/v/conf/dot.emacs  (revision 267)
+++ /home/collins/v/conf/dot.emacs  (working copy)
@@ -55,0 +56 @@
+ '(agda2-include-dirs (\` ("." (\, (file-truename "~/local/opt/agda-std-lib/src")))) nil nil "!!! CAREFUL: CUSTOM-SET IN /home/collins/.emacs.d/extensions/agda.el !!!")
@@ -58,0 +60,3 @@
+ '(global-whitespace-mode t)
+ '(indent-tabs-mode nil nil nil "!!! CAREFUL: CUSTOM-SET IN /home/collins/.emacs.d/extensions/whitespace.el !!!")
+ '(indicate-empty-lines t nil nil "!!! CAREFUL: CUSTOM-SET IN /home/collins/.emacs.d/extensions/whitespace.el !!!")
@@ -72,0 +77 @@
+ '(search-whitespace-regexp "" nil nil "!!! CAREFUL: CUSTOM-SET IN /home/collins/.emacs.d/extensions/whitespace.el !!!")
@@ -74,0 +80 @@
+ '(tab-width 2 nil nil "!!! CAREFUL: CUSTOM-SET IN /home/collins/.emacs.d/extensions/whitespace.el !!!")

Макрос не помогает мне вспомнить, что я изменился search-whitespace-regexp, только то, что оно уже установлено где-то еще, но это помогает мне узнать, какие переменные настройки я должен удалить из мои ~/.emacs (все с предупреждениями) и какие из них мне следует оставить в моем ~/.emacs, или перейти на другие отдельные файлы (все те, без предупреждения).

Заключение

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

2 голосов
/ 17 января 2010

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

2 голосов
/ 17 января 2010

Вы можете сделать (require 'foo), и это загрузит первые находки "foo.el" elisp в вашем пути загрузки, или (require 'foo "/home/user/experimental/foo.el") для чего-то вне вашего пути загрузки. Он сообщит об ошибке, если «foo.el» не содержит выражения (provide 'foo). В порочной ситуации вы можете выполнить (require 'foo "bar.el"), и это будет работать до тех пор, пока в "bar.el" есть предложение (provide 'foo).

2 голосов
/ 17 января 2010

Что не так с использованием load-file?

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

  • file-exists-p
  • file-expand-wildcards

Используйте C-h f <function>, чтобы получить помощь, и вы можете найти Введение в программирование в Emacs Lisp полезным (или загрузить PDF )

1 голос
/ 28 декабря 2014

Спасибо @JoeCasadonte за упоминание страницы EmacsWiki . Поскольку я использую Debian и Ubuntu, этот конкретный фрагмент из этого кода работал очень хорошо (для помещения в .emacs.d / init.el):

(setq dotfiles-dir (file-name-directory (or load-file-name (buffer-file-name))))

(let ((user-site-start-dir (concat dotfiles-dir "/site-start.d")))
    (debian-run-directories user-site-start-dir))

Затем мне просто нужно поместить мои .el файлы в ~ / .emacs.d / site-start.d (например, ~/.emacs.d/site-start.d/50cedet.el), и все они будут загружены автоматически.

1 голос
/ 06 августа 2011

Вот библиотека, которая позволяет устанавливать новые модули, просто сохраняя их в назначенном каталоге. Его можно загрузить и установить с http://github.com/tripleee/my-site-start/

    ;;; my-site-start.el --- set up personal .emacs.d/site-start.d/
    ;;
    ;; Copyright (C) era eriksson <http://www.iki.fi/~era/> 2008-2009
    ;; License: GPL v2
    ;; Version: see `my-site-start-version' below
    ;;
    ;;; Commentary:
    ;;
    ;; The purpose of my-site-start is to simplify maintenance of user libraries.
    ;; Instead of indefinitely tweaking your .emacs, just create a site-start.d
    ;; directory and add symlinks to the libraries you want to load into Emacs.

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

Я являюсь автором этого кода и благодарен за любые отзывы (хотя и не напрямую через этот общедоступный форум).

0 голосов
/ 05 апреля 2013

Вы можете попробовать init-loader.el, это загрузчик файлов конфигурации. init-loader.el загружает файлы конфигурации из указанного каталога. Это позволяет вам классифицировать ваши конфигурации и разделить их на несколько файлов.

Для получения дополнительной информации посетите init-loader GitHub Repo

0 голосов
/ 17 января 2010

Я сделал для каждой вещи, X, которую я мог бы использовать, создал файл с именем configure-X и поместил соответствующий require в .emacs. Затем эту функцию можно удалить, закомментировав одну строку.

Например, чтобы выбрать самое простое (если наименее названное), у меня есть configure-picture-and-artist-mode.el. Этот файл очень прост:

(global-set-key (kbd "C-M-P")
                'picture-mode)

(provide 'configure-picture-and-artist-mode)

И в .emacs:

(require 'configure-picture-and-artist-mode)

После сортировки у меня ничего нет в моем .emacs, за исключением большого списка require s и нескольких изменений в load-path, данный пакет может быть удален довольно легко, и вся конфигурация для каждая упаковка в одном месте.

(У меня также есть универсальный файл .el, который я использую для хранения вещей, которые не имеют очевидного дома (мои глобальные привязки клавиш, вспомогательные функции и т. Д.), Но в идеале хотят остаться вне. emacs. Этот бит не очень модульный, и может вводить неявные зависимости от пакетов, которые моя схема должна легко выгружать, но на практике это не кажется большой проблемой.)

...