Подтвердить что ты не робот

Как модулировать конфигурацию emacs?

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

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

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

Пока я все еще общаюсь, чтобы думать о структуре, я ищу несколько указателей на то, как добиться этого.
Я посмотрел на некоторые .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)))

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

4b9b3361

Ответ 1

Мой файл .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 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
  • org.el
  • packages.el
  • fonts.el
  • цвет-theme.el
  • frame.el
  • server.el
  • keys.el
  • aquamacs.el

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

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

Ответ 5

Если вы хотите разделить свой 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, только, что он уже установлен где-то в другом месте, но это помогает мне узнать, какие переменные настройки я должен удалить из my ~/.emacs (все с предупреждениями), и какие я должен уйти в моем ~/.emacs, или перейдите к другим отдельным файлам (все без предупреждения).

Заключение

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

Ответ 6

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

Ответ 7

Вот библиотека, которая позволяет вам устанавливать новые модули, просто сохраняя их в назначенном каталоге. Его можно загрузить и установить из 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.

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

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

Ответ 8

Что я сделал для каждой вещи 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 и нескольких изменений в load-path, данный пакет можно удалить довольно легко, и вся конфигурация для каждого пакет находится в одном месте.

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

Ответ 9

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

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

Ответ 10

Спасибо @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), и все они автоматически загружаются.