]> code.delx.au - gnu-emacs/blobdiff - lisp/startup.el
* lisp/net/tramp-gvfs.el (tramp-gvfs-mount-spec): Fix typo.
[gnu-emacs] / lisp / startup.el
index 0da2e14199e792b744c90228645aeb49d53edbc7..761e69e03b1da8a6d833cb56806d101b0533393b 100644 (file)
@@ -1,6 +1,6 @@
 ;;; startup.el --- process Emacs shell arguments  -*- lexical-binding: t -*-
 
-;; Copyright (C) 1985-1986, 1992, 1994-2015 Free Software Foundation,
+;; Copyright (C) 1985-1986, 1992, 1994-2016 Free Software Foundation,
 ;; Inc.
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -76,17 +76,28 @@ once you are familiar with the contents of the startup screen."
 
 (defvar startup-screen-inhibit-startup-screen nil)
 
-;; FIXME? Why does this get such weirdly extreme treatment, when the
-;; more important inhibit-startup-screen does not.
+;; The mechanism used to ensure that only end users can disable this
+;; message is not complex.  Clearly, it is possible for a determined
+;; system administrator to inhibit this message anyway, but at least
+;; they will do so with knowledge of why the Emacs developers think
+;; this is a bad idea.
 (defcustom inhibit-startup-echo-area-message nil
   "Non-nil inhibits the initial startup echo area message.
-Setting this variable takes effect
-only if you do it with the customization buffer
-or if your init file contains a line of this form:
+
+The startup message is in the echo area as it provides information
+about GNU Emacs and the GNU system in general, which we want all
+users to see.  As this is the least intrusive startup message,
+this variable gets specialized treatment to prevent the message
+from being disabled site-wide by systems administrators, while
+still allowing individual users to do so.
+
+Setting this variable takes effect only if you do it with the
+customization buffer or if your init file contains a line of this
+form:
  (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")
 If your init file is byte-compiled, use the following form
 instead:
- (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
+ (eval \\='(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
 Thus, someone else using a copy of your init file will see the
 startup message unless he personally acts to inhibit it."
   :type '(choice (const :tag "Don't inhibit")
@@ -114,7 +125,7 @@ the remaining command-line args are in the variable `command-line-args-left'.")
 
 (defvaralias 'argv 'command-line-args-left
   "List of command-line args not yet processed.
-This is a convenience alias, so that one can write \(pop argv\)
+This is a convenience alias, so that one can write \(pop argv)
 inside of --eval command line arguments in order to access
 following arguments.")
 (internal-make-var-non-special 'argv)
@@ -360,7 +371,7 @@ this variable usefully is to set it while building and dumping Emacs."
   :group 'initialization
   :initialize #'custom-initialize-default
   :set (lambda (_variable _value)
-         (error "Customizing ‘site-run-file’ does not work")))
+         (error "Customizing `site-run-file' does not work")))
 
 (make-obsolete-variable 'system-name "use (system-name) instead" "25.1")
 
@@ -428,7 +439,7 @@ Warning Warning!!!  Pure space overflow    !!!Warning Warning
   :initialize #'custom-initialize-delay)
 
 (defun normal-top-level-add-subdirs-to-load-path ()
-  "Add all subdirectories of `default-directory' to `load-path'.
+  "Recursively add all subdirectories of `default-directory' to `load-path'.
 More precisely, this uses only the subdirectories whose names
 start with letters or digits; it excludes any subdirectory named `RCS'
 or `CVS', and any subdirectory that contains a file named `.nosearch'."
@@ -544,7 +555,11 @@ It is the default value of the variable `top-level'."
            (set-buffer elt)
            (if default-directory
                (setq default-directory
-                     (decode-coding-string default-directory coding t)))))
+                      (if (eq system-type 'windows-nt)
+                          ;; Convert backslashes to forward slashes.
+                          (expand-file-name
+                           (decode-coding-string default-directory coding t))
+                        (decode-coding-string default-directory coding t))))))
 
        ;; Decode all the important variables and directory lists, now
        ;; that we know the locale's encoding.  This is because the
@@ -720,7 +735,7 @@ Window system startup files should add their own function to this
 method, which should parse the command line arguments.  Those
 pertaining to the window system should be processed and removed
 from the returned command line.")
-(cl-defmethod handle-args-function (args &context (window-system (eql nil)))
+(cl-defmethod handle-args-function (args &context (window-system nil))
   (tty-handle-args args))
 
 (cl-defgeneric window-system-initialization (&optional _display)
@@ -752,7 +767,7 @@ to prepare for opening the first frame (e.g. open a connection to an X server)."
                (let ((elt (assoc completion tty-long-option-alist)))
                  ;; Check for abbreviated long option.
                  (or elt
-                     (error "Option ‘%s’ is ambiguous" argi))
+                     (error "Option `%s' is ambiguous" argi))
                  (setq argi (cdr elt)))
              ;; Check for a short option.
              (setq argval nil
@@ -803,6 +818,62 @@ to prepare for opening the first frame (e.g. open a connection to an X server)."
 (defvar server-name)
 (defvar server-process)
 
+(defun startup--setup-quote-display (&optional style)
+  "If needed, display ASCII approximations to curved quotes.
+Do this by modifying `standard-display-table'.  Optional STYLE
+specifies the desired quoting style, as in `text-quoting-style'.
+If STYLE is nil, display appropriately for the terminal."
+  (let ((repls (let ((style-repls (assq style '((grave . "`'\"\"")
+                                                (straight . "''\"\"")))))
+                 (if style-repls (cdr style-repls) (make-vector 4 nil))))
+        glyph-count)
+    ;; REPLS is a sequence of the four replacements for "‘’“”", respectively.
+    ;; If STYLE is nil, infer REPLS from terminal characteristics.
+    (unless style
+      ;; On a terminal that supports glyph codes,
+      ;; GLYPH-COUNT[i] is the number of times that glyph code I
+      ;; represents either an ASCII character or one of the 4
+      ;; quote characters.  This assumes glyph codes are valid
+      ;; Elisp characters, which is a safe assumption in practice.
+      (when (integerp (internal-char-font nil (max-char)))
+        (setq glyph-count (make-char-table nil 0))
+        (dotimes (i 132)
+          (let ((glyph (internal-char-font
+                        nil (if (< i 128) i (aref "‘’“”" (- i 128))))))
+            (when (<= 0 glyph)
+              (aset glyph-count glyph (1+ (aref glyph-count glyph)))))))
+      (dotimes (i 2)
+        (let ((lq (aref "‘“" i)) (rq (aref "’”" i))
+              (lr (aref "`\"" i)) (rr (aref "'\"" i))
+              (i2 (* i 2)))
+          (unless (if glyph-count
+                      ;; On a terminal that supports glyph codes, use
+                      ;; ASCII replacements unless both quotes are displayable.
+                      ;; If not using ASCII replacements, highlight
+                      ;; quotes unless they are both unique among the
+                      ;; 128 + 4 characters of concern.
+                      (let ((lglyph (internal-char-font nil lq))
+                            (rglyph (internal-char-font nil rq)))
+                        (when (and (<= 0 lglyph) (<= 0 rglyph))
+                          (setq lr lq rr rq)
+                          (and (= 1 (aref glyph-count lglyph))
+                               (= 1 (aref glyph-count rglyph)))))
+                    ;; On a terminal that does not support glyph codes, use
+                    ;; ASCII replacements unless both quotes are displayable.
+                    (and (char-displayable-p lq)
+                         (char-displayable-p rq)))
+            (aset repls i2 lr)
+            (aset repls (1+ i2) rr)))))
+    (dotimes (i 4)
+      (let ((char (aref "‘’“”" i))
+            (repl (aref repls i)))
+        (if repl
+            (aset (or standard-display-table
+                      (setq standard-display-table (make-display-table)))
+                  char (vector (make-glyph-code repl 'escape-glyph)))
+          (when standard-display-table
+            (aset standard-display-table char nil)))))))
+
 (defun command-line ()
   "A subroutine of `normal-top-level'.
 Amongst another things, it parses the command-line arguments."
@@ -902,7 +973,7 @@ please check its value")
                  ((stringp completion)
                   (let ((elt (assoc completion longopts)))
                     (unless elt
-                      (error "Option ‘%s’ is ambiguous" argi))
+                      (error "Option `%s' is ambiguous" argi))
                     (setq argi (substring (car elt) 1))))
                  (t
                   (setq argval nil
@@ -945,7 +1016,7 @@ please check its value")
           (setq done t)))
        ;; Was argval set but not used?
        (and argval
-            (error "Option ‘%s’ doesn't allow an argument" argi))))
+            (error "Option `%s' doesn't allow an argument" argi))))
 
     ;; Re-attach the --display arg.
     (and display-arg (setq args (append display-arg args)))
@@ -964,7 +1035,7 @@ please check its value")
               (not (featurep
                     (intern
                      (concat (symbol-name initial-window-system) "-win")))))
-         (error "Unsupported window system ‘%s’" initial-window-system))
+         (error "Unsupported window system `%s'" initial-window-system))
       ;; Process window-system specific command line parameters.
       (setq command-line-args
             (let ((window-system initial-window-system)) ;Hack attack!
@@ -1017,13 +1088,9 @@ please check its value")
                                '("no" "off" "false" "0")))))
     (setq no-blinking-cursor t))
 
-  ;; If curved quotes don't work, display ASCII approximations.
-  (dolist (char-repl '((?‘ . [?\`]) (?’ . [?\']) (?“ . [?\"]) (?” . [?\"])))
-    (when (not (char-displayable-p (car char-repl)))
-      (or standard-display-table
-          (setq standard-display-table (make-display-table)))
-      (aset standard-display-table (car char-repl) (cdr char-repl))))
-  (setq internal--text-quoting-flag t)
+  (unless noninteractive
+    (startup--setup-quote-display)
+    (setq internal--text-quoting-flag t))
 
   ;; Re-evaluate predefined variables whose initial value depends on
   ;; the runtime context.
@@ -1179,10 +1246,10 @@ please check its value")
             (display-warning
              'initialization
              (format-message "\
-An error occurred while loading ‘%s’:\n\n%s%s%s\n\n\
+An error occurred while loading `%s':\n\n%s%s%s\n\n\
 To ensure normal operation, you should investigate and remove the
 cause of the error in your initialization file.  Start Emacs with
-the ‘--debug-init’ option to view a complete error backtrace."
+the `--debug-init' option to view a complete error backtrace."
                      user-init-file
                      (get (car error) 'error-message)
                      (if (cdr error) ": " "")
@@ -1315,8 +1382,8 @@ the ‘--debug-init’ option to view a complete error backtrace."
           (setq warned t)
           (display-warning 'initialization
                            (format-message "\
-Your ‘load-path’ seems to contain\n\
-your ‘.emacs.d’ directory: %s\n\
+Your `load-path' seems to contain\n\
+your `.emacs.d' directory: %s\n\
 This is likely to cause problems...\n\
 Consider using a subdirectory instead, e.g.: %s"
                                     dir (expand-file-name
@@ -1374,12 +1441,11 @@ settings will be marked as \"CHANGED outside of Customize\"."
       (put 'cursor 'face-modified t))))
 
 (defcustom initial-scratch-message (purecopy "\
-;; This buffer is for notes you don't want to save, and for Lisp evaluation.
-;; If you want to create a file, visit that file with C-x C-f,
-;; then enter the text in that file's own buffer.
+;; This buffer is for text that is not saved, and for Lisp evaluation.
+;; To create a file, visit it with \\[find-file] and enter text in its buffer.
 
 ")
-  "Initial message displayed in *scratch* buffer at startup.
+  "Initial documentation displayed in *scratch* buffer at startup.
 If this is nil, no message will be displayed."
   :type '(choice (text :tag "Message")
                 (const :tag "none" nil))
@@ -1824,10 +1890,12 @@ we put it on this frame."
       (when frame
        (let* ((img (create-image (fancy-splash-image-file)))
               (image-height (and img (cdr (image-size img nil frame))))
-              ;; We test frame-height so that, if the frame is split
-              ;; by displaying a warning, that doesn't cause the normal
-              ;; splash screen to be used.
-              (frame-height (1- (frame-height frame))))
+              ;; We test frame-height and not window-height so that,
+              ;; if the frame is split by displaying a warning, that
+              ;; doesn't cause the normal splash screen to be used.
+              ;; We subtract 2 from frame-height to account for the
+              ;; echo area and the mode line.
+              (frame-height (- (frame-height frame) 2)))
          (> frame-height (+ image-height 19)))))))
 
 
