Jak modularyzować konfigurację Emacsa?

Postanowiłem przepisać swoje .emacs od podstaw i chcę ustawić coś modułowego, aby uniknąć strasznego 1K + LoC init.plik el...

Myślę, że są pewne podstawowe problemy, które każda konfiguracja musi rozwiązać:

  • opcje globalne
  • funkcje edycji
  • nawigacja (ramki i bufory)
  • skróty klawiszowe
  • modyfikacje trybów
/ Align = "left" / wskazówki, jak to osiągnąć.
Obejrzałem kilka .emacs na GitHubie i takie tam, i wydaje się być deifferent podejścia, i nie preferowany sposób, aby przejść z tym, co jest nieco mylące.
Byłbym zainteresowany przeczytaniem kilku pomysłów dotyczących struktury takiej konfiguracji, a zwłaszcza jakiegoś związanego z nią kodu elisp.

Edit: nie miałem jeszcze zbyt wiele czasu na zabawę. Wypróbuje proponowane metody w ciągu kilku dni i zobacz, co jest najlepsze, tymczasem dzięki za wszystkie zalecenia !


Edit2: używałem literate pliku init z org-mode , i to jest absolutnie wspaniałe !
Nie jestem jeszcze ustawiony na konkretnym mechanizmie ładowania, używam tego kodu, aby rekurencyjnie załadować mój katalog elisp, a następnie wymagać lub cokolwiek mówią instrukcje konfiguracji.

  (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)))

Nadal muszę to wypolerować, może za pomocą autoload, i trochę bajtów-przekompilować, jeśli zmodyfikowane sztuczki ; chętnie usłyszę sugestie na to.

Author: julien, 2010-01-17

10 answers

Mój .emacs file loads ~/.emacs.d/init.el , który definiuje następujące funkcje, napisane najpierw dla Xemacsa, ale obecnie działające wystarczająco dobrze dla Emacsa:

(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)))

Następnie reszta pliku przechodzi i ładuje wiele pojedynczych plików z formularzami takimi jak:

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

Mój obecny zestaw plików jest jak follows:

    Osobiste.el
  • Platforma.el
  • cygwin.el
  • zmienne.el
  • ścieżki.el
  • mail-news.el
  • misc-funcs.el
  • bbdb.el
  • kalendarz.el
  • gnus-funcs.el
  • c-i-java.el
  • lisp.el
  • clojure.el
  • Idź.el
  • markdown.el
  • sgml-xml.el
  • tex.el
  • ortografia.el
  • org.el
  • Pakiety.el
  • czcionki.el
  • kolor-motyw.el
  • frame.el
  • serwer.el
  • klucze.el
  • aquamacs.el

Niektóre z nich są o wiele bardziej szczegółowe w intencji niż inne, jak sugerują nazwy. Im bardziej drobnoziarniste pliki, tym łatwiej jest wyłączyć klaster formularzy podczas ponownej instalacji pakietu lub biblioteki. Jest to szczególnie przydatne podczas "przechodzenia" do nowego systemu, gdzie przeciągasz pliki konfiguracyjne, ale nie masz jeszcze zainstalowanych wszystkich pakietów pomocniczych.

 38
Author: seh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 00:19:30

Aby podzielić konfiguracje na różne pliki, możesz użyć initsplit.el . Ponadto wiki ma stronę modular .emacs layout .

 6
Author: Joe Casadonte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-17 14:17:53

Co jest złego w używaniu load-file?

Niektóre dodatkowe bity, które mogą okazać się przydatne, obejmują

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

Użyj C-h f <function>, aby uzyskać pomoc, a może znajdziesz Wprowadzenie do programowania w Emacs Lisp przydatne (lub Pobierz PDF)

 2
Author: dmckee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-16 22:30:17

Rzućcie okiem na doskonały Zestaw Startowy emacs , który jest bardzo dobrze zorganizowany i zawiera również pakiety ELPA. Użyłem tej struktury jako inspiracji dla mojej własnej, znacznie prostszej konfiguracji.

 2
Author: justinhj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-17 05:56:40

Jeśli chcesz podzielić swoje custom-set-variables, ale chcesz coś lżejszego niż initsplit.el, a następnie spróbuj tego:

(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))))

Teraz umieść swoje moduły konfiguracyjne w osobnych plikach i załaduj je z {[9] } w twoim ~/.emacs, jak sugerowali inni. W każdym moduł konfiguracji, użyj

(custom-set-variable var value)

Zamiast

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

Lub

(setq-default var value)

Podczas ustawiania zmiennych zarządzanych przez customize. Wtedy, jeśli kiedykolwiek będziesz potrzebować aby dostosować zmienną za pomocą interfejsu dostosuj, zobaczysz a ostrzeżenie informujące o tym, w którym pliku Personalizacja powinna być przechowywana:

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

Jeśli kontrolujesz wersję swoich plików konfiguracyjnych, to diff powie, które linia ~/.emacs, aby przejść do modułu niestandardowego.

Dyskusja o problemach z naiwnym użyciem wielu custom-set-variables wywołania: http://www.dotemacs.de/custbuffer.html

Edit: odpowiedź na pytania Alana

Problem custom-set-variable makro powyżej rozwiązuje

