Ponieważ przy inicjowaniu jest coś więcej niż tylko ładowanie pliku, a z drugiej strony symlinkowanie .emacs.d
lub zmiana HOME
zmian w moim środowisku wykonawczym, zdecydowałem się na wariant zaproponowany przez @glucas. Użyłem kodu z startup.el
i dodałem łatkę z # 15539, aby użyć zmiennej środowiskowej do przełączania między różnymi katalogami init. Jeśli nie podano żadnej, używana jest wartość domyślna.
Wystąpił jeden problem z spacemacs: async
nie wie o zmienionym katalogu init, więc nie może znaleźć potrzebnych plików. Ale problem został ostatnio rozwiązany w metodzie spacemacs: Błąd podczas korzystania z katalogu konfiguracji innego niż .emacs.d · Problem # 3390
Oto moje, ~/.emacs
które powinny zachowywać się jak oryginalny kod init, ale z konfigurowalnym katalogiem init:
;;; .emacs --- let the user choose the emacs environment to use
;;; Commentary:
;;; This code mimics the behaviour of `startup.el' to let the
;;; usage of the custom init directory behave just like the
;;; one and only "~/.emacs.d".
;;;
;;; By setting the environment variable `EMACS_USER_DIRECTORY'
;;; the user-emacs-directory can be chosen and if there is an
;;; `init.el' the configuration from that directory will be used.
;;; If the environment variable is not set or there is no `init.el'
;;; the default configuration directory `~/.emacs.d/' will be used.
;;;
;;; The variable `server-name' will be set to the name of the directory
;;; chosen as start path. So if the server will be started, it can be
;;; reached with 'emacsclient -s servername'.
;;;
;;; This now works with a current version of spacemacs but does not
;;; work with `async-start' in general, if the code executed with `async'
;;; uses `user-init-dir' or makes other assumptions about the emacs
;;; start-directory.
;;; Code:
(let* ((user-init-dir-default
(file-name-as-directory (concat "~" init-file-user "/.emacs.d")))
(user-init-dir
(file-name-as-directory (or (getenv "EMACS_USER_DIRECTORY")
user-init-dir-default)))
(user-init-file-1
(expand-file-name "init" user-init-dir)))
(setq user-emacs-directory user-init-dir)
(with-eval-after-load "server"
(setq server-name
(let ((server--name (file-name-nondirectory
(directory-file-name user-emacs-directory))))
(if (equal server--name ".emacs.d")
"server"
server--name))))
(setq user-init-file t)
(load user-init-file-1 t t)
(when (eq user-init-file t)
(setq user-emacs-directory user-init-dir-default)
(load (expand-file-name "init" user-init-dir-default) t t)))
(provide '.emacs)
;;; .emacs ends here
Jest też miły dodatek, który sprawia, że działa on jako demon bez dodatkowego wysiłku: nazwa-serwera zostanie ustawiona na nazwę katalogu init. Teraz możesz uruchomić drugiego demona emacs z waniliowymi znakami kosmicznymi
EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs --daemon
i nadal używamy emacsclient
emacsclient -s spacemacs -c -e '(message "Hello spacemacs")'
Mój przypadek użycia jest bardzo prosty i jestem zdumiony, że jestem jedyny: mam zawsze działającego demona emacs i używam go z GUI i na konsoli (na przykład z ssh). W tym emacsie przygotowuję całą moją dokumentację i dziennik pracy, więc musi być tam cały czas. Ale potem chcę wypróbować kosmiczne lub jeden z innych pakietów dystrybucyjnych, a nawet je skonfigurować, dopóki nie mogę wycofać mojej obecnej konfiguracji lub skorzystać z niektórych sprytnych pomysłów. I podobnie jak inni, chciałem stworzyć prostą konfigurację podstawową dla moich współpracowników - i udokumentować ją w trybie org w uruchomionej instancji.
Ponieważ jedynym znanym mi problemem jest async
to, że nie wie on o zmienionym katalogu init, myślę o najlepszym sposobie dodania konfiguracji, async
która zawiera zmienne, które powinny być wstrzykiwane domyślnie, aby nie było potrzeby łatania wszystkich inwokacje async-start
tak, jak zrobiły to kosmiczne maszyny.