emacsstartup

How to start emacs with specific user-init-file and user-emacs-directory?


I want to be able to start parallel several emacs instances with different configurations. I also want to be able to symlink the corresponding directories to ~/.emacs.d (or in my case ~/.config/emacs) without the need to overlook the init.el files inside the symlinked directories or to write extra lisp-code into init.el to handle this. The last part will become clear, after I listed the possible but (for me) not satisfying solutions, I found:

  1. Solution:

    env HOME=$HOME/path/to/a/pseudo/home/directory emacs
    

    Found at How to start up emacs with different configurations?

    Problem:

    The down-side to this technique is that Emacs won't see all your other dot files (because it will be looking in $HOME), and so running other processes from within Emacs won't necessarily work as normal; but that's not likely to be a huge issue if you're just experimenting, and you can always symlink or copy the bits you need.

  2. Solution:

    alias emacs='emacs -q --load "/path/to/init.el"'
    

    Each init.el file begins like this, to correctly set up the user-init-file and user-emacs-directory variables:

    (setq user-init-file (or load-file-name (buffer-file-name)))
    (setq user-emacs-directory (file-name-directory user-init-file))
    

    Found at How to start emacs with a custom user-emacs-directory?

    Problem:

    • it breaks emacs-init-time[...].
    • it is not equivalent to a normal startup [...]:
      • after-init-hook is run before the init file is loaded.
      • The *scratch* buffer is created before the init file is loaded. You'll have to change its mode explicitly (instead of using initial-major-mode).
      • You'll need to explicitly call package-initialize; it won't be done automatically
  3. Perhaps a Solution:

    The following doesn't work.

    alias emacs='emacs -q --eval "(progn (setq user-init-file /path/to/init.el) (setq 
    user-emacs-directory (file-name-directory user-init-file)))"
    

    But I have no clue, if something like this would really work and solve the problems with the solutions above. I couldn't find when --eval is executed in the startup process. I also don't know, how I could test, when after-init-hook is executed.

  4. Solution (Edit #2):

    Another solution -- mentioned in some threads (dropped the link, but google helps) -- is to use the standard init.el to write a switch, for example controlled by a dedicated environment variable, which than loads the corresponding init.el and sets the user-emacs-directory.

    Tianshu Wang mentioned chemacs2, what does exactly that via a command line argument, instead of an environment variable.

    For my part, I will take that way, bacause it handles also extra config files for example created by spacemacs. But see also solution 5.

It puzzles me, that emacs doesn't offer any command line arguments for user-init-file and user-emacs-directory.

Or am I missing something?

Edit #1: Really. It puzzles me. I looked further around. People are messing around with config files to get such a behaviour. Or flying to the moon to solve this. Or talking in tongues. Or summuning devils. Or whatever.

  1. Solution (Edit #3):

    Use git version of emacs or wait for official release emacs29.1

    Changlog for emacs on git:

    * Startup Changes in Emacs 29.1
    
    +++
    ** Emacs now supports setting 'user-emacs-directory' via '--init-directory'.
    

Note to myself: First look into upcoming changes in a software, before asking rest of internet. But in this special case, it was still worth it.


Solution

  • check chemacs2, it's what you need.