emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Fixing package-initialize, adding early init file


From: Clément Pit-Claudel
Subject: Re: [PATCH] Fixing package-initialize, adding early init file
Date: Thu, 25 Jan 2018 10:43:53 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0

On 2018-01-24 23:35, Radon Rosborough wrote:
> Since it has been more than a month with no response, I am re-posting
> the patch which fixes the problems previously discussed [1] [2] [3]
> with `package-initialize' by adding a second (optional) init-file
> `early-init.el'. This patch includes some refactoring of the code in
> `startup.el' to provide for loading any number of init-files in an
> extensible way. I hope that the change can be included in Emacs 26.2
> or Emacs 27.

Thanks for this patch. I think it'd be great to have it.  I've added some (very 
few) comments below.

> diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi
> index 215f50cb40..bd7cccce6c 100644
> --- a/doc/emacs/package.texi
> +++ b/doc/emacs/package.texi
> @@ -253,30 +253,16 @@ Package Installation
>  consult the package's help buffer.
>  
>    By default, Emacs also automatically loads all installed packages in
> -subsequent Emacs sessions.  This happens at startup, after processing
> -the init file (@pxref{Init File}).  As an exception, Emacs does not
> -load packages at startup if invoked with the @samp{-q} or
> address@hidden options (@pxref{Initial Options}).
> +subsequent Emacs sessions.  This happens at startup, before processing

Was this supposed to be "previous" rather than "subsequent" (this isn't from 
your patch, though).

> +the init file but after processing the early init file (@pxref{Early
> +Init File,,, elisp, The Emacs Lisp Reference Manual}).  As an
> +exception, Emacs does not load packages at startup if invoked with the
> address@hidden or @samp{--no-init-file} options (@xref{Initial Options}).
>  
>  @vindex package-enable-at-startup
>    To disable automatic package loading, change the variable
> address@hidden to @code{nil}.
> -
> address@hidden package-initialize
> -  The reason automatic package loading occurs after loading the init
> -file is that user options only receive their customized values after
> -loading the init file, including user options which affect the
> -packaging system.  In some circumstances, you may want to load
> -packages explicitly in your init file (usually because some other code
> -in your init file depends on a package).  In that case, your init file
> -should call the function @code{package-initialize}.  It is up to you
> -to ensure that relevant user options, such as @code{package-load-list}
> -(see below), are set up prior to the @code{package-initialize} call.
> -This will automatically set @code{package-enable-at-startup} to @code{nil}, 
> to
> -avoid loading the packages again after processing the init file.
> -Alternatively, you may choose to completely inhibit package loading at
> -startup, and invoke the command @kbd{M-x package-initialize} to load
> -your packages manually.
> address@hidden to @code{nil}.  You must do this in
> +the early init file.  Currently it cannot be done via Customize.

I'd add ", as this variable is read before loading the regular init file." 
after "in the early init file".

>  @vindex package-load-list
>    For finer control over package loading, you can use the variable
> diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
> index 501960bdc3..c6990909ab 100644
> --- a/doc/lispref/os.texi
> +++ b/doc/lispref/os.texi
> @@ -361,6 +361,7 @@ Init File
>  @cindex init file
>  @cindex @file{.emacs}
>  @cindex @file{init.el}
> address@hidden @file{early-init.el}
>  
>    When you start Emacs, it normally attempts to load your @dfn{init
>  file}.  This is either a file named @file{.emacs} or @file{.emacs.el}
> @@ -384,6 +385,19 @@ Init File
>  file.  If those environment variables are absent, though, Emacs uses
>  your user-id to find your home directory.
>  
> address@hidden early init file
> +  Emacs also attempts to load a second init file, called the
> +  @dfn{early init file}, if it exists.  This is a file named
> +  @file{early-init.el} in a subdirectory named @file{.emacs.d} in your
> +  home directory.  The difference is that the early init file is
> +  loaded much earlier during the startup process, so you can use it to
> +  customize some things that are initialized before loading the
> +  regular init file.  For example, here you can customize the process

I'd say "For example, you can use that file to customize the process"

> +  of loading installed packages, by setting variables such as
> +  @var{package-load-list} or
> +  @var{package-enable-at-startup}. @xref{Package Installation,,,
> +  emacs,The GNU Emacs Manual}.
> +
>  @cindex default init file
>    An Emacs installation may have a @dfn{default init file}, which is a
>  Lisp library named @file{default.el}.  Emacs finds this file through
> diff --git a/doc/lispref/package.texi b/doc/lispref/package.texi
> index 153ee48741..2e93f29bd2 100644
> --- a/doc/lispref/package.texi
> +++ b/doc/lispref/package.texi
> @@ -106,10 +106,12 @@ Packaging Basics
>  
>    Whenever Emacs starts up, it automatically calls the function
>  @code{package-initialize} to load installed packages.  This is done
> -after loading the init file and abbrev file (if any) and before
> -running @code{after-init-hook} (@pxref{Startup Summary}).  Automatic
> -package loading is disabled if the user option
> address@hidden is @code{nil}.
> +after loading the early init file, but before loading the early init

This should say "but before loading the *reguar* init file."

> +file and abbrev file (if any) and before running
> address@hidden (@pxref{Startup Summary}).  Automatic package
> +loading is disabled if the user option
> address@hidden is @code{nil}.  (Of course, the
> +setting of this user option must be done in the early init file.)

I'd simplify this to "if the option … is *set to* nil in the early init file."

>  @deffn Command package-initialize &optional no-activate
>  This function initializes Emacs' internal record of which packages are
> @@ -123,6 +125,12 @@ Packaging Basics
>  The optional argument @var{no-activate}, if address@hidden, causes
>  Emacs to update its record of installed packages without actually
>  loading them; it is for internal use only.
> +
> +In most cases, you should not need to call @code{package-initialize},
> +as this is done automatically during startup.  Simply make sure to put
> +any code that should run before @code{package-initialize} in the early
> +init file, and any code that should run after in the primary init

after *it*, maybe?

> +file (@xref{Init File,,, emacs, The GNU Emacs Manual}).
>  @end deffn
>  
>  @node Simple Packages
> diff --git a/doc/misc/org.texi b/doc/misc/org.texi
> index 1f6e10287d..36b7f87248 100644
> --- a/doc/misc/org.texi
> +++ b/doc/misc/org.texi
> @@ -890,9 +890,7 @@ Installation
>  been visited, i.e., where no Org built-in function have been loaded.
>  Otherwise autoload Org functions will mess up the installation.
>  
> -Then, to make sure your Org configuration is taken into account, initialize
> -the package system with @code{(package-initialize)} in your Emacs init file
> -before setting any Org option.  If you want to use Org's package repository,
> +If you want to use Org's package repository,
>  check out the @uref{http://orgmode.org/elpa.html, Org ELPA page}.
>  
>  @subsubheading Downloading Org as an archive
> diff --git a/etc/NEWS b/etc/NEWS
> index 1382f96a37..4bbf3e237a 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -41,6 +41,24 @@ can enable it when configuring, e.g., './configure 
> CFLAGS="-g3 -O2
>  
>  * Startup Changes in Emacs 27.1
>  
> ++++
> +** Emacs can now be configured using an early init file.
> +The file is called early-init.el, in `user-emacs-directory'.  It is
> +loaded very early in the startup process: in particular, before

