Como hay mucho más que hacer en init que solo cargar un archivo y, por otro lado, simular .emacs.d
o cambiar los HOME
cambios en mi entorno de tiempo de ejecución, opté por una variante de lo que @glucas había propuesto. Usé el código de startup.el
y agregué el parche # 15539 para usar una variable de entorno para cambiar entre diferentes directorios de inicio. Si no se da ninguno, se usa el predeterminado.
Hubo un problema con spacemacs: async
no conoce el directorio init cambiado y, por lo tanto, no puede encontrar algunos archivos necesarios. Pero esto se ha resuelto recientemente en spacemacs: error al usar un directorio de configuración que no sea .emacs.d · Problema # 3390
Así que aquí está mi ~/.emacs
que debería comportarse como el código de inicio original pero con un directorio de inicio configurable:
;;; .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
También hay una buena adición que lo hace funcionar como un demonio sin esfuerzo adicional: el nombre del servidor se establecerá en el nombre del directorio init. Así que ahora puedes comenzar un segundo demonio emacs con un vainilla spacemacs
EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs --daemon
y sigo usando emacsclient
emacsclient -s spacemacs -c -e '(message "Hello spacemacs")'
Mi caso de uso es muy simple y estoy asombrado de ser el único: tengo un demonio emacs siempre en ejecución y lo uso desde la interfaz gráfica de usuario y sobre la consola (con ssh, por ejemplo). En este emacs preparo toda mi documentación y registro de trabajo, por lo que tiene que estar allí todo el tiempo. Pero luego quiero probar spacemacs o uno de los otros paquetes de distribución e incluso configurarlo, hasta que pueda retirar mi configuración actual o usar algunas de las ideas inteligentes. Y como otros, quería crear una configuración básica simple para mis compañeros de trabajo y documentarla con el modo org en mi instancia de ejecución.
Dado que el único problema que conozco es async
y que no conoce el directorio de inicio cambiado, pienso en la mejor manera de agregar alguna configuración async
que tenga variables que deberían inyectarse de forma predeterminada, por lo que no es necesario parchear todo invocaciones de async-start
lo que habían hecho los spacemacs.