all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [PATCH] Setting user-emacs-directory
@ 2015-03-23 23:25 François Févotte
  2015-04-01 15:24 ` bug#15539: " François Févotte
  2015-04-01 15:24 ` François Févotte
  0 siblings, 2 replies; 10+ messages in thread
From: François Févotte @ 2015-03-23 23:25 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1407 bytes --]

Hello emacs-devel,

below is a patch trying to address old bug #15539.

It introduces an EMACS_USER_DIRECTORY environment variable which (if
present) has two effects:
1- it provides a custom value for `user-emacs-directory' (instead of
the default `~/.emacs.d').
2- it instructs emacs to look for the initialization file in the
provided directory (instead of `~USER/.emacs.d')

As explained in the bug's discussion, this covers more use cases than
simply symlinking ~/.emacs.d. Here are for example a few words about
my use case: at work, I try to maintain a sensible set of init files
for my co-workers to use (with the very outdated default version that
we have installed by default on our systems: 23.2). On the other hand,
on my machine, I maintain a locally-installed Emacs version that is
more up-to-date. In order to maintain both sets of init files, I need
to be able to run
both versions of Emacs at the same time, which prevents me from
symlinking ~/.emacs.d/
There are also reddit[1] and stackexchange[2] questions hinting at the
same kind of use.

Please do not hesitate to comment and criticize the patch; this is my
first time and I might very well have overlooked some details.

Thanks in advance,
   François


[1] http://www.reddit.com/r/emacs/comments/2y1b3a/how_can_i_easily_keep_different_emacsd_folders/

[2] http://emacs.stackexchange.com/q/4253/221

[-- Attachment #2: 0001-Look-for-an-EMACS_USER_DIRECTORY-environment-variabl.patch --]
[-- Type: text/x-patch, Size: 5189 bytes --]

From f98d2af08d2346121556f4fd91628dc0316cbff0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20F=C3=A9votte?= <francois.fevotte@ensta.org>
Date: Tue, 17 Mar 2015 08:50:01 +0100
Subject: [PATCH] Look for an `EMACS_USER_DIRECTORY' environment variable.

This sets `user-emacs-directory' and looks for `init.el' in it.

Fixes: bug#15539
---
 doc/emacs/cmdargs.texi |    9 ++++++++-
 doc/emacs/custom.texi  |    8 ++++++++
 lisp/custom.el         |    1 +
 lisp/startup.el        |   21 +++++++++++++++++----
 4 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index 42c8e33..1cc8ac3 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -349,7 +349,9 @@ Do not reload any saved desktop.  @xref{Saving Emacs Sessions}.
 @opindex --user
 @cindex load init file of another user
 Load @var{user}'s initialization file instead of your
-own@footnote{This option has no effect on MS-Windows.}.
+own@footnote{This option has no effect on MS-Windows, nor when the
+@env{EMACS_USER_DIRECTORY} environment variable is set (@pxref{General
+Variables}).}.
 
 @item --debug-init
 @opindex --debug-init
@@ -600,6 +602,11 @@ does not use @env{TZ} at all.
 @item USER
 The user's login name.  See also @env{LOGNAME}.  On MS-DOS, this
 defaults to @samp{root}.
+@item EMACS_USER_DIRECTORY
+This specifies a directory in which the initialization file will be
+looked for; @xref{Find Init}. This directory will also be used as the
+default place where user-specific configuration data will be stored;
+@xref{Standard File Names,,, elisp}.
 @item VERSION_CONTROL
 Used to initialize the @code{version-control} variable (@pxref{Backup
 Names}).
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 9fd823b..1e1d482 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -2516,6 +2516,14 @@ otherwise, it looks up the home directory corresponding to that user
 name in the system's data base of users.
 @c  LocalWords:  backtab
 
+  The whole mechanism described above is bypassed if the
+@env{EMACS_USER_DIRECTORY} environment variable is specified, in which
+case Emacs directly looks for @file{init.el} inside the directory
+specified by @env{EMACS_USER_DIRECTORY} (@pxref{General Variables}).
+This directory is also used to hold user-specific configuration
+(@pxref{Standard File Names,,, elisp}).
+
+
 @node Init Non-ASCII
 @subsection Non-@acronym{ASCII} Characters in Init Files
 @cindex international characters in @file{.emacs}
diff --git a/lisp/custom.el b/lisp/custom.el
index e5fe0eb..36983aa 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1119,6 +1119,7 @@ directory.  By default, Emacs searches for custom themes in this
 directory first---see `custom-theme-load-path'."
   :type 'string
   :group 'customize
+  :initialize 'custom-initialize-delay
   :version "22.1")
 
 (defcustom custom-theme-load-path (list 'custom-theme-directory t)
diff --git a/lisp/startup.el b/lisp/startup.el
index 7fa929a..2b2c324 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -397,7 +397,8 @@ Set this to nil if you want to prevent `auto-save-list-file-name'
 from being initialized."
   :type '(choice (const :tag "Don't record a session's auto save list" nil)
 		 string)
-  :group 'auto-save)
+  :group 'auto-save
+  :initialize 'custom-initialize-delay)
 
 (defvar emacs-basic-display nil)
 
