Include interactive-only information in describe-function output
[bpt/emacs.git] / lisp / files.el
index f9ff3c9..a17677b 100644 (file)
@@ -1,8 +1,8 @@
 ;;; files.el --- file input and output commands for Emacs  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1985-1987, 1992-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1987, 1992-2014 Free Software Foundation, Inc.
 
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Package: emacs
 
 ;; This file is part of GNU Emacs.
@@ -96,9 +96,9 @@ The choice of renaming or copying is controlled by the variables
 ;; Do this so that local variables based on the file name
 ;; are not overridden by the major mode.
 (defvar backup-inhibited nil
-  "Non-nil means don't make a backup, regardless of the other parameters.
-This variable is intended for use by making it local to a buffer.
-But it is local only if you make it local.")
+  "If non-nil, backups will be inhibited.
+This variable is intended for use by making it local to a buffer,
+but it is not an automatically buffer-local variable.")
 (put 'backup-inhibited 'permanent-local t)
 
 (defcustom backup-by-copying nil
@@ -159,9 +159,11 @@ under another name, you get the existing buffer instead of a new buffer."
   :group 'find-file)
 
 (defcustom find-file-visit-truename nil
-  "Non-nil means visit a file under its truename.
-The truename of a file is found by chasing all links
-both at the file level and at the levels of the containing directories."
+  "Non-nil means visiting a file uses its truename as the visited-file name.
+That is, the buffer visiting the file has the truename as the
+value of `buffer-file-name'.  The truename of a file is found by
+chasing all links both at the file level and at the levels of the
+containing directories."
   :type 'boolean
   :group 'find-file)
 (put 'find-file-visit-truename 'safe-local-variable 'booleanp)
@@ -248,10 +250,12 @@ See also: `break-hardlink-on-save'."
   :group 'backup)
 
 (defcustom break-hardlink-on-save nil
-  "Non-nil means when saving a file that exists under several names
-\(i.e., has multiple hardlinks), break the hardlink associated with
-`buffer-file-name' and write to a new file, so that the other
-instances of the file are not affected by the save.
+  "Whether to allow breaking hardlinks when saving files.
+If non-nil, then when saving a file that exists under several
+names \(i.e., has multiple hardlinks), break the hardlink
+associated with `buffer-file-name' and write to a new file, so
+that the other instances of the file are not affected by the
+save.
 
 If `buffer-file-name' refers to a symlink, do not break the symlink.
 
@@ -743,8 +747,8 @@ The path separator is colon in GNU and GNU-like systems."
 
 (defun locate-file (filename path &optional suffixes predicate)
   "Search for FILENAME through PATH.
-If found, return the absolute file name of FILENAME, with its suffixes;
-otherwise return nil.
+If found, return the absolute file name of FILENAME; otherwise
+return nil.
 PATH should be a list of directories to look in, like the lists in
 `exec-path' or `load-path'.
 If SUFFIXES is non-nil, it should be a list of suffixes to append to
@@ -916,6 +920,57 @@ which we're looking."
              (setq file nil))))
     (if root (file-name-as-directory root))))
 