@@ -1886,7 +1954,7 @@ splash screen in another window."
                                   auto-save-list-file-prefix)))
            t)
           (insert "\n\nIf an Emacs session crashed recently, "
-                  "type Meta-x recover-session RET\nto recover"
+                  "type M-x recover-session RET\nto recover"
                   " the files you were editing.\n"))
 
       (use-local-map splash-screen-keymap)
@@ -1918,7 +1986,7 @@ To quit a partially entered command, type Control-g.\n")
                 'action (lambda (_button) (info-emacs-manual))
                 'follow-link t)
   (insert "\tView the Emacs manual using Info\n")
-  (insert-button "\(Non)Warranty"
+  (insert-button "(Non)Warranty"
                 'action (lambda (_button) (describe-no-warranty))
                 'follow-link t)
   (insert "\t\tGNU Emacs comes with ABSOLUTELY NO WARRANTY\n")
@@ -1935,7 +2003,8 @@ To quit a partially entered command, type Control-g.\n")
   (insert-button "Visit New File"
                 'action (lambda (_button) (call-interactively 'find-file))
                 'follow-link t)
-  (insert "\t\tSpecify a new file's name, to edit the file\n")
+  (insert (substitute-command-keys
+          "\t\tSpecify a new file's name, to edit the file\n"))
   (insert-button "Open Home Directory"
                 'action (lambda (_button) (dired "~"))
                 'follow-link t)
@@ -2001,9 +2070,9 @@ To quit a partially entered command, type Control-g.\n")
     (insert (substitute-command-keys "   \\[tmm-menubar]")))
 
   ;; Many users seem to have problems with these.
-  (insert "
+  (insert (substitute-command-keys "
 \(`C-' means use the CTRL key.  `M-' means use the Meta (or Alt) key.
-If you have no Meta key, you may instead type ESC followed by the character.)")
+If you have no Meta key, you may instead type ESC followed by the character.)"))
 
   ;; Insert links to useful tasks
   (insert "\nUseful tasks:\n")
@@ -2264,7 +2333,7 @@ nil default-directory" name)
                     (if (stringp completion)
                         (let ((elt (member completion longopts)))
                           (or elt
-                              (error "Option ‘%s’ is ambiguous" argi))
+                              (error "Option `%s' is ambiguous" argi))
                           (setq argi (substring (car elt) 1)))
                       (setq argval nil
                             argi orig-argi)))))
