diff options
| author | Jim Blandy | 1991-07-11 23:17:40 +0000 |
|---|---|---|
| committer | Jim Blandy | 1991-07-11 23:17:40 +0000 |
| commit | a726e0d12ccb1c49ca1f3e1fbe64addea9b7d3b4 (patch) | |
| tree | 4250802664a87cee8743758b4407b4c8b890d917 | |
| parent | 8769d6482a05a1ef4bf6038dad42351f556947bf (diff) | |
| download | emacs-a726e0d12ccb1c49ca1f3e1fbe64addea9b7d3b4.tar.gz emacs-a726e0d12ccb1c49ca1f3e1fbe64addea9b7d3b4.zip | |
Initial revision
| -rw-r--r-- | lisp/startup.el | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/lisp/startup.el b/lisp/startup.el new file mode 100644 index 00000000000..d8cfb1e3409 --- /dev/null +++ b/lisp/startup.el | |||
| @@ -0,0 +1,355 @@ | |||
| 1 | ;; Process Emacs shell arguments | ||
| 2 | ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ; These are processed only at the beginning of the argument list. | ||
| 22 | ; -batch execute noninteractively (messages go to stdout, | ||
| 23 | ; variable noninteractive set to t) | ||
| 24 | ; This option must be the first in the arglist. | ||
| 25 | ; Processed by `main' in emacs.c -- never seen by lisp | ||
| 26 | ; -t file Specify to use file rather than stdin/stdout | ||
| 27 | ; as the terminal. | ||
| 28 | ; This option must be the first in the arglist. | ||
| 29 | ; Processed by `main' in emacs.c -- never seen by lisp | ||
| 30 | ; -nw Inhibit the use of any window-system-specific display | ||
| 31 | ; code; use the current virtual terminal. | ||
| 32 | ; This option must be the first in the arglist. | ||
| 33 | ; Processed by `main' in emacs.c -- never seen by lisp | ||
| 34 | ; -q load no init file | ||
| 35 | ; -no-init-file same | ||
| 36 | ; -u user load user's init file | ||
| 37 | ; -user user same | ||
| 38 | ; -debug-init Don't catch errors in init file; let debugger run. | ||
| 39 | |||
| 40 | ; These are processed in the order encountered. | ||
| 41 | ; -f function execute function | ||
| 42 | ; -funcall function same | ||
| 43 | ; -l file load file | ||
| 44 | ; -load file same | ||
| 45 | ; -i file insert file into buffer | ||
| 46 | ; -insert file same | ||
| 47 | ; file visit file | ||
| 48 | ; -kill kill (exit) emacs | ||
| 49 | |||
| 50 | (setq top-level '(normal-top-level)) | ||
| 51 | |||
| 52 | (defvar command-line-processed nil "t once command line has been processed") | ||
| 53 | |||
| 54 | (defconst inhibit-startup-message nil | ||
| 55 | "*Non-nil inhibits the initial startup messages. | ||
| 56 | This is for use in your personal init file, once you are familiar | ||
| 57 | with the contents of the startup message.") | ||
| 58 | |||
| 59 | (defconst inhibit-default-init nil | ||
| 60 | "*Non-nil inhibits loading the `default' library.") | ||
| 61 | |||
| 62 | (defconst command-switch-alist nil | ||
| 63 | "Alist of command-line switches. | ||
| 64 | Elements look like (SWITCH-STRING . HANDLER-FUNCTION). | ||
| 65 | HANDLER-FUNCTION receives switch name as sole arg; | ||
| 66 | remaining command-line args are in the variable `command-line-args-left'.") | ||
| 67 | |||
| 68 | (defvar command-line-functions nil ;; lrs 7/31/89 | ||
| 69 | "List of functions to process unrecognized command-line arguments. | ||
| 70 | Each function should access the dynamically bound variables | ||
| 71 | argi (the current argument) and command-line-args-left (the remaining | ||
| 72 | arguments). The function should return non-nil only if it recognizes and | ||
| 73 | processes argi. If it does so, it may consume successive arguments by | ||
| 74 | altering command-line-args-left to remove them.") | ||
| 75 | |||
| 76 | (defvar term-setup-hook nil | ||
| 77 | "Function to be called after loading terminal-specific lisp code. | ||
| 78 | It is called with no arguments. This variable exists for users to set, | ||
| 79 | so as to override the definitions made by the terminal-specific file. | ||
| 80 | Emacs never sets this variable itself.") | ||
| 81 | |||
| 82 | (defvar keyboard-type nil | ||
| 83 | "The brand of keyboard you are using. This variable is used to define | ||
| 84 | the proper function and keypad keys for use under X. It is used in a | ||
| 85 | fashion analogous to the environment value TERM.") | ||
| 86 | |||
| 87 | (defvar window-setup-hook nil | ||
| 88 | "Function used to initialize window system display, after command line args. | ||
| 89 | Users should not set this variable; use term-setup-hook instead.") | ||
| 90 | |||
| 91 | (defconst initial-major-mode 'lisp-interaction-mode | ||
| 92 | "Major mode command symbol to use for the initial *scratch* buffer.") | ||
| 93 | |||
| 94 | (defvar init-file-user nil | ||
| 95 | "Identity of user whose `.emacs' file is or was read. | ||
| 96 | The value may be the null string or a string containing a user's name. | ||
| 97 | If the value is a null string, it means that the init file was taken from | ||
| 98 | the user that originally logged in. | ||
| 99 | |||
| 100 | In all cases, `(concat \"~\" init-file-user \"/\")' evaluates to the | ||
| 101 | directory name of the directory where the `.emacs' file was looked for.") | ||
| 102 | |||
| 103 | (defvar init-file-debug nil) | ||
| 104 | |||
| 105 | (defun normal-top-level () | ||
| 106 | (if command-line-processed | ||
| 107 | (message "Back to top level.") | ||
| 108 | (setq command-line-processed t) | ||
| 109 | ;; In presence of symlinks, switch to cleaner form of default directory. | ||
| 110 | (if (and (not (eq system-type 'vax-vms)) | ||
| 111 | (getenv "PWD")) | ||
| 112 | (setq default-directory (file-name-as-directory (getenv "PWD")))) | ||
| 113 | (let ((tail directory-abbrev-alist)) | ||
| 114 | (while tail | ||
| 115 | (if (string-match (car (car tail)) default-directory) | ||
| 116 | (setq default-directory | ||
| 117 | (concat (cdr (car tail)) | ||
| 118 | (substring default-directory (match-end 0))))) | ||
| 119 | (setq tail (cdr tail)))) | ||
| 120 | (unwind-protect | ||
| 121 | (command-line) | ||
| 122 | (run-hooks 'emacs-startup-hook) | ||
| 123 | (and term-setup-hook | ||
| 124 | (run-hooks 'term-setup-hook)) | ||
| 125 | (and window-setup-hook | ||
| 126 | (run-hooks 'window-setup-hook))))) | ||
| 127 | |||
| 128 | (defun command-line () | ||
| 129 | ;; See if we should import version-control from the envionment variable. | ||
| 130 | (let ((vc (getenv "VERSION_CONTROL"))) | ||
| 131 | (cond ((eq vc nil)) ;don't do anything if not set | ||
| 132 | ((or (string= vc "t") | ||
| 133 | (string= vc "numbered")) | ||
| 134 | (setq version-control t)) | ||
| 135 | ((or (string= vc "nil") | ||
| 136 | (string= vc "existing")) | ||
| 137 | (setq version-control nil)) | ||
| 138 | ((or (string= vc "never") | ||
| 139 | (string= vc "simple")) | ||
| 140 | (setq version-control 'never)))) | ||
| 141 | |||
| 142 | ;; Read window system's init file if using a window system. | ||
| 143 | (if (and window-system (not noninteractive)) | ||
| 144 | (condition-case data | ||
| 145 | (load (concat term-file-prefix | ||
| 146 | (symbol-name window-system) | ||
| 147 | "-win") | ||
| 148 | ;; Every window system should have a startup file; | ||
| 149 | ;; barf if we can't find it. | ||
| 150 | nil t) | ||
| 151 | (error | ||
| 152 | (let ((standard-output 'external-debugging-output)) | ||
| 153 | (princ "Error initializing window system: ") | ||
| 154 | (prin1 data) | ||
| 155 | (terpri) | ||
| 156 | (kill-emacs))))) | ||
| 157 | |||
| 158 | (let ((args (cdr command-line-args)) | ||
| 159 | (done nil)) | ||
| 160 | ;; Figure out which user's init file to load, | ||
| 161 | ;; either from the environment or from the options. | ||
| 162 | (setq init-file-user (if noninteractive nil (user-login-name))) | ||
| 163 | ;; If user has not done su, use current $HOME to find .emacs. | ||
| 164 | (and init-file-user (string= init-file-user (user-real-login-name)) | ||
| 165 | (setq init-file-user "")) | ||
| 166 | (while (and (not done) args) | ||
| 167 | (let ((argi (car args))) | ||
| 168 | (cond | ||
| 169 | ((or (string-equal argi "-q") | ||
| 170 | (string-equal argi "-no-init-file")) | ||
| 171 | (setq init-file-user nil | ||
| 172 | args (cdr args))) | ||
| 173 | ((or (string-equal argi "-u") | ||
| 174 | (string-equal argi "-user")) | ||
| 175 | (setq args (cdr args) | ||
| 176 | init-file-user (car args) | ||
| 177 | args (cdr args))) | ||
| 178 | ((string-equal argi "-debug-init") | ||
| 179 | (setq init-file-debug t | ||
| 180 | args (cdr args))) | ||
| 181 | (t (setq done t)))))) | ||
| 182 | |||
| 183 | ;; Load that user's init file, or the default one, or none. | ||
| 184 | (let ((debug-on-error init-file-debug) | ||
| 185 | ;; This function actually reads the init files. | ||
| 186 | (inner | ||
| 187 | (function | ||
| 188 | (lambda () | ||
| 189 | (if init-file-user | ||
| 190 | (progn (load (if (eq system-type 'vax-vms) | ||
| 191 | "sys$login:.emacs" | ||
| 192 | (concat "~" init-file-user "/.emacs")) | ||
| 193 | t t t) | ||
| 194 | (or inhibit-default-init | ||
| 195 | (let ((inhibit-startup-message nil)) | ||
| 196 | ;; Users are supposed to be told their rights. | ||
| 197 | ;; (Plus how to get help and how to undo.) | ||
| 198 | ;; Don't you dare turn this off for anyone | ||
| 199 | ;; except yourself. | ||
| 200 | (load "default" t t))))))))) | ||
| 201 | (if init-file-debug | ||
| 202 | ;; Do this without a condition-case if the user wants to debug. | ||
| 203 | (funcall inner) | ||
| 204 | (condition-case error | ||
| 205 | (funcall inner) | ||
| 206 | (error (message "Error in init file: %s%s%s" | ||
| 207 | (get (car error) 'error-message) | ||
| 208 | (if (cdr error) ": ") | ||
| 209 | (mapconcat 'prin1-to-string (cdr error) ", ")))))) | ||
| 210 | ;; If *scratch* exists and init file didn't change its mode, initialize it. | ||
| 211 | (if (get-buffer "*scratch*") | ||
| 212 | (save-excursion | ||
| 213 | (set-buffer "*scratch*") | ||
| 214 | (if (eq major-mode 'fundamental-mode) | ||
| 215 | (funcall initial-major-mode)))) | ||
| 216 | ;; Load library for our terminal type. | ||
| 217 | ;; User init file can set term-file-prefix to nil to prevent this. | ||
| 218 | (and term-file-prefix (not noninteractive) (not window-system) | ||
| 219 | (let ((term (getenv "TERM")) | ||
| 220 | hyphend) | ||
| 221 | (while (and term | ||
| 222 | (not (load (concat term-file-prefix term) t t))) | ||
| 223 | ;; Strip off last hyphen and what follows, then try again | ||
| 224 | (if (setq hyphend (string-match "[-_][^-_]+$" term)) | ||
| 225 | (setq term (substring term 0 hyphend)) | ||
| 226 | (setq term nil))))) | ||
| 227 | |||
| 228 | ;; Handle all the other options. | ||
| 229 | (command-line-1 (cdr command-line-args)) | ||
| 230 | |||
| 231 | ;; If -batch, terminate after processing the command options. | ||
| 232 | (if noninteractive (kill-emacs t))) | ||
| 233 | |||
| 234 | (defun command-line-1 (command-line-args-left) | ||
| 235 | (if (null command-line-args-left) | ||
| 236 | (cond ((and (not inhibit-startup-message) (not noninteractive) | ||
| 237 | ;; Don't clobber a non-scratch buffer if init file | ||
| 238 | ;; has selected it. | ||
| 239 | (string= (buffer-name) "*scratch*") | ||
| 240 | (not (input-pending-p))) | ||
| 241 | ;; If there are no switches to process, we might as well | ||
| 242 | ;; run this hook now, and there may be some need to do it | ||
| 243 | ;; before doing any output. | ||
| 244 | (and term-setup-hook | ||
| 245 | (run-hooks 'term-setup-hook)) | ||
| 246 | ;; Don't let the hook be run twice. | ||
| 247 | (setq term-setup-hook nil) | ||
| 248 | (and window-setup-hook | ||
| 249 | (run-hooks 'window-setup-hook)) | ||
| 250 | (setq window-setup-hook nil) | ||
| 251 | (unwind-protect | ||
| 252 | (progn | ||
| 253 | (insert (emacs-version) | ||
| 254 | " | ||
| 255 | Copyright (C) 1989 Free Software Foundation, Inc.\n\n") | ||
| 256 | ;; If keys have their default meanings, | ||
| 257 | ;; use precomputed string to save lots of time. | ||
| 258 | (if (and (eq (key-binding "\C-h") 'help-command) | ||
| 259 | (eq (key-binding "\C-xu") 'advertised-undo) | ||
| 260 | (eq (key-binding "\C-x\C-c") 'save-buffers-kill-emacs) | ||
| 261 | (eq (key-binding "\C-h\C-c") 'describe-copying) | ||
| 262 | (eq (key-binding "\C-h\C-d") 'describe-distribution) | ||
| 263 | (eq (key-binding "\C-h\C-w") 'describe-no-warranty) | ||
| 264 | (eq (key-binding "\C-ht") 'help-with-tutorial)) | ||
| 265 | (insert | ||
| 266 | "Type C-h for help; C-x u to undo changes. (`C-' means use CTRL key.) | ||
| 267 | To kill the Emacs job, type C-x C-c. | ||
| 268 | Type C-h t for a tutorial on using Emacs. | ||
| 269 | |||
| 270 | GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details. | ||
| 271 | You may give out copies of Emacs; type C-h C-c to see the conditions. | ||
| 272 | Type C-h C-d for information on getting the latest version.") | ||
| 273 | (insert (substitute-command-keys | ||
| 274 | "Type \\[help-command] for help; \\[advertised-undo] to undo changes. (`C-' means use CTRL key.) | ||
| 275 | To kill the Emacs job, type \\[save-buffers-kill-emacs]. | ||
| 276 | Type \\[help-with-tutorial] for a tutorial on using Emacs. | ||
| 277 | |||
| 278 | GNU Emacs comes with ABSOLUTELY NO WARRANTY; type \\[describe-no-warranty] for full details. | ||
| 279 | You may give out copies of Emacs; type \\[describe-copying] to see the conditions. | ||
| 280 | Type \\[describe-distribution] for information on getting the latest version."))) | ||
| 281 | (set-buffer-modified-p nil) | ||
| 282 | (sit-for 120)) | ||
| 283 | (save-excursion | ||
| 284 | ;; In case the Emacs server has already selected | ||
| 285 | ;; another buffer, erase the one our message is in. | ||
| 286 | (set-buffer (get-buffer "*scratch*")) | ||
| 287 | (erase-buffer) | ||
| 288 | (set-buffer-modified-p nil))))) | ||
| 289 | (let ((dir default-directory) | ||
| 290 | (file-count 0) | ||
| 291 | first-file-buffer | ||
| 292 | (line 0)) | ||
| 293 | (while command-line-args-left | ||
| 294 | (let ((argi (car command-line-args-left)) | ||
| 295 | tem) | ||
| 296 | (setq command-line-args-left (cdr command-line-args-left)) | ||
| 297 | (cond ((setq tem (assoc argi command-switch-alist)) | ||
| 298 | (funcall (cdr tem) argi)) | ||
| 299 | ;; These args were already processed; ignore them. | ||
| 300 | ((or (string-equal argi "-q") | ||
| 301 | (string-equal argi "-no-init-file") | ||
| 302 | (string-equal argi "-debug-init") | ||
| 303 | (string-equal argi "-batch"))) | ||
| 304 | ((or (string-equal argi "-u") | ||
| 305 | (string-equal argi "-user")) | ||
| 306 | (setq command-line-args-left (cdr command-line-args-left))) | ||
| 307 | ((or (string-equal argi "-f") ;what the manual claims | ||
| 308 | (string-equal argi "-funcall") | ||
| 309 | (string-equal argi "-e")) ; what the source used to say | ||
| 310 | (setq tem (intern (car command-line-args-left))) | ||
| 311 | (setq command-line-args-left (cdr command-line-args-left)) | ||
| 312 | (funcall tem)) | ||
| 313 | ((or (string-equal argi "-l") | ||
| 314 | (string-equal argi "-load")) | ||
| 315 | (let ((file (car command-line-args-left))) | ||
| 316 | ;; Take file from default dir if it exists there; | ||
| 317 | ;; otherwise let `load' search for it. | ||
| 318 | (if (file-exists-p (expand-file-name file)) | ||
| 319 | (setq file (expand-file-name file))) | ||
| 320 | (load file nil t)) | ||
| 321 | (setq command-line-args-left (cdr command-line-args-left))) | ||
| 322 | ((or (string-equal argi "-i") | ||
| 323 | (string-equal argi "-insert")) | ||
| 324 | (insert-file-contents (car command-line-args-left)) | ||
| 325 | (setq command-line-args-left (cdr command-line-args-left))) | ||
| 326 | ((string-equal argi "-kill") | ||
| 327 | (kill-emacs t)) | ||
| 328 | ((string-match "^\\+[0-9]+\\'" argi) | ||
| 329 | (setq line (string-to-int argi))) | ||
| 330 | (t | ||
| 331 | ;; We have almost exhausted our options. See if the | ||
| 332 | ;; user has made any other command-line options available | ||
| 333 | (let ((hooks command-line-functions);; lrs 7/31/89 | ||
| 334 | (did-hook nil)) | ||
| 335 | (while (and hooks | ||
| 336 | (not (setq did-hook (funcall (car hooks))))) | ||
| 337 | (setq hooks (cdr hooks))) | ||
| 338 | (if (not did-hook) | ||
| 339 | ;; Ok, presume that the argument is a file name | ||
| 340 | (progn | ||
| 341 | (setq file-count (1+ file-count)) | ||
| 342 | (cond ((= file-count 1) | ||
| 343 | (setq first-file-buffer | ||
| 344 | (find-file (expand-file-name argi dir)))) | ||
| 345 | (t | ||
| 346 | (find-file-other-window (expand-file-name argi dir)))) | ||
| 347 | (or (zerop line) | ||
| 348 | (goto-line line)) | ||
| 349 | (setq line 0)))))))) | ||
| 350 | ;; If 3 or more files visited, and not all visible, | ||
| 351 | ;; show user what they all are. | ||
| 352 | (if (> file-count 2) | ||
| 353 | (or (get-buffer-window first-file-buffer) | ||
| 354 | (progn (other-window) | ||
| 355 | (buffer-menu))))))) | ||