+(defcustom user-emacs-directory-warning t
+  "Non-nil means warn if cannot access `user-emacs-directory'.
+Set this to nil at your own risk..."
+  :type 'boolean
+  :group 'initialization
+  :version "24.4")
+
+(defun locate-user-emacs-file (new-name &optional old-name)
+  "Return an absolute per-user Emacs-specific file name.
+If NEW-NAME exists in `user-emacs-directory', return it.
+Else if OLD-NAME is non-nil and ~/OLD-NAME exists, return ~/OLD-NAME.
+Else return NEW-NAME in `user-emacs-directory', creating the
+directory if it does not exist."
+  (convert-standard-filename
+   (let* ((home (concat "~" (or init-file-user "")))
+         (at-home (and old-name (expand-file-name old-name home)))
+          (bestname (abbreviate-file-name
+                     (expand-file-name new-name user-emacs-directory))))
+     (if (and at-home (not (file-readable-p bestname))
+              (file-readable-p at-home))
+        at-home
+       ;; Make sure `user-emacs-directory' exists,
+       ;; unless we're in batch mode or dumping Emacs.
+       (or noninteractive
+          purify-flag
+          (let (errtype)
+            (if (file-directory-p user-emacs-directory)
+                (or (file-accessible-directory-p user-emacs-directory)
+                    (setq errtype "access"))
+              (let ((umask (default-file-modes)))
+                (unwind-protect
+                    (progn
+                      (set-default-file-modes ?\700)
+                      (condition-case nil
+                          (make-directory user-emacs-directory)
+                        (error (setq errtype "create"))))
+                  (set-default-file-modes umask))))
+            (when (and errtype
+                       user-emacs-directory-warning
+                       (not (get 'user-emacs-directory-warning 'this-session)))
+              ;; Only warn once per Emacs session.
+              (put 'user-emacs-directory-warning 'this-session t)
+              (display-warning 'initialization
+                               (format "\
+Unable to %s `user-emacs-directory' (%s).
+Any data that would normally be written there may be lost!
+If you never want to see this message again,
+customize the variable `user-emacs-directory-warning'."
+                                       errtype user-emacs-directory)))))
+       bestname))))
+
 
 (defun executable-find (command)
   "Search for COMMAND in `exec-path' and return the absolute file name.
@@ -1374,7 +1429,7 @@ You can visit files on remote machines by specifying something
 like /ssh:SOME_REMOTE_MACHINE:FILE for the file name.  You can
 also visit local files as a different user by specifying
 /sudo::FILE for the file name.
-See the Info node `(tramp)Filename Syntax' in the Tramp Info
+See the Info node `(tramp)File name Syntax' in the Tramp Info
 manual, for more about this.
 
 Interactively, or if WILDCARDS is non-nil in a call from Lisp,
@@ -1855,10 +1910,12 @@ the various files."
                              (eq read-only buffer-file-read-only)
                              (eq read-only buffer-read-only))
                    (when (or nowarn
-                             (let ((question
-                                    (format "File %s is %s on disk.  Change buffer mode? "
-                                            buffer-file-name
-                                            (if read-only "read-only" "writable"))))
+                             (let* ((new-status
+                                     (if read-only "read-only" "writable"))
+                                    (question
+                                     (format "File %s is %s on disk.  Make buffer %s, too? "
+                                             buffer-file-name
+                                             new-status new-status)))
                                (y-or-n-p question)))
                      (setq buffer-read-only read-only)))
                  (setq buffer-file-read-only read-only))
@@ -2032,6 +2089,7 @@ This function ensures that none of these modifications will take place."
 This function is meant for the user to run interactively.
 Don't call it from programs!  Use `insert-file-contents-literally' instead.
 \(Its calling sequence is different; see its documentation)."
+  (declare (interactive-only insert-file-contents-literally))
   (interactive "*fInsert file literally: ")
   (insert-file-1 filename #'insert-file-contents-literally))
 
@@ -2269,6 +2327,10 @@ since only a single case-insensitive search through the alist is made."
      ;; .PROCESSORNAME-gdbinit so that the host and target gdbinit files
      ;; don't interfere with each other.
      ("/\\.[a-z0-9-]*gdbinit" . gdb-script-mode)
+     ;; GDB 7.5 introduced OBJFILE-gdb.gdb script files; e.g. a file
+     ;; named 'emacs-gdb.gdb', if it exists, will be automatically
+     ;; loaded when GDB reads an objfile called 'emacs'.
+     ("-gdb\\.gdb" . gdb-script-mode)
      ("[cC]hange\\.?[lL]og?\\'" . change-log-mode)
      ("[cC]hange[lL]og[-.][0-9]+\\'" . change-log-mode)
      ("\\$CHANGE_LOG\\$\\.TXT" . change-log-mode)
@@ -2447,35 +2509,22 @@ and `magic-mode-alist', which determines modes based on file contents.")
   (mapcar
    (lambda (l)
      (cons (purecopy (car l)) (cdr l)))
-   '(("perl" . perl-mode)
-     ("perl5" . perl-mode)
-     ("miniperl" . perl-mode)
-     ("wish" . tcl-mode)
-     ("wishx" . tcl-mode)
-     ("tcl" . tcl-mode)
-     ("tclsh" . tcl-mode)
+   '(("\\(mini\\)?perl5?" . perl-mode)
+     ("wishx?" . tcl-mode)
+     ("tcl\\(sh\\)?" . tcl-mode)
      ("expect" . tcl-mode)
+     ("octave" . octave-mode)
      ("scm" . scheme-mode)
-     ("ash" . sh-mode)
-     ("bash" . sh-mode)
-     ("bash2" . sh-mode)
-     ("csh" . sh-mode)
-     ("dtksh" . sh-mode)
+     ("[acjkwz]sh" . sh-mode)
+     ("r?bash2?" . sh-mode)
+     ("dash" . sh-mode)
+     ("\\(dt\\|pd\\|w\\)ksh" . sh-mode)
      ("es" . sh-mode)
-     ("itcsh" . sh-mode)
-     ("jsh" . sh-mode)
-     ("ksh" . sh-mode)
+     ("i?tcsh" . sh-mode)
      ("oash" . sh-mode)
-     ("pdksh" . sh-mode)
-     ("rbash" . sh-mode)
      ("rc" . sh-mode)
      ("rpm" . sh-mode)
-     ("sh" . sh-mode)
-     ("sh5" . sh-mode)
-     ("tcsh" . sh-mode)
-     ("wksh" . sh-mode)
-     ("wsh" . sh-mode)
-     ("zsh" . sh-mode)
+     ("sh5?" . sh-mode)
      ("tail" . text-mode)
      ("more" . text-mode)
      ("less" . text-mode)
@@ -2486,9 +2535,10 @@ and `magic-mode-alist', which determines modes based on file contents.")
      ("emacs" . emacs-lisp-mode)))
   "Alist mapping interpreter names to major modes.
 This is used for files whose first lines match `auto-mode-interpreter-regexp'.
-Each element looks like (INTERPRETER . MODE).
-If INTERPRETER matches the name of the interpreter specified in the first line
-of a script, mode MODE is enabled.
+Each element looks like (REGEXP . MODE).
+If \\\\`REGEXP\\\\' matches the name (minus any directory part) of
+the interpreter specified in the first line of a script, enable
+major mode MODE.
 
 See also `auto-mode-alist'.")
 
@@ -2683,19 +2733,23 @@ we don't actually set it to the same mode the buffer already has."
     ;; If we didn't, look for an interpreter specified in the first line.
     ;; As a special case, allow for things like "#!/bin/env perl", which
     ;; finds the interpreter anywhere in $PATH.
-    (unless done
-      (setq mode (save-excursion
-                  (goto-char (point-min))
-                  (if (looking-at auto-mode-interpreter-regexp)
-                      (match-string 2)
-                    ""))
-           ;; Map interpreter name to a mode, signaling we're done at the
-           ;; same time.
-           done (assoc (file-name-nondirectory mode)
-                       interpreter-mode-alist))
-      ;; If we found an interpreter mode to use, invoke it now.
-      (if done
-         (set-auto-mode-0 (cdr done) keep-mode-if-same)))
+    (and (not done)
+        (setq mode (save-excursion
+                     (goto-char (point-min))
+                     (if (looking-at auto-mode-interpreter-regexp)
+                         (match-string 2))))
+        ;; Map interpreter name to a mode, signaling we're done at the
+        ;; same time.
+        (setq done (assoc-default
+                    (file-name-nondirectory mode)
+                    (mapcar (lambda (e)
+                               (cons
+                                (format "\\`%s\\'" (car e))
+                                (cdr e)))
+                            interpreter-mode-alist)
+                    #'string-match-p))
+        ;; If we found an interpreter mode to use, invoke it now.
+        (set-auto-mode-0 done keep-mode-if-same))
     ;; Next try matching the buffer beginning against magic-mode-alist.
     (unless done
       (if (setq done (save-excursion
@@ -3159,6 +3213,9 @@ DIR-NAME is the name of the associated directory.  Otherwise it is nil."
                   (assq-delete-all (car elt) file-local-variables-alist)))
           (push elt file-local-variables-alist)))))
 
