| 1 | ;;; startup.el --- process Emacs shell arguments |
| 2 | |
| 3 | ;; Copyright (C) 1985, 86, 92, 94, 95, 1996 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Maintainer: FSF |
| 6 | ;; Keywords: internal |
| 7 | |
| 8 | ;; This file is part of GNU Emacs. |
| 9 | |
| 10 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 11 | ;; it under the terms of the GNU General Public License as published by |
| 12 | ;; the Free Software Foundation; either version 2, or (at your option) |
| 13 | ;; any later version. |
| 14 | |
| 15 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | ;; GNU General Public License for more details. |
| 19 | |
| 20 | ;; You should have received a copy of the GNU General Public License |
| 21 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 22 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 23 | ;; Boston, MA 02111-1307, USA. |
| 24 | |
| 25 | ;;; Commentary: |
| 26 | |
| 27 | ;; This file parses the command line and gets Emacs running. Options on |
| 28 | ;; the command line are handled in precedence order. The order is the |
| 29 | ;; one in the list below; first described means first handled. Options |
| 30 | ;; within each category (delimited by a bar) are handled in the order |
| 31 | ;; encountered on the command line. |
| 32 | |
| 33 | ;; ------------------------- |
| 34 | ;; -version Print Emacs version to stderr, then exit |
| 35 | ;; --version successfully right away. |
| 36 | ;; This option is handled by emacs.c |
| 37 | ;; ------------------------- |
| 38 | ;; -help Print a short usage description and exit |
| 39 | ;; --help successfully right away. |
| 40 | ;; This option is handled by emacs.c |
| 41 | ;; ------------------------- |
| 42 | ;; -nl Do not use shared memory (for systems that |
| 43 | ;; -no-shared-memory support this) for the dumped Emacs data. |
| 44 | ;; This option is handled by emacs.c |
| 45 | ;; |
| 46 | ;; -map For VMS. |
| 47 | ;; --map-data This option is handled by emacs.c |
| 48 | ;; ------------------------- |
| 49 | ;; -t FILE Use FILE as the name of the terminal. |
| 50 | ;; --terminal FILE Using this implies "-nw" also. |
| 51 | ;; This option is handled by emacs.c |
| 52 | ;; ------------------------- |
| 53 | ;; -d DISPNAME Use DISPNAME as the name of the X-windows |
| 54 | ;; -display DISPNAME display for the initial frame. |
| 55 | ;; --display DISPNAME This option is handled by emacs.c |
| 56 | ;; ------------------------- |
| 57 | ;; -nw Do not use a windows system (but use the |
| 58 | ;; --no-windows terminal instead.) |
| 59 | ;; This option is handled by emacs.c |
| 60 | ;; ------------------------- |
| 61 | ;; -batch Execute noninteractively (messages go to stdout, |
| 62 | ;; --batch variable noninteractive set to t) |
| 63 | ;; This option is handled by emacs.c |
| 64 | ;; ------------------------- |
| 65 | ;; -q Do not load user's init file and do not load |
| 66 | ;; -no-init-file "default.el". Regardless of this switch, |
| 67 | ;; --no-init-file "site-start" is still loaded. |
| 68 | ;; ------------------------- |
| 69 | ;; -no-site-file Do not load "site-start.el". (This is the ONLY |
| 70 | ;; --no-site-file way to prevent loading that file.) |
| 71 | ;; ------------------------- |
| 72 | ;; -u USER Load USER's init file instead of the init |
| 73 | ;; -user USER file belonging to the user starting Emacs. |
| 74 | ;; --user USER |
| 75 | ;; ------------------------- |
| 76 | ;; -debug-init Don't catch errors in init files; let the |
| 77 | ;; --debug-init debugger run. |
| 78 | ;; ------------------------- |
| 79 | ;; -i ICONTYPE Set type of icon using when Emacs is |
| 80 | ;; -itype ICONTYPE iconified under X-windows. |
| 81 | ;; --icon-type ICONTYPE This option is passed on to term/x-win.el |
| 82 | ;; |
| 83 | ;; -iconic Start Emacs iconified under X-windows. |
| 84 | ;; --iconic This option is passed on to term/x-win.el |
| 85 | ;; ------------------------- |
| 86 | ;; Various X-windows options for colors/fonts/geometry/title etc. |
| 87 | ;; These options are passed on to term/x-win.el which see. Certain |
| 88 | ;; of these are also found in term/pc-win.el |
| 89 | ;; ------------------------- |
| 90 | ;; FILE Visit FILE. |
| 91 | ;; |
| 92 | ;; -L DIRNAME Add DIRNAME to load-path |
| 93 | ;; -directory DIRNAME |
| 94 | ;; --directory DIRNAME |
| 95 | ;; |
| 96 | ;; -l FILE Load and execute the Emacs lisp code |
| 97 | ;; -load FILE in FILE. |
| 98 | ;; --load FILE |
| 99 | ;; |
| 100 | ;; -f FUNC Execute Emacs lisp function FUNC with |
| 101 | ;; -funcall FUNC no arguments. The "-e" form is outdated |
| 102 | ;; --funcall FUNC and should not be used. (It's a typo |
| 103 | ;; -e FUNC promoted to a feature.) |
| 104 | ;; |
| 105 | ;; -eval FORM Execute Emacs lisp form FORM. |
| 106 | ;; --eval FORM |
| 107 | ;; |
| 108 | ;; -insert FILE Insert the contents of FILE into buffer. |
| 109 | ;; --insert FILE |
| 110 | ;; ------------------------- |
| 111 | ;; -kill Kill (exit) Emacs right away. |
| 112 | ;; --kill |
| 113 | ;; ------------------------- |
| 114 | |
| 115 | ;;; Code: |
| 116 | |
| 117 | (setq top-level '(normal-top-level)) |
| 118 | |
| 119 | (defvar command-line-processed nil "t once command line has been processed") |
| 120 | |
| 121 | (defvar inhibit-startup-message nil |
| 122 | "*Non-nil inhibits the initial startup message. |
| 123 | This is for use in your personal init file, once you are familiar |
| 124 | with the contents of the startup message.") |
| 125 | |
| 126 | (defvar inhibit-startup-echo-area-message nil |
| 127 | "*Non-nil inhibits the initial startup echo area message. |
| 128 | Inhibition takes effect only if your `.emacs' file contains |
| 129 | a line of this form: |
| 130 | (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\") |
| 131 | If your `.emacs' file is byte-compiled, use the following form instead: |
| 132 | (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")) |
| 133 | Thus, someone else using a copy of your `.emacs' file will see |
| 134 | the startup message unless he personally acts to inhibit it.") |
| 135 | |
| 136 | (defvar inhibit-default-init nil |
| 137 | "*Non-nil inhibits loading the `default' library.") |
| 138 | |
| 139 | (defvar command-switch-alist nil |
| 140 | "Alist of command-line switches. |
| 141 | Elements look like (SWITCH-STRING . HANDLER-FUNCTION). |
| 142 | HANDLER-FUNCTION receives switch name as sole arg; |
| 143 | remaining command-line args are in the variable `command-line-args-left'.") |
| 144 | |
| 145 | (defvar command-line-args-left nil |
| 146 | "List of command-line args not yet processed.") |
| 147 | |
| 148 | (defvar command-line-functions nil ;; lrs 7/31/89 |
| 149 | "List of functions to process unrecognized command-line arguments. |
| 150 | Each function should access the dynamically bound variables |
| 151 | `argi' (the current argument) and `command-line-args-left' (the remaining |
| 152 | arguments). The function should return non-nil only if it recognizes and |
| 153 | processes `argi'. If it does so, it may consume successive arguments by |
| 154 | altering `command-line-args-left' to remove them.") |
| 155 | |
| 156 | (defvar command-line-default-directory nil |
| 157 | "Default directory to use for command line arguments. |
| 158 | This is normally copied from `default-directory' when Emacs starts.") |
| 159 | |
| 160 | ;;; This is here, rather than in x-win.el, so that we can ignore these |
| 161 | ;;; options when we are not using X. |
| 162 | (defvar command-line-x-option-alist |
| 163 | '(("-bw" 1 x-handle-numeric-switch border-width) |
| 164 | ("-d" 1 x-handle-display) |
| 165 | ("-display" 1 x-handle-display) |
| 166 | ("-name" 1 x-handle-name-switch) |
| 167 | ("-title" 1 x-handle-switch title) |
| 168 | ("-T" 1 x-handle-switch title) |
| 169 | ("-r" 0 x-handle-switch reverse t) |
| 170 | ("-rv" 0 x-handle-switch reverse t) |
| 171 | ("-reverse" 0 x-handle-switch reverse t) |
| 172 | ("-reverse-video" 0 x-handle-switch reverse t) |
| 173 | ("-fn" 1 x-handle-switch font) |
| 174 | ("-font" 1 x-handle-switch font) |
| 175 | ("-ib" 1 x-handle-numeric-switch internal-border-width) |
| 176 | ("-g" 1 x-handle-geometry) |
| 177 | ("-geometry" 1 x-handle-geometry) |
| 178 | ("-fg" 1 x-handle-switch foreground-color) |
| 179 | ("-foreground" 1 x-handle-switch foreground-color) |
| 180 | ("-bg" 1 x-handle-switch background-color) |
| 181 | ("-background" 1 x-handle-switch background-color) |
| 182 | ("-ms" 1 x-handle-switch mouse-color) |
| 183 | ("-itype" 0 x-handle-switch icon-type t) |
| 184 | ("-i" 0 x-handle-switch icon-type t) |
| 185 | ("-iconic" 0 x-handle-iconic) |
| 186 | ("-xrm" 1 x-handle-xrm-switch) |
| 187 | ("-cr" 1 x-handle-switch cursor-color) |
| 188 | ("-vb" 0 x-handle-switch vertical-scroll-bars t) |
| 189 | ("-hb" 0 x-handle-switch horizontal-scroll-bars t) |
| 190 | ("-bd" 1 x-handle-switch) |
| 191 | ("--border-width" 1 x-handle-numeric-switch border-width) |
| 192 | ("--display" 1 x-handle-display) |
| 193 | ("--name" 1 x-handle-name-switch) |
| 194 | ("--title" 1 x-handle-switch title) |
| 195 | ("--reverse-video" 0 x-handle-switch reverse t) |
| 196 | ("--font" 1 x-handle-switch font) |
| 197 | ("--internal-border" 1 x-handle-numeric-switch internal-border-width) |
| 198 | ("--geometry" 1 x-handle-geometry) |
| 199 | ("--foreground-color" 1 x-handle-switch foreground-color) |
| 200 | ("--background-color" 1 x-handle-switch background-color) |
| 201 | ("--mouse-color" 1 x-handle-switch mouse-color) |
| 202 | ("--icon-type" 0 x-handle-switch icon-type t) |
| 203 | ("--iconic" 0 x-handle-iconic) |
| 204 | ("--xrm" 1 x-handle-xrm-switch) |
| 205 | ("--cursor-color" 1 x-handle-switch cursor-color) |
| 206 | ("--vertical-scroll-bars" 0 x-handle-switch vertical-scroll-bars t) |
| 207 | ("--border-color" 1 x-handle-switch border-width)) |
| 208 | "Alist of X Windows options. |
| 209 | Each element has the form |
| 210 | (NAME NUMARGS HANDLER FRAME-PARAM VALUE) |
| 211 | where NAME is the option name string, NUMARGS is the number of arguments |
| 212 | that the option accepts, HANDLER is a function to call to handle the option. |
| 213 | FRAME-PARAM (optional) is the frame parameter this option specifies, |
| 214 | and VALUE is the value which is given to that frame parameter |
| 215 | \(most options use the argument for this, so VALUE is not present).") |
| 216 | |
| 217 | (defvar before-init-hook nil |
| 218 | "Normal hook run after handling urgent options but before loading init files.") |
| 219 | |
| 220 | (defvar after-init-hook nil |
| 221 | "Normal hook run after loading the init files, `~/.emacs' and `default.el'. |
| 222 | There is no `condition-case' around the running of these functions; |
| 223 | therefore, if you set `debug-on-error' non-nil in `.emacs', |
| 224 | an error in one of these functions will invoke the debugger.") |
| 225 | |
| 226 | (defvar emacs-startup-hook nil |
| 227 | "Normal hook run after loading init files and handling the command line.") |
| 228 | |
| 229 | (defvar term-setup-hook nil |
| 230 | "Normal hook run after loading terminal-specific Lisp code. |
| 231 | It also follows `emacs-startup-hook'. This hook exists for users to set, |
| 232 | so as to override the definitions made by the terminal-specific file. |
| 233 | Emacs never sets this variable itself.") |
| 234 | |
| 235 | (defvar keyboard-type nil |
| 236 | "The brand of keyboard you are using. |
| 237 | This variable is used to define |
| 238 | the proper function and keypad keys for use under X. It is used in a |
| 239 | fashion analogous to the environment value TERM.") |
| 240 | |
| 241 | (defvar window-setup-hook nil |
| 242 | "Normal hook run to initialize window system display. |
| 243 | Emacs runs this hook after processing the command line arguments and loading |
| 244 | the user's init file.") |
| 245 | |
| 246 | (defvar initial-major-mode 'lisp-interaction-mode |
| 247 | "Major mode command symbol to use for the initial *scratch* buffer.") |
| 248 | |
| 249 | (defvar init-file-user nil |
| 250 | "Identity of user whose `.emacs' file is or was read. |
| 251 | The value is nil if `-q' or `--no-init-file' was specified, |
| 252 | meaning do not load any init file. |
| 253 | |
| 254 | Otherwise, the value may be the null string, meaning use the init file |
| 255 | for the user that originally logged in, or it may be a |
| 256 | string containing a user's name meaning use that person's init file. |
| 257 | |
| 258 | In either of the latter cases, `(concat \"~\" init-file-user \"/\")' |
| 259 | evaluates to the name of the directory where the `.emacs' file was |
| 260 | looked for. |
| 261 | |
| 262 | Setting `init-file-user' does not prevent Emacs from loading |
| 263 | `site-start.el'. The only way to do that is to use `--no-site-file'.") |
| 264 | |
| 265 | (defvar site-run-file "site-start" |
| 266 | "File containing site-wide run-time initializations. |
| 267 | This file is loaded at run-time before `~/.emacs'. It contains inits |
| 268 | that need to be in place for the entire site, but which, due to their |
| 269 | higher incidence of change, don't make sense to load into emacs' |
| 270 | dumped image. Thus, the run-time load order is: 1. file described in |
| 271 | this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'. |
| 272 | |
| 273 | Don't use the `site-start.el' file for things some users may not like. |
| 274 | Put them in `default.el' instead, so that users can more easily |
| 275 | override them. Users can prevent loading `default.el' with the `-q' |
| 276 | option or by setting `inhibit-default-init' in their own init files, |
| 277 | but inhibiting `site-start.el' requires `--no-site-file', which |
| 278 | is less convenient.") |
| 279 | |
| 280 | (defconst iso-8859-n-locale-regexp "8859[-_]?\\([1-5]\\)" |
| 281 | "Regexp that specifies when to enable an ISO 8859-N character set. |
| 282 | We do that if this regexp matches the locale name |
| 283 | specified by the LC_ALL, LC_CTYPE and LANG environment variables. |
| 284 | The paren group in the regexp should match the specific character |
| 285 | set number, N.") |
| 286 | |
| 287 | (defvar mail-host-address nil |
| 288 | "*Name of this machine, for purposes of naming users.") |
| 289 | |
| 290 | (defvar user-mail-address nil |
| 291 | "*Full mailing address of this user. |
| 292 | This is initialized based on `mail-host-address', |
| 293 | after your init file is read, in case it sets `mail-host-address'.") |
| 294 | |
| 295 | (defvar auto-save-list-file-prefix |
| 296 | (if (eq system-type 'ms-dos) |
| 297 | "~/_s" ; MS-DOS cannot have initial dot, and allows only 8.3 names |
| 298 | "~/.saves-") |
| 299 | "Prefix for generating `auto-save-list-file-name'. |
| 300 | This is used after reading your `.emacs' file to initialize |
| 301 | `auto-save-list-file-name', by appending Emacs's pid and the system name, |
| 302 | if you have not already set `auto-save-list-file-name' yourself. |
| 303 | Set this to nil if you want to prevent `auto-save-list-file-name' |
| 304 | from being initialized.") |
| 305 | |
| 306 | (defvar init-file-debug nil) |
| 307 | |
| 308 | (defvar init-file-had-error nil) |
| 309 | |
| 310 | ;; This function is called from the subdirs.el file. |
| 311 | (defun normal-top-level-add-to-load-path (dirs) |
| 312 | (let ((tail (member (directory-file-name default-directory) load-path))) |
| 313 | (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail))))) |
| 314 | |
| 315 | (defun normal-top-level () |
| 316 | (if command-line-processed |
| 317 | (message "Back to top level.") |
| 318 | (setq command-line-processed t) |
| 319 | ;; Give *Messages* the same default-directory as *scratch*, |
| 320 | ;; just to keep things predictable. |
| 321 | (let ((dir default-directory)) |
| 322 | (save-excursion |
| 323 | (set-buffer (get-buffer "*Messages*")) |
| 324 | (setq default-directory dir))) |
| 325 | ;; Look in each dir in load-path for a subdirs.el file. |
| 326 | ;; If we find one, load it, which will add the appropriate subdirs |
| 327 | ;; of that dir into load-path, |
| 328 | (let ((tail load-path) |
| 329 | new) |
| 330 | (while tail |
| 331 | (setq new (cons (car tail) new)) |
| 332 | (let ((default-directory (car tail))) |
| 333 | (load (expand-file-name "subdirs.el" (car tail)) t t t)) |
| 334 | (setq tail (cdr tail)))) |
| 335 | (if (not (eq system-type 'vax-vms)) |
| 336 | (progn |
| 337 | ;; If the PWD environment variable isn't accurate, delete it. |
| 338 | (let ((pwd (getenv "PWD"))) |
| 339 | (and (stringp pwd) |
| 340 | ;; Use FOO/., so that if FOO is a symlink, file-attributes |
| 341 | ;; describes the directory linked to, not FOO itself. |
| 342 | (or (equal (file-attributes |
| 343 | (concat (file-name-as-directory pwd) ".")) |
| 344 | (file-attributes |
| 345 | (concat (file-name-as-directory default-directory) |
| 346 | "."))) |
| 347 | (setq process-environment |
| 348 | (delete (concat "PWD=" pwd) |
| 349 | process-environment))))))) |
| 350 | (setq default-directory (abbreviate-file-name default-directory)) |
| 351 | (let ((menubar-bindings-done nil)) |
| 352 | (unwind-protect |
| 353 | (command-line) |
| 354 | ;; Do this again, in case .emacs defined more abbreviations. |
| 355 | (setq default-directory (abbreviate-file-name default-directory)) |
| 356 | ;; Specify the file for recording all the auto save files of this session. |
| 357 | ;; This is used by recover-session. |
| 358 | (or auto-save-list-file-name |
| 359 | (and auto-save-list-file-prefix |
| 360 | (setq auto-save-list-file-name |
| 361 | ;; Under MS-DOS our PID is almost always reused between |
| 362 | ;; Emacs invocations. We need something more unique. |
| 363 | (if (eq system-type 'ms-dos) |
| 364 | (concat |
| 365 | (make-temp-name |
| 366 | (expand-file-name auto-save-list-file-prefix)) |
| 367 | "~") |
| 368 | |
| 369 | (expand-file-name (format "%s%d-%s~" |
| 370 | auto-save-list-file-prefix |
| 371 | (emacs-pid) |
| 372 | (system-name))))))) |
| 373 | (run-hooks 'emacs-startup-hook) |
| 374 | (and term-setup-hook |
| 375 | (run-hooks 'term-setup-hook)) |
| 376 | ;; Modify the initial frame based on what .emacs puts into |
| 377 | ;; ...-frame-alist. |
| 378 | (if (fboundp 'frame-notice-user-settings) |
| 379 | (frame-notice-user-settings)) |
| 380 | ;; Now we know the user's default font, so add it to the menu. |
| 381 | (if (fboundp 'font-menu-add-default) |
| 382 | (font-menu-add-default)) |
| 383 | (and window-setup-hook |
| 384 | (run-hooks 'window-setup-hook)) |
| 385 | (or menubar-bindings-done |
| 386 | (if (memq window-system '(x w32)) |
| 387 | (precompute-menubar-bindings))))))) |
| 388 | |
| 389 | ;; Precompute the keyboard equivalents in the menu bar items. |
| 390 | (defun precompute-menubar-bindings () |
| 391 | (let ((submap (lookup-key global-map [menu-bar]))) |
| 392 | (while submap |
| 393 | (and (consp (car submap)) |
| 394 | (symbolp (car (car submap))) |
| 395 | (stringp (car-safe (cdr (car submap)))) |
| 396 | (keymapp (cdr (cdr (car submap)))) |
| 397 | (progn |
| 398 | (x-popup-menu nil (cdr (cdr (car submap)))) |
| 399 | (if purify-flag |
| 400 | (garbage-collect)))) |
| 401 | (setq submap (cdr submap)))) |
| 402 | (setq define-key-rebound-commands t)) |
| 403 | |
| 404 | (defun command-line () |
| 405 | (setq command-line-default-directory default-directory) |
| 406 | |
| 407 | ;; See if we should import version-control from the environment variable. |
| 408 | (let ((vc (getenv "VERSION_CONTROL"))) |
| 409 | (cond ((eq vc nil)) ;don't do anything if not set |
| 410 | ((or (string= vc "t") |
| 411 | (string= vc "numbered")) |
| 412 | (setq version-control t)) |
| 413 | ((or (string= vc "nil") |
| 414 | (string= vc "existing")) |
| 415 | (setq version-control nil)) |
| 416 | ((or (string= vc "never") |
| 417 | (string= vc "simple")) |
| 418 | (setq version-control 'never)))) |
| 419 | |
| 420 | (let ((ctype |
| 421 | ;; Use the first of these three envvars that has a nonempty value. |
| 422 | (or (let ((string (getenv "LC_ALL"))) |
| 423 | (and (not (equal string "")) string)) |
| 424 | (let ((string (getenv "LC_CTYPE"))) |
| 425 | (and (not (equal string "")) string)) |
| 426 | (let ((string (getenv "LANG"))) |
| 427 | (and (not (equal string "")) string)))) |
| 428 | charset) |
| 429 | (when (and ctype |
| 430 | (string-match iso-8859-n-locale-regexp ctype)) |
| 431 | (setq charset (concat "latin-" (match-string 1 ctype))) |
| 432 | (if (default-value 'enable-multibyte-characters) |
| 433 | (if (string-match "latin-[12345]" charset) |
| 434 | (set-language-environment charset)) |
| 435 | ;; These two lines are ok for any Latin-N character set, |
| 436 | ;; as long as the terminal displays it. |
| 437 | (require 'disp-table) |
| 438 | (standard-display-european t) |
| 439 | ;; Set up syntax for the chosen character set. |
| 440 | (if (string-match "latin-[1234]" charset) |
| 441 | (require (intern charset)))))) |
| 442 | |
| 443 | ;;! This has been commented out; I currently find the behavior when |
| 444 | ;;! split-window-keep-point is nil disturbing, but if I can get used |
| 445 | ;;! to it, then it would be better to eliminate the option. |
| 446 | ;;! ;; Choose a good default value for split-window-keep-point. |
| 447 | ;;! (setq split-window-keep-point (> baud-rate 2400)) |
| 448 | |
| 449 | ;; Read window system's init file if using a window system. |
| 450 | (condition-case error |
| 451 | (if (and window-system (not noninteractive)) |
| 452 | (load (concat term-file-prefix |
| 453 | (symbol-name window-system) |
| 454 | "-win") |
| 455 | ;; Every window system should have a startup file; |
| 456 | ;; barf if we can't find it. |
| 457 | nil t)) |
| 458 | ;; If we can't read it, print the error message and exit. |
| 459 | (error |
| 460 | (princ |
| 461 | (if (eq (car error) 'error) |
| 462 | (apply 'concat (cdr error)) |
| 463 | (if (memq 'file-error (get (car error) 'error-conditions)) |
| 464 | (format "%s: %s" |
| 465 | (nth 1 error) |
| 466 | (mapconcat '(lambda (obj) (prin1-to-string obj t)) |
| 467 | (cdr (cdr error)) ", ")) |
| 468 | (format "%s: %s" |
| 469 | (get (car error) 'error-message) |
| 470 | (mapconcat '(lambda (obj) (prin1-to-string obj t)) |
| 471 | (cdr error) ", ")))) |
| 472 | 'external-debugging-output) |
| 473 | (setq window-system nil) |
| 474 | (kill-emacs))) |
| 475 | |
| 476 | (let ((done nil) |
| 477 | (args (cdr command-line-args))) |
| 478 | |
| 479 | ;; Figure out which user's init file to load, |
| 480 | ;; either from the environment or from the options. |
| 481 | (setq init-file-user (if noninteractive nil (user-login-name))) |
| 482 | ;; If user has not done su, use current $HOME to find .emacs. |
| 483 | (and init-file-user (string= init-file-user (user-real-login-name)) |
| 484 | (setq init-file-user "")) |
| 485 | |
| 486 | ;; Process the command-line args, and delete the arguments |
| 487 | ;; processed. This is consistent with the way main in emacs.c |
| 488 | ;; does things. |
| 489 | (while (and (not done) args) |
| 490 | (let ((longopts '(("--no-init-file") ("--no-site-file") ("--user") |
| 491 | ("--debug-init") ("--iconic") ("--icon-type"))) |
| 492 | (argi (car args)) |
| 493 | (argval nil)) |
| 494 | ;; Handle --OPTION=VALUE format. |
| 495 | (if (and (string-match "\\`--" argi) |
| 496 | (string-match "=" argi)) |
| 497 | (setq argval (substring argi (match-end 0)) |
| 498 | argi (substring argi 0 (match-beginning 0)))) |
| 499 | (or (equal argi "--") |
| 500 | (let ((completion (try-completion argi longopts))) |
| 501 | (if (eq completion t) |
| 502 | (setq argi (substring argi 1)) |
| 503 | (if (stringp completion) |
| 504 | (let ((elt (assoc completion longopts))) |
| 505 | (or elt |
| 506 | (error "Option `%s' is ambiguous" argi)) |
| 507 | (setq argi (substring (car elt) 1))) |
| 508 | (setq argval nil))))) |
| 509 | (cond |
| 510 | ((or (string-equal argi "-q") |
| 511 | (string-equal argi "-no-init-file")) |
| 512 | (setq init-file-user nil |
| 513 | args (cdr args))) |
| 514 | ((or (string-equal argi "-u") |
| 515 | (string-equal argi "-user")) |
| 516 | (or argval |
| 517 | (setq args (cdr args) |
| 518 | argval (car args))) |
| 519 | (setq init-file-user argval |
| 520 | argval nil |
| 521 | args (cdr args))) |
| 522 | ((string-equal argi "-no-site-file") |
| 523 | (setq site-run-file nil |
| 524 | args (cdr args))) |
| 525 | ((string-equal argi "-debug-init") |
| 526 | (setq init-file-debug t |
| 527 | args (cdr args))) |
| 528 | ((string-equal argi "-iconic") |
| 529 | (setq initial-frame-alist |
| 530 | (cons '(visibility . icon) initial-frame-alist)) |
| 531 | (setq args (cdr args))) |
| 532 | ((or (string-equal argi "-icon-type") |
| 533 | (string-equal argi "-i") |
| 534 | (string-equal argi "-itype")) |
| 535 | (setq default-frame-alist |
| 536 | (cons '(icon-type . t) default-frame-alist)) |
| 537 | (setq args (cdr args))) |
| 538 | (t (setq done t))) |
| 539 | ;; Was argval set but not used? |
| 540 | (and argval |
| 541 | (error "Option `%s' doesn't allow an argument" argi)))) |
| 542 | |
| 543 | ;; Re-attach the program name to the front of the arg list. |
| 544 | (and command-line-args (setcdr command-line-args args))) |
| 545 | |
| 546 | ;; Under X Windows, this creates the X frame and deletes the terminal frame. |
| 547 | (if (fboundp 'face-initialize) |
| 548 | (face-initialize)) |
| 549 | (if (fboundp 'frame-initialize) |
| 550 | (frame-initialize)) |
| 551 | ;; If frame was created with a menu bar, set menu-bar-mode on. |
| 552 | (if (or (not (memq window-system '(x w32))) |
| 553 | (> (cdr (assq 'menu-bar-lines (frame-parameters))) 0)) |
| 554 | (menu-bar-mode t)) |
| 555 | |
| 556 | (run-hooks 'before-init-hook) |
| 557 | |
| 558 | ;; Run the site-start library if it exists. The point of this file is |
| 559 | ;; that it is run before .emacs. There is no point in doing this after |
| 560 | ;; .emacs; that is useless. |
| 561 | (if site-run-file |
| 562 | (load site-run-file t t)) |
| 563 | |
| 564 | ;; Sites should not disable this. Only individuals should disable |
| 565 | ;; the startup message. |
| 566 | (setq inhibit-startup-message nil) |
| 567 | |
| 568 | ;; Load that user's init file, or the default one, or none. |
| 569 | (let (debug-on-error-from-init-file |
| 570 | debug-on-error-should-be-set |
| 571 | (debug-on-error-initial |
| 572 | (if (eq init-file-debug t) 'startup init-file-debug))) |
| 573 | (let ((debug-on-error debug-on-error-initial) |
| 574 | ;; This function actually reads the init files. |
| 575 | (inner |
| 576 | (function |
| 577 | (lambda () |
| 578 | (if init-file-user |
| 579 | (progn |
| 580 | (setq user-init-file |
| 581 | (cond |
| 582 | ((eq system-type 'ms-dos) |
| 583 | (concat "~" init-file-user "/_emacs")) |
| 584 | ((eq system-type 'windows-nt) |
| 585 | (if (file-exists-p "~/.emacs") |
| 586 | "~/.emacs" |
| 587 | "~/_emacs")) |
| 588 | ((eq system-type 'vax-vms) |
| 589 | "sys$login:.emacs") |
| 590 | (t |
| 591 | (concat "~" init-file-user "/.emacs")))) |
| 592 | (load user-init-file t t t) |
| 593 | (or inhibit-default-init |
| 594 | (let ((inhibit-startup-message nil)) |
| 595 | ;; Users are supposed to be told their rights. |
| 596 | ;; (Plus how to get help and how to undo.) |
| 597 | ;; Don't you dare turn this off for anyone |
| 598 | ;; except yourself. |
| 599 | (load "default" t t))))))))) |
| 600 | (if init-file-debug |
| 601 | ;; Do this without a condition-case if the user wants to debug. |
| 602 | (funcall inner) |
| 603 | (condition-case error |
| 604 | (progn |
| 605 | (funcall inner) |
| 606 | (setq init-file-had-error nil)) |
| 607 | (error (message "Error in init file: %s%s%s" |
| 608 | (get (car error) 'error-message) |
| 609 | (if (cdr error) ": " "") |
| 610 | (mapconcat 'prin1-to-string (cdr error) ", ")) |
| 611 | (setq init-file-had-error t)))) |
| 612 | ;; If we can tell that the init file altered debug-on-error, |
| 613 | ;; arrange to preserve the value that it set up. |
| 614 | (or (eq debug-on-error debug-on-error-initial) |
| 615 | (setq debug-on-error-should-be-set t |
| 616 | debug-on-error-from-init-file debug-on-error))) |
| 617 | (if debug-on-error-should-be-set |
| 618 | (setq debug-on-error debug-on-error-from-init-file))) |
| 619 | |
| 620 | ;; Do this here in case the init file sets mail-host-address. |
| 621 | (or user-mail-address |
| 622 | (setq user-mail-address (concat (user-login-name) "@" |
| 623 | (or mail-host-address |
| 624 | (system-name))))) |
| 625 | |
| 626 | (run-hooks 'after-init-hook) |
| 627 | |
| 628 | ;; If *scratch* exists and init file didn't change its mode, initialize it. |
| 629 | (if (get-buffer "*scratch*") |
| 630 | (save-excursion |
| 631 | (set-buffer "*scratch*") |
| 632 | (if (eq major-mode 'fundamental-mode) |
| 633 | (funcall initial-major-mode)))) |
| 634 | ;; Load library for our terminal type. |
| 635 | ;; User init file can set term-file-prefix to nil to prevent this. |
| 636 | (and term-file-prefix (not noninteractive) (not window-system) |
| 637 | (let ((term (getenv "TERM")) |
| 638 | hyphend) |
| 639 | (while (and term |
| 640 | (not (load (concat term-file-prefix term) t t))) |
| 641 | ;; Strip off last hyphen and what follows, then try again |
| 642 | (if (setq hyphend (string-match "[-_][^-_]+$" term)) |
| 643 | (setq term (substring term 0 hyphend)) |
| 644 | (setq term nil))))) |
| 645 | |
| 646 | ;; Process the remaining args. |
| 647 | (command-line-1 (cdr command-line-args)) |
| 648 | |
| 649 | ;; If -batch, terminate after processing the command options. |
| 650 | (if noninteractive (kill-emacs t))) |
| 651 | |
| 652 | (defun command-line-1 (command-line-args-left) |
| 653 | (or noninteractive (input-pending-p) init-file-had-error |
| 654 | (and inhibit-startup-echo-area-message |
| 655 | (let ((buffer (get-buffer-create " *temp*"))) |
| 656 | (prog1 |
| 657 | (condition-case nil |
| 658 | (save-excursion |
| 659 | (set-buffer buffer) |
| 660 | (insert-file-contents user-init-file) |
| 661 | (re-search-forward |
| 662 | (concat |
| 663 | "([ \t\n]*setq[ \t\n]+" |
| 664 | "inhibit-startup-echo-area-message[ \t\n]+" |
| 665 | (regexp-quote |
| 666 | (prin1-to-string |
| 667 | (if (string= init-file-user "") |
| 668 | (user-login-name) |
| 669 | init-file-user))) |
| 670 | "[ \t\n]*)") |
| 671 | nil t)) |
| 672 | (error nil)) |
| 673 | (kill-buffer buffer)))) |
| 674 | (message (if (eq (key-binding "\C-h\C-p") 'describe-project) |
| 675 | "For information about the GNU Project and its goals, type C-h C-p." |
| 676 | (substitute-command-keys |
| 677 | "For information about the GNU Project and its goals, type \\[describe-project].")))) |
| 678 | (if (null command-line-args-left) |
| 679 | (cond ((and (not inhibit-startup-message) (not noninteractive) |
| 680 | ;; Don't clobber a non-scratch buffer if init file |
| 681 | ;; has selected it. |
| 682 | (string= (buffer-name) "*scratch*") |
| 683 | (not (input-pending-p))) |
| 684 | ;; If there are no switches to process, we might as well |
| 685 | ;; run this hook now, and there may be some need to do it |
| 686 | ;; before doing any output. |
| 687 | (and term-setup-hook |
| 688 | (run-hooks 'term-setup-hook)) |
| 689 | ;; Don't let the hook be run twice. |
| 690 | (setq term-setup-hook nil) |
| 691 | |
| 692 | ;; It's important to notice the user settings before we |
| 693 | ;; display the startup message; otherwise, the settings |
| 694 | ;; won't take effect until the user gives the first |
| 695 | ;; keystroke, and that's distracting. |
| 696 | (if (fboundp 'frame-notice-user-settings) |
| 697 | (frame-notice-user-settings)) |
| 698 | |
| 699 | (and window-setup-hook |
| 700 | (run-hooks 'window-setup-hook)) |
| 701 | (setq window-setup-hook nil) |
| 702 | ;; Do this now to avoid an annoying delay if the user |
| 703 | ;; clicks the menu bar during the sit-for. |
| 704 | (if (memq window-system '(x w32)) |
| 705 | (precompute-menubar-bindings)) |
| 706 | (setq menubar-bindings-done t) |
| 707 | (unwind-protect |
| 708 | (progn |
| 709 | ;; The convention for this piece of code is that |
| 710 | ;; each piece of output starts with one or two newlines |
| 711 | ;; and does not end with any newlines. |
| 712 | (insert "Welcome to GNU Emacs") |
| 713 | (if (eq system-type 'gnu/linux) |
| 714 | (insert ", one component of a Linux-based GNU system.")) |
| 715 | (insert "\n") |
| 716 | ;; If keys have their default meanings, |
| 717 | ;; use precomputed string to save lots of time. |
| 718 | (if (and (eq (key-binding "\C-h") 'help-command) |
| 719 | (eq (key-binding "\C-xu") 'advertised-undo) |
| 720 | (eq (key-binding "\C-x\C-c") 'save-buffers-kill-emacs) |
| 721 | (eq (key-binding "\C-ht") 'help-with-tutorial) |
| 722 | (eq (key-binding "\C-hi") 'info) |
| 723 | (eq (key-binding "\C-h\C-n") 'view-emacs-news)) |
| 724 | (insert " |
| 725 | Get help C-h (Hold down CTRL and press h) |
| 726 | Undo changes C-x u Exit Emacs C-x C-c |
| 727 | Get a tutorial C-h t Use Info to read docs C-h i") |
| 728 | (insert (substitute-command-keys |
| 729 | (format "\n |
| 730 | Get help %s |
| 731 | Undo changes \\[advertised-undo] |
| 732 | Exit Emacs \\[save-buffers-kill-emacs] |
| 733 | Get a tutorial \\[help-with-tutorial] |
| 734 | Use Info to read docs \\[info]" |
| 735 | (let ((where (where-is-internal |
| 736 | 'help-command nil t))) |
| 737 | (if where |
| 738 | (key-description where) |
| 739 | "M-x help")))))) |
| 740 | ;; Say how to use the menu bar |
| 741 | ;; if that is not with the mouse. |
| 742 | (if (not (assq 'display (frame-parameters))) |
| 743 | (if (and (eq (key-binding "\M-`") 'tmm-menubar) |
| 744 | (eq (key-binding [f10]) 'tmm-menubar)) |
| 745 | (insert " |
| 746 | Activate menubar F10 or ESC ` or M-`") |
| 747 | (insert (substitute-command-keys " |
| 748 | Activate menubar \\[tmm-menubar]")))) |
| 749 | |
| 750 | ;; Windows and MSDOS (currently) do not count as |
| 751 | ;; window systems, but do have mouse support. |
| 752 | (if window-system |
| 753 | (insert " |
| 754 | Mode-specific menu C-mouse-3 (third button, with CTRL)")) |
| 755 | ;; Many users seem to have problems with these. |
| 756 | (insert " |
| 757 | \(`C-' means use the CTRL key. `M-' means use the Meta (or Alt) key. |
| 758 | If you have no Meta key, you may instead type ESC followed by the character.)") |
| 759 | (and auto-save-list-file-prefix |
| 760 | (directory-files |
| 761 | (file-name-directory auto-save-list-file-prefix) |
| 762 | nil |
| 763 | (concat "\\`" |
| 764 | (regexp-quote (file-name-nondirectory |
| 765 | auto-save-list-file-prefix))) |
| 766 | t) |
| 767 | (insert "\n\nIf an Emacs session crashed recently, " |
| 768 | "type M-x recover-session RET\nto recover" |
| 769 | " the files you were editing.")) |
| 770 | |
| 771 | (insert "\n\n" (emacs-version) |
| 772 | " |
| 773 | Copyright (C) 1996 Free Software Foundation, Inc.") |
| 774 | (if (and (eq (key-binding "\C-h\C-c") 'describe-copying) |
| 775 | (eq (key-binding "\C-h\C-d") 'describe-distribution) |
| 776 | (eq (key-binding "\C-h\C-w") 'describe-no-warranty)) |
| 777 | (insert |
| 778 | "\n |
| 779 | GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details. |
| 780 | You may give out copies of Emacs; type C-h C-c to see the conditions. |
| 781 | Type C-h C-d for information on getting the latest version.") |
| 782 | (insert (substitute-command-keys |
| 783 | "\n |
| 784 | GNU Emacs comes with ABSOLUTELY NO WARRANTY; type \\[describe-no-warranty] for full details. |
| 785 | You may give out copies of Emacs; type \\[describe-copying] to see the conditions. |
| 786 | Type \\[describe-distribution] for information on getting the latest version."))) |
| 787 | (goto-char (point-min)) |
| 788 | |
| 789 | (set-buffer-modified-p nil) |
| 790 | (sit-for 120)) |
| 791 | (with-current-buffer (get-buffer "*scratch*") |
| 792 | (erase-buffer) |
| 793 | (insert "\ |
| 794 | If you want to create a file, don't type the text in this buffer. |
| 795 | This buffer is for notes you don't want to save, and for Lisp evaluation. |
| 796 | If you want to create a file, first visit that file with C-x C-f, |
| 797 | then enter the text in that file's own buffer. |
| 798 | |
| 799 | ") |
| 800 | (set-buffer-modified-p nil))))) |
| 801 | ;; Delay 2 seconds after the init file error message |
| 802 | ;; was displayed, so user can read it. |
| 803 | (if init-file-had-error |
| 804 | (sit-for 2)) |
| 805 | (let ((dir command-line-default-directory) |
| 806 | (file-count 0) |
| 807 | first-file-buffer |
| 808 | tem |
| 809 | just-files ;; t if this follows the magic -- option. |
| 810 | ;; This includes our standard options' long versions |
| 811 | ;; and long versions of what's on command-switch-alist. |
| 812 | (longopts |
| 813 | (append '(("--funcall") ("--load") ("--insert") ("--kill") |
| 814 | ("--directory") ("--eval") ("--find-file") ("--visit")) |
| 815 | (mapcar '(lambda (elt) |
| 816 | (list (concat "-" (car elt)))) |
| 817 | command-switch-alist))) |
| 818 | (line 0)) |
| 819 | |
| 820 | ;; Add the long X options to longopts. |
| 821 | (setq tem command-line-x-option-alist) |
| 822 | (while tem |
| 823 | (if (string-match "^--" (car (car tem))) |
| 824 | (setq longopts (cons (list (car (car tem))) longopts))) |
| 825 | (setq tem (cdr tem))) |
| 826 | |
| 827 | ;; Loop, processing options. |
| 828 | (while (and command-line-args-left) |
| 829 | (let* ((argi (car command-line-args-left)) |
| 830 | (orig-argi argi) |
| 831 | argval completion |
| 832 | ;; List of directories specified in -L/--directory, |
| 833 | ;; in reverse of the order specified. |
| 834 | extra-load-path |
| 835 | (initial-load-path load-path)) |
| 836 | (setq command-line-args-left (cdr command-line-args-left)) |
| 837 | |
| 838 | ;; Do preliminary decoding of the option. |
| 839 | (if just-files |
| 840 | ;; After --, don't look for options; treat all args as files. |
| 841 | (setq argi "") |
| 842 | ;; Convert long options to ordinary options |
| 843 | ;; and separate out an attached option argument into argval. |
| 844 | (if (string-match "^--[^=]*=" argi) |
| 845 | (setq argval (substring argi (match-end 0)) |
| 846 | argi (substring argi 0 (1- (match-end 0))))) |
| 847 | (if (equal argi "--") |
| 848 | (setq completion nil) |
| 849 | (setq completion (try-completion argi longopts))) |
| 850 | (if (eq completion t) |
| 851 | (setq argi (substring argi 1)) |
| 852 | (if (stringp completion) |
| 853 | (let ((elt (assoc completion longopts))) |
| 854 | (or elt |
| 855 | (error "Option `%s' is ambiguous" argi)) |
| 856 | (setq argi (substring (car elt) 1))) |
| 857 | (setq argval nil argi orig-argi)))) |
| 858 | |
| 859 | ;; Execute the option. |
| 860 | (cond ((setq tem (assoc argi command-switch-alist)) |
| 861 | (if argval |
| 862 | (let ((command-line-args-left |
| 863 | (cons argval command-line-args-left))) |
| 864 | (funcall (cdr tem) argi)) |
| 865 | (funcall (cdr tem) argi))) |
| 866 | ((or (string-equal argi "-f") ;what the manual claims |
| 867 | (string-equal argi "-funcall") |
| 868 | (string-equal argi "-e")) ; what the source used to say |
| 869 | (if argval |
| 870 | (setq tem (intern argval)) |
| 871 | (setq tem (intern (car command-line-args-left))) |
| 872 | (setq command-line-args-left (cdr command-line-args-left))) |
| 873 | (if (arrayp (symbol-function tem)) |
| 874 | (command-execute tem) |
| 875 | (funcall tem))) |
| 876 | ((string-equal argi "-eval") |
| 877 | (if argval |
| 878 | (setq tem argval) |
| 879 | (setq tem (car command-line-args-left)) |
| 880 | (setq command-line-args-left (cdr command-line-args-left))) |
| 881 | (eval (read tem))) |
| 882 | ;; Set the default directory as specified in -L. |
| 883 | ((or (string-equal argi "-L") |
| 884 | (string-equal argi "-directory")) |
| 885 | (if argval |
| 886 | (setq tem argval) |
| 887 | (setq tem (car command-line-args-left) |
| 888 | command-line-args-left (cdr command-line-args-left))) |
| 889 | (setq tem (command-line-normalize-file-name tem)) |
| 890 | (setq extra-load-path |
| 891 | (cons (expand-file-name tem) extra-load-path)) |
| 892 | (setq load-path (append (nreverse extra-load-path) |
| 893 | initial-load-path))) |
| 894 | ((or (string-equal argi "-l") |
| 895 | (string-equal argi "-load")) |
| 896 | (if argval |
| 897 | (setq tem argval) |
| 898 | (setq tem (car command-line-args-left) |
| 899 | command-line-args-left (cdr command-line-args-left))) |
| 900 | (let ((file (command-line-normalize-file-name tem))) |
| 901 | ;; Take file from default dir if it exists there; |
| 902 | ;; otherwise let `load' search for it. |
| 903 | (if (file-exists-p (expand-file-name file)) |
| 904 | (setq file (expand-file-name file))) |
| 905 | (load file nil t))) |
| 906 | ((string-equal argi "-insert") |
| 907 | (if argval |
| 908 | (setq tem argval) |
| 909 | (setq tem (car command-line-args-left) |
| 910 | command-line-args-left (cdr command-line-args-left))) |
| 911 | (or (stringp tem) |
| 912 | (error "File name omitted from `-insert' option")) |
| 913 | (insert-file-contents (command-line-normalize-file-name tem))) |
| 914 | ((string-equal argi "-kill") |
| 915 | (kill-emacs t)) |
| 916 | ((string-match "^\\+[0-9]+\\'" argi) |
| 917 | (setq line (string-to-int argi))) |
| 918 | ((setq tem (assoc argi command-line-x-option-alist)) |
| 919 | ;; Ignore X-windows options and their args if not using X. |
| 920 | (setq command-line-args-left |
| 921 | (nthcdr (nth 1 tem) command-line-args-left))) |
| 922 | ((or (string-equal argi "-find-file") |
| 923 | (string-equal argi "-visit")) |
| 924 | ;; An explicit option to specify visiting a file. |
| 925 | (setq file-count (1+ file-count)) |
| 926 | (let ((file |
| 927 | (expand-file-name |
| 928 | (command-line-normalize-file-name orig-argi) |
| 929 | dir))) |
| 930 | (if (= file-count 1) |
| 931 | (setq first-file-buffer (find-file file)) |
| 932 | (find-file-other-window file))) |
| 933 | (or (zerop line) |
| 934 | (goto-line line)) |
| 935 | (setq line 0)) |
| 936 | ((equal argi "--") |
| 937 | (setq just-files t)) |
| 938 | (t |
| 939 | ;; We have almost exhausted our options. See if the |
| 940 | ;; user has made any other command-line options available |
| 941 | (let ((hooks command-line-functions);; lrs 7/31/89 |
| 942 | (did-hook nil)) |
| 943 | (while (and hooks |
| 944 | (not (setq did-hook (funcall (car hooks))))) |
| 945 | (setq hooks (cdr hooks))) |
| 946 | (if (not did-hook) |
| 947 | ;; Ok, presume that the argument is a file name |
| 948 | (progn |
| 949 | (if (string-match "\\`-" argi) |
| 950 | (error "Unknown option `%s'" argi)) |
| 951 | (setq file-count (1+ file-count)) |
| 952 | (let ((file |
| 953 | (expand-file-name |
| 954 | (command-line-normalize-file-name orig-argi) |
| 955 | dir))) |
| 956 | (if (= file-count 1) |
| 957 | (setq first-file-buffer (find-file file)) |
| 958 | (find-file-other-window file))) |
| 959 | (or (zerop line) |
| 960 | (goto-line line)) |
| 961 | (setq line 0)))))))) |
| 962 | ;; If 3 or more files visited, and not all visible, |
| 963 | ;; show user what they all are. |
| 964 | (and (> file-count 2) |
| 965 | (not noninteractive) |
| 966 | (or (get-buffer-window first-file-buffer) |
| 967 | (progn (other-window 1) |
| 968 | (buffer-menu))))))) |
| 969 | |
| 970 | (defun command-line-normalize-file-name (file) |
| 971 | "Collapse multiple slashes to one, to handle non-Emacs file names." |
| 972 | (save-match-data |
| 973 | ;; Use arg 1 so that we don't collapse // at the start of the file name. |
| 974 | ;; That is significant on some systems. |
| 975 | ;; However, /// at the beginning is supposed to mean just /, not //. |
| 976 | (if (string-match "^///+" file) |
| 977 | (setq file (replace-match "/" t t file))) |
| 978 | (while (string-match "//+" file 1) |
| 979 | (setq file (replace-match "/" t t file))) |
| 980 | file)) |
| 981 | |
| 982 | ;;; startup.el ends here |