From 231fc9cf535b912ca44a8c43b7fcda999c1567d4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 18 Sep 2022 13:55:47 +0200 Subject: [PATCH] fix(cli): link $XDG_*_HOME to fake $HOME for `doom run` Due to a technical limitation of Emacs <=28, launching Emacs out of a non-standard location is non-trivial, and `doom run` tries to promise that it can do so on demand. Emacs 29 does introduce a --init-directory switch that would make this easy, but it'll be some time before we can rely on it. So 'doom run' creates a fake $HOME in /tmp/doom.run/ and writes a bootloader there to load your Doom config remotely. But there's a problem: in this fake $HOME, none of the user's config, cache, data, or binscript directories are available, so I symlink them there. This should at least resolve the most trivial incompatibilities (like the lack of all-the-icons fonts, which typically get installed to $HOME/.local/share/fonts/ -- see #6807), but there may be yet more edge cases. Still, this is a good enough compromise for now. Fix: #6807 --- lisp/cli/run.el | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lisp/cli/run.el b/lisp/cli/run.el index 9026beca1..1d4699056 100644 --- a/lisp/cli/run.el +++ b/lisp/cli/run.el @@ -43,16 +43,32 @@ performance, it is best to run Doom out of ~/.config/emacs or ~/.emacs.d." ;; Evaluate piped-in text directly, if given. (eval (read input) t) (doom-run-repl context)) - ;; TODO Does this work on Windows? (let* ((tempdir (doom-path (temporary-file-directory) "doom.run")) (tempemacsdir (doom-path tempdir ".emacs.d"))) - (delete-directory tempdir t) + (delete-directory tempdir t) ; start from scratch (make-directory tempemacsdir t) + ;; HACK: So that Emacs doesn't lose track of local state, like user fonts, + ;; configs, or binscripts, we symlink these to the sandbox. + ;; REVIEW: Use `--init-directory' when we drop 29 support OR when Doom is + ;; in bootloader mode. + (dolist (dir (list (or (getenv "XDG_DATA_HOME") "~/.local/share") + (or (getenv "XDG_BIN_HOME") "~/.local/bin") + (or (getenv "XDG_CONFIG_HOME") "~/.config") + (or (getenv "XDG_CACHE_HOME") "~/.cache"))) + (let* ((xdg-dir (doom-path dir)) + (target (doom-path tempdir (file-relative-name xdg-dir "~")))) + (when (file-directory-p xdg-dir) + (unless (file-symlink-p target) + (make-directory (file-name-directory target) t) + (make-symbolic-link xdg-dir target))))) (with-temp-file (doom-path tempemacsdir "early-init.el") (prin1 `(progn (setenv "HOME" ,(getenv "HOME")) - (setq user-emacs-directory ,doom-emacs-dir) - (load-file ,(doom-path doom-emacs-dir "early-init.el"))) + (setenv "EMACSDIR" ,doom-emacs-dir) + (setenv "DOOMDIR" ,doom-user-dir) + (setenv "DOOMPROFILE" ,(getenv "DOOMPROFILE")) + (setq early-init-file ,(doom-path doom-emacs-dir "early-init.el")) + (load early-init-file nil (not ,init-file-debug) 'nosuffix)) (current-buffer))) (exit! (format "HOME=%S %s %s" tempdir