Subject: Re: bug#16242: 24.3; wish: set init directory (.emacs.d) by commandline flag for easy custom environments

From: Lars Ingebrigtsen <[email-masked]>
Date: Wed, 26 Jan 2022 17:44:17 +0100

Lars Ingebrigtsen <[email-masked]> writes:

> Ah, I see.  So I think the XDG patch should go in first, and then adding
> --init-dir should be pretty trivial.

Below is a stab at this, and it seems to work fine -- except that after
starting Emacs with --init-directory /tmp/, the async nativecomp never
fires.   I poked at it for half an hour, but was unable to determine
why.

Andrea, do you see something obvious here that would disable nativecomp
if user-emacs-directory isn't the default?

diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index 5c444fc648..da9947ece3 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -329,6 +329,10 @@ Initial Options
 Do not include the @file{site-lisp} directories in @code{load-path}
 (@pxref{Init File}).  The @samp{-Q} option does this too.
 
+@item --init-directory
+@opindex --init-directory
+Specify the directory to use when looking for the Emacs init file.
+
 @item --no-splash
 @opindex --no-splash
 @cindex splash screen
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 3750abc4e8..25a2b9e2e4 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -363,6 +363,9 @@ Startup Summary
 @itemx -Q
 Equivalent to @samp{-q --no-site-file --no-splash}.
 @c and --no-site-lisp, but let's not mention that here.
+
+@item --init-directory
+Specify the directory to use when finding the Emacs init file.
 @end table

diff --git a/lisp/startup.el b/lisp/startup.el
index d90e7a7d26..41749848a4 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -550,26 +550,6 @@ normal-top-level
     (setq user-emacs-directory
 	  (startup--xdg-or-homedot startup--xdg-config-home-emacs nil))
 
-    (when (featurep 'native-compile)
-      ;; Form `native-comp-eln-load-path'.
-      (let ((path-env (getenv "EMACSNATIVELOADPATH")))
-        (when path-env
-          (dolist (path (split-string path-env path-separator))
-            (unless (string= "" path)
-              (push path native-comp-eln-load-path)))))
-      (push (expand-file-name "eln-cache/" user-emacs-directory)
-            native-comp-eln-load-path)
-      ;; When $HOME is set to '/nonexistent' means we are running the
-      ;; testsuite, add a temporary folder in front to produce there
-      ;; new compilations.
-      (when (and (equal (getenv "HOME") "/nonexistent")
-                 ;; We may be running in a chroot environment where we
-                 ;; can't write anything.
-                 (file-writable-p (expand-file-name
-                                   (or temporary-file-directory ""))))
-        (let ((tmp-dir (make-temp-file "emacs-testsuite-" t)))
-          (add-hook 'kill-emacs-hook (lambda () (delete-directory tmp-dir t)))
-          (push tmp-dir native-comp-eln-load-path))))
     ;; Look in each dir in load-path for a subdirs.el file.  If we
     ;; find one, load it, which will add the appropriate subdirs of
     ;; that dir into load-path.  This needs to be done before setting
@@ -781,6 +761,30 @@ normal-top-level
 	    (font-menu-add-default))
 	(unless inhibit-startup-hooks
 	  (run-hooks 'window-setup-hook))))
+
+    ;; Do this after `command-line', since it may alter
+    ;; `user-emacs-directory'.
+    (when (featurep 'native-compile)
+      ;; Form `native-comp-eln-load-path'.
+      (let ((path-env (getenv "EMACSNATIVELOADPATH")))
+        (when path-env
+          (dolist (path (split-string path-env path-separator))
+            (unless (string= "" path)
+              (push path native-comp-eln-load-path)))))
+      (push (expand-file-name "eln-cache/" user-emacs-directory)
+            native-comp-eln-load-path)
+      ;; When $HOME is set to '/nonexistent' means we are running the
+      ;; testsuite, add a temporary folder in front to produce there
+      ;; new compilations.
+      (when (and (equal (getenv "HOME") "/nonexistent")
+                 ;; We may be running in a chroot environment where we
+                 ;; can't write anything.
+                 (file-writable-p (expand-file-name
+                                   (or temporary-file-directory ""))))
+        (let ((tmp-dir (make-temp-file "emacs-testsuite-" t)))
+          (add-hook 'kill-emacs-hook (lambda () (delete-directory tmp-dir t)))
+          (push tmp-dir native-comp-eln-load-path))))
+
     ;; Subprocesses of Emacs do not have direct access to the terminal, so
     ;; unless told otherwise they should only assume a dumb terminal.
     ;; We are careful to do it late (after term-setup-hook), although the
@@ -1145,7 +1149,8 @@ command-line
                          ("--no-x-resources") ("--debug-init")
                          ("--user") ("--iconic") ("--icon-type") ("--quick")
 			 ("--no-blinking-cursor") ("--basic-display")
-                         ("--dump-file") ("--temacs") ("--seccomp")))
+                         ("--dump-file") ("--temacs") ("--seccomp")
+                         ("--init-directory")))
              (argi (pop args))
              (orig-argi argi)
              argval)
@@ -1185,6 +1190,9 @@ command-line
 	  (push '(vertical-scroll-bars . nil) initial-frame-alist))
 	 ((member argi '("-q" "-no-init-file"))
 	  (setq init-file-user nil))
+	 ((member argi '("-init-directory"))
+	  (setq user-emacs-directory (or argval (pop args))
+                argval nil))
 	 ((member argi '("-u" "-user"))
 	  (setq init-file-user (or argval (pop args))
 		argval nil))
@@ -1261,7 +1269,8 @@ command-line
 		(and (eq xdg-dir user-emacs-directory)
 		     (not (eq xdg-dir startup--xdg-config-default))))
 	    user-emacs-directory
-	  ;; The name is not obvious, so access more directories to calculate it.
+	  ;; The name is not obvious, so access more directories
+	  ;; to calculate it.
 	  (setq xdg-dir (concat "~" init-file-user "/.config/emacs/"))
 	  (startup--xdg-or-homedot xdg-dir init-file-user)))
 
diff --git a/src/emacs.c b/src/emacs.c
index f6e2c01ee7..2014e97fbf 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2472,6 +2472,7 @@ main (int argc, char **argv)
   { "-quick", 0, 55, 0 },
   { "-q", "--no-init-file", 50, 0 },
   { "-no-init-file", 0, 50, 0 },
+  { "-init-directory", "--init-directory", 30, 1 },
   { "-no-x-resources", "--no-x-resources", 40, 0 },
   { "-no-site-file", "--no-site-file", 40, 0 },
   { "-u", "--user", 30, 1 },

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no