Оскільки на init можна зробити більше, ніж просто завантажувати файл, а з іншого боку, поєднуючи .emacs.d
або змінюючи HOME
зміни мого середовища виконання, я обрав варіант, який запропонував @glucas. Я використав код startup.el
і додав патч від # 15539, щоб використовувати змінну середовища для переключення між різними init dirs. Якщо нічого не вказано, використовується типова умова.
Була одна проблема з spacemacs: async
не знає про змінений каталог init і тому не може знайти потрібні файли. Але це було вирішено нещодавно у spacemacs: Помилка під час використання конфігураційного каталогу, відмінного від .emacs.d · Випуск № 3390
Тож ось мій, ~/.emacs
який повинен вести себе як оригінал init-коду, але з налаштованою каталогом 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
Існує також приємне доповнення, яке змушує його працювати як демон без зайвих зусиль: ім'я сервера буде встановлено на ім'я каталогу init. Тож тепер ви можете запустити другий демон emacs з ванільним spacemacs
EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs --daemon
і досі використовувати emacsclient
emacsclient -s spacemacs -c -e '(message "Hello spacemacs")'
Мій шафа дуже простий, і я здивований, що я єдиний: у мене постійно працює демон emacs і використовую його від gui та через консоль (наприклад, з ssh). У цьому emacs я готую всю свою документацію та журнал роботи, тому він повинен бути там весь час. Але тоді я хочу спробувати spacemacs або один з інших пакетів розповсюдження і навіть налаштувати його, поки я не можу вийти зі своєї поточної конфігурації або використати деякі розумні ідеї. І як інші, я хотів створити просту базову конфігурацію для своїх колег - і документувати її в org-mode в моєму запущеному екземплярі.
Оскільки єдина проблема, про яку я знаю, - це async
те, що вона не знає про змінений init dir, я думаю, що найкращий спосіб додати певну конфігурацію до async
змінних, які слід вводити за замовчуванням, так що не потрібно виправляти всі виклики так async-start
само, як це робили Spacemacs.