@@ -814,6 +815,12 @@ Amongst another things, it parses the command-line arguments."
 	  ((member vc '("never" "simple"))
 	   (setq version-control 'never))))
 
+  ;; Set `user-emacs-directory' early so that delayed init variables
+  ;; can be updated.
+  (let ((ued (getenv "EMACS_USER_DIRECTORY")))
+    (when ued
+      (setq user-emacs-directory (file-name-as-directory ued))))
+
   ;;! This has been commented out; I currently find the behavior when
   ;;! split-window-keep-point is nil disturbing, but if I can get used
   ;;! to it, then it would be better to eliminate the option.
@@ -1101,11 +1108,15 @@ please check its value")
 				    delayed-warnings-list)
 			      "~/_emacs")
 			     (t ;; But default to .emacs if _emacs does not exist.
-			      "~/.emacs"))))
+			      "~/.emacs")))
+                          (user-emacs-directory--from-env (getenv "EMACS_USER_DIRECTORY")))
 		      ;; 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)
+
+                      ;; Don't load `~/.emacs' if EMACS_USER_DIRECTORY was set
+                      (unless user-emacs-directory--from-env
+                        (load user-init-file-1 t t))
 
 		      (when (eq user-init-file t)
 			;; If we did not find ~/.emacs, try
@@ -1114,7 +1125,9 @@ please check its value")
 			       (expand-file-name
 				"init"
 				(file-name-as-directory
-				 (concat "~" init-file-user "/.emacs.d")))))
+                                 (if user-emacs-directory--from-env
+                                     user-emacs-directory
+                                   (concat "~" init-file-user "/.emacs.d"))))))
 			  (load otherfile t t)
 
 			  ;; If we did not find the user's init file,
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-03-23 23:25 [PATCH] Setting user-emacs-directory François Févotte
@ 2015-04-01 15:24 ` François Févotte
  2015-04-01 15:24 ` François Févotte
  1 sibling, 0 replies; 10+ messages in thread
From: François Févotte @ 2015-04-01 15:24 UTC (permalink / raw)
  To: emacs-devel, 15539

Hello,

On Tue, Mar 24, 2015 at 12:25 AM, François Févotte <fevotte@gmail.com> wrote:
> below is a patch trying to address old bug #15539.

after the lack of reaction to my last email, I would like to have one
more chance of getting emacs-devel's feedback on this issue (namely:
being able to tell Emacs where to find its init file).

Is nobody interested in this feature?  Or is the proposed patch not adequate?
In the former case, please just say so, so that we can maybe mark the
bug as "wontfix" and let it be clear.  In the latter case, I'm still
welcoming any comment on the proposed solution.  And of course I'm
willing to work on any improvement you might suggest.

Thanks in advance,
   François





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Setting user-emacs-directory
  2015-03-23 23:25 [PATCH] Setting user-emacs-directory François Févotte
  2015-04-01 15:24 ` bug#15539: " François Févotte
@ 2015-04-01 15:24 ` François Févotte
  2015-04-01 15:38   ` bug#15539: " Oleh Krehel
  1 sibling, 1 reply; 10+ messages in thread
From: François Févotte @ 2015-04-01 15:24 UTC (permalink / raw)
  To: emacs-devel, 15539

Hello,

On Tue, Mar 24, 2015 at 12:25 AM, François Févotte <fevotte@gmail.com> wrote:
> below is a patch trying to address old bug #15539.

after the lack of reaction to my last email, I would like to have one
more chance of getting emacs-devel's feedback on this issue (namely:
being able to tell Emacs where to find its init file).

Is nobody interested in this feature?  Or is the proposed patch not adequate?
In the former case, please just say so, so that we can maybe mark the
bug as "wontfix" and let it be clear.  In the latter case, I'm still
welcoming any comment on the proposed solution.  And of course I'm
willing to work on any improvement you might suggest.

Thanks in advance,
   François



^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-04-01 15:24 ` François Févotte
@ 2015-04-01 15:38   ` Oleh Krehel
  2015-04-01 15:49     ` Drew Adams
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Oleh Krehel @ 2015-04-01 15:38 UTC (permalink / raw)
  To: François Févotte; +Cc: 15539, emacs-devel

François Févotte <francois.fevotte@ensta.org> writes:

> Hello,
>
> On Tue, Mar 24, 2015 at 12:25 AM, François Févotte <fevotte@gmail.com> wrote:
>> below is a patch trying to address old bug #15539.
>
> after the lack of reaction to my last email, I would like to have one
> more chance of getting emacs-devel's feedback on this issue (namely:
> being able to tell Emacs where to find its init file).
>
> Is nobody interested in this feature?  Or is the proposed patch not adequate?
> In the former case, please just say so, so that we can maybe mark the
> bug as "wontfix" and let it be clear.  In the latter case, I'm still
> welcoming any comment on the proposed solution.  And of course I'm
> willing to work on any improvement you might suggest.

I'm interested in this feature, I just didn't have time to test it yet.
I'll try to look at it soon.

Oleh





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-04-01 15:38   ` bug#15539: " Oleh Krehel
@ 2015-04-01 15:49     ` Drew Adams
  2015-04-01 15:49     ` Drew Adams
  2015-04-01 16:48     ` bug#15539: " Oleh Krehel
  2 siblings, 0 replies; 10+ messages in thread
From: Drew Adams @ 2015-04-01 15:49 UTC (permalink / raw)
  To: Oleh Krehel, François Févotte; +Cc: 15539, emacs-devel

> I'm interested in this feature, I just didn't have time to test it yet.
> I'll try to look at it soon.

Can y'all please drop one of the mailing lists (e.g. emacs-devel)?  Thx.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH] Setting user-emacs-directory
  2015-04-01 15:38   ` bug#15539: " Oleh Krehel
  2015-04-01 15:49     ` Drew Adams
@ 2015-04-01 15:49     ` Drew Adams
  2015-04-01 16:48     ` bug#15539: " Oleh Krehel
  2 siblings, 0 replies; 10+ messages in thread
From: Drew Adams @ 2015-04-01 15:49 UTC (permalink / raw)
  To: Oleh Krehel, François Févotte; +Cc: 15539, emacs-devel

> I'm interested in this feature, I just didn't have time to test it yet.
> I'll try to look at it soon.

Can y'all please drop one of the mailing lists (e.g. emacs-devel)?  Thx.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-04-01 15:38   ` bug#15539: " Oleh Krehel
  2015-04-01 15:49     ` Drew Adams
  2015-04-01 15:49     ` Drew Adams
