X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a4c5c70594f6f9cfb6a8414abdced5ff0490d280..332ad7ce48d611a232ddd085331b1069637d85a1:/lisp/startup.el diff --git a/lisp/startup.el b/lisp/startup.el index b48b742da7..081b3aed12 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1,6 +1,6 @@ ;;; startup.el --- process Emacs shell arguments -;; Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc. +;; Copyright (C) 1985, 1986, 1992, 1994 Free Software Foundation, Inc. ;; Maintainer: FSF ;; Keywords: internal @@ -41,13 +41,14 @@ ; -u user load user's init file ; -user user same ; -debug-init Don't catch errors in init file; let debugger run. +; -no-site-file Don't load site-run-file. ; These are processed in the order encountered. ; -f function execute function ; -funcall function same ; -l file load file ; -load file same -; -insert file same +; -insert file insert file into buffer ; file visit file ; -kill kill (exit) emacs @@ -58,10 +59,20 @@ (defvar command-line-processed nil "t once command line has been processed") (defconst inhibit-startup-message nil - "*Non-nil inhibits the initial startup messages. + "*Non-nil inhibits the initial startup message. This is for use in your personal init file, once you are familiar with the contents of the startup message.") +(defconst inhibit-startup-echo-area-message nil + "*Non-nil inhibits the initial startup echo area message. +Inhibition takes effect only if your `.emacs' file contains +a line of this form: + (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\") +If your `.emacs' file is byte-compiled, use the following form instead: + (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")) +Thus, someone else using a copy of your `.emacs' file will see +the startup message unless he personally acts to inhibit it.") + (defconst inhibit-default-init nil "*Non-nil inhibits loading the `default' library.") @@ -71,16 +82,23 @@ Elements look like (SWITCH-STRING . HANDLER-FUNCTION). HANDLER-FUNCTION receives switch name as sole arg; remaining command-line args are in the variable `command-line-args-left'.") +(defvar command-line-args-left nil + "List of command-line args not yet processed.") + (defvar command-line-functions nil ;; lrs 7/31/89 "List of functions to process unrecognized command-line arguments. Each function should access the dynamically bound variables -argi (the current argument) and command-line-args-left (the remaining +`argi' (the current argument) and `command-line-args-left' (the remaining arguments). The function should return non-nil only if it recognizes and -processes argi. If it does so, it may consume successive arguments by -altering command-line-args-left to remove them.") +processes `argi'. If it does so, it may consume successive arguments by +altering `command-line-args-left' to remove them.") + +(defvar command-line-default-directory nil + "Default directory to use for command line arguments. +This is normally copied from `default-directory' when Emacs starts.") (defvar before-init-hook nil - "Functions to call after handling urgent options but before loading init file. + "Functions to call after handling urgent options but before init files. The frame system uses this to open frames to display messages while Emacs loads the user's initialization file.") @@ -90,34 +108,34 @@ The call is not protected by a condition-case, so you can set `debug-on-error' in `.emacs', and put all the actual code on `after-init-hook'.") (defvar term-setup-hook nil - "Functions to be called after loading terminal-specific lisp code. + "Functions to be called after loading terminal-specific Lisp code. See `run-hooks'. This variable exists for users to set, so as to override the definitions made by the terminal-specific file. Emacs never sets this variable itself.") (defvar keyboard-type nil - "The brand of keyboard you are using. This variable is used to define + "The brand of keyboard you are using. +This variable is used to define the proper function and keypad keys for use under X. It is used in a fashion analogous to the environment value TERM.") (defvar window-setup-hook nil - "Function called to initialize window system display. -Emacs calls this after processing the command line arguments and loading -the user's init file. - -Users should not set this variable; use term-setup-hook instead.") + "Normal hook run to initialize window system display. +Emacs runs this hook after processing the command line arguments and loading +the user's init file.") (defconst initial-major-mode 'lisp-interaction-mode "Major mode command symbol to use for the initial *scratch* buffer.") (defvar init-file-user nil "Identity of user whose `.emacs' file is or was read. -The value may be the null string or a string containing a user's name. -If the value is a null string, it means that the init file was taken from -the user that originally logged in. +The value is nil if no init file is being used; otherwise, it may be either +the null string, meaning that the init file was taken from the user that +originally logged in, or it may be a string containing a user's name. -In all cases, `(concat \"~\" init-file-user \"/\")' evaluates to the -directory name of the directory where the `.emacs' file was looked for.") +In either of the latter cases, `(concat \"~\" init-file-user \"/\")' +evaluates to the name of the directory where the `.emacs' file was +looked for.") (defvar site-run-file "site-start" "File containing site-wide run-time initializations. @@ -127,14 +145,40 @@ higher incidence of change, don't make sense to load into emacs' dumped image. Thus, the run-time load order is: 1. file described in this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") +(defconst iso-8859-1-locale-regexp "8859[-_]?1" + "Regexp that specifies when to enable the ISO 8859-1 character set. +We do that if this regexp matches the locale name +specified by the LC_ALL, LC_CTYPE and LANG environment variables.") + +(defvar mail-host-address nil + "*Name of this machine, for purposes of naming users.") + +(defvar user-mail-address nil + "*Full mailing address of this user.") + (defvar init-file-debug nil) (defvar init-file-had-error nil) +;; This function is called from the subdirs.el file. +(defun normal-top-level-add-to-load-path (dirs) + (let ((tail (member default-directory load-path))) + (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail))))) + (defun normal-top-level () (if command-line-processed (message "Back to top level.") (setq command-line-processed t) + ;; Look in each dir in load-path for a subdirs.el file. + ;; If we find one, load it, which will add the appropriate subdirs + ;; of that dir into load-path, + (let ((tail load-path) + new) + (while tail + (setq new (cons (car tail) new)) + (let ((default-directory (car tail))) + (load (expand-file-name "subdirs.el" (car tail)) t t t)) + (setq tail (cdr tail)))) (if (not (eq system-type 'vax-vms)) (progn ;; If the PWD environment variable isn't accurate, delete it. @@ -151,24 +195,44 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") (delete (concat "PWD=" pwd) process-environment))))))) (setq default-directory (abbreviate-file-name default-directory)) - (unwind-protect - (command-line) - ;; Do this again, in case .emacs defined more abbreviations. - (setq default-directory (abbreviate-file-name default-directory)) - (run-hooks 'emacs-startup-hook) - (and term-setup-hook - (run-hooks 'term-setup-hook)) - ;; Modify the initial frame based on what .emacs puts into - ;; ...-frame-alist. - (if (fboundp 'frame-notice-user-settings) - (frame-notice-user-settings)) - ;; 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))))) + (setq user-mail-address (concat (user-login-name) "@" + (or mail-host-address + (system-name)))) + (let ((menubar-bindings-done nil)) + (unwind-protect + (command-line) + ;; Do this again, in case .emacs defined more abbreviations. + (setq default-directory (abbreviate-file-name default-directory)) + (run-hooks 'emacs-startup-hook) + (and term-setup-hook + (run-hooks 'term-setup-hook)) + ;; Modify the initial frame based on what .emacs puts into + ;; ...-frame-alist. + (if (fboundp 'frame-notice-user-settings) + (frame-notice-user-settings)) + ;; 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 + (precompute-menubar-bindings)))))) + +;; Precompute the keyboard equivalents in the menu bar items. +(defun precompute-menubar-bindings () + (if (eq window-system 'x) + (let ((submap (lookup-key global-map [menu-bar]))) + (while submap + (and (consp (car submap)) + (symbolp (car (car submap))) + (stringp (car-safe (cdr (car submap)))) + (keymapp (cdr (cdr (car submap)))) + (x-popup-menu nil (cdr (cdr (car submap))))) + (setq submap (cdr submap)))))) (defun command-line () + (setq command-line-default-directory default-directory) + ;; See if we should import version-control from the environment variable. (let ((vc (getenv "VERSION_CONTROL"))) (cond ((eq vc nil)) ;don't do anything if not set @@ -182,6 +246,21 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") (string= vc "simple")) (setq version-control 'never)))) + (if (let ((ctype + ;; Use the first of these three envvars that has a nonempty value. + (or (let ((string (getenv "LC_ALL"))) + (and (not (equal string "")) string)) + (let ((string (getenv "LC_CTYPE"))) + (and (not (equal string "")) string)) + (let ((string (getenv "LANG"))) + (and (not (equal string "")) string))))) + (and ctype + (string-match iso-8859-1-locale-regexp ctype))) + (progn + (require 'disp-table) + (standard-display-european t) + (require 'iso-syntax))) + ;;! 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. @@ -189,13 +268,31 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") ;;! (setq split-window-keep-point (> baud-rate 2400)) ;; Read window system's init file if using a window system. - (if (and window-system (not noninteractive)) - (load (concat term-file-prefix - (symbol-name window-system) - "-win") - ;; Every window system should have a startup file; - ;; barf if we can't find it. - nil t)) + (condition-case error + (if (and window-system (not noninteractive)) + (load (concat term-file-prefix + (symbol-name window-system) + "-win") + ;; Every window system should have a startup file; + ;; barf if we can't find it. + nil t)) + ;; If we can't read it, 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 error) ", ")))) + 'external-debugging-output) + (setq window-system nil) + (kill-emacs))) (let ((done nil) (args (cdr command-line-args))) @@ -211,7 +308,21 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") ;; processed. This is consistent with the way main in emacs.c ;; does things. (while (and (not done) args) - (let ((argi (car args))) + (let ((longopts '(("--no-init-file") ("--no-site-file") ("--user") + ("--debug-init"))) + (argi (car args)) + (argval nil)) + (if (string-match "=" argi) + (setq argval (substring argi (match-end 0)) + argi (substring argi 0 (match-beginning 0)))) + (let ((completion (try-completion argi longopts))) + (if (eq completion t) + (setq argi (substring argi 1)) + (if (stringp completion) + (let ((elt (assoc completion longopts))) + (or elt + (error "Option `%s' is ambiguous" argi)) + (setq argi (substring (car elt) 1)))))) (cond ((or (string-equal argi "-q") (string-equal argi "-no-init-file")) @@ -219,8 +330,11 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") args (cdr args))) ((or (string-equal argi "-u") (string-equal argi "-user")) - (setq args (cdr args) - init-file-user (car args) + (or argval + (setq argval (car args) + args (cdr args))) + (setq init-file-user argval + argval nil args (cdr args))) ((string-equal argi "-no-site-file") (setq site-run-file nil @@ -228,16 +342,23 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") ((string-equal argi "-debug-init") (setq init-file-debug t args (cdr args))) - (t (setq done t))))) - + (t (setq done t))) + ;; Was argval set but not used? + (and argval + (error "Option `%s' doesn't allow an argument" argi)))) + ;; Re-attach the program name to the front of the arg list. (setcdr command-line-args args)) ;; Under X Windows, this creates the X frame and deletes the terminal frame. - (if (fboundp 'frame-initialize) - (frame-initialize)) (if (fboundp 'face-initialize) (face-initialize)) + (if (fboundp 'frame-initialize) + (frame-initialize)) + ;; If frame was created with a menu bar, set menu-bar-mode on. + (if (and (eq window-system 'x) + (> (cdr (assq 'menu-bar-lines (frame-parameters))) 0)) + (menu-bar-mode t)) (run-hooks 'before-init-hook) @@ -288,10 +409,10 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") (setq init-file-had-error nil)) (error (message "Error in init file: %s%s%s" (get (car error) 'error-message) - (if (cdr error) ": ") + (if (cdr error) ": " "") (mapconcat 'prin1-to-string (cdr error) ", ")) (setq init-file-had-error t)))) - ;; If we can tell that the init file altered debug-on-error., + ;; 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 @@ -327,6 +448,26 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") (defun command-line-1 (command-line-args-left) (or noninteractive (input-pending-p) init-file-had-error + (and inhibit-startup-echo-area-message + (let ((buffer (get-buffer-create " *temp*"))) + (prog1 + (condition-case nil + (save-excursion + (set-buffer buffer) + (insert-file-contents user-init-file) + (re-search-forward + (concat + "([ \t\n]*setq[ \t\n]+" + "inhibit-startup-echo-area-message[ \t\n]+" + (regexp-quote + (prin1-to-string + (if (string= init-file-user "") + (user-login-name) + init-file-user))) + "[ \t\n]*)") + nil t)) + (error nil)) + (kill-buffer buffer)))) (message (if (eq (key-binding "\C-h\C-p") 'describe-project) "For information about the GNU Project and its goals, type C-h C-p." (substitute-command-keys @@ -355,11 +496,15 @@ this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.") (and window-setup-hook (run-hooks 'window-setup-hook)) (setq window-setup-hook nil) + ;; Do this now to avoid an annoying delay if the user + ;; clicks the menu bar during the sit-for. + (precompute-menubar-bindings) + (setq menubar-bindings-done t) (unwind-protect (progn (insert (emacs-version) " -Copyright (C) 1993 Free Software Foundation, Inc.\n\n") +Copyright (C) 1994 Free Software Foundation, Inc.\n\n") ;; If keys have their default meanings, ;; use precomputed string to save lots of time. (if (and (eq (key-binding "\C-h") 'help-command) @@ -395,7 +540,7 @@ Type \\[describe-distribution] for information on getting the latest version.")) (set-buffer (get-buffer "*scratch*")) (erase-buffer) (set-buffer-modified-p nil))))) - (let ((dir default-directory) + (let ((dir command-line-default-directory) (file-count 0) first-file-buffer (line 0))