+;; TODO?  Warn once per file rather than once per session?
+(defvar hack-local-variables--warned-lexical nil)
+
 (defun hack-local-variables (&optional mode-only)
   "Parse and put into effect this buffer's local variables spec.
 Uses `hack-local-variables-apply' to apply the variables.
@@ -3280,13 +3337,21 @@ local variables, but directory-local variables may still be applied."
                                     "-minor\\'"
                                     (setq val2 (downcase (symbol-name val)))))
                               (setq result (intern (concat val2 "-mode"))))
-                       (unless (eq var 'coding)
-                         (condition-case nil
-                             (push (cons (if (eq var 'eval)
-                                             'eval
-                                           (indirect-variable var))
-                                         val) result)
-                           (error nil)))))
+                       (cond ((eq var 'coding))
+                             ((eq var 'lexical-binding)
+                              (unless hack-local-variables--warned-lexical
+                                (setq hack-local-variables--warned-lexical t)
+                                (display-warning
+                                  :warning
+                                  (format "%s: `lexical-binding' at end of file unreliable"
+                                          (file-name-nondirectory
+                                           (or buffer-file-name ""))))))
+                             (t
+                              (ignore-errors
+                                (push (cons (if (eq var 'eval)
+                                                'eval
+                                              (indirect-variable var))
+                                            val) result))))))
                    (forward-line 1))))))))
       ;; Now we've read all the local variables.
       ;; If MODE-ONLY is non-nil, return whether the mode was specified.
