(send-mail-function): Customize.
[bpt/emacs.git] / lisp / startup.el
index ca7c2d4..2efe5d7 100644 (file)
@@ -1,6 +1,7 @@
 ;;; startup.el --- process Emacs shell arguments
 
-;; Copyright (C) 1985, 86, 92, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 86, 92, 94, 95, 96, 97, 98, 99, 2000
+;;   Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -359,8 +360,9 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
          (setq normal-top-level-add-subdirs-inode-list
                (cons attrs normal-top-level-add-subdirs-inode-list))
          (while contents
-           (unless (member (car contents) '("." ".." "RCS" "CVS"))
-             (when (and (string-match "\\`[a-zA-Z0-9]" (car contents))
+           ;; The lower-case variants of RCS and CVS are for DOS/Windows.
+           (unless (member (car contents) '("." ".." "RCS" "CVS" "rcs" "cvs"))
+             (when (and (string-match "\\`[[:alnum:]]" (car contents))
                         ;; Avoid doing a `stat' when it isn't necessary
                         ;; because that can cause trouble when an NFS server
                         ;; is down.
@@ -473,13 +475,35 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
        ;; ...-frame-alist.
        (if (fboundp 'frame-notice-user-settings)
            (frame-notice-user-settings))
+       (if (fboundp 'frame-set-background-mode)
+           ;; Set the faces for the initial background mode even if
+           ;; frame-notice-user-settings didn't (such as on a tty).
+           ;; frame-set-background-mode is idempotent, so it won't
+           ;; cause any harm if it's already been done.
+           (let ((frame-background-mode frame-background-mode)
+                 (frame (selected-frame))
+                 term)
+             (when (and (null window-system)
+                        ;; Don't override a possibly customized value.
+                        (null frame-background-mode)
+                        ;; Don't override user specifications.
+                        (null (frame-parameter frame 'reverse))
+                        (let ((bg (frame-parameter frame 'background-color)))
+                          (or (null bg)
+                              (member bg '(unspecified "unspecified-bg")))))
+               (setq term (getenv "TERM"))
+               (if (string-match "^\\(xterm\\|rxvt\\|dtterm\\|eterm\\)"
+                                 term)
+                   (setq frame-background-mode 'light)))
+             (frame-set-background-mode (selected-frame))))
+
        ;; Now we know the user's default font, so add it to the menu.
        (if (fboundp 'font-menu-add-default)
            (font-menu-add-default))
        (and window-setup-hook
             (run-hooks 'window-setup-hook))
        (or menubar-bindings-done
-           (if (memq window-system '(x w32))
+           (if (display-popup-menus-p)
                (precompute-menubar-bindings)))))))
 
 ;; Precompute the keyboard equivalents in the menu bar items.
@@ -497,6 +521,79 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
       (setq submap (cdr submap))))
     (setq define-key-rebound-commands t))
 
+;; Command-line options supported by tty's:
+(defconst tty-long-option-alist
+  '(("--name" .                "-name")
+    ("--title" .       "-T")
+    ("--reverse-video" . "-reverse")
+    ("--foreground-color" . "-fg")
+    ("--background-color" . "-bg")))
+
+;; Handle the X-like command line parameters "-fg", "-bg", "-name", etc.
+(defun tty-handle-args (args)
+  (let ((rest nil))
+    (message "%s" args)
+    (while (and args
+               (not (equal (car args) "--")))
+      (let* ((this (car args))
+            (orig-this this)
+            completion argval)
+       (setq args (cdr args))
+       ;; Check for long options with attached arguments
+       ;; and separate out the attached option argument into argval.
+       (if (string-match "^--[^=]*=" this)
+           (setq argval (substring this (match-end 0))
+                 this (substring this 0 (1- (match-end 0)))))
+       (when (string-match "^--" this)
+         (setq completion (try-completion this tty-long-option-alist))
+         (if (eq completion t)
+             ;; Exact match for long option.
+             (setq this (cdr (assoc this tty-long-option-alist)))
+           (if (stringp completion)
+               (let ((elt (assoc completion tty-long-option-alist)))
+                 ;; Check for abbreviated long option.
+                 (or elt
+                     (error "Option `%s' is ambiguous" this))
+                 (setq this (cdr elt)))
+             ;; Check for a short option.
+             (setq argval nil this orig-this))))
+       (cond ((or (string= this "-fg") (string= this "-foreground"))
+              (or argval (setq argval (car args) args (cdr args)))
+              (setq default-frame-alist
+                    (cons (cons 'foreground-color argval)
+                          default-frame-alist)))
+             ((or (string= this "-bg") (string= this "-background"))
+              (or argval (setq argval (car args) args (cdr args)))
+              (setq default-frame-alist
+                    (cons (cons 'background-color argval)
+                          default-frame-alist)))
+             ((or (string= this "-T") (string= this "-name"))
+              (or argval (setq argval (car args) args (cdr args)))
+              (setq default-frame-alist
+                    (cons
+                     (cons 'title
+                           (if (stringp argval)
+                               argval
+                             (let ((case-fold-search t)
+                                   i)
+                               (setq argval (invocation-name))
+
+                               ;; Change any . or * characters in name to
+                               ;; hyphens, so as to emulate behavior on X.
+                               (while
+                                   (setq i (string-match "[.*]" argval))
+                                 (aset argval i ?-))
+                               argval)))
+                     default-frame-alist)))
+             ((or (string= this "-r")
+                  (string= this "-rv")
+                  (string= this "-reverse"))
+              (setq default-frame-alist
+                    (cons '(reverse . t)
+                          default-frame-alist)))
+             (t (setq rest (cons this rest))))))
+      (nreverse rest)))
+
 (defun command-line ()
   (setq command-line-default-directory default-directory)
 
@@ -526,8 +623,6 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
               (string= vc "simple"))
           (setq version-control 'never))))
 
-  (set-locale-environment nil)
-
   ;;! 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.
@@ -573,6 +668,13 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
      (setq window-system nil)
      (kill-emacs)))
 
+  ;; Windowed displays do this inside their *-win.el.
+  (when (and (not (display-graphic-p))
+            (not noninteractive))
+    (setq command-line-args (tty-handle-args command-line-args)))
+
+  (set-locale-environment nil)
+
   (let ((done nil)
        (args (cdr command-line-args)))
 
@@ -654,7 +756,7 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
 
   ;; If frame was created with a tool bar, switch tool-bar-mode on.
   (when (and (not noninteractive)
-            (memq window-system '(x w32))
+            (display-graphic-p)
             (> (frame-parameter nil 'tool-bar-lines) 0))
     (tool-bar-mode t))
 
@@ -665,6 +767,39 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
     (setq-default blink-cursor t)
     (blink-cursor-mode 1))
 
+  (when (and (not noninteractive)
+            ;; DOS/Windows systems have a PC-type keyboard which has both
+            ;; <delete> and <backspace> keys.
+            (or (memq system-type '(ms-dos windows-nt))
+                (memq window-system '(x))))
+    (setq-default delete-key-deletes-forward
+                 (or (not (fboundp 'x-backspace-delete-keys-p))
+                     (x-backspace-delete-keys-p)))
+    (delete-key-deletes-forward-mode 1))
+
+  (when (and (not noninteractive)
+            (display-graphic-p)
+            (fboundp 'x-show-tip))
+    (setq-default tooltip-mode t)
+    (tooltip-mode 1))
+
+  ;; Register default TTY colors for the case the terminal hasn't a
+  ;; terminal init file.
+  (or (memq window-system '(x w32))
+      (not (tty-display-color-p))
+      (let* ((colors (cond ((eq window-system 'pc)
+                            msdos-color-values)
+                           ((eq system-type 'windows-nt)
+                            w32-tty-standard-colors)
+                           (t tty-standard-colors)))
+            (color (car colors)))
+       (while colors
+         (tty-color-define (car color) (cadr color) (cddr color))
+         (setq colors (cdr colors) color (car colors)))
+       ;; Modifying color mappings means realized faces don't
+       ;; use the right colors, so clear them.
+       (clear-face-cache)))
+
   (run-hooks 'before-init-hook)
 
   ;; Run the site-start library if it exists.  The point of this file is
@@ -705,24 +840,31 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
                    ;; into user-init-file.
                    (setq user-init-file t)
                    (load user-init-file-1 t t)
+
                    ;; If we did not find the user's init file,
                    ;; set user-init-file conclusively to nil;
                    ;; don't let it be set from default.el.
                    (if (eq user-init-file t)
                        (setq user-init-file nil))
+
                    ;; 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")
-                              (file-exists-p user-init-file-1))
-                     (when (file-newer-than-file-p
-                            user-init-file-1 user-init-file)
-                       (message "Warning: %s is newer than %s"
-                                user-init-file-1 user-init-file)
-                       (sit-for 1))
-                     (setq user-init-file user-init-file-1))
+                                     "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))))
+
                    (or inhibit-default-init
                        (let ((inhibit-startup-message nil))
                          ;; Users are supposed to be told their rights.
@@ -796,23 +938,6 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
        (set-buffer "*scratch*")
        (if (eq major-mode 'fundamental-mode)
            (funcall initial-major-mode))))
-
-  ;; Register default TTY colors for the case the terminal hasn't a
-  ;; terminal init file.
-  (or (memq window-system '(x w32))
-      (not (tty-display-color-p))
-      (let* ((colors (cond ((eq window-system 'pc)
-                            msdos-color-values)
-                           ((eq system-type 'windows-nt)
-                            w32-tty-standard-colors)
-                           (t tty-standard-colors)))
-            (color (car colors)))
-       (while colors
-         (tty-color-define (car color) (cadr color) (cddr color))
-         (setq colors (cdr colors) color (car colors)))
-       ;; Modifying color mappings means realized faces don't
-       ;; use the right colors, so clear them.
-       (clear-face-cache)))
   
   ;; Load library for our terminal type.
   ;; User init file can set term-file-prefix to nil to prevent this.
@@ -852,28 +977,28 @@ If this is nil, no message will be displayed."
           "You can do basic editing with the menu bar and scroll bar \
 using the mouse.\n\n"
           :face (variable-pitch :weight bold)
-          "Useful Files menu items:\n"
+          "Useful File menu items:\n"
           :face variable-pitch "\
-Exit Emacs             (or type Control-x followed by Control-c)
-Recover Session                recover files you were editing before a crash
+Exit Emacs\t(or type Control-x followed by Control-c)
+Recover Session\trecover files you were editing before a crash
 
 
 "
           )
-  (:face 'variable-pitch
+  (: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)
           "Important Help menu items:\n"
           :face variable-pitch "\
-Emacs Tutorial         Learn-by-doing tutorial for using Emacs efficiently.
-Emacs FAQ              Frequently asked questions and answers
-\(Non)Warranty         GNU Emacs comes with "
+Emacs Tutorial\tLearn-by-doing tutorial for using Emacs efficiently.
+Emacs FAQ\tFrequently asked questions and answers
+\(Non)Warranty\tGNU Emacs comes with "
           :face (variable-pitch :slant oblique)
           "ABSOLUTELY NO WARRANTY\n"
           :face variable-pitch
-          "Copying Conditions  Conditions for redistributing and \
-changing Emacs\n"))
+          "\
+Copying Conditions\tConditions for redistributing and changing Emacs\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
 `:face FACE', like `fancy-splash-insert' accepts them.")
@@ -885,12 +1010,19 @@ Each element in the list should be a list of strings or pairs
   :group 'initialization)
 
 
-(defcustom fancy-splash-delay 5
+(defcustom fancy-splash-delay 10
   "*Delay in seconds between splash screens."
   :group 'fancy-splash-screen
   :type 'integer)
 
 
+(defcustom fancy-splash-max-time 60
+  "*Show splash screens for at most this number of seconds.
+Values less than 60 seconds are ignored."
+  :group 'fancy-splash-screen
+  :type 'integer)
+
+
 (defcustom fancy-splash-image nil
   "*The image to show in the splash screens, or nil for defaults."
   :group 'fancy-splash-screen
@@ -902,6 +1034,7 @@ Each element in the list should be a list of strings or pairs
 
 (defvar fancy-current-text nil)
 (defvar fancy-splash-help-echo nil)
+(defvar fancy-splash-stop-time nil)
 
 
 (defun fancy-splash-insert (&rest args)
@@ -941,11 +1074,11 @@ where FACE is a valid face specification, as it can be used with
 
        ;; Insert the image with a help-echo and a keymap.
        (let ((map (make-sparse-keymap))
-             (help-echo "mouse-2: browse http://www.gnu.org"))
+             (help-echo "mouse-2: browse http://www.gnu.org/"))
          (define-key map [mouse-2]
            (lambda ()
              (interactive)
-             (browse-url "http://www.gnu.org")
+             (browse-url "http://www.gnu.org/")
              (throw 'exit nil)))
          (define-key map [down-mouse-2] 'ignore)
          (define-key map [up-mouse-2] 'ignore)
@@ -976,6 +1109,8 @@ where FACE is a valid face specification, as it can be used with
 
 (defun fancy-splash-screens-1 (buffer)
   "Timer function displaying a splash screen."
+  (when (> (float-time) fancy-splash-stop-time)
+    (throw 'stop-splashing nil))
   (unless fancy-current-text
     (setq fancy-current-text fancy-splash-text))
   (let ((text (car fancy-current-text)))
@@ -987,6 +1122,7 @@ where FACE is a valid face specification, as it can be used with
     (unless (current-message)
       (message fancy-splash-help-echo))
     (set-buffer-modified-p nil)
+    (goto-char (point-min))
     (force-mode-line-update)
     (setq fancy-current-text (cdr fancy-current-text))))
 
@@ -998,51 +1134,49 @@ where FACE is a valid face specification, as it can be used with
   (throw 'exit nil))
 
 
-(defvar fancy-splash-pending-command nil
-  "If non-nil, a command to be executed after the splash screen display.")
-
-(defun fancy-splash-pre-command ()
-  (unless (memq this-command
-               '(ignore fancy-splash-default-action browse-url))
-    (setq fancy-splash-pending-command this-command)
-    (throw 'exit nil)))
-
-
 (defun fancy-splash-screens ()
   "Display fancy splash screens when Emacs starts."
   (setq fancy-splash-help-echo (startup-echo-area-message))
   (switch-to-buffer "GNU Emacs")
-  (let ((old-global-map (current-global-map))
-       (old-busy-cursor display-busy-cursor)
+  (setq tab-width 20)
+  (let ((old-busy-cursor display-busy-cursor)
        (splash-buffer (current-buffer))
-       ;; Don't update menu bindings in the following.  Since
-       ;; C-x etc. are not bound in the map installed below,
-       ;; there wouldn't be any bindings shown otherwise.
-       (update-menu-bindings nil)
        timer)
-    (unwind-protect
-       (let ((map (nconc (make-sparse-keymap)
-                         '((t . fancy-splash-default-action))))
-             (show-help-function nil))
-         (use-global-map map)
-         (use-local-map nil)
-         (define-key map [mouse-movement] 'ignore)
-         (define-key map [menu-bar] (lookup-key old-global-map [menu-bar]))
-         (define-key map [tool-bar] (lookup-key old-global-map [tool-bar]))
-         (setq cursor-type nil
-               display-busy-cursor nil
-               mode-line-format
-               (propertize "---- %b %-" 'face '(:weight bold))
-               timer (run-with-timer 0 5 #'fancy-splash-screens-1
-                                     splash-buffer))
-         (add-hook 'pre-command-hook 'fancy-splash-pre-command)
-         (recursive-edit))
-      (trace-to-stderr "EXITTT\n")
-      (cancel-timer timer)
-      (remove-hook 'pre-command-hook 'fancy-splash-pre-command)
-      (use-global-map old-global-map)
-      (setq display-busy-cursor old-busy-cursor)
-      (kill-buffer splash-buffer))))
+    (catch 'stop-splashing
+      (unwind-protect
+         (let ((map (make-sparse-keymap))
+               (show-help-function nil))
+           (use-local-map map)
+           (define-key map [t] 'fancy-splash-default-action)
+           (define-key map [mouse-movement] 'ignore)
+           (setq cursor-type nil
+                 display-busy-cursor nil
+                 buffer-undo-list t
+                 mode-line-format
+                 (propertize "---- %b %-" 'face '(:weight bold))
+                 fancy-splash-stop-time (+ (float-time)
+                                           (max 60 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-busy-cursor old-busy-cursor)
+         (kill-buffer splash-buffer)))))
+
+
+(defun use-fancy-splash-screens-p ()
+  "Return t if fancy splash screens should be used."
+  (when (or (and (display-color-p)
+                (image-type-available-p 'xpm))
+           (image-type-available-p 'pbm))
+    (let* ((img (create-image (or fancy-splash-image
+                                 (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 (selected-window)))))
+      (> window-height (+ image-height 14)))))
 
 
 (defun startup-echo-area-message ()
@@ -1111,7 +1245,7 @@ where FACE is a valid face specification, as it can be used with
               (run-hooks 'window-setup-hook)
               (setq window-setup-hook nil))
             
-            (when (memq window-system '(x w32))
+            (when (display-popup-menus-p)
               (precompute-menubar-bindings))
             (setq menubar-bindings-done t)
             
@@ -1133,9 +1267,7 @@ where FACE is a valid face specification, as it can be used with
                       
                       (if (assq 'display (frame-parameters))
                           
-                          (if (or (and (display-color-p)
-                                       (image-type-available-p 'xpm))
-                                  (image-type-available-p 'pbm))
+                          (if (use-fancy-splash-screens-p)
                               (progn
                                 (setq wait-for-input nil)
                                 (fancy-splash-screens))
@@ -1143,7 +1275,7 @@ where FACE is a valid face specification, as it can be used with
                               (insert "\
 You can do basic editing with the menu bar and scroll bar using the mouse.
 
-Useful Files menu items:
+Useful File menu items:
 Exit Emacs             (or type Control-x followed by Control-c)
 Recover Session                recover files you were editing before a crash
 
@@ -1191,9 +1323,7 @@ Activate menubar   F10  or  ESC `  or   M-`")
                           (insert (substitute-command-keys "
 Activate menubar     \\[tmm-menubar]")))
 
-                        ;; Windows and MSDOS (currently) do not count as
-                        ;; window systems, but do have mouse support.
-                        (if window-system
+                        (if (display-mouse-p)
                             (insert "
 Mode-specific menu   C-mouse-3 (third button, with CTRL)"))
                         ;; Many users seem to have problems with these.
@@ -1245,10 +1375,7 @@ Type \\[describe-distribution] for information on getting the latest version."))
                     (erase-buffer)
                     (when initial-scratch-message
                       (insert initial-scratch-message))
-                    (set-buffer-modified-p nil))
-
-                  (when fancy-splash-pending-command
-                    (call-interactively fancy-splash-pending-command)))))))
+                    (set-buffer-modified-p nil)))))))
     
     ;; Delay 2 seconds after the init file error message
     ;; was displayed, so user can read it.