@@ -2334,7 +2403,7 @@ nil default-directory" name)
                      (setq inhibit-startup-screen t)
                      (setq tem (or argval (pop command-line-args-left)))
                      (or (stringp tem)
-                         (error "File name omitted from ‘-insert’ option"))
+                         (error "File name omitted from `-insert' option"))
                      (insert-file-contents (command-line-normalize-file-name tem)))
 
                     ((equal argi "-kill")
@@ -2369,7 +2438,7 @@ nil default-directory" name)
                      ;; An explicit option to specify visiting a file.
                      (setq tem (or argval (pop command-line-args-left)))
                      (unless (stringp tem)
-                       (error "File name omitted from ‘%s’ option" argi))
+                       (error "File name omitted from `%s' option" argi))
                      (funcall process-file-arg tem))
 
                     ;; These command lines now have no effect.
@@ -2390,7 +2459,7 @@ nil default-directory" name)
                        (unless did-hook
                          ;; Presume that the argument is a file name.
                          (if (string-match "\\`-" argi)
-                             (error "Unknown option ‘%s’" argi))
+                             (error "Unknown option `%s'" argi))
                          ;; FIXME: Why do we only inhibit the startup
                          ;; screen for -nw?
                          (unless initial-window-system
@@ -2414,7 +2483,7 @@ nil default-directory" name)
         (get-buffer "*scratch*")
         (with-current-buffer "*scratch*"
           (when (zerop (buffer-size))
-            (insert initial-scratch-message)
+            (insert (substitute-command-keys initial-scratch-message))
             (set-buffer-modified-p nil))))
 
     ;; Prepend `initial-buffer-choice' to `displayable-buffers'.