;;; startup.el --- process SXEmacs shell arguments
;; Copyright (C) 1985-1986, 1990, 1992-1997 Free Software Foundation, Inc.
;; Copyright (c) 1993, 1994 Sun Microsystems, Inc.
;; Copyright (C) 1995 Board of Trustees, University of Illinois
;; Copyright (C) 2004 - 2015 Steve Youngs
;; Maintainer: SXEmacs Development Team
;; Keywords: internal, dumped
;; This file is part of SXEmacs.
;; SXEmacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; SXEmacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see .
;;; Synched up with: FSF 19.34.
;;; Commentary:
;; This file is dumped with SXEmacs.
;; -batch, -t, and -nw are processed by main() in emacs.c and are
;; never seen by lisp code.
;; -version and -help are special-cased as well: they imply -batch,
;; but are left on the list for lisp code to process.
;;; Code:
(setq top-level '(normal-top-level))
(defvar command-line-processed nil "t once command line has been processed")
(defconst startup-message-timeout 12000) ; More or less disable the timeout
(defconst splash-frame-timeout 10) ; interval between splash frame elements
(defconst inhibit-startup-message nil
"*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-default-init nil
"*Non-nil inhibits loading the `default' library.")
(defvar command-line-args-left nil
"List of command-line args not yet processed.") ; bound by `command-line'
(defvar command-line-default-directory nil
"Default directory to use for command line arguments.
This is normally copied from `default-directory' when SXEmacs starts.")
(defvar before-init-hook nil
"Functions to call after handling urgent options but before init files.
The frame system uses this to open frames to display messages while
SXEmacs loads the user's initialization file.")
(defvar after-init-hook nil
"*Functions to call after loading the init file.
The call is not protected by a condition-case, so you can set `debug-on-error'
in the init file, 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.
See `run-hooks'. This variable exists for users to set, so as to
override the definitions made by the terminal-specific file. SXEmacs
never sets this variable itself.")
(defvar keyboard-type nil
"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
"Normal hook run to initialize window system display.
SXEmacs 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 emacs-roots nil
"List of plausible roots of the SXEmacs hierarchy.")
(defun find-user-init-directory ()
"Find and set the user's init directory.
If no init directory currently exists, this will return:
\"$XDG_CONFIG_HOME/sxemacs\", which falls back to
\"~/.config/sxemacs\" if $XDG_CONFIG_HOME is not set in the user's
environment.
If the legacy init directory, \"~/.sxemacs\" exists, return that.
If both the legacy directory and the XDG-based directory exist, return
the XDG-based directory unless $SXE_USE_LEGACY is set in the user's
environment."
(let* ((legacy (getenv "SXE_USE_LEGACY"))
(xdg (getenv "XDG_CONFIG_HOME"))
(xdgdir (or (and xdg
(paths-construct-path
(list xdg "sxemacs")))
(paths-construct-path
(list (user-home-directory) ".config" "sxemacs"))))
(legacydir (paths-construct-path
(list (user-home-directory) ".sxemacs")))
(locations (list xdgdir legacydir))
(multi (count-if #'file-directory-p locations)))
(if legacy
(setq user-init-directory (file-name-as-directory legacydir))
(catch 'found
(dolist (dir locations)
(and (paths-file-readable-directory-p dir)
(throw 'found (setq user-init-directory
(file-name-as-directory dir)))))
(setq user-init-directory (file-name-as-directory xdgdir))))
;; Warn if multiple init directories exist
(when (> multi 1)
(lwarn 'multi-initd nil
"Multiple init directories found:
%S
Currently using: %s
See `display-warning-suppressed-classes' to suppress this warning"
locations user-init-directory))))
(defvar user-init-directory ""
"Directory where user-installed init files may go.
See: `find-user-init-directory'.")
(defvar user-init-file-base-list '("init.elc" "init.el")
"List of allowed init files in the user's init directory.
The first one found takes precedence.")
(defvar load-user-init-file-p t
"Non-nil if SXEmacs should load the user's init file.")
;; #### called `site-run-file' in FSFmacs
(defvar site-start-file "site-start"
"File containing site-wide run-time initializations.
This file is loaded at run-time before `user-init-file'. It
contains inits that need to be in place for the entire site, but
which, due to their higher incidence of change, don't make sense to
load into SXEmacs' dumped image. Thus, the run-time load order is:
1. file described in this variable, if non-nil;
2. `user-init-file';
3. `/path/to/sxemacs/lisp/default.el'.
Don't use the `site-start.el' file for things some users may not like.
Put them in `default.el' instead, so that users can more easily
override them. Users can prevent loading `default.el' with the `-q'
option or by setting `inhibit-default-init' in their own init files,
but inhibiting `site-start.el' requires `--no-site-file', which
is less convenient.")
;;(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.")
(defcustom mail-host-address nil
"*Name of this machine, for purposes of naming users."
:type 'string
:group 'mail)
(defcustom user-mail-address nil
"*Full mailing address of this user.
This is initialized based on `mail-host-address',
after your init file is read, in case it sets `mail-host-address'."
:type 'string
:group 'mail)
(defvar init-file-debug nil)
(defvar init-file-had-error nil)
(defvar init-file-loaded nil
"True after the user's init file has been loaded (or suppressed with -q).
This will be true when `after-init-hook' is run and at all times
after, and will not be true at any time before.")
(defvar initial-frame-unmapped-p nil)
(defvar command-switch-alist
'(("-help" . command-line-do-help)
("-h" . command-line-do-help)
("-version" . command-line-do-version)
("-V" . command-line-do-version)
("-funcall" . command-line-do-funcall)
("-f" . command-line-do-funcall)
("-e" . command-line-do-funcall-1)
("-eval" . command-line-do-eval)
("-load" . command-line-do-load)
("-l" . command-line-do-load)
("-insert" . command-line-do-insert)
("-i" . command-line-do-insert)
("-kill" . command-line-do-kill)
;; Options like +35 are handled specially.
;; Window-system, site, or package-specific code might add to this.
;; X11 handles its options by letting Xt remove args from this list.
)
"Alist of command-line switches.
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'.")
;;; default switches
;;; Note: these doc strings are semi-magical.
(defun command-line-do-help (arg)
"Print the SXEmacs usage message and exit."
(let ((standard-output 'external-debugging-output))
(princ (concat "\n" (emacs-version) "\n\n"))
(princ
(if (featurep 'x)
(concat "When creating a window on an X display, "
(emacs-name)
" accepts all standard X Toolkit
command line options plus the following:
-iconname
Use title as the icon name.
-mc Use color as the mouse color.
-cr Use color as the text-cursor foregound color.
-private Install a private colormap.
In addition, the")
"The"))
(princ " following options are accepted:
-sd Show dump ID. Ignored when configured without --pdump.
-nd Don't load the dump file. Roughly like old temacs.
Ignored when configured without --pdump.
-t Use TTY instead of the terminal for input
and output. This implies the -nw option.
-nw Inhibit the use of any window-system-specific
display code: use the current tty.
-batch Execute noninteractively (messages go to stderr).
-debug-init Enter the debugger if an error in the init file occurs.
-unmapped Do not map the initial frame.
-no-site-file Do not load the site-specific init file (site-start.el).
-no-init-file Do not load the user-specific init file.
-no-early-packages Do not process early packages.
-no-autoloads Do not load global symbol files (auto-autoloads) at
startup. Also implies `-vanilla'.
-vanilla Equivalent to -q -no-site-file -no-early-packages.
-q Same as -no-init-file.
-user-init-file Use as init file.
-user-init-directory Use as init directory.
-user-pkgs-directory Use as the top of the local (early)
packages tree.
-user Load user's init file instead of your own.
Probably not a wise thing to do.
-u Same as -user.\n")
(let ((l command-switch-alist)
(insert (lambda (&rest x)
(princ " ")
(let ((len 2))
(while x
(princ (car x))
(incf len (length (car x)))
(setq x (cdr x)))
(when (>= len 24)
(terpri) (setq len 0))
(while (< len 24)
(princ " ")
(incf len))))))
(while l
(let ((name (car (car l)))
(fn (cdr (car l)))
doc arg cons)
(cond
((and (symbolp fn) (get fn 'undocumented)) nil)
(t
(setq doc (documentation fn))
(if (member doc '(nil "")) (setq doc "(undocumented)"))
(cond ((string-match "\n\\(<.*>\\)\n?\\'" doc)
;; Doc of the form "The frobber switch\n "
(setq arg (substring doc (match-beginning 1) (match-end 1))
doc (substring doc 0 (match-beginning 0))))
((string-match "\n+\\'" doc)
(setq doc (substring doc 0 (match-beginning 0)))))
(if (and (setq cons (rassq fn command-switch-alist))
(not (eq cons (car l))))
(setq doc (format "Same as %s." (car cons))))
(if arg
(funcall insert name " " arg)
(funcall insert name))
(princ doc)
(terpri))))
(setq l (cdr l))))
(princ (concat "+N Start displaying at line N.
Anything else is considered a file name, and is placed into a buffer for
editing.
" (emacs-name) " has an online tutorial and manuals. Type ^Ht (Control-h t) after
starting SXEmacs to run the tutorial. Type ^Hi to enter the manual browser.
Type ^H^H^H (Control-h Control-h Control-h) to get more help options.\n")
(kill-emacs 0))))
(defun command-line-do-funcall (arg)
"Invoke the named lisp function with no arguments.
"
(funcall (intern (pop command-line-args-left))))
(fset 'command-line-do-funcall-1 'command-line-do-funcall)
(put 'command-line-do-funcall-1 'undocumented t)
(defun command-line-do-eval (arg)
"Evaluate the lisp form. Quote it carefully.