Como há mais o que fazer no init do que apenas carregar um arquivo e, por outro lado, desvincular .emacs.d
ou alterar HOME
alterações no meu ambiente de tempo de execução, optei por uma variante do que o @glucas havia proposto. Usei o código startup.el
e adicionei o patch do # 15539 para usar uma variável de ambiente para alternar entre diferentes diretórios init. Se nenhum for fornecido, o padrão é usado.
Houve um problema com o spacemacs: async
não sabe sobre o diretório init alterado e, portanto, não consegue encontrar alguns arquivos necessários. Mas isso foi resolvido recentemente no spacemacs: Erro ao usar um diretório de configuração diferente de .emacs.d · Edição nº 3390
Então, aqui está o meu ~/.emacs
que deve se comportar como o código init original, mas com o diretório init configurável:
;;; .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
Há também uma boa adição que o faz funcionar como um daemon sem esforço extra: o nome do servidor será definido como o nome do diretório init. Então agora você pode iniciar um segundo daemon do emacs com um spacemacs de baunilha
EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs --daemon
e ainda use o emacsclient
emacsclient -s spacemacs -c -e '(message "Hello spacemacs")'
Meu caso de usuário é muito simples e estou surpreso por ser o único: tenho um daemon do emacs sempre em execução e o uso no gui e no console (com ssh por exemplo). Neste emacs, preparo toda a minha documentação e registro de trabalho, para que esteja lá o tempo todo. Mas então eu quero experimentar o spacemacs ou um dos outros pacotes de distribuição e até configurá-lo, até que eu possa aposentar minha configuração atual ou usar algumas das idéias inteligentes. E, como outros, eu queria criar uma configuração básica simples para meus colegas de trabalho - e documentá-la com o modo org na minha instância em execução.
Como o único problema que conheço é async
e ele não conhece o diretório init alterado, penso na melhor maneira de adicionar algumas configurações às async
variáveis que devem ser injetadas por padrão, para que não seja necessário corrigir todos os invocações async-start
exatamente como os spacemacs haviam feito.