@@ -3647,21 +3712,17 @@ FILE is the name of the file holding the variables to apply.
 The new class name is the same as the directory in which FILE
 is found.  Returns the new class name."
   (with-temp-buffer
-    ;; This is with-demoted-errors, but we want to mention dir-locals
-    ;; in any error message.
-    (condition-case err
-        (progn
-          (insert-file-contents file)
-          (unless (zerop (buffer-size))
-            (let* ((dir-name (file-name-directory file))
-                   (class-name (intern dir-name))
-                   (variables (let ((read-circle nil))
-                                (read (current-buffer)))))
-              (dir-locals-set-class-variables class-name variables)
-              (dir-locals-set-directory-class dir-name class-name
-                                              (nth 5 (file-attributes file)))
-              class-name)))
-      (error (message "Error reading dir-locals: %S" err) nil))))
+    (with-demoted-errors "Error reading dir-locals: %S"
+      (insert-file-contents file)
+      (unless (zerop (buffer-size))
+        (let* ((dir-name (file-name-directory file))
+               (class-name (intern dir-name))
+               (variables (let ((read-circle nil))
+                            (read (current-buffer)))))
+          (dir-locals-set-class-variables class-name variables)
+          (dir-locals-set-directory-class dir-name class-name
+                                          (nth 5 (file-attributes file)))
+          class-name)))))
 
 (defcustom enable-remote-dir-locals nil
   "Non-nil means dir-local variables will be applied to remote files."
@@ -4416,6 +4477,8 @@ Uses `backup-directory-alist' in the same way as does
   "Convert FILENAME to be relative to DIRECTORY (default: `default-directory').
 This function returns a relative file name which is equivalent to FILENAME
 when used with that default directory as the default.
+If FILENAME is a relative file name, it will be interpreted as existing in
+`default-directory'.
 If FILENAME and DIRECTORY lie on different machines or on different drives
 on a DOS/Windows machine, it returns FILENAME in expanded form."
   (save-match-data
@@ -4480,7 +4543,7 @@ on a DOS/Windows machine, it returns FILENAME in expanded form."
             ;; We matched FILENAME's directory equivalent.
             ancestor))))))
 \f
-(defun save-buffer (&optional args)
+(defun save-buffer (&optional arg)
   "Save current buffer in visited file if modified.
 Variations are described below.
 
@@ -4494,7 +4557,7 @@ Prefixed with three \\[universal-argument]'s, marks this version
  to become a backup when the next save is done,
  and unconditionally makes the previous version into a backup file.
 
-With a numeric argument of 0, never make the previous version
+With a numeric prefix argument of 0, never make the previous version
 into a backup file.
 
 If a file's name is FOO, the names of its numbered backup versions are
@@ -4518,9 +4581,9 @@ If `vc-make-backup-files' is nil, which is the default,
 See the subroutine `basic-save-buffer' for more information."
   (interactive "p")
   (let ((modp (buffer-modified-p))
-       (make-backup-files (or (and make-backup-files (not (eq args 0)))
-                              (memq args '(16 64)))))
-    (and modp (memq args '(16 64)) (setq buffer-backed-up nil))
+       (make-backup-files (or (and make-backup-files (not (eq arg 0)))
+                              (memq arg '(16 64)))))
+    (and modp (memq arg '(16 64)) (setq buffer-backed-up nil))
     ;; We used to display the message below only for files > 50KB, but
     ;; then Rmail-mbox never displays it due to buffer swapping.  If
     ;; the test is ever re-introduced, be sure to handle saving of
@@ -4528,7 +4591,7 @@ See the subroutine `basic-save-buffer' for more information."
     (if (and modp (buffer-file-name))
        (message "Saving file %s..." (buffer-file-name)))
     (basic-save-buffer)
-    (and modp (memq args '(4 64)) (setq buffer-backed-up nil))))
+    (and modp (memq arg '(4 64)) (setq buffer-backed-up nil))))
 
 (defun delete-auto-save-file-if-necessary (&optional force)
   "Delete auto-save file for current buffer if `delete-auto-save-files' is t.
@@ -4936,6 +4999,7 @@ With prefix ARG, mark buffer as modified, so \\[save-buffer] will save.
 
 It is not a good idea to use this function in Lisp programs, because it
 prints a message in the minibuffer.  Instead, use `set-buffer-modified-p'."
+  (declare (interactive-only set-buffer-modified-p))
   (interactive "P")
   (message (if arg "Modification-flag set"
               "Modification-flag cleared"))
@@ -4955,6 +5019,7 @@ Set mark after the inserted text.
 This function is meant for the user to run interactively.
 Don't call it from programs!  Use `insert-file-contents' instead.
 \(Its calling sequence is different; see its documentation)."
+  (declare (interactive-only insert-file-contents))
   (interactive "*fInsert file: ")
   (insert-file-1 filename #'insert-file-contents))
 
@@ -5516,7 +5581,7 @@ non-nil, it is called instead of rereading visited file contents."
             (insert-file-contents file-name nil)
             (set-buffer-file-coding-system coding-system))
           (after-find-file nil nil t))
-         (t (user-error "Recover-file cancelled")))))
+         (t (user-error "Recover-file canceled")))))
 
 (defun recover-session ()
   "Recover auto save files from a previous Emacs session.
@@ -6438,10 +6503,11 @@ the low level primitive, does not.  See also `kill-emacs-hook'.")
 (defcustom confirm-kill-emacs nil
   "How to ask for confirmation when leaving Emacs.
 If nil, the default, don't ask at all.  If the value is non-nil, it should
-be a predicate function such as `yes-or-no-p'."
+be a predicate function; for example `yes-or-no-p'."
   :type '(choice (const :tag "Ask with yes-or-no-p" yes-or-no-p)
                 (const :tag "Ask with y-or-n-p" y-or-n-p)
-                (const :tag "Don't confirm" nil))
+                (const :tag "Don't confirm" nil)
+                (function :tag "Predicate function"))
   :group 'convenience
   :version "21.1")
 
@@ -6469,7 +6535,7 @@ if any returns nil.  If `confirm-kill-emacs' is non-nil, calls it."
                    (setq active t))
               (setq processes (cdr processes)))
             (or (not active)
-                (with-temp-buffer-window
+                (with-current-buffer-window
                  (get-buffer-create "*Process List*") nil
                  #'(lambda (window _value)
                      (with-selected-window window