@ 2015-04-01 16:48     ` Oleh Krehel
  2015-04-01 17:16       ` François Févotte
  2 siblings, 1 reply; 10+ messages in thread
From: Oleh Krehel @ 2015-04-01 16:48 UTC (permalink / raw)
  To: François Févotte; +Cc: 15539

Oleh Krehel <ohwoeowho@gmail.com> writes:

> François Févotte <francois.fevotte@ensta.org> writes:
>
>> Hello,
>>
>> On Tue, Mar 24, 2015 at 12:25 AM, François Févotte <fevotte@gmail.com> wrote:
>>> below is a patch trying to address old bug #15539.
>>
>> after the lack of reaction to my last email, I would like to have one
>> more chance of getting emacs-devel's feedback on this issue (namely:
>> being able to tell Emacs where to find its init file).
>>
>> Is nobody interested in this feature?  Or is the proposed patch not adequate?
>> In the former case, please just say so, so that we can maybe mark the
>> bug as "wontfix" and let it be clear.  In the latter case, I'm still
>> welcoming any comment on the proposed solution.  And of course I'm
>> willing to work on any improvement you might suggest.
>
> I'm interested in this feature, I just didn't have time to test it yet.
> I'll try to look at it soon.

OK, I've tested it and it works great. I vote for merging this if
someone is counting.

Just one question: why is `getenv' called twice?

Oleh






^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-04-01 16:48     ` bug#15539: " Oleh Krehel
@ 2015-04-01 17:16       ` François Févotte
  2015-04-01 21:03         ` Stefan Monnier
  0 siblings, 1 reply; 10+ messages in thread
From: François Févotte @ 2015-04-01 17:16 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: 15539

Thanks for testing

On Wed, Apr 1, 2015 at 6:48 PM, Oleh Krehel <ohwoeowho@gmail.com> wrote:
> Just one question: why is `getenv' called twice?

with the currently implemented logic, the environment variable has two
different impacts: (1) it sets the `user-emacs-directory' variable,
and (2) it changes the logic used to determine the init file. There is
currently no `let' form encompassing the whole `command-line'
function, so I had to either
1- add one (which might be the most correct implementation, but
generates a very large patch for mostly unchanged lines)
2- define a global variable (which seems unnecessary), or
3- call `getenv' multiple times.

I chose the latter, but am perfectly open to rewriting the
implementation if you feel it would be better.

    François





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-04-01 17:16       ` François Févotte
@ 2015-04-01 21:03         ` Stefan Monnier
  2015-04-02  8:12           ` François Févotte
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Monnier @ 2015-04-01 21:03 UTC (permalink / raw)
  To: François Févotte; +Cc: 15539, Oleh Krehel

> 1- add one (which might be the most correct implementation, but
> generates a very large patch for mostly unchanged lines)

That's the better option.
You can ask diff to ignore whitespace changes, which keeps the patch readable.


        Stefan





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#15539: [PATCH] Setting user-emacs-directory
  2015-04-01 21:03         ` Stefan Monnier
@ 2015-04-02  8:12           ` François Févotte
  0 siblings, 0 replies; 10+ messages in thread
From: François Févotte @ 2015-04-02  8:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 15539, Oleh Krehel