no need for "in particular," here?

> +graphical elements such as the tool bar are initialized, and before
> +the package manager is initialized.
> +
> ++++
> +** Emacs now initializes package.el before loading the init-file.

I think "calls package-initialize" would be clearer.

> +This is part of a change intended to eliminate the behavior of
> +package.el inserting a call to (package-initialize) into the
> +init-file, which was previously done when Emacs was started.  Users
> +who do not configure package.el variables such as `package-load-list'
> +and `package-user-dir' need not make any configuration changes.  Users
> +who do configure such variables should place the configuration into
> +the newly introduced early init file, which is loaded before
> +package.el is initialized.

I'd mention here that variables like package-archives do not need to move to 
the early init file.

> +
>  
>  * Changes in Emacs 27.1
>  
> diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
> index f8b4cc888d..815b679cae 100644
> --- a/lisp/emacs-lisp/package.el
> +++ b/lisp/emacs-lisp/package.el
> @@ -1431,16 +1431,11 @@ package-read-all-archive-contents
>  ;; available on disk.
>  (defvar package--initialized nil)
>  
> -(defvar package--init-file-ensured nil
> -  "Whether we know the init file has package-initialize.")
> -
>  ;;;###autoload
>  (defun package-initialize (&optional no-activate)
>    "Load Emacs Lisp packages, and activate them.
>  The variable `package-load-list' controls which packages to load.
>  If optional arg NO-ACTIVATE is non-nil, don't activate packages.
> -If `user-init-file' does not mention `(package-initialize)', add
> -it to the file.
>  If called as part of loading `user-init-file', set
>  `package-enable-at-startup' to nil, to prevent accidentally
>  loading packages twice.
> @@ -1449,13 +1444,7 @@ package-initialize
>  taken care of by `package-initialize'."
>    (interactive)
>    (setq package-alist nil)
> -  (if after-init-time
> -      (package--ensure-init-file)
> -    ;; If `package-initialize' is before we finished loading the init
> -    ;; file, it's obvious we don't need to ensure-init.
> -    (setq package--init-file-ensured t
> -          ;; And likely we don't need to run it again after init.
> -          package-enable-at-startup nil))
> +  (setq package-enable-at-startup nil)
>    (package-load-all-descriptors)
>    (package-read-all-archive-contents)
>    (unless no-activate
> @@ -1872,64 +1861,6 @@ package-download-transaction
>  using `package-compute-transaction'."
>    (mapc #'package-install-from-archive packages))
>  
> -(defun package--ensure-init-file ()
> -  "Ensure that the user's init file has `package-initialize'.
> -`package-initialize' doesn't have to be called, as long as it is
> -present somewhere in the file, even as a comment.  If it is not,
> -add a call to it along with some explanatory comments."
> -  ;; Don't mess with the init-file from "emacs -Q".
> -  (when (and (stringp user-init-file)
> -             (not package--init-file-ensured)
> -             (file-readable-p user-init-file)
> -             (file-writable-p user-init-file))
> -    (let* ((buffer (find-buffer-visiting user-init-file))
> -           buffer-name
> -           (contains-init
> -            (if buffer
> -                (with-current-buffer buffer
> -                  (save-excursion
> -                    (save-restriction
> -                      (widen)
> -                      (goto-char (point-min))
> -                      (re-search-forward "(package-initialize\\_>" nil 
> 'noerror))))
> -              ;; Don't visit the file if we don't have to.
> -              (with-temp-buffer
> -                (insert-file-contents user-init-file)
> -                (goto-char (point-min))
> -                (re-search-forward "(package-initialize\\_>" nil 
> 'noerror)))))
> -      (unless contains-init
> -        (with-current-buffer (or buffer
> -                                 (let ((delay-mode-hooks t)
> -                                       (find-file-visit-truename t))
> -                                   (find-file-noselect user-init-file)))
> -          (when buffer
> -            (setq buffer-name (buffer-file-name))
> -            (set-visited-file-name (file-chase-links user-init-file)))
> -          (save-excursion
> -            (save-restriction
> -              (widen)
> -              (goto-char (point-min))
> -              (while (and (looking-at-p "[[:blank:]]*\\(;\\|$\\)")
> -                          (not (eobp)))
> -                (forward-line 1))
> -              (insert
> -               "\n"
> -               ";; Added by Package.el.  This must come before 
> configurations of\n"
> -               ";; installed packages.  Don't delete this line.  If you 
> don't want it,\n"
> -               ";; just comment it out by adding a semicolon to the start of 
> the line.\n"
> -               ";; You may delete these explanatory comments.\n"
> -               "(package-initialize)\n")
> -              (unless (looking-at-p "$")
> -                (insert "\n"))
> -              (let ((file-precious-flag t))
> -                (save-buffer))
> -              (if buffer
> -                  (progn
> -                    (set-visited-file-name buffer-name)
> -                    (set-buffer-modified-p nil))
> -                (kill-buffer (current-buffer)))))))))
> -  (setq package--init-file-ensured t))
> -
>  ;;;###autoload
>  (defun package-install (pkg &optional dont-select)
>    "Install the package PKG.
> diff --git a/lisp/startup.el b/lisp/startup.el
> index 4575f1f94d..de85933983 100644
> --- a/lisp/startup.el
> +++ b/lisp/startup.el
> @@ -312,6 +312,15 @@ inhibit-startup-hooks
>  Currently this applies to: `emacs-startup-hook', `term-setup-hook',
>  and `window-setup-hook'.")
>  
> +(defvar early-init-file nil
> +  "File name, including directory, of user's early init file.
> +If the file loaded had extension `.elc', and the corresponding
> +source file exists, this variable contains the name of source
> +file, suitable for use by functions like `custom-save-all' which
> +edit the init file.  While Emacs loads and evaluates the init
> +file, value is the real name of the file, regardless of whether
> +or not it has the `.elc' extension.")
> +
>  (defvar keyboard-type nil
>    "The brand of keyboard you are using.
>  This variable is used to define the proper function and keypad
> @@ -870,6 +879,129 @@ startup--setup-quote-display
>            (when standard-display-table
>              (aset standard-display-table char nil)))))))
>  
> +(defun load-user-init-file
> +    (compute-filename &optional compute-alternate-filename load-defaults)
> +  "Load a user init-file.
> +COMPUTE-FILENAME is called with no arguments and should return
> +the name of the init-file to load. If this file cannot be loaded,
> +and COMPUTE-ALTERNATE-FILENAME 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."
> +  (let ((debug-on-error-from-init-file nil)
> +        (debug-on-error-should-be-set nil)
> +        (debug-on-error-initial
> +         (if (eq init-file-debug t)
> +             'startup
> +           init-file-debug))
> +        (orig-enable-multibyte (default-value 'enable-multibyte-characters)))
> +    (let ((debug-on-error debug-on-error-initial)
> +          ;; We create an anonymous function here so that we can call
> +          ;; it in different contexts depending on the value of
> +          ;; `debug-on-error'.
> +          (read-init-file
> +           (lambda ()
> +             (when init-file-user
> +               (let ((init-file-name (funcall compute-filename)))
> +
> +                 ;; If `user-init-file' is t, then `load' will store
> +                 ;; the name of the file that it loads into
> +                 ;; `user-init-file'.
> +                 (setq user-init-file t)
> +                 (load init-file-name 'noerror 'nomessage)
> +
> +                 (when (eq user-init-file t)
> +                   (let ((alt-file-name (funcall 
> compute-alternate-filename)))
> +                     (load alt-file-name '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)))))
> +
> +               ;; If we loaded a compiled file, set `user-init-file' to
> +               ;; the source version if that exists.
> +               (when (equal (file-name-extension user-init-file)
> +                            "elc")
> +                 (let* ((source (file-name-sans-extension user-init-file))
> +                        (alt (concat source ".el")))
> +                   (setq source (cond ((file-exists-p alt) alt)
> +                                      ((file-exists-p source) source)
> +                                      (t nil)))
> +                   (when source
> +                     (when (file-newer-than-file-p source user-init-file)
> +                       (message "Warning: %s is newer than %s"
> +                                source user-init-file)
> +                       (sit-for 1))
> +                     (setq user-init-file source))))
> +
> +               (when load-defaults
> +
> +                 ;; Prevent default.el from changing the value of
> +                 ;; `inhibit-startup-screen'.
> +                 (let ((inhibit-startup-screen nil))
> +                   (load "default" 'noerror 'nomessage)))))))
> +      ;; Now call our anonymous function.
> +      (if init-file-debug
> +          ;; Do this without a `condition-case' if the user wants to
> +          ;; debug.
> +          (funcall read-init-file)
> +        (condition-case error
> +            (progn
> +              (funcall read-init-file)
> +
> +              ;; If a previous init-file had an error, don't forget
> +              ;; about that.
> +              (unless init-file-had-error
> +                (setq init-file-had-error nil)))
> +          (error
> +           (display-warning
> +            'initialization
> +            (format-message "\
> +An error occurred while loading `%s':\n\n%s%s%s\n\n\
> +To ensure normal operation, you should investigate and remove the
> +cause of the error in your initialization file.  Start Emacs with
> +the `--debug-init' option to view a complete error backtrace."
> +                            user-init-file
> +                            (get (car error) 'error-message)
> +                            (if (cdr error) ": " "")
> +                            (mapconcat (lambda (s) (prin1-to-string s t))
> +                                       (cdr error) ", "))
> +            :warning)
> +           (setq init-file-had-error t))))
> +
> +      ;; If we can tell that the init file altered debug-on-error,
> +      ;; arrange to preserve the value that it set up.
> +      (or (eq debug-on-error debug-on-error-initial)
> +          (setq debug-on-error-should-be-set t
> +                debug-on-error-from-init-file debug-on-error)))
> +
> +    (when debug-on-error-should-be-set
> +      (setq debug-on-error debug-on-error-from-init-file))
> +
> +    (unless (or (default-value 'enable-multibyte-characters)
> +                (eq orig-enable-multibyte (default-value
> +                                            'enable-multibyte-characters)))
> +
> +      ;; Init file changed to unibyte.  Reset existing multibyte
> +      ;; buffers (probably *scratch*, *Messages*, *Minibuf-0*).
> +      ;; Arguably this should only be done if they're free of
> +      ;; multibyte characters.
> +      (mapc (lambda (buffer)
> +              (with-current-buffer buffer
> +                (if enable-multibyte-characters
> +                    (set-buffer-multibyte nil))))
> +            (buffer-list))
> +
> +      ;; Also re-set the language environment in case it was
> +      ;; originally done before unibyte was set and is sensitive to
> +      ;; unibyte (display table, terminal coding system &c).
> +      (set-language-environment current-language-environment))))
> +
>  (defun command-line ()
>    "A subroutine of `normal-top-level'.
>  Amongst another things, it parses the command-line arguments."
> @@ -1021,6 +1153,69 @@ command-line
>      (and command-line-args
>           (setcdr command-line-args args)))
>  
> +  ;; Warn for invalid user name.
> +  (when init-file-user
> +    (if (string-match "[~/:\n]" init-file-user)
> +        (display-warning 'initialization
> +                         (format "Invalid user name %s"
> +                                 init-file-user)
> +                         :error)
> +      (if (file-directory-p (expand-file-name
> +                             ;; We don't support ~USER on MS-Windows
> +                             ;; and MS-DOS except for the current
> +                             ;; user, and always load .emacs from
> +                             ;; the current user's home directory
> +                             ;; (see below).  So always check "~",
> +                             ;; even if invoked with "-u USER", or
> +                             ;; if $USER or $LOGNAME are set to
> +                             ;; something different.
> +                             (if (memq system-type '(windows-nt ms-dos))
> +                                 "~"
> +                               (concat "~" init-file-user))))
> +          nil
> +        (display-warning 'initialization
> +                         (format "User %s has no home directory"
> +                                 (if (equal init-file-user "")
> +                                     (user-real-login-name)
> +                                   init-file-user))
> +                         :error))))
> +
> +  ;; Load the early init file, if found.
> +  (load-user-init-file
> +   (lambda ()
> +     (expand-file-name
> +      "early-init"
> +      (file-name-as-directory
> +       (concat "~" init-file-user "/.emacs.d")))))
> +  (setq early-init-file user-init-file)
> +
> +  ;; If any package directory exists, initialize the package system.
> +  (and user-init-file
> +       package-enable-at-startup
> +       (catch 'package-dir-found
> +      (let (dirs)
> +        (if (boundp 'package-directory-list)
> +            (setq dirs package-directory-list)
> +          (dolist (f load-path)
> +            (and (stringp f)
> +                 (equal (file-name-nondirectory f) "site-lisp")
> +                 (push (expand-file-name "elpa" f) dirs))))
> +        (push (if (boundp 'package-user-dir)
> +                  package-user-dir
> +                (locate-user-emacs-file "elpa"))
> +              dirs)
> +        (dolist (dir dirs)
> +          (when (file-directory-p dir)
> +            (dolist (subdir (directory-files dir))
> +              (when (let ((subdir (expand-file-name subdir dir)))
> +                         (and (file-directory-p subdir)
> +                              (file-exists-p
> +                               (expand-file-name
> +                                (package--description-file subdir)
> +                                subdir))))
> +                (throw 'package-dir-found t)))))))
> +       (package-initialize))
> +
>    ;; Make sure window system's init file was loaded in loadup.el if
>    ;; using a window system.
>    ;; Initialize the window-system only after processing the command-line
> @@ -1127,170 +1322,47 @@ command-line
>      ;; the startup screen.
>      (setq inhibit-startup-screen nil)
>  
> -    ;; Warn for invalid user name.
> -    (when init-file-user
> -      (if (string-match "[~/:\n]" init-file-user)
> -       (display-warning 'initialization
> -                        (format "Invalid user name %s"
> -                                init-file-user)
> -                        :error)
> -     (if (file-directory-p (expand-file-name
> -                            ;; We don't support ~USER on MS-Windows
> -                            ;; and MS-DOS except for the current
> -                            ;; user, and always load .emacs from
> -                            ;; the current user's home directory
> -                            ;; (see below).  So always check "~",
> -                            ;; even if invoked with "-u USER", or
> -                            ;; if $USER or $LOGNAME are set to
> -                            ;; something different.
> -                            (if (memq system-type '(windows-nt ms-dos))
> -                                "~"
> -                              (concat "~" init-file-user))))
> -         nil
> -       (display-warning 'initialization
> -                        (format "User %s has no home directory"
> -                                (if (equal init-file-user "")
> -                                    (user-real-login-name)
> -                                  init-file-user))
> -                        :error))))
> -
>      ;; Load that user's init file, or the default one, or none.
> -    (let (debug-on-error-from-init-file
> -       debug-on-error-should-be-set
> -       (debug-on-error-initial
> -        (if (eq init-file-debug t) 'startup init-file-debug))
> -       (orig-enable-multibyte (default-value 'enable-multibyte-characters)))
> -      (let ((debug-on-error debug-on-error-initial)
> -         ;; This function actually reads the init files.
> -         (inner
> -          (function
> -           (lambda ()
> -             (if init-file-user
> -                 (let ((user-init-file-1
> -                        (cond
> -                          ((eq system-type 'ms-dos)
> -                           (concat "~" init-file-user "/_emacs"))
> -                          ((not (eq system-type 'windows-nt))
> -                           (concat "~" init-file-user "/.emacs"))
> -                          ;; Else deal with the Windows situation
> -                          ((directory-files "~" nil 
> "^\\.emacs\\(\\.elc?\\)?$")
> -                           ;; Prefer .emacs on Windows.
> -                           "~/.emacs")
> -                          ((directory-files "~" nil "^_emacs\\(\\.elc?\\)?$")
> -                           ;; Also support _emacs for compatibility, but 
> warn about it.
> -                           (push `(initialization
> -                                   ,(format-message
> -                                     "`_emacs' init file is deprecated, 
> please use `.emacs'"))
> -                                 delayed-warnings-list)
> -                           "~/_emacs")
> -                          (t ;; But default to .emacs if _emacs does not 
> exist.
> -                           "~/.emacs"))))
> -                   ;; This tells `load' to store the file name found
> -                   ;; into user-init-file.
> -                   (setq user-init-file t)
> -                   (load user-init-file-1 t t)
> -
> -                   (when (eq user-init-file t)
> -                     ;; If we did not find ~/.emacs, try
> -                     ;; ~/.emacs.d/init.el.
> -                     (let ((otherfile
> -                            (expand-file-name
> -                             "init"
> -                             (file-name-as-directory
> -                              (concat "~" init-file-user "/.emacs.d")))))
> -                       (load otherfile t t)
> -
> -                       ;; 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 user-init-file-1))))
> -
> -                   ;; If we loaded a compiled file, set
> -                   ;; `user-init-file' to the source version if that
> -                   ;; exists.
> -                   (when (and user-init-file
> -                              (equal (file-name-extension user-init-file)
> -                                     "elc"))
> -                     (let* ((source (file-name-sans-extension 
> user-init-file))
> -                            (alt (concat source ".el")))
> -                       (setq source (cond ((file-exists-p alt) alt)
> -                                          ((file-exists-p source) source)
> -                                          (t nil)))
> -                       (when source
> -                         (when (file-newer-than-file-p source user-init-file)
> -                           (message "Warning: %s is newer than %s"
> -                                    source user-init-file)
> -                           (sit-for 1))
> -                         (setq user-init-file source))))
> -
> -                   (unless inhibit-default-init
> -                        (let ((inhibit-startup-screen nil))
> -                          ;; Users are supposed to be told their rights.
> -                          ;; (Plus how to get help and how to undo.)
> -                          ;; Don't you dare turn this off for anyone
> -                          ;; except yourself.
> -                          (load "default" t t)))))))))
> -     (if init-file-debug
> -         ;; Do this without a condition-case if the user wants to debug.
> -         (funcall inner)
> -       (condition-case error
> -           (progn
> -             (funcall inner)
> -             (setq init-file-had-error nil))
> -         (error
> -          (display-warning
> -           'initialization
> -           (format-message "\
> -An error occurred while loading `%s':\n\n%s%s%s\n\n\
> -To ensure normal operation, you should investigate and remove the
> -cause of the error in your initialization file.  Start Emacs with
> -the `--debug-init' option to view a complete error backtrace."
> -                   user-init-file
> -                   (get (car error) 'error-message)
> -                   (if (cdr error) ": " "")
> -                   (mapconcat (lambda (s) (prin1-to-string s t))
> -                              (cdr error) ", "))
> -           :warning)
> -          (setq init-file-had-error t))))
> -
> -      (if (and deactivate-mark transient-mark-mode)
> -         (with-current-buffer (window-buffer)
> -           (deactivate-mark)))
> -
> -     ;; If the user has a file of abbrevs, read it (unless -batch).
> -     (when (and (not noninteractive)
> -                (file-exists-p abbrev-file-name)
> -                (file-readable-p abbrev-file-name))
> -         (quietly-read-abbrev-file abbrev-file-name))
> -
> -     ;; If the abbrevs came entirely from the init file or the
> -     ;; abbrevs file, they do not need saving.
> -     (setq abbrevs-changed nil)
> -
> -     ;; If we can tell that the init file altered debug-on-error,
> -     ;; arrange to preserve the value that it set up.
> -     (or (eq debug-on-error debug-on-error-initial)
> -         (setq debug-on-error-should-be-set t
> -               debug-on-error-from-init-file debug-on-error)))
> -      (if debug-on-error-should-be-set
> -       (setq debug-on-error debug-on-error-from-init-file))
> -      (unless (or (default-value 'enable-multibyte-characters)
> -               (eq orig-enable-multibyte (default-value
> -                                           'enable-multibyte-characters)))
> -     ;; Init file changed to unibyte.  Reset existing multibyte
> -     ;; buffers (probably *scratch*, *Messages*, *Minibuf-0*).
> -     ;; Arguably this should only be done if they're free of
> -     ;; multibyte characters.
> -     (mapc (lambda (buffer)
> -             (with-current-buffer buffer
> -               (if enable-multibyte-characters
> -                   (set-buffer-multibyte nil))))
> -           (buffer-list))
> -     ;; Also re-set the language environment in case it was
> -     ;; originally done before unibyte was set and is sensitive to
> -     ;; unibyte (display table, terminal coding system &c).
> -     (set-language-environment current-language-environment)))
> +    (load-user-init-file
> +     (lambda ()
> +       (cond
> +        ((eq system-type 'ms-dos)
> +         (concat "~" init-file-user "/_emacs"))
> +        ((not (eq system-type 'windows-nt))
> +         (concat "~" init-file-user "/.emacs"))
> +        ;; Else deal with the Windows situation.
> +        ((directory-files "~" nil "^\\.emacs\\(\\.elc?\\)?$")
> +         ;; Prefer .emacs on Windows.
> +         "~/.emacs")
> +        ((directory-files "~" nil "^_emacs\\(\\.elc?\\)?$")
> +         ;; Also support _emacs for compatibility, but warn about it.
> +         (push `(initialization
> +                 ,(format-message
> +                   "`_emacs' init file is deprecated, please use `.emacs'"))
> +               delayed-warnings-list)
> +         "~/_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)
> +      (with-current-buffer (window-buffer)
> +        (deactivate-mark)))
> +
> +    ;; If the user has a file of abbrevs, read it (unless -batch).
> +    (when (and (not noninteractive)
> +               (file-exists-p abbrev-file-name)
> +               (file-readable-p abbrev-file-name))
> +      (quietly-read-abbrev-file abbrev-file-name))
> +
> +    ;; If the abbrevs came entirely from the init file or the
> +    ;; abbrevs file, they do not need saving.
> +    (setq abbrevs-changed nil)
>  
>      ;; Do this here in case the init file sets mail-host-address.
>      (and mail-host-address
> @@ -1312,33 +1384,6 @@ command-line
>                (eq face-ignored-fonts old-face-ignored-fonts))
>        (clear-face-cache)))
>  
> -  ;; If any package directory exists, initialize the package system.
> -  (and user-init-file
> -       package-enable-at-startup
> -       (catch 'package-dir-found
> -      (let (dirs)
> -        (if (boundp 'package-directory-list)
> -            (setq dirs package-directory-list)
> -          (dolist (f load-path)
> -            (and (stringp f)
> -                 (equal (file-name-nondirectory f) "site-lisp")
> -                 (push (expand-file-name "elpa" f) dirs))))
> -        (push (if (boundp 'package-user-dir)
> -                  package-user-dir
> -                (locate-user-emacs-file "elpa"))
> -              dirs)
> -        (dolist (dir dirs)
> -          (when (file-directory-p dir)
> -            (dolist (subdir (directory-files dir))
> -              (when (let ((subdir (expand-file-name subdir dir)))
> -                         (and (file-directory-p subdir)
> -                              (file-exists-p
> -                               (expand-file-name
> -                                (package--description-file subdir)
> -                                subdir))))
> -                (throw 'package-dir-found t)))))))
> -       (package-initialize))
> -
>    (setq after-init-time (current-time))
>    ;; Display any accumulated warnings after all functions in
>    ;; `after-init-hook' like `desktop-read' have finalized possible
> diff --git a/src/lread.c b/src/lread.c
> index 52897b4fcc..5ff438041b 100644
> --- a/src/lread.c
> +++ b/src/lread.c
> @@ -4892,7 +4892,7 @@ directory.  These file names are converted to absolute 
> at startup.  */);
>  If the file loaded had extension `.elc', and the corresponding source file
>  exists, this variable contains the name of source file, suitable for use
>  by functions like `custom-save-all' which edit the init file.
> -While Emacs loads and evaluates the init file, value is the real name
> +While Emacs loads and evaluates any init file, value is the real name
>  of the file, regardless of whether or not it has the `.elc' extension.  */);
>    Vuser_init_file = Qnil;
>  
> -- 
> 2.14.3
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]