Vì có nhiều việc phải làm trên init hơn là chỉ tải một tệp và mặt khác là liên kết .emacs.d
hoặc thay đổi thay HOME
đổi môi trường thời gian chạy của tôi, tôi đã chọn một biến thể của những gì @glucas đã đề xuất. Tôi đã sử dụng mã từ startup.el
và thêm bản vá từ # 15539 để sử dụng biến môi trường để chuyển đổi giữa các thư mục init khác nhau. Nếu không được đưa ra, mặc định được sử dụng.
Có một vấn đề với spacemacs: async
không biết về thư mục init đã thay đổi và vì vậy không thể tìm thấy một số tệp cần thiết. Nhưng điều này đã được giải quyết trong spacemacs gần đây: Lỗi khi sử dụng thư mục cấu hình khác với .emacs.d · Vấn đề # 3390
Vì vậy, đây là của tôi ~/.emacs
nên hoạt động như mã init ban đầu nhưng với thư mục init có thể cấu hình:
;;; .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
Ngoài ra còn có một bổ sung thú vị làm cho nó hoạt động như một daemon mà không cần nỗ lực thêm: tên máy chủ sẽ được đặt thành tên của thư mục init. Vì vậy, bây giờ bạn có thể bắt đầu một daemon thứ hai với một spacemacs vani
EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs --daemon
và vẫn sử dụng emacsclient
emacsclient -s spacemacs -c -e '(message "Hello spacemacs")'
Usecase của tôi rất đơn giản và tôi rất ngạc nhiên, tôi là người duy nhất: Tôi có một trình nền emacs luôn chạy và sử dụng nó từ gui và trên bảng điều khiển (ví dụ với ssh). Trong emacs này, tôi chuẩn bị tất cả tài liệu và nhật ký công việc của mình, vì vậy nó phải ở đó mọi lúc. Nhưng sau đó tôi muốn dùng thử spacemacs hoặc một trong các gói phân phối khác và thậm chí định cấu hình nó, cho đến khi tôi có thể rút lại cấu hình hiện tại của mình hoặc sử dụng một số ý tưởng thông minh. Và như những người khác, tôi muốn tạo một cấu hình cơ bản đơn giản cho đồng nghiệp của mình - và ghi lại nó với chế độ org trong ví dụ chạy của tôi.
Vì vấn đề duy nhất tôi biết là async
và nó không biết về init dir đã thay đổi, tôi nghĩ về cách tốt nhất để thêm một số cấu hình vào async
đó có các biến nên được chèn theo mặc định, do đó không cần thiết phải vá tất cả yêu cầu của async-start
spacemacs đã làm.