(ldap-search-internal): Skip error message from ldapsearch. Allow listing
[bpt/emacs.git] / lisp / files.el
index 20bd88f..ff47462 100644 (file)
@@ -312,8 +312,9 @@ editing a remote file."
   :version "21.1")
 
 (defcustom save-abbrevs t
-  "*Non-nil means save word abbrevs too when files are saved."
-  :type 'boolean
+  "*Non-nil means save word abbrevs too when files are saved.
+If `silently', don't ask the user before saving."
+  :type '(choice (const t) (const nil) (const silently))
   :group 'abbrev)
 
 (defcustom find-file-run-dired t
@@ -1575,66 +1576,31 @@ If the optional argument JUST-FROM-FILE-NAME is non-nil,
 then we do not set anything but the major mode,
 and we don't even do that unless it would come from the file name."
   ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
-  (let (beg end done modes)
+  (let (end done modes)
     (save-excursion
       (goto-char (point-min))
       (skip-chars-forward " \t\n")
       (and enable-local-variables
-          ;; Don't look for -*- if this file name matches any
-          ;; of the regexps in inhibit-first-line-modes-regexps.
-          (let ((temp inhibit-first-line-modes-regexps)
-                (name (if buffer-file-name
-                          (file-name-sans-versions buffer-file-name)
-                        (buffer-name))))
-            (while (let ((sufs inhibit-first-line-modes-suffixes))
-                     (while (and sufs (not (string-match (car sufs) name)))
-                       (setq sufs (cdr sufs)))
-                     sufs)
-              (setq name (substring name 0 (match-beginning 0))))
-            (while (and temp
-                        (not (string-match (car temp) name)))
-              (setq temp (cdr temp)))
-            (not temp))
-          (search-forward "-*-" (save-excursion
-                                  ;; If the file begins with "#!"
-                                  ;; (exec interpreter magic), look
-                                  ;; for mode frobs in the first two
-                                  ;; lines.  You cannot necessarily
-                                  ;; put them in the first line of
-                                  ;; such a file without screwing up
-                                  ;; the interpreter invocation.
-                                  (end-of-line (and (looking-at "^#!") 2))
-                                  (point)) t)
-          (progn
-            (skip-chars-forward " \t")
-            (setq beg (point))
-            (search-forward "-*-"
-                            (save-excursion (end-of-line) (point))
-                            t))
-          (progn
-            (forward-char -3)
-            (skip-chars-backward " \t")
-            (setq end (point))
-            (goto-char beg)
-            (if (save-excursion (search-forward ":" end t))
-                ;; Find all specifications for the `mode:' variable
-                ;; and execute them left to right.
-                (while (let ((case-fold-search t))
-                         (or (and (looking-at "mode:")
-                                  (goto-char (match-end 0)))
-                             (re-search-forward "[ \t;]mode:" end t)))
-                  (skip-chars-forward " \t")
-                  (setq beg (point))
+          (setq end (set-auto-mode-1))
+          (if (save-excursion (search-forward ":" end t))
+              ;; Find all specifications for the `mode:' variable
+              ;; and execute them left to right.
+              (while (let ((case-fold-search t))
+                       (or (and (looking-at "mode:")
+                                (goto-char (match-end 0)))
+                           (re-search-forward "[ \t;]mode:" end t)))
+                (skip-chars-forward " \t")
+                (let ((beg (point)))
                   (if (search-forward ";" end t)
                       (forward-char -1)
                     (goto-char end))
                   (skip-chars-backward " \t")
                   (push (intern (concat (downcase (buffer-substring beg (point))) "-mode"))
-                        modes))
-              ;; Simple -*-MODE-*- case.
-              (push (intern (concat (downcase (buffer-substring beg end))
-                                    "-mode"))
-                    modes)))))
+                        modes)))
+            ;; Simple -*-MODE-*- case.
+            (push (intern (concat (downcase (buffer-substring (point) end))
+                                  "-mode"))
+                  modes))))
     ;; If we found modes to use, invoke them now,
     ;; outside the save-excursion.
     (unless just-from-file-name
@@ -1692,6 +1658,54 @@ and we don't even do that unless it would come from the file name."
                    (if elt
                        (funcall (cdr elt))))))))))))
 
+
+(defun set-auto-mode-1 ()
+  "Find the -*- spec in the buffer.
+Call with point at the place to start searching from.
+If one is found, set point to the beginning
+and return the position of the end.
+Otherwise, return nil; point may be changed."
+  (let (beg end)
+    (and
+     ;; Don't look for -*- if this file name matches any
+     ;; of the regexps in inhibit-first-line-modes-regexps.
+     (let ((temp inhibit-first-line-modes-regexps)
+          (name (if buffer-file-name
+                    (file-name-sans-versions buffer-file-name)
+                  (buffer-name))))
+       (while (let ((sufs inhibit-first-line-modes-suffixes))
+               (while (and sufs (not (string-match (car sufs) name)))
+                 (setq sufs (cdr sufs)))
+               sufs)
+        (setq name (substring name 0 (match-beginning 0))))
+       (while (and temp
+                  (not (string-match (car temp) name)))
+        (setq temp (cdr temp)))
+       (not temp))
+
+     (search-forward "-*-" (save-excursion
+                            ;; If the file begins with "#!"
+                            ;; (exec interpreter magic), look
+                            ;; for mode frobs in the first two
+                            ;; lines.  You cannot necessarily
+                            ;; put them in the first line of
+                            ;; such a file without screwing up
+                            ;; the interpreter invocation.
+                            (end-of-line (and (looking-at "^#!") 2))
+                            (point)) t)
+     (progn
+       (skip-chars-forward " \t")
+       (setq beg (point))
+       (search-forward "-*-"
+                      (save-excursion (end-of-line) (point))
+                      t))
+     (progn
+       (forward-char -3)
+       (skip-chars-backward " \t")
+       (setq end (point))
+       (goto-char beg)
+       end))))
+
 (defun hack-local-variables-prop-line ()
   "Set local variables specified in the -*- line.
 Ignore any specification for `mode:' and `coding:';
@@ -1700,12 +1714,11 @@ Ignore any specification for `mode:' and `coding:';
   (save-excursion
     (goto-char (point-min))
     (let ((result nil)
-         (end (save-excursion (end-of-line (and (looking-at "^#!") 2)) (point)))
+         (end (set-auto-mode-1))
          (enable-local-variables
           (and local-enable-local-variables enable-local-variables)))
       ;; Parse the -*- line into the `result' alist.
-      (cond ((not (search-forward "-*-" end t))
-            ;; doesn't have one.
+      (cond ((not end)
             nil)
            ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)")
             ;; Simple form: "-*- MODENAME -*-".  Already handled.
@@ -1713,10 +1726,6 @@ Ignore any specification for `mode:' and `coding:';
            (t
             ;; Hairy form: '-*-' [ <variable> ':' <value> ';' ]* '-*-'
             ;; (last ";" is optional).
-            (save-excursion
-              (if (search-forward "-*-" end t)
-                  (setq end (- (point) 3))
-                (error "-*- not terminated before end of line")))
             (while (< (point) end)
               (or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*")
                   (error "Malformed -*- line"))
@@ -1877,6 +1886,7 @@ is specified, returning t if it is specified."
 ;; Don't wait for outline.el to be loaded, for the sake of outline-minor-mode.
 (put 'outline-level 'risky-local-variable t)
 (put 'rmail-output-file-alist 'risky-local-variable t)
+(put 'font-lock-defaults 'risky-local-variable t)
 
 ;; This one is safe because the user gets to check it before it is used.
 (put 'compile-command 'safe-local-variable t)
@@ -1899,7 +1909,7 @@ A few variable names are treated specially."
        ;; Likewise for setting hook variables.
        ((or (get var 'risky-local-variable)
             (and
-             (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$\\|-predicate$"
+             (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$\\|-predicate$\\|font-lock-keywords$\\|font-lock-keywords-[0-9]+$\\|font-lock-syntactic-keywords$"
                            (symbol-name var))
              (not (get var 'safe-local-variable))))
         ;; Permit evalling a put of a harmless property.
@@ -2804,6 +2814,7 @@ to consider it or not when called with that buffer current."
            (and save-abbrevs abbrevs-changed
                 (progn
                   (if (or arg
+                          (eq save-abbrevs 'silently)
                           (y-or-n-p (format "Save abbrevs in %s? "
                                             abbrev-file-name)))
                       (write-abbrev-file nil))
@@ -3544,6 +3555,60 @@ PATTERN that already quotes some of the special characters."
 (defvar insert-directory-program "ls"
   "Absolute or relative name of the `ls' program used by `insert-directory'.")
 
+(defcustom directory-free-space-program "df"
+  "*Program to get the amount of free space on a file system.
+We assume the output has the format of `df'.
+The value of this variable must be just a command name or file name;
+if you want to specify options, use `directory-free-space-args'.
+
+A value of nil disables this feature.
+
+If the function `file-system-info' is defined, it is always used in
+preference to the program given by this variable."
+  :type '(choice (string :tag "Program") (const :tag "None" nil))
+  :group 'dired)
+
+(defcustom directory-free-space-args "-Pk"
+  "*Options to use when running `directory-free-space-program'."
+  :type 'string
+  :group 'dired)
+
+(defun get-free-disk-space (dir)
+  "Return the mount of free space on directory DIR's file system.
+The result is a string that gives the number of free 1KB blocks,
+or nil if the system call or the program which retrieve the infornmation
+fail.
+
+This function calls `file-system-info' if it is available, or invokes the
+program specified by `directory-free-space-program' if that is non-nil."
+  ;; Try to find the number of free blocks.  Non-Posix systems don't
+  ;; always have df, but might have an equivalent system call.
+  (if (fboundp 'file-system-info)
+      (let ((fsinfo (file-system-info dir)))
+       (if fsinfo
+           (format "%.0f" (/ (nth 2 fsinfo) 1024))))
+    (save-match-data
+      (with-temp-buffer
+       (when (and directory-free-space-program
+                  (zerop (call-process directory-free-space-program
+                                       nil t nil
+                                       directory-free-space-args
+                                       dir)))
+         ;; Usual format is a header line followed by a line of
+         ;; numbers.
+         (goto-char (point-min))
+         (forward-line 1)
+         (if (not (eobp))
+             (progn
+               ;; Move to the end of the "available blocks" number.
+               (skip-chars-forward "^ \t")
+               (forward-word 3)
+               ;; Copy it into AVAILABLE.
+               (let ((end (point)))
+                 (forward-word -1)
+                 (buffer-substring (point) end)))))))))
+
+
 ;; insert-directory
 ;; - must insert _exactly_one_line_ describing FILE if WILDCARD and
 ;;   FULL-DIRECTORY-P is nil.
@@ -3663,28 +3728,12 @@ If WILDCARD, it also runs the shell specified by `shell-file-name'."
            (goto-char (point-min))
            ;; First find the line to put it on.
            (when (re-search-forward "^total" nil t)
-             ;; Try to find the number of free blocks.
-             (save-match-data
-               (with-temp-buffer
-                 (call-process "df" nil t nil ".")
-                 ;; Usual format is a header line
-                 ;; followed by a line of numbers.
-                 (goto-char (point-min))
-                 (forward-line 1)
-                 (if (not (eobp))
-                     (progn
-                       ;; Move to the end of the "available blocks" number.
-                       (skip-chars-forward "^ \t")
-                       (forward-word 3)
-                       ;; Copy it into AVAILABLE.
-                       (let ((end (point)))
-                         (forward-word -1)
-                         (setq available (buffer-substring (point) end)))))))
-             (when available
-               ;; Replace "total" with "used", to avoid confusion.
-               (replace-match "used")
-               (end-of-line)
-               (insert " available " available)))))))))
+             (let ((available (get-free-disk-space ".")))
+               (when available
+                 ;; Replace "total" with "used", to avoid confusion.
+                 (replace-match "total used in directory")
+                 (end-of-line)
+                 (insert " available " available))))))))))
 
 (defun insert-directory-safely (file switches
                                     &optional wildcard full-directory-p)