[-- Attachment #1: Type: text/plain, Size: 633 bytes --]

Here is a new version introducing a `let' form spanning everything
needed.  There is no need for two calls to `getenv' anymore.
I've attached the patch in two versions: with and without whitespace
changes (git diff -b), to make it easier to review.


Thanks,
   François

On Wed, Apr 1, 2015 at 11:03 PM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
>> 1- add one (which might be the most correct implementation, but
>> generates a very large patch for mostly unchanged lines)
>
> That's the better option.
> You can ask diff to ignore whitespace changes, which keeps the patch readable.
>
>
>         Stefan

[-- Attachment #2: EMACS_USER_DIRECTORY-nowhitespace.patch --]
[-- Type: text/x-patch, Size: 5465 bytes --]

From e15fd3120a995e38708ca73d293973dd8e596b22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20F=C3=A9votte?= <francois.fevotte@ensta.org>
Date: Thu, 2 Apr 2015 09:17:03 +0200
Subject: [PATCH] Look for an `EMACS_USER_DIRECTORY' environment variable.

This sets `user-emacs-directory' and looks for `init.el' in it.

Fixes: bug#15539
---
 doc/emacs/cmdargs.texi |    9 ++++++++-
 doc/emacs/custom.texi  |    8 ++++++++
 lisp/custom.el         |    1 +
 lisp/startup.el        |   20 ++++++++++++++++----
 4 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index 071cd68..30d3472 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -349,7 +349,9 @@ Do not reload any saved desktop.  @xref{Saving Emacs Sessions}.
 @opindex --user
 @cindex load init file of another user
 Load @var{user}'s initialization file instead of your
-own@footnote{This option has no effect on MS-Windows.}.
+own@footnote{This option has no effect on MS-Windows, nor when the
+@env{EMACS_USER_DIRECTORY} environment variable is set (@pxref{General
+Variables}).}.
 
 @item --debug-init
 @opindex --debug-init
@@ -642,6 +644,11 @@ does not use @env{TZ} at all.
 @vindex USER, environment variable
 The user's login name.  See also @env{LOGNAME}.  On MS-DOS, this
 defaults to @samp{root}.
+@item EMACS_USER_DIRECTORY
+This specifies a directory in which the initialization file will be
+looked for; @xref{Find Init}. This directory will also be used as the
+default place where user-specific configuration data will be stored;
+@xref{Standard File Names,,, elisp}.
 @item VERSION_CONTROL
 @vindex VERSION_CONTROL, environment variable
 Used to initialize the @code{version-control} variable (@pxref{Backup
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 9fd823b..1e1d482 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -2516,6 +2516,14 @@ otherwise, it looks up the home directory corresponding to that user
 name in the system's data base of users.
 @c  LocalWords:  backtab
 
+  The whole mechanism described above is bypassed if the
+@env{EMACS_USER_DIRECTORY} environment variable is specified, in which
+case Emacs directly looks for @file{init.el} inside the directory
+specified by @env{EMACS_USER_DIRECTORY} (@pxref{General Variables}).
+This directory is also used to hold user-specific configuration
+(@pxref{Standard File Names,,, elisp}).
+
+
 @node Init Non-ASCII
 @subsection Non-@acronym{ASCII} Characters in Init Files
 @cindex international characters in @file{.emacs}
diff --git a/lisp/custom.el b/lisp/custom.el
index e5fe0eb..36983aa 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1119,6 +1119,7 @@ directory.  By default, Emacs searches for custom themes in this
 directory first---see `custom-theme-load-path'."
   :type 'string
   :group 'customize
+  :initialize 'custom-initialize-delay
   :version "22.1")
 
 (defcustom custom-theme-load-path (list 'custom-theme-directory t)
diff --git a/lisp/startup.el b/lisp/startup.el
index 7fa929a..1c403c6 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -397,7 +397,8 @@ Set this to nil if you want to prevent `auto-save-list-file-name'
 from being initialized."
   :type '(choice (const :tag "Don't record a session's auto save list" nil)
 		 string)
-  :group 'auto-save)
+  :group 'auto-save
+  :initialize 'custom-initialize-delay)
 
 (defvar emacs-basic-display nil)
 
@@ -814,6 +815,12 @@ Amongst another things, it parses the command-line arguments."
 	  ((member vc '("never" "simple"))
 	   (setq version-control 'never))))
 
+  ;; Set `user-emacs-directory' early so that delayed init variables
+  ;; can be updated.
+  (let ((user-emacs-directory--from-env (getenv "EMACS_USER_DIRECTORY")))
+    (when user-emacs-directory--from-env
+      (setq user-emacs-directory (file-name-as-directory user-emacs-directory--from-env)))
+
   ;;! This has been commented out; I currently find the behavior when
   ;;! split-window-keep-point is nil disturbing, but if I can get used
   ;;! to it, then it would be better to eliminate the option.
@@ -1105,7 +1112,10 @@ please check its value")
 		      ;; 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)
+
+                        ;; Don't load `~/.emacs' if EMACS_USER_DIRECTORY was set
+                        (unless user-emacs-directory--from-env
+                          (load user-init-file-1 t t))
 
 		      (when (eq user-init-file t)
 			;; If we did not find ~/.emacs, try
@@ -1114,7 +1124,9 @@ please check its value")
 			       (expand-file-name
 				"init"
 				(file-name-as-directory
-				 (concat "~" init-file-user "/.emacs.d")))))
+                                   (if user-emacs-directory--from-env
+                                       user-emacs-directory
+                                     (concat "~" init-file-user "/.emacs.d"))))))
 			  (load otherfile t t)
 
 			  ;; If we did not find the user's init file,
@@ -1227,7 +1239,7 @@ the `--debug-init' option to view a complete error backtrace."
     ;; be realized.
     (unless (and (eq scalable-fonts-allowed old-scalable-fonts-allowed)
 		 (eq face-ignored-fonts old-face-ignored-fonts))
-      (clear-face-cache)))
+        (clear-face-cache))))
 
   ;; If any package directory exists, initialize the package system.
   (and user-init-file
-- 
1.7.2.5


[-- Attachment #3: EMACS_USER_DIRECTORY.patch --]
[-- Type: text/x-patch, Size: 40886 bytes --]

From e15fd3120a995e38708ca73d293973dd8e596b22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20F=C3=A9votte?= <francois.fevotte@ensta.org>
Date: Thu, 2 Apr 2015 09:17:03 +0200
Subject: [PATCH] Look for an `EMACS_USER_DIRECTORY' environment variable.

This sets `user-emacs-directory' and looks for `init.el' in it.

Fixes: bug#15539
---
 doc/emacs/cmdargs.texi |    9 +-
 doc/emacs/custom.texi  |    8 +
 lisp/custom.el         |    1 +
 lisp/startup.el        |  832 ++++++++++++++++++++++++------------------------
 4 files changed, 439 insertions(+), 411 deletions(-)

diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index 071cd68..30d3472 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -349,7 +349,9 @@ Do not reload any saved desktop.  @xref{Saving Emacs Sessions}.
 @opindex --user
 @cindex load init file of another user
 Load @var{user}'s initialization file instead of your
-own@footnote{This option has no effect on MS-Windows.}.
+own@footnote{This option has no effect on MS-Windows, nor when the
+@env{EMACS_USER_DIRECTORY} environment variable is set (@pxref{General
+Variables}).}.
 
 @item --debug-init
 @opindex --debug-init
@@ -642,6 +644,11 @@ does not use @env{TZ} at all.
 @vindex USER, environment variable
 The user's login name.  See also @env{LOGNAME}.  On MS-DOS, this
 defaults to @samp{root}.
+@item EMACS_USER_DIRECTORY
+This specifies a directory in which the initialization file will be
+looked for; @xref{Find Init}. This directory will also be used as the
+default place where user-specific configuration data will be stored;
+@xref{Standard File Names,,, elisp}.
 @item VERSION_CONTROL
 @vindex VERSION_CONTROL, environment variable
 Used to initialize the @code{version-control} variable (@pxref{Backup
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 9fd823b..1e1d482 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -2516,6 +2516,14 @@ otherwise, it looks up the home directory corresponding to that user
 name in the system's data base of users.
 @c  LocalWords:  backtab
 
+  The whole mechanism described above is bypassed if the
+@env{EMACS_USER_DIRECTORY} environment variable is specified, in which
+case Emacs directly looks for @file{init.el} inside the directory
+specified by @env{EMACS_USER_DIRECTORY} (@pxref{General Variables}).
+This directory is also used to hold user-specific configuration
+(@pxref{Standard File Names,,, elisp}).
+
+
 @node Init Non-ASCII
 @subsection Non-@acronym{ASCII} Characters in Init Files
 @cindex international characters in @file{.emacs}
diff --git a/lisp/custom.el b/lisp/custom.el
index e5fe0eb..36983aa 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1119,6 +1119,7 @@ directory.  By default, Emacs searches for custom themes in this
 directory first---see `custom-theme-load-path'."
   :type 'string
   :group 'customize
+  :initialize 'custom-initialize-delay
   :version "22.1")
 
 (defcustom custom-theme-load-path (list 'custom-theme-directory t)
diff --git a/lisp/startup.el b/lisp/startup.el
index 7fa929a..1c403c6 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -397,7 +397,8 @@ Set this to nil if you want to prevent `auto-save-list-file-name'
 from being initialized."
   :type '(choice (const :tag "Don't record a session's auto save list" nil)
 		 string)
-  :group 'auto-save)
+  :group 'auto-save
+  :initialize 'custom-initialize-delay)
 
 (defvar emacs-basic-display nil)
 
@@ -814,420 +815,431 @@ Amongst another things, it parses the command-line arguments."
 	  ((member vc '("never" "simple"))
 	   (setq version-control 'never))))
 
-  ;;! This has been commented out; I currently find the behavior when
-  ;;! split-window-keep-point is nil disturbing, but if I can get used
-  ;;! to it, then it would be better to eliminate the option.
-  ;;! ;; Choose a good default value for split-window-keep-point.
-  ;;! (setq split-window-keep-point (> baud-rate 2400))
-
-  ;; Convert preloaded file names in load-history to absolute.
-  (let ((simple-file-name
-	 ;; Look for simple.el or simple.elc and use their directory
-	 ;; as the place where all Lisp files live.
-	 (locate-file "simple" load-path (get-load-suffixes)))
-	lisp-dir)
-    ;; Don't abort if simple.el cannot be found, but print a warning.
-    ;; Although in most usage we are going to cryptically abort a moment
-    ;; later anyway, due to missing required bidi data files (eg bug#13430).
-    (if (null simple-file-name)
-	(let ((standard-output 'external-debugging-output)
-	      (lispdir (expand-file-name "../lisp" data-directory)))
-	  (princ "Warning: Could not find simple.el or simple.elc")
-	  (terpri)
-	  (when (getenv "EMACSLOADPATH")
-	    (princ "The EMACSLOADPATH environment variable is set, \
+  ;; Set `user-emacs-directory' early so that delayed init variables
+  ;; can be updated.
+  (let ((user-emacs-directory--from-env (getenv "EMACS_USER_DIRECTORY")))
+    (when user-emacs-directory--from-env
+      (setq user-emacs-directory (file-name-as-directory user-emacs-directory--from-env)))
+
+    ;;! This has been commented out; I currently find the behavior when
+    ;;! split-window-keep-point is nil disturbing, but if I can get used
+    ;;! to it, then it would be better to eliminate the option.
+    ;;! ;; Choose a good default value for split-window-keep-point.
+    ;;! (setq split-window-keep-point (> baud-rate 2400))
+
+    ;; Convert preloaded file names in load-history to absolute.
+    (let ((simple-file-name
+           ;; Look for simple.el or simple.elc and use their directory
+           ;; as the place where all Lisp files live.
+           (locate-file "simple" load-path (get-load-suffixes)))
+          lisp-dir)
+      ;; Don't abort if simple.el cannot be found, but print a warning.
+      ;; Although in most usage we are going to cryptically abort a moment
+      ;; later anyway, due to missing required bidi data files (eg bug#13430).
+      (if (null simple-file-name)
+          (let ((standard-output 'external-debugging-output)
+                (lispdir (expand-file-name "../lisp" data-directory)))
+            (princ "Warning: Could not find simple.el or simple.elc")
+            (terpri)
+            (when (getenv "EMACSLOADPATH")
+              (princ "The EMACSLOADPATH environment variable is set, \
 please check its value")
-	    (terpri))
-	  (unless (file-readable-p lispdir)
-	    (princ (format "Lisp directory %s not readable?" lispdir))
-	    (terpri)))
-      (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
-      (setq load-history
-	    (mapcar (lambda (elt)
-		      (if (and (stringp (car elt))
-			       (not (file-name-absolute-p (car elt))))
-			  (cons (concat lisp-dir
-					(car elt))
-				(cdr elt))
-			elt))
-		    load-history))))
-
-  ;; Convert the arguments to Emacs internal representation.
-  (let ((args command-line-args))
-    (while args
-      (setcar args
-	      (decode-coding-string (car args) locale-coding-system t))
-      (pop args)))
-
-  (let ((done nil)
-	(args (cdr command-line-args))
-	display-arg)
-
-    ;; Figure out which user's init file to load,
-    ;; either from the environment or from the options.
-    (setq init-file-user (if noninteractive nil (user-login-name)))
-    ;; If user has not done su, use current $HOME to find .emacs.
-    (and init-file-user
-         (equal init-file-user (user-real-login-name))
-	 (setq init-file-user ""))
-
-    ;; Process the command-line args, and delete the arguments
-    ;; processed.  This is consistent with the way main in emacs.c
-    ;; does things.
-    (while (and (not done) args)
-      (let* ((longopts '(("--no-init-file") ("--no-site-file")
-                         ("--no-x-resources") ("--debug-init")
-                         ("--user") ("--iconic") ("--icon-type") ("--quick")
-			 ("--no-blinking-cursor") ("--basic-display")))
-             (argi (pop args))
-             (orig-argi argi)
-             argval)
-	;; Handle --OPTION=VALUE format.
-	(when (string-match "\\`\\(--[^=]*\\)=" argi)
-	  (setq argval (substring argi (match-end 0))
-                argi (match-string 1 argi)))
-	(when (string-match "\\`--." orig-argi)
-	  (let ((completion (try-completion argi longopts)))
-	    (cond ((eq completion t)
-		   (setq argi (substring argi 1)))
-		  ((stringp completion)
-		   (let ((elt (assoc completion longopts)))
-		     (unless elt
-		       (error "Option `%s' is ambiguous" argi))
-		     (setq argi (substring (car elt) 1))))
-		  (t
-		   (setq argval nil
-			 argi orig-argi)))))
-	(cond
-	 ;; The --display arg is handled partly in C, partly in Lisp.
-	 ;; When it shows up here, we just put it back to be handled
-	 ;; by `command-line-1'.
-	 ((member argi '("-d" "-display"))
-	  (setq display-arg (list argi (pop args))))
-	 ((member argi '("-Q" "-quick"))
-	  (setq init-file-user nil
-		site-run-file nil
-                inhibit-x-resources t))
-         ((member argi '("-no-x-resources"))
-          (setq inhibit-x-resources t))
-	 ((member argi '("-D" "-basic-display"))
-	  (setq no-blinking-cursor t
-		emacs-basic-display t)
-	  (push '(vertical-scroll-bars . nil) initial-frame-alist))
-	 ((member argi '("-q" "-no-init-file"))
-	  (setq init-file-user nil))
-	 ((member argi '("-u" "-user"))
-	  (setq init-file-user (or argval (pop args))
-		argval nil))
-	 ((equal argi "-no-site-file")
-	  (setq site-run-file nil))
-	 ((equal argi "-debug-init")
-	  (setq init-file-debug t))
-	 ((equal argi "-iconic")
-	  (push '(visibility . icon) initial-frame-alist))
-	 ((member argi '("-nbc" "-no-blinking-cursor"))
-	  (setq no-blinking-cursor t))
-	 ;; Push the popped arg back on the list of arguments.
-	 (t
-          (push argi args)
-          (setq done t)))
-	;; Was argval set but not used?
-	(and argval
-	     (error "Option `%s' doesn't allow an argument" argi))))
-
-    ;; Re-attach the --display arg.
-    (and display-arg (setq args (append display-arg args)))
-
-    ;; Re-attach the program name to the front of the arg list.
-    (and command-line-args
-         (setcdr command-line-args args)))
-
-  ;; 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
-  ;; args so that -Q can influence this initialization.
-  (condition-case error
-    (unless noninteractive
-      (if (and initial-window-system
-	       (not (featurep
-		     (intern
-		      (concat (symbol-name initial-window-system) "-win")))))
-	  (error "Unsupported window system `%s'" initial-window-system))
-      ;; Process window-system specific command line parameters.
-      (setq command-line-args
-	    (funcall
-             (gui-method handle-args-function initial-window-system)
-	     command-line-args))
-      ;; Initialize the window system. (Open connection, etc.)
-      (funcall
-       (gui-method window-system-initialization initial-window-system))
-      (put initial-window-system 'window-system-initialized t))
-    ;; If there was an error, print the error message and exit.
-    (error
-     (princ
-      (if (eq (car error) 'error)
-	  (apply 'concat (cdr error))
-	(if (memq 'file-error (get (car error) 'error-conditions))
-	    (format "%s: %s"
-                    (nth 1 error)
+              (terpri))
+            (unless (file-readable-p lispdir)
+              (princ (format "Lisp directory %s not readable?" lispdir))
+              (terpri)))
+        (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
+        (setq load-history
+              (mapcar (lambda (elt)
+                        (if (and (stringp (car elt))
+                                 (not (file-name-absolute-p (car elt))))
+                            (cons (concat lisp-dir
+                                          (car elt))
+                                  (cdr elt))
+                          elt))
+                      load-history))))
+
+    ;; Convert the arguments to Emacs internal representation.
+    (let ((args command-line-args))
+      (while args
+        (setcar args
+                (decode-coding-string (car args) locale-coding-system t))
+        (pop args)))
+
+    (let ((done nil)
+          (args (cdr command-line-args))
+          display-arg)
+
+      ;; Figure out which user's init file to load,
+      ;; either from the environment or from the options.
+      (setq init-file-user (if noninteractive nil (user-login-name)))
+      ;; If user has not done su, use current $HOME to find .emacs.
+      (and init-file-user
+           (equal init-file-user (user-real-login-name))
+           (setq init-file-user ""))
+
+      ;; Process the command-line args, and delete the arguments
+      ;; processed.  This is consistent with the way main in emacs.c
+      ;; does things.
+      (while (and (not done) args)
+        (let* ((longopts '(("--no-init-file") ("--no-site-file")
+                           ("--no-x-resources") ("--debug-init")
+                           ("--user") ("--iconic") ("--icon-type") ("--quick")
+                           ("--no-blinking-cursor") ("--basic-display")))
+               (argi (pop args))
+               (orig-argi argi)
+               argval)
+          ;; Handle --OPTION=VALUE format.
+          (when (string-match "\\`\\(--[^=]*\\)=" argi)
+            (setq argval (substring argi (match-end 0))
+                  argi (match-string 1 argi)))
+          (when (string-match "\\`--." orig-argi)
+            (let ((completion (try-completion argi longopts)))
+              (cond ((eq completion t)
+                     (setq argi (substring argi 1)))
+                    ((stringp completion)
+                     (let ((elt (assoc completion longopts)))
+                       (unless elt
+                         (error "Option `%s' is ambiguous" argi))
+                       (setq argi (substring (car elt) 1))))
+                    (t
+                     (setq argval nil
+                           argi orig-argi)))))
+          (cond
+           ;; The --display arg is handled partly in C, partly in Lisp.
+           ;; When it shows up here, we just put it back to be handled
+           ;; by `command-line-1'.
+           ((member argi '("-d" "-display"))
+            (setq display-arg (list argi (pop args))))
+           ((member argi '("-Q" "-quick"))
+            (setq init-file-user nil
+                  site-run-file nil
+                  inhibit-x-resources t))
+           ((member argi '("-no-x-resources"))
+            (setq inhibit-x-resources t))
+           ((member argi '("-D" "-basic-display"))
+            (setq no-blinking-cursor t
+                  emacs-basic-display t)
+            (push '(vertical-scroll-bars . nil) initial-frame-alist))
+           ((member argi '("-q" "-no-init-file"))
+            (setq init-file-user nil))
+           ((member argi '("-u" "-user"))
+            (setq init-file-user (or argval (pop args))
+                  argval nil))
+           ((equal argi "-no-site-file")
+            (setq site-run-file nil))
+           ((equal argi "-debug-init")
+            (setq init-file-debug t))
+           ((equal argi "-iconic")
+            (push '(visibility . icon) initial-frame-alist))
+           ((member argi '("-nbc" "-no-blinking-cursor"))
+            (setq no-blinking-cursor t))
+           ;; Push the popped arg back on the list of arguments.
+           (t
+            (push argi args)
+            (setq done t)))
+          ;; Was argval set but not used?
+          (and argval
+               (error "Option `%s' doesn't allow an argument" argi))))
+
+      ;; Re-attach the --display arg.
+      (and display-arg (setq args (append display-arg args)))
+
+      ;; Re-attach the program name to the front of the arg list.
+      (and command-line-args
+           (setcdr command-line-args args)))
+
+    ;; 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
+    ;; args so that -Q can influence this initialization.
+    (condition-case error
+        (unless noninteractive
+          (if (and initial-window-system
+                   (not (featurep
+                         (intern
+                          (concat (symbol-name initial-window-system) "-win")))))
+              (error "Unsupported window system `%s'" initial-window-system))
+          ;; Process window-system specific command line parameters.
+          (setq command-line-args
+                (funcall
+                 (gui-method handle-args-function initial-window-system)
+                 command-line-args))
+          ;; Initialize the window system. (Open connection, etc.)
+          (funcall
+           (gui-method window-system-initialization initial-window-system))
+          (put initial-window-system 'window-system-initialized t))
+      ;; If there was an error, print the error message and exit.
+      (error
+       (princ
+        (if (eq (car error) 'error)
+            (apply 'concat (cdr error))
+          (if (memq 'file-error (get (car error) 'error-conditions))
+              (format "%s: %s"
+                      (nth 1 error)
+                      (mapconcat (lambda (obj) (prin1-to-string obj t))
+                                 (cdr (cdr error)) ", "))
+            (format "%s: %s"
+                    (get (car error) 'error-message)
                     (mapconcat (lambda (obj) (prin1-to-string obj t))
-                               (cdr (cdr error)) ", "))
-	  (format "%s: %s"
-                  (get (car error) 'error-message)
-                  (mapconcat (lambda (obj) (prin1-to-string obj t))
-                             (cdr error) ", "))))
-      'external-debugging-output)
-     (terpri 'external-debugging-output)
-     (setq initial-window-system nil)
-     (kill-emacs)))
-
-  (run-hooks 'before-init-hook)
-
-  ;; Under X, create the X frame and delete the terminal frame.
-  (unless (daemonp)
-    (if (or noninteractive emacs-basic-display)
-	(setq menu-bar-mode nil
-	      tool-bar-mode nil
-	      no-blinking-cursor t))
-    (frame-initialize))
-
-  (when (fboundp 'x-create-frame)
-    ;; Set up the tool-bar (even in tty frames, since Emacs might open a
-    ;; graphical frame later).
-    (unless noninteractive
-      (tool-bar-setup)))
-
-  ;; Turn off blinking cursor if so specified in X resources.  This is here
-  ;; only because all other settings of no-blinking-cursor are here.
-  (unless (or noninteractive
-	      emacs-basic-display
-	      (and (memq window-system '(x w32 ns))
-		   (not (member (x-get-resource "cursorBlink" "CursorBlink")
-				'("no" "off" "false" "0")))))
-    (setq no-blinking-cursor t))
-
-  ;; Re-evaluate predefined variables whose initial value depends on
-  ;; the runtime context.
-  (mapc 'custom-reevaluate-setting
-        ;; Initialize them in the same order they were loaded, in case there
-        ;; are dependencies between them.
-        (prog1 (nreverse custom-delayed-init-variables)
-          (setq custom-delayed-init-variables nil)))
-
-  (normal-erase-is-backspace-setup-frame)
-
-  ;; Register default TTY colors for the case the terminal hasn't a
-  ;; terminal init file.  We do this regardless of whether the terminal
-  ;; supports colors or not and regardless the current display type,
-  ;; since users can connect to color-capable terminals and also
-  ;; switch color support on or off in mid-session by setting the
-  ;; tty-color-mode frame parameter.
-  ;; Exception: the `pc' ``window system'' has only 16 fixed colors,
-  ;; and they are already set at this point by a suitable function in
-  ;; window-system-initialization-alist.
-  (or (eq initial-window-system 'pc)
-      (tty-register-default-colors))
-
-  (let ((old-scalable-fonts-allowed scalable-fonts-allowed)
-	(old-face-ignored-fonts face-ignored-fonts))
-
-    ;; Run the site-start library if it exists.  The point of this file is
-    ;; that it is run before .emacs.  There is no point in doing this after
-    ;; .emacs; that is useless.
-    ;; Note that user-init-file is nil at this point.  Code that might
-    ;; be loaded from site-run-file and wants to test if -q was given
-    ;; should check init-file-user instead, since that is already set.
-    ;; See cus-edit.el for an example.
-    (if site-run-file
-	(load site-run-file t t))
-
-    ;; Sites should not disable this.  Only individuals should disable
-    ;; 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
-				      "`_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
-	     ;; Postpone displaying the warning until all hooks
-	     ;; in `after-init-hook' like `desktop-read' will finalize
-	     ;; possible changes in the window configuration.
-	     (add-hook
-	      'after-init-hook
-	      (lambda ()
-		(display-warning
-		 'initialization
-		 (format "An error occurred while loading `%s':\n\n%s%s%s\n\n\
+                               (cdr error) ", "))))
+        'external-debugging-output)
+       (terpri 'external-debugging-output)
+       (setq initial-window-system nil)
+       (kill-emacs)))
+
+    (run-hooks 'before-init-hook)
+
+    ;; Under X, create the X frame and delete the terminal frame.
+    (unless (daemonp)
+      (if (or noninteractive emacs-basic-display)
+          (setq menu-bar-mode nil
+                tool-bar-mode nil
+                no-blinking-cursor t))
+      (frame-initialize))
+
+    (when (fboundp 'x-create-frame)
+      ;; Set up the tool-bar (even in tty frames, since Emacs might open a
+      ;; graphical frame later).
+      (unless noninteractive
+        (tool-bar-setup)))
+
+    ;; Turn off blinking cursor if so specified in X resources.  This is here
+    ;; only because all other settings of no-blinking-cursor are here.
+    (unless (or noninteractive
+                emacs-basic-display
+                (and (memq window-system '(x w32 ns))
+                     (not (member (x-get-resource "cursorBlink" "CursorBlink")
+                                  '("no" "off" "false" "0")))))
+      (setq no-blinking-cursor t))
+
+    ;; Re-evaluate predefined variables whose initial value depends on
+    ;; the runtime context.
+    (mapc 'custom-reevaluate-setting
+          ;; Initialize them in the same order they were loaded, in case there
+          ;; are dependencies between them.
+          (prog1 (nreverse custom-delayed-init-variables)
+            (setq custom-delayed-init-variables nil)))
+
+    (normal-erase-is-backspace-setup-frame)
+
+    ;; Register default TTY colors for the case the terminal hasn't a
+    ;; terminal init file.  We do this regardless of whether the terminal
+    ;; supports colors or not and regardless the current display type,
+    ;; since users can connect to color-capable terminals and also
+    ;; switch color support on or off in mid-session by setting the
+    ;; tty-color-mode frame parameter.
+    ;; Exception: the `pc' ``window system'' has only 16 fixed colors,
+    ;; and they are already set at this point by a suitable function in
+    ;; window-system-initialization-alist.
+    (or (eq initial-window-system 'pc)
+        (tty-register-default-colors))
+
+    (let ((old-scalable-fonts-allowed scalable-fonts-allowed)
+          (old-face-ignored-fonts face-ignored-fonts))
+
+      ;; Run the site-start library if it exists.  The point of this file is
+      ;; that it is run before .emacs.  There is no point in doing this after
+      ;; .emacs; that is useless.
+      ;; Note that user-init-file is nil at this point.  Code that might
+      ;; be loaded from site-run-file and wants to test if -q was given
+      ;; should check init-file-user instead, since that is already set.
+      ;; See cus-edit.el for an example.
+      (if site-run-file
+          (load site-run-file t t))
+
+      ;; Sites should not disable this.  Only individuals should disable
+      ;; 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
+                                       "`_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)
+
+                        ;; Don't load `~/.emacs' if EMACS_USER_DIRECTORY was set
+                        (unless user-emacs-directory--from-env
+                          (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
+                                   (if user-emacs-directory--from-env
+                                       user-emacs-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
+               ;; Postpone displaying the warning until all hooks
+               ;; in `after-init-hook' like `desktop-read' will finalize
+               ;; possible changes in the window configuration.
+               (add-hook
+                'after-init-hook
+                (lambda ()
+                  (display-warning
+                   'initialization
+                   (format "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))
-	      t)
-	     (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)))
-
-    ;; Do this here in case the init file sets mail-host-address.
-    (if (equal user-mail-address "")
-	(setq user-mail-address (or (getenv "EMAIL")
-				    (concat (user-login-name) "@"
-					    (or mail-host-address
-						(system-name))))))
-
-    ;; If parameter have been changed in the init file which influence
-    ;; face realization, clear the face cache so that new faces will
-    ;; be realized.
-    (unless (and (eq scalable-fonts-allowed old-scalable-fonts-allowed)
-		 (eq face-ignored-fonts old-face-ignored-fonts))
-      (clear-face-cache)))
+                           user-init-file
+                           (get (car error) 'error-message)
+                           (if (cdr error) ": " "")
+                           (mapconcat (lambda (s) (prin1-to-string s t))
+                                      (cdr error) ", "))
+                   :warning))
+                t)
+               (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)))
+
+      ;; Do this here in case the init file sets mail-host-address.
+      (if (equal user-mail-address "")
+          (setq user-mail-address (or (getenv "EMAIL")
+                                      (concat (user-login-name) "@"
+                                              (or mail-host-address
+                                                  (system-name))))))
+
+      ;; If parameter have been changed in the init file which influence
+      ;; face realization, clear the face cache so that new faces will
+      ;; be realized.
+      (unless (and (eq scalable-fonts-allowed old-scalable-fonts-allowed)
+                   (eq face-ignored-fonts old-face-ignored-fonts))
+        (clear-face-cache))))
 
   ;; If any package directory exists, initialize the package system.
   (and user-init-file
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-04-02  8:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-23 23:25 [PATCH] Setting user-emacs-directory François Févotte
2015-04-01 15:24 ` bug#15539: " François Févotte
2015-04-01 15:24 ` François Févotte
2015-04-01 15:38   ` bug#15539: " Oleh Krehel
2015-04-01 15:49     ` Drew Adams
2015-04-01 15:49     ` Drew Adams
2015-04-01 16:48     ` bug#15539: " Oleh Krehel
2015-04-01 17:16       ` François Févotte
2015-04-01 21:03         ` Stefan Monnier
2015-04-02  8:12           ` François Févotte

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.