Merge from emacs--devo--0
[bpt/emacs.git] / lisp / startup.el
index 12a5311..3ab65eb 100644 (file)
@@ -1,7 +1,7 @@
 ;;; startup.el --- process Emacs shell arguments
 
 ;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-;;   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+;;   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -10,7 +10,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -49,10 +49,10 @@ The value is nil if the selected frame is on a text-only-terminal.")
 
 (defcustom inhibit-splash-screen nil
   "Non-nil inhibits the startup screen.
-It also inhibits display of the initial message in the *scratch* buffer.
+It also inhibits display of the initial message in the `*scratch*' buffer.
 
-This is for use in your personal init file, once you are familiar
-with the contents of the startup screen."
+This is for use in your personal init file (but NOT site-start.el), once
+you are familiar with the contents of the startup screen."
   :type 'boolean
   :group 'initialization)
 
@@ -151,7 +151,7 @@ This is normally copied from `default-directory' when Emacs starts.")
     ("--foreground-color" 1 x-handle-switch foreground-color)
     ("--background-color" 1 x-handle-switch background-color)
     ("--mouse-color" 1 x-handle-switch mouse-color)
-    ("--no-bitmap-icon" 0 x-handle-switch icon-type nil)
+    ("--no-bitmap-icon" 0 x-handle-no-bitmap-icon)
     ("--iconic" 0 x-handle-iconic)
     ("--xrm" 1 x-handle-xrm-switch)
     ("--cursor-color" 1 x-handle-switch cursor-color)
@@ -202,7 +202,7 @@ Emacs runs this hook after processing the command line arguments and loading
 the user's init file.")
 
 (defcustom initial-major-mode 'lisp-interaction-mode
-  "Major mode command symbol to use for the initial *scratch* buffer."
+  "Major mode command symbol to use for the initial `*scratch*' buffer."
   :type 'function
   :group 'initialization)
 
@@ -254,23 +254,25 @@ this variable usefully is to set it while building and dumping Emacs."
   :group 'mail)
 
 (defcustom user-mail-address (if command-line-processed
-                                (concat (user-login-name) "@"
-                                        (or mail-host-address
-                                            (system-name)))
+                                (or (getenv "EMAIL")
+                                    (concat (user-login-name) "@"
+                                            (or mail-host-address
+                                                (system-name))))
                               ;; Empty string means "not set yet".
                               "")
   "*Full mailing address of this user.
-This is initialized based on `mail-host-address',
-after your init file is read, in case it sets `mail-host-address'."
+This is initialized with environment variable `EMAIL' or, as a
+fallback, using `mail-host-address'. This is done after your
+init file is read, in case it sets `mail-host-address'."
   :type 'string
   :group 'mail)
 
 (defcustom auto-save-list-file-prefix
   (cond ((eq system-type 'ms-dos)
         ;; MS-DOS cannot have initial dot, and allows only 8.3 names
-        "~/_emacs.d/auto-save.list/_s")
+        (concat user-emacs-directory "auto-save.list/_s"))
        (t
-        "~/.emacs.d/auto-save-list/.saves-"))
+        (concat user-emacs-directory "auto-save-list/.saves-")))
   "Prefix for generating `auto-save-list-file-name'.
 This is used after reading your `.emacs' file to initialize
 `auto-save-list-file-name', by appending Emacs's pid and the system name,
@@ -288,7 +290,8 @@ from being initialized."
 
 (defvar init-file-debug nil)
 
-(defvar init-file-had-error nil)
+(defvar init-file-had-error nil
+  "Non-nil if there was an error loading the user's init file.")
 
 (defvar normal-top-level-add-subdirs-inode-list nil)
 
@@ -511,7 +514,7 @@ opening the first frame (e.g. open a connection to an X server).")
 ;; Handle the X-like command-line arguments "-fg", "-bg", "-name", etc.
 (defun tty-handle-args (args)
   (let (rest)
-    (message "%s" args)
+    (message "%S" args)
     (while (and args
                (not (equal (car args) "--")))
       (let* ((argi (pop args))
@@ -648,23 +651,28 @@ opening the first frame (e.g. open a connection to an X server).")
 
   (set-locale-environment nil)
 
-  ;; Convert preloaded file names to absolute.
-  (let ((lisp-dir
-        (file-name-directory
-         (locate-file "simple" load-path
-                      (get-load-suffixes)))))
-
-    (setq load-history
-         (mapcar (lambda (elt)
-                   (if (and (stringp (car elt))
-                            (not (file-name-absolute-p (car elt))))
-                       (cons (concat lisp-dir
-                                     (car elt)
-                                     (if (string-match "[.]el$" (car elt))
-                                         "" ".elc"))
-                             (cdr elt))
-                     elt))
-                 load-history)))
+  ;; 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.
+    (if (null simple-file-name)
+       (progn
+         (princ "Warning: Could not find simple.el nor simple.elc"
+                'external-debugging-output)
+         (terpri 'external-debugging-output))
+      (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 (cdr command-line-args)))
@@ -783,6 +791,7 @@ opening the first frame (e.g. open a connection to an X server).")
   (custom-reevaluate-setting 'mouse-wheel-up-event)
   (custom-reevaluate-setting 'file-name-shadow-mode)
   (custom-reevaluate-setting 'send-mail-function)
+  (custom-reevaluate-setting 'focus-follows-mouse)
 
   (normal-erase-is-backspace-setup-frame)
 
@@ -953,7 +962,11 @@ opening the first frame (e.g. open a connection to an X server).")
              (deactivate-mark)))
 
        ;; If the user has a file of abbrevs, read it.
-       (if (file-exists-p abbrev-file-name)
+        ;; FIXME: after the 22.0 release this should be changed so
+       ;; that it does not read the abbrev file when -batch is used
+       ;; on the command line.
+       (when (and (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
@@ -985,9 +998,10 @@ opening the first frame (e.g. open a connection to an X server).")
 
     ;; Do this here in case the init file sets mail-host-address.
     (if (equal user-mail-address "")
-       (setq user-mail-address (concat (user-login-name) "@"
-                                       (or mail-host-address
-                                           (system-name)))))
+       (setq user-mail-address (or (getenv "EMAIL")
+                                   (concat (user-login-name) "@"
+                                           (or mail-host-address
+                                               (system-name))))))
 
     ;; Originally face attributes were specified via
     ;; `font-lock-face-attributes'.  Users then changed the default
@@ -1048,7 +1062,10 @@ opening the first frame (e.g. open a connection to an X server).")
   (if (get-buffer "*scratch*")
       (with-current-buffer "*scratch*"
        (if (eq major-mode 'fundamental-mode)
-           (funcall initial-major-mode))))
+           (funcall initial-major-mode))
+       ;; Don't lose text that users type in *scratch*.
+       (setq buffer-offer-save t)
+       (auto-save-mode 1)))
 
   ;; Load library for our terminal type.
   ;; User init file can set term-file-prefix to nil to prevent this.
@@ -1095,10 +1112,7 @@ regardless of the value of this variable."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (defvar fancy-splash-text
-  '((:face variable-pitch
-          "You can do basic editing with the menu bar and scroll bar \
-using the mouse.\n\n"
-          :face (variable-pitch :weight bold)
+  '((:face (variable-pitch :weight bold)
           "Important Help menu items:\n"
           :face variable-pitch
            (lambda ()
@@ -1115,35 +1129,45 @@ using the mouse.\n\n"
                ;; If there is a specific tutorial for the current language
                ;; environment and it is not English, append its title.
                (concat
-                "Emacs Tutorial\tLearn how to use Emacs efficiently"
+                "Emacs Tutorial\t\tLearn how to use Emacs efficiently"
                 (if (string= en tut)
                     ""
                   (concat " (" title ")"))
                 "\n")))
            :face variable-pitch "\
-Emacs FAQ\tFrequently asked questions and answers
-Read the Emacs Manual\tView the Emacs manual using Info
-\(Non)Warranty\tGNU Emacs comes with "
+Emacs FAQ\t\tFrequently asked questions and answers
+View Emacs Manual\t\tView the Emacs manual using Info
+Absence of Warranty\tGNU Emacs comes with "
           :face (variable-pitch :slant oblique)
           "ABSOLUTELY NO WARRANTY\n"
           :face variable-pitch
           "\
-Copying Conditions\tConditions for redistributing and changing Emacs
+Copying Conditions\t\tConditions for redistributing and changing Emacs
 Getting New Versions\tHow to obtain the latest version of Emacs
 More Manuals / Ordering Manuals       Buying printed manuals from the FSF\n")
   (:face variable-pitch
-          "You can do basic editing with the menu bar and scroll bar \
-using the mouse.\n\n"
-          :face (variable-pitch :weight bold)
-          "Useful File menu items:\n"
-          :face variable-pitch "\
-Exit Emacs\t(Or type Control-x followed by Control-c)
-Recover Crashed Session\tRecover files you were editing before a crash
-
-
+        "\nTo quit a partially entered command, type "
+        :face default
+        "Control-g"
+        :face variable-pitch
+        ".
 
+Emacs Guided Tour\t\tSee http://www.gnu.org/software/emacs/tour/
 
 "
+        :face (variable-pitch :weight bold)
+        "Useful File menu items:\n"
+        :face variable-pitch
+        "Exit Emacs\t\t(Or type "
+        :face default
+        "Control-x"
+        :face variable-pitch
+        " followed by "
+        :face default
+        "Control-c"
+        :face variable-pitch
+        ")
+Recover Crashed Session\tRecover files you were editing before a crash\n"
           ))
   "A list of texts to show in the middle part of splash screens.
 Each element in the list should be a list of strings or pairs
@@ -1182,6 +1206,7 @@ Values less than twice `fancy-splash-delay' are ignored."
 (defvar fancy-splash-help-echo nil)
 (defvar fancy-splash-stop-time nil)
 (defvar fancy-splash-outer-buffer nil)
+(defvar fancy-splash-last-input-event nil)
 
 (defun fancy-splash-insert (&rest args)
   "Insert text into the current buffer, with faces.
@@ -1247,11 +1272,22 @@ where FACE is a valid face specification, as it can be used with
        "GNU Emacs is one component of the GNU/Linux operating system."
      "GNU Emacs is one component of the GNU operating system."))
   (insert "\n")
-  (unless (equal (buffer-name fancy-splash-outer-buffer) "*scratch*")
-    (fancy-splash-insert :face 'variable-pitch
-                        (substitute-command-keys
-                         "Type \\[recenter] to begin editing your file.\n"))))
-
+  (fancy-splash-insert
+   :face 'variable-pitch
+   "You can do basic editing with the menu bar and scroll bar \
+using the mouse.\n\n")
+  (when fancy-splash-outer-buffer
+    (fancy-splash-insert
+     :face 'variable-pitch
+     "Type "
+     :face 'default
+     "Control-l"
+     :face 'variable-pitch
+     " to begin editing"
+     (if (equal (buffer-name fancy-splash-outer-buffer)
+               "*scratch*")
+        ".\n"
+       " your file.\n"))))
 
 (defun fancy-splash-tail ()
   "Insert the tail part of the splash screen into the current buffer."
@@ -1262,7 +1298,7 @@ where FACE is a valid face specification, as it can be used with
                         (emacs-version)
                         "\n"
                         :face '(variable-pitch :height 0.5)
-                        "Copyright (C) 2006 Free Software Foundation, Inc.")
+                        emacs-copyright)
     (and auto-save-list-file-prefix
         ;; Don't signal an error if the
         ;; directory for auto-save-list files
@@ -1278,7 +1314,11 @@ where FACE is a valid face specification, as it can be used with
          t)
         (fancy-splash-insert :face '(variable-pitch :foreground "red")
                              "\n\nIf an Emacs session crashed recently, "
-                             "type M-x recover-session RET\nto recover"
+                             "type "
+                             :face '(fixed-pitch :foreground "red")
+                             "Meta-x recover-session RET"
+                             :face '(variable-pitch :foreground "red")
+                             "\nto recover"
                              " the files you were editing."))))
 
 (defun fancy-splash-screens-1 (buffer)
@@ -1331,55 +1371,112 @@ mouse."
   (if (frame-live-p frame)
       (run-at-time 0 nil 'fancy-splash-exit)))
 
-(defun fancy-splash-screens ()
+(defun fancy-splash-screens (&optional hide-on-input)
   "Display fancy splash screens when Emacs starts."
-  (setq fancy-splash-help-echo (startup-echo-area-message))
-  (let ((old-hourglass display-hourglass)
-       (fancy-splash-outer-buffer (current-buffer))
-       splash-buffer
-       (old-minor-mode-map-alist minor-mode-map-alist)
-       (old-emulation-mode-map-alists emulation-mode-map-alists)
-       (frame (fancy-splash-frame))
-       timer)
-    (save-selected-window
-      (select-frame frame)
-      (switch-to-buffer "GNU Emacs")
-      (setq tab-width 20)
-      (setq splash-buffer (current-buffer))
-      (catch 'stop-splashing
-       (unwind-protect
-           (let* ((map (make-sparse-keymap))
-                  (overriding-local-map map)
-                  ;; Catch if our frame is deleted; the delete-frame
-                  ;; event is unreliable and is handled by
-                  ;; `special-event-map' anyway.
-                  (delete-frame-functions (cons 'fancy-splash-delete-frame
-                                                delete-frame-functions)))
-             (define-key map [t] 'fancy-splash-default-action)
-             (define-key map [mouse-movement] 'ignore)
-             (define-key map [mode-line t] 'ignore)
-             (define-key map [select-window] 'ignore)
-             (setq cursor-type nil
-                   display-hourglass nil
-                   minor-mode-map-alist nil
-                   emulation-mode-map-alists nil
-                   buffer-undo-list t
-                   mode-line-format (propertize "---- %b %-"
-                                                'face 'mode-line-buffer-id)
-                   fancy-splash-stop-time (+ (float-time)
-                                             fancy-splash-max-time)
-                   timer (run-with-timer 0 fancy-splash-delay
-                                         #'fancy-splash-screens-1
-                                         splash-buffer))
-             (recursive-edit))
-         (cancel-timer timer)
-         (setq display-hourglass old-hourglass
-               minor-mode-map-alist old-minor-mode-map-alist
-               emulation-mode-map-alists old-emulation-mode-map-alists)
-         (kill-buffer splash-buffer)
-         (when (frame-live-p frame)
-           (select-frame frame)
-           (switch-to-buffer fancy-splash-outer-buffer)))))))
+  (if hide-on-input
+      (let ((old-hourglass display-hourglass)
+           (fancy-splash-outer-buffer (current-buffer))
+           splash-buffer
+           (old-minor-mode-map-alist minor-mode-map-alist)
+           (old-emulation-mode-map-alists emulation-mode-map-alists)
+           (old-special-event-map special-event-map)
+           (frame (fancy-splash-frame))
+           timer)
+       (save-selected-window
+         (select-frame frame)
+         (switch-to-buffer " GNU Emacs")
+         (make-local-variable 'cursor-type)
+         (setq splash-buffer (current-buffer))
+         (catch 'stop-splashing
+           (unwind-protect
+               (let* ((map (make-sparse-keymap))
+                      (cursor-type nil)
+                      (overriding-local-map map)
+                      ;; Catch if our frame is deleted; the delete-frame
+                      ;; event is unreliable and is handled by
+                      ;; `special-event-map' anyway.
+                      (delete-frame-functions (cons 'fancy-splash-delete-frame
+                                                    delete-frame-functions)))
+                 (define-key map [t] 'fancy-splash-default-action)
+                 (define-key map [mouse-movement] 'ignore)
+                 (define-key map [mode-line t] 'ignore)
+                 (define-key map [select-window] 'ignore)
+                 ;; Temporarily bind special events to
+                 ;; fancy-splash-special-event-action so as to stop
+                 ;; displaying splash screens with such events.
+                 ;; Otherwise, drag-n-drop into splash screens may
+                 ;; leave us in recursive editing with invisible
+                 ;; cursors for a while.
+                 (setq special-event-map (make-sparse-keymap))
+                 (map-keymap
+                  (lambda (key def)
+                    (define-key special-event-map (vector key)
+                      (if (eq def 'ignore)
+                          'ignore
+                        'fancy-splash-special-event-action)))
+                  old-special-event-map)
+                 (setq display-hourglass nil
+                       minor-mode-map-alist nil
+                       emulation-mode-map-alists nil
+                       buffer-undo-list t
+                       mode-line-format (propertize "---- %b %-"
+                                                    'face 'mode-line-buffer-id)
+                       fancy-splash-stop-time (+ (float-time)
+                                                 fancy-splash-max-time)
+                       timer (run-with-timer 0 fancy-splash-delay
+                                             #'fancy-splash-screens-1
+                                             splash-buffer))
+                 (message "%s" (startup-echo-area-message))
+                 (recursive-edit))
+             (cancel-timer timer)
+             (setq display-hourglass old-hourglass
+                   minor-mode-map-alist old-minor-mode-map-alist
+                   emulation-mode-map-alists old-emulation-mode-map-alists
+                   special-event-map old-special-event-map)
+             (kill-buffer splash-buffer)
+             (when (frame-live-p frame)
+               (select-frame frame)
+               (switch-to-buffer fancy-splash-outer-buffer))
+             (when fancy-splash-last-input-event
+               (setq last-input-event fancy-splash-last-input-event
+                     fancy-splash-last-input-event nil)
+               (command-execute (lookup-key special-event-map
+                                            (vector last-input-event))
+                                nil (vector last-input-event) t))))))
+    ;; If hide-on-input is nil, don't hide the buffer on input.
+    (if (or (window-minibuffer-p)
+           (window-dedicated-p (selected-window)))
+       (pop-to-buffer (current-buffer))
+      (switch-to-buffer "*About GNU Emacs*"))
+    (setq buffer-read-only nil)
+    (erase-buffer)
+    (if pure-space-overflow
+       (insert "\
+Warning Warning!!!  Pure space overflow    !!!Warning Warning
+\(See the node Pure Storage in the Lisp manual for details.)\n"))
+    (let (fancy-splash-outer-buffer)
+      (fancy-splash-head)
+      (dolist (text fancy-splash-text)
+       (apply #'fancy-splash-insert text)
+       (insert "\n"))
+      (skip-chars-backward "\n")
+      (delete-region (point) (point-max))
+      (insert "\n")
+      (fancy-splash-tail)
+      (set-buffer-modified-p nil)
+      (setq buffer-read-only t)
+      (if (and view-read-only (not view-mode))
+         (view-mode-enter nil 'kill-buffer))
+      (goto-char (point-min)))))
+
+(defun fancy-splash-special-event-action ()
+  "Save the last event and stop displaying the splash screen buffer.
+This is an internal function used to turn off the splash screen after
+the user caused an input event that is bound in `special-event-map'"
+  (interactive)
+  (setq fancy-splash-last-input-event last-input-event)
+  (throw 'exit nil))
+
 
 (defun fancy-splash-frame ()
   "Return the frame to use for the fancy splash screen.
@@ -1405,19 +1502,25 @@ we put it on this frame."
                                      (if (and (display-color-p)
                                               (image-type-available-p 'xpm))
                                          "splash.xpm" "splash.pbm"))))
-              (image-height (and img (cdr (image-size img))))
-              (window-height (1- (window-height (frame-selected-window frame)))))
-         (> window-height (+ image-height 19)))))))
+              (image-height (and img (cdr (image-size img nil frame))))
+              ;; We test frame-height so that, if the frame is split
+              ;; by displaying a warning, that doesn't cause the normal
+              ;; splash screen to be used.
+              (frame-height (1- (frame-height frame))))
+         (> frame-height (+ image-height 19)))))))
 
 
-(defun normal-splash-screen ()
+(defun normal-splash-screen (&optional hide-on-input)
   "Display splash screen when Emacs starts."
   (let ((prev-buffer (current-buffer)))
     (unwind-protect
        (with-current-buffer (get-buffer-create "GNU Emacs")
+         (setq buffer-read-only nil)
+         (erase-buffer)
          (set (make-local-variable 'tab-width) 8)
-          (set (make-local-variable 'mode-line-format)
-               (propertize "---- %b %-" 'face 'mode-line-buffer-id))
+         (if hide-on-input
+             (set (make-local-variable 'mode-line-format)
+                  (propertize "---- %b %-" 'face 'mode-line-buffer-id)))
 
           (if pure-space-overflow
               (insert "\
@@ -1433,9 +1536,13 @@ Warning Warning!!!  Pure space overflow    !!!Warning Warning
                ", one component of the GNU/Linux operating system.\n"
              ", a part of the GNU operating system.\n"))
 
-          (unless (equal (buffer-name prev-buffer) "*scratch*")
-            (insert (substitute-command-keys
-                     "\nType \\[recenter] to begin editing your file.\n")))
+         (if hide-on-input
+             (insert (substitute-command-keys
+                      (concat
+                       "\nType \\[recenter] to begin editing"
+                       (if (equal (buffer-name prev-buffer) "*scratch*")
+                           ".\n"
+                         " your file.\n")))))
 
           (if (display-mouse-p)
               ;; The user can use the mouse to activate menus
@@ -1443,6 +1550,7 @@ Warning Warning!!!  Pure space overflow    !!!Warning Warning
               (progn
                 (insert "\
 You can do basic editing with the menu bar and scroll bar using the mouse.
+To quit a partially entered command, type Control-g.
 
 Useful File menu items:
 Exit Emacs             (or type Control-x followed by Control-c)
@@ -1458,8 +1566,7 @@ Getting New Versions      How to obtain the latest version of Emacs
 More Manuals / Ordering Manuals    How to order printed manuals from the FSF
 ")
                 (insert "\n\n" (emacs-version)
-                        "
-Copyright (C) 2006 Free Software Foundation, Inc."))
+                        "\n" emacs-copyright))
 
            ;; No mouse menus, so give help using kbd commands.
 
@@ -1505,9 +1612,8 @@ Activate menubar     \\[tmm-menubar]")))
 \(`C-' means use the CTRL key.  `M-' means use the Meta (or Alt) key.
 If you have no Meta key, you may instead type ESC followed by the character.)")
 
-           (insert "\n\n" (emacs-version)
-                   "
-Copyright (C) 2006 Free Software Foundation, Inc.")
+            (insert "\n\n" (emacs-version)
+                    "\n" emacs-copyright)
 
            (if (and (eq (key-binding "\C-h\C-c") 'describe-copying)
                     (eq (key-binding "\C-h\C-d") 'describe-distribution)
@@ -1543,23 +1649,32 @@ Type \\[describe-distribution] for information on getting the latest version."))
                                       auto-save-list-file-prefix)))
                t)
               (insert "\n\nIf an Emacs session crashed recently, "
-                      "type M-x recover-session RET\nto recover"
+                      "type Meta-x recover-session RET\nto recover"
                       " the files you were editing."))
 
-         ;; Display the input that we set up in the buffer.
-         (set-buffer-modified-p nil)
-         (goto-char (point-min))
-          (if (or (window-minibuffer-p)
-                  (window-dedicated-p (selected-window)))
-              ;; There's no point is using pop-to-buffer since creating
-              ;; a new frame will generate enough events that the
-              ;; subsequent `sit-for' will immediately return anyway.
-              nil ;; (pop-to-buffer (current-buffer))
-            (save-window-excursion
-              (switch-to-buffer (current-buffer))
-              (sit-for 120))))
-    ;; Unwind ... ensure splash buffer is killed
-    (kill-buffer "GNU Emacs"))))
+          ;; Display the input that we set up in the buffer.
+          (set-buffer-modified-p nil)
+         (setq buffer-read-only t)
+         (if (and view-read-only (not view-mode))
+             (view-mode-enter nil 'kill-buffer))
+          (goto-char (point-min))
+         (if hide-on-input
+             (if (or (window-minibuffer-p)
+                     (window-dedicated-p (selected-window)))
+                 ;; If hide-on-input is nil, creating a new frame will
+                 ;; generate enough events that the subsequent `sit-for'
+                 ;; will immediately return anyway.
+                 nil ;; (pop-to-buffer (current-buffer))
+               (save-window-excursion
+                 (switch-to-buffer (current-buffer))
+                 (sit-for 120))
+               (condition-case nil
+                   (switch-to-buffer (current-buffer))))))
+      ;; Unwind ... ensure splash buffer is killed
+      (if hide-on-input
+         (kill-buffer "GNU Emacs")
+       (switch-to-buffer "GNU Emacs")
+       (rename-buffer "*About GNU Emacs*" t)))))
 
 
 (defun startup-echo-area-message ()
@@ -1613,16 +1728,17 @@ Type \\[describe-distribution] for information on getting the latest version."))
          (message "%s" (startup-echo-area-message))))))
 
 
-(defun display-splash-screen ()
+(defun display-splash-screen (&optional hide-on-input)
   "Display splash screen according to display.
 Fancy splash screens are used on graphic displays,
-normal otherwise."
-  (interactive)
+normal otherwise.
+With a prefix argument, any user input hides the splash screen."
+  (interactive "P")
   ;; Prevent recursive calls from server-process-filter.
   (if (not (get-buffer "GNU Emacs"))
       (if (use-fancy-splash-screens-p)
-         (fancy-splash-screens)
-       (normal-splash-screen))))
+         (fancy-splash-screens hide-on-input)
+       (normal-splash-screen hide-on-input))))
 
 (defun command-line-1 (command-line-args-left)
   (display-startup-echo-area-message)
@@ -1829,7 +1945,12 @@ normal otherwise."
                          (setq line 0)
                          (unless (< column 1)
                            (move-to-column (1- column)))
-                         (setq column 0))))))))
+                         (setq column 0))))))
+         ;; In unusual circumstances, the execution of Lisp code due
+         ;; to command-line options can cause the last visible frame
+         ;; to be deleted.  In this case, kill emacs to avoid an
+         ;; abort later.
+         (unless (frame-live-p (selected-frame)) (kill-emacs nil))))
 
       ;; If 3 or more files visited, and not all visible,
       ;; show user what they all are.  But leave the last one current.
@@ -1875,18 +1996,18 @@ normal otherwise."
     (with-no-warnings
      (setq menubar-bindings-done t))
 
-    ;; If *scratch* is selected and it is empty, insert an
-    ;; initial message saying not to create a file there.
-    (when (and initial-scratch-message
-              (equal (buffer-name) "*scratch*")
-              (= 0 (buffer-size)))
-      (insert initial-scratch-message)
-      (set-buffer-modified-p nil))
+    ;; If *scratch* exists and is empty, insert initial-scratch-message.
+    (and initial-scratch-message
+         (get-buffer "*scratch*")
+         (with-current-buffer "*scratch*"
+           (when (zerop (buffer-size))
+             (insert initial-scratch-message)
+             (set-buffer-modified-p nil))))
 
     ;; If user typed input during all that work,
     ;; abort the startup screen.  Otherwise, display it now.
     (unless (input-pending-p)
-      (display-splash-screen))))
+      (display-splash-screen t))))
 
 
 (defun command-line-normalize-file-name (file)