From 729fb4b7dc1ec6512db8838c6a4fff8d5810e115 Mon Sep 17 00:00:00 2001
From: Radon Rosborough <radon.neon@gmail.com>
Date: Sun, 13 Jan 2019 21:55:42 -0700
Subject: [PATCH] Fix `early-init-file' value when file is missing

Previously, if no early init-file existed in `user-emacs-directory',
then the value of `early-init-file' after startup would be
~/.emacs.d/early-init (note the missing extension).  This commit
adjusts that value to ~/.emacs.d/early-init.el as desired, while not
changing other behavior.  Note that when the early init-file did
exist, then the value of `early-init-file' after startup was already
correct; this commit fixes a bug that occurred only when the file did
not exist.

lisp/startup.el (load-user-init-file): Update logic.
---
 lisp/startup.el | 57 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 39 insertions(+), 18 deletions(-)

diff --git a/lisp/startup.el b/lisp/startup.el
index f2410f6f2c..367b04ad71 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -887,17 +887,22 @@ startup--setup-quote-display
             (aset standard-display-table char nil)))))))
 
 (defun load-user-init-file
-    (filename-function &optional alternate-filename-function load-defaults)
+    (filename-function &optional old-filename-function load-defaults)
   "Load a user init-file.
 FILENAME-FUNCTION is called with no arguments and should return
-the name of the init-file to load.  If this file cannot be
-loaded, and ALTERNATE-FILENAME-FUNCTION is non-nil, then it is
-called with no arguments and should return the name of an
-alternate init-file to load.  If LOAD-DEFAULTS is non-nil, then
-load default.el after the init-file.
-
-This function sets `user-init-file' to the name of the loaded
-init-file, or to a default value if loading is not possible."
+the name of the init-file to load.  If OLD-FILENAME-FUNCTION is
+non-nil, then try it first, and use FILENAME-FUNCTION only if the
+file cannot be found.
+
+Set `user-init-file' to the name of the loaded init-file, or to a
+default value if loading is not possible.  This default value
+will end in .el, unless OLD-FILENAME-FUNCTION is nil (this caveat
+being for backwards compatibility).  Additionally, if the
+filename of the loaded init-file ended in .elc, then replace it
+with .el, unconditionally.
+
+If LOAD-DEFAULTS is non-nil, then load default.el after the
+init-file."
   (let ((debug-on-error-from-init-file nil)
         (debug-on-error-should-be-set nil)
         (debug-on-error-initial
@@ -907,7 +912,9 @@ load-user-init-file
     (let ((debug-on-error debug-on-error-initial))
       (condition-case-unless-debug error
           (when init-file-user
-            (let ((init-file-name (funcall filename-function)))
+            ;; The first filename to try is the old one, if provided.
+            (let ((init-file-name
+                   (funcall (or old-filename-function filename-function))))
 
               ;; If `user-init-file' is t, then `load' will store
               ;; the name of the file that it loads into
@@ -915,15 +922,29 @@ load-user-init-file
               (setq user-init-file t)
               (load init-file-name 'noerror 'nomessage)
 
-              (when (and (eq user-init-file t) alternate-filename-function)
-                (load (funcall alternate-filename-function)
+              ;; If we were given an old filename and couldn't load
+              ;; it, then try the new filename.
+              (when (and (eq user-init-file t) old-filename-function)
+                (load (funcall filename-function)
                       'noerror 'nomessage))
 
               ;; If we did not find the user's init file, set
               ;; user-init-file conclusively.  Don't let it be
               ;; set from default.el.
               (when (eq user-init-file t)
-                (setq user-init-file init-file-name)))
+                (setq user-init-file
+                      ;; If the init-file doesn't exist, default to
+                      ;; the .el version, not the bare filename.  But
+                      ;; for backwards compatibility, don't do this if
+                      ;; an OLD-FILENAME-FUNCTION was provided (so we
+                      ;; use ~/.emacs instead of ~/.emacs.el, but
+                      ;; ~/.emacs.d/early-init.el instead of
+                      ;; ~/.emacs.d/early-init, by default).
+                      (if old-filename-function
+                          init-file-name
+                        (concat
+                         (file-name-sans-extension init-file-name)
+                         ".el")))))
 
             ;; If we loaded a compiled file, set `user-init-file' to
             ;; the source version if that exists.
@@ -1305,6 +1326,11 @@ command-line
 
     ;; Load that user's init file, or the default one, or none.
     (load-user-init-file
+     (lambda ()
+       (expand-file-name
+        "init"
+        (file-name-as-directory
+         (concat "~" init-file-user "/.emacs.d"))))
      (lambda ()
        (cond
         ((eq system-type 'ms-dos)
@@ -1324,11 +1350,6 @@ command-line
          "~/_emacs")
         (t ;; But default to .emacs if _emacs does not exist.
          "~/.emacs")))
-     (lambda ()
-       (expand-file-name
-        "init"
-        (file-name-as-directory
-         (concat "~" init-file-user "/.emacs.d"))))
      (not inhibit-default-init))
 
     (when (and deactivate-mark transient-mark-mode)
-- 
2.20.1