Customize interface w Emacsie zapisuje wszystkie niestandardowe ustawianie zmiennych w twoja ~/.emacs za każdym razem, gdy edytujesz dowolną zmienną niestandardową. Jeśli modularyzować zmienne ustawione przez rozłożenie ich na wiele plików, Następnie trzeba uświadomić sobie, gdy emacs wstawia duplikat ustawienia w Twoim .emacs, i usunąć je. custom-set-variable makro powyżej pomaga Ci to zrobić.

Prawdziwy przykład z moich plików konfiguracyjnych

Ustawiam zmienne związane z białymi znakami w ~/.emacs.d/extensions/whitespace.el plik, który zostanie załadowany przez moją ~/.emacs. Na przykład ustawiłem mój search-whitespace-regexp zmienna taka jak ta:

(nc:custom-set-variable search-whitespace-regexp "[ \t\r\n]+")
Teraz dzieją się dwie rzeczy. Po pierwsze, kiedy natknąłem się na tę zmienną w w przeciwieństwie do innych gier, nie jest to gra logiczna.]}

Wygenerowane ostrzeżenie w oknie dostosowywania Emacsa

Po drugie, jeśli edytuję jakieś zmienne za pomocą interfejsu dostosowywania, mój ~/.emacs sprawia, że to bardzo oczywiste, że zaciemniłem niektóre definicje. Na przykład po zmianie search-whitespace-regexp i global-whitespace-mode w interfejsie dostosowywania dostaję:

$ 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 !!!")

Makro nie pomaga mi pamiętać, że I zmieniony search-whitespace-regexp, tyle że jest już ustawione gdzie indziej, ale to pomaga mi wiedzieć, które ustawienia zmiennej powinienem usunąć z moje ~/.emacs (wszystkie z ostrzeżeniami), a które powinienem zostawić w moim ~/.emacs, lub przenieść do innych oddzielnych plików (wszystkie te bez Ostrzeżenia).

Podsumowanie

Makro to chyba przesada, ale gdy już istnieje, jest łatwe w użyciu i sprawia, że łatwiej uniknąć strzelania w stopę dzięki shadowed custom set zmienne.

 2
Author: ntc2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-03 04:03:56

Możesz zrobić (require 'foo) i to załaduje pierwszy " foo.el " elisp znajduje w ścieżce ładowania lub (require 'foo "/home/user/experimental/foo.el") coś poza ścieżką ładowania. Zgłosi błąd, jeśli "foo.el " nie zawiera wyrażenia (provide 'foo). W przewrotnej sytuacji można zrobić (require 'foo "bar.el"), a to działa tak długo, jak " bar.el " miał (provide 'foo) klauzulę.

 1
Author: Justin Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-16 23:30:15

Tutaj znajduje się biblioteka, która pozwala instalować nowe moduły po prostu zapisując je w wyznaczonym katalogu. Można go pobrać i zainstalować z 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.

Ta architektura narzuca pewne konwencje, które mogą ci się podobać lub nie. Zobacz resztę sekcji komentarzy w górnej części pliku, aby uzyskać pełną informację.

Jestem autorem tego kodu i doceniam wszelkie opinie (choć nie bezpośrednio za pośrednictwem tej publicznej forum).

 1
Author: tripleee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-10 06:18:00

To, co zrobiłem, to dla każdej rzeczy, X, której mogę chcieć użyć, utworzyć plik o nazwie configure-X i umieścić odpowiedni require.emacs. Tę funkcję można następnie usunąć, komentując jedną linię.

Na przykład, aby wybrać najprostszy (jeśli najbardziej źle nazwany), mam configure-picture-and-artist-mode.el. Ten plik jest bardzo prosty:

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

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

I w .emacs:

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

Po uporządkowaniu tego nie mam nic w moim .emacs z wyjątkiem dużej listy require s I kilku zmiany w load-path, dany pakiet można dość łatwo usunąć, a cała konfiguracja dla każdego pakietu jest w jednym miejscu.

(mam też catch-all .plik el, którego używam do przechowywania rzeczy, które nie mają oczywistego domu (moje globalne powiązania klawiszy, funkcje pomocnicze itp.), ale nadal najlepiej trzymać się z dala .emacs. Ten bit nie jest zbyt modularny i może wprowadzać Ukryte zależności od pakietów, które mój schemat ma łatwo uczynić unloadable, ale w praktyce nie wydaje się to być Wielka mi rzecz.)

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-16 22:36:08

Możesz spróbować init-loader.el, jest to program ładujący pliki konfiguracyjne. init-loader.el wczytuje pliki konfiguracyjne z podanego katalogu. Umożliwia kategoryzowanie konfiguracji i dzielenie ich na wiele plików.

Aby uzyskać więcej informacji, odwiedź init-loader GitHub Repo

 0
Author: Juanito Fatas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-05 17:26:14

Podziękowania dla @ JoeCasadonte za wzmiankę o stronie EmacsWiki . Ponieważ używam Debiana i Ubuntu, ten konkretny fragment z niego działał po prostu dobrze (do umieszczenia w .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))
W takim razie, muszę tylko umieścić mój .el files inside ~/.emacs.d / site-start.d (np. ~/.emacs.d/site-start.d/50cedet.el) i wszystkie są ładowane automatycznie.
 0
Author: Paulo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-28 13:02:33