compare symbol names with `equal'
[bpt/emacs.git] / lisp / files-x.el
index 2ae1a0e..c3dbcd5 100644 (file)
@@ -1,9 +1,9 @@
 ;;; files-x.el --- extended file handling commands
 
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
 
 ;; Author: Juri Linkov <juri@jurta.org>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: files
 ;; Package: emacs
 
 Intended to be used in the `interactive' spec of
 `add-file-local-variable', `delete-file-local-variable',
 `add-dir-local-variable', `delete-dir-local-variable'."
-  (let (default variable)
-    (setq default (variable-at-point))
-    (setq default (and (symbolp default) (boundp default)
+  (let* ((default (variable-at-point))
+         (default (and (symbolp default) (boundp default)
                       (symbol-name default)))
-    (setq variable
+         (variable
          (completing-read
           (if default
               (format "%s (default %s): " prompt default)
@@ -52,48 +51,47 @@ Intended to be used in the `interactive' spec of
             (or (custom-variable-p sym)
                  (get sym 'safe-local-variable)
                 (memq sym '(mode eval coding unibyte))))
-          nil nil nil default nil))
+          nil nil nil default nil)))
     (and (stringp variable) (intern variable))))
 
 (defun read-file-local-variable-value (variable)
   "Read value of file-local VARIABLE using completion.
 Intended to be used in the `interactive' spec of
 `add-file-local-variable' and `add-dir-local-variable'."
-  (let (default value)
-    (cond
-     ((eq variable 'mode)
-      (setq default (and (symbolp major-mode) (symbol-name major-mode)))
-      (setq value
-           (completing-read
-            (if default
-                (format "Add %s with value (default %s): " variable default)
-              (format "Add %s with value: " variable))
-            obarray
-            (lambda (sym)
-              (string-match-p "-mode\\'" (symbol-name sym)))
-            nil nil nil default nil))
+  (cond
+   ((eq variable 'mode)
+    (let* ((default (and (symbolp major-mode) (symbol-name major-mode)))
+           (value
+            (completing-read
+             (if default
+                 (format "Add %s with value (default %s): " variable default)
+               (format "Add %s with value: " variable))
+             obarray
+             (lambda (sym)
+               (string-match-p "-mode\\'" (symbol-name sym)))
+             nil nil nil default nil)))
       (and (stringp value)
-          (intern (replace-regexp-in-string "-mode\\'" "" value))))
-     ((eq variable 'eval)
-      (let ((minibuffer-completing-symbol t))
-       (read-from-minibuffer (format "Add %s with expression: " variable)
-                             nil read-expression-map t
-                             'read-expression-history)))
-     ((eq variable 'coding)
-      (setq default (and (symbolp buffer-file-coding-system)
-                        (symbol-name buffer-file-coding-system)))
+           (intern (replace-regexp-in-string "-mode\\'" "" value)))))
+   ((eq variable 'eval)
+    (read--expression (format "Add %s with expression: " variable)))
+   ((eq variable 'coding)
+    (let ((default (and (symbolp buffer-file-coding-system)
+                        (symbol-name buffer-file-coding-system))))
       (read-coding-system
        (if default
-          (format "Add %s with value (default %s): " variable default)
-        (format "Add %s with value: " variable))
-       default))
-     (t
-      (read (read-string (format "Add %s with value: " variable)
-                        nil 'set-variable-value-history
-                        (format "%S"
-                                (cond ((eq variable 'unibyte) t)
-                                      ((boundp variable)
-                                       (symbol-value variable))))))))))
+           (format "Add %s with value (default %s): " variable default)
+         (format "Add %s with value: " variable))
+       default)))
+   (t
+    (let ((default (format "%S"
+                           (cond ((eq variable 'unibyte) t)
+                                 ((boundp variable)
+                                  (symbol-value variable)))))
+          (minibuffer-completing-symbol t))
+      (read-from-minibuffer (format "Add %s with value: " variable)
+                            nil read-expression-map t
+                            'set-variable-value-history
+                           default)))))
 
 (defun read-file-local-variable-mode ()
   "Read per-directory file-local variable's mode using completion.
@@ -108,14 +106,47 @@ Intended to be used in the `interactive' spec of
           obarray
           (lambda (sym)
             (and (string-match-p "-mode\\'" (symbol-name sym))
-                 (not (string-match-p "-minor-mode\\'" (symbol-name sym)))))
+                 (not (or (memq sym minor-mode-list)
+                           (string-match-p "-minor-mode\\'"
+                                           (symbol-name sym))))))
           nil nil nil default nil)))
     (cond
      ((equal mode "nil") nil)
      ((and (stringp mode) (fboundp (intern mode))) (intern mode))
      (t mode))))
 
-(defun modify-file-local-variable (variable value op)
+(defun modify-file-local-variable-message (variable value op)
+  (let* ((not-value (make-symbol ""))
+        (old-value (cond ((eq variable 'mode)
+                          major-mode)
+                         ((eq variable 'coding)
+                          buffer-file-coding-system)
+                         (t (if (and (symbolp variable)
+                                     (boundp variable))
+                                (symbol-value variable)
+                              not-value))))
+        (new-value (if (eq op 'delete)
+                       (cond ((eq variable 'mode)
+                              (default-value 'major-mode))
+                             ((eq variable 'coding)
+                              (default-value 'buffer-file-coding-system))
+                             (t (if (and (symbolp variable)
+                                         (default-boundp variable))
+                                    (default-value variable)
+                                  not-value)))
+                     (cond ((eq variable 'mode)
+                            (let ((string (format "%S" value)))
+                              (if (string-match-p "-mode\\'" string)
+                                  value
+                                (intern (concat string "-mode")))))
+                           (t value)))))
+    (when (or (eq old-value not-value)
+             (eq new-value not-value)
+             (not (equal old-value new-value)))
+      (message "%s" (substitute-command-keys
+                    "For this change to take effect revisit file using \\[revert-buffer]")))))
+
+(defun modify-file-local-variable (variable value op &optional interactive)
   "Modify file-local VARIABLE in Local Variables depending on operation OP.
 
 If OP is `add-or-replace' then delete all existing settings of
@@ -198,10 +229,13 @@ from the Local Variables list ignoring the input argument VALUE."
           ((eq variable 'mode) (goto-char beg))
           ((null replaced-pos) (goto-char end))
           (replaced-pos (goto-char replaced-pos)))
-         (insert (format "%s%S: %S%s\n" prefix variable value suffix)))))))
+         (insert (format "%s%S: %S%s\n" prefix variable value suffix))))
+
+      (when interactive
+       (modify-file-local-variable-message variable value op)))))
 
 ;;;###autoload
-(defun add-file-local-variable (variable value)
+(defun add-file-local-variable (variable value &optional interactive)
   "Add file-local VARIABLE with its VALUE to the Local Variables list.
 
 This command deletes all existing settings of VARIABLE (except `mode'
@@ -213,17 +247,17 @@ then this function adds the first line containing the string
 `Local Variables:' and the last line containing the string `End:'."
   (interactive
    (let ((variable (read-file-local-variable "Add file-local variable")))
-     (list variable (read-file-local-variable-value variable))))
-  (modify-file-local-variable variable value 'add-or-replace))
+     (list variable (read-file-local-variable-value variable) t)))
+  (modify-file-local-variable variable value 'add-or-replace interactive))
 
 ;;;###autoload
-(defun delete-file-local-variable (variable)
+(defun delete-file-local-variable (variable &optional interactive)
   "Delete all settings of file-local VARIABLE from the Local Variables list."
   (interactive
-   (list (read-file-local-variable "Delete file-local variable")))
-  (modify-file-local-variable variable nil 'delete))
+   (list (read-file-local-variable "Delete file-local variable") t))
+  (modify-file-local-variable variable nil 'delete interactive))
 
-(defun modify-file-local-variable-prop-line (variable value op)
+(defun modify-file-local-variable-prop-line (variable value op &optional interactive)
   "Modify file-local VARIABLE in the -*- line depending on operation OP.
 
 If OP is `add-or-replace' then delete all existing settings of
@@ -261,11 +295,11 @@ from the -*- line ignoring the input argument VALUE."
                  (looking-at "<\\?xml[^>\n]*>$"))
          (forward-line 1))
 
-       (comment-normalize-vars)
        (let ((comment-style 'plain)
              (comment-start (or comment-start ";;; "))
              (line-beg (line-beginning-position))
              (ce nil))
+         (comment-normalize-vars)
          ;; If the first line contains a comment.
          (if (save-excursion
                (and (looking-at comment-start-skip)
@@ -337,14 +371,19 @@ from the -*- line ignoring the input argument VALUE."
           ((null replaced-pos) (goto-char end))
           (replaced-pos (goto-char replaced-pos)))
          (if (and (not (eq (char-before) ?\;))
-                  (not (equal (point) (marker-position beg))))
+                  (not (equal (point) (marker-position beg)))
+                  ;; When existing `-*- -*-' is empty, beg > end.
+                  (not (> (marker-position beg) (marker-position end))))
              (insert ";"))
          (unless (eq (char-before) ?\s) (insert " "))
          (insert (format "%S: %S;" variable value))
-         (unless (eq (char-after) ?\s) (insert " "))))))))
+         (unless (eq (char-after) ?\s) (insert " ")))))
+
+      (when interactive
+       (modify-file-local-variable-message variable value op)))))
 
 ;;;###autoload
-(defun add-file-local-variable-prop-line (variable value)
+(defun add-file-local-variable-prop-line (variable value &optional interactive)
   "Add file-local VARIABLE with its VALUE to the -*- line.
 
 This command deletes all existing settings of VARIABLE (except `mode'
@@ -355,15 +394,15 @@ If there is no -*- line at the beginning of the current file buffer
 then this function adds it."
   (interactive
    (let ((variable (read-file-local-variable "Add -*- file-local variable")))
-     (list variable (read-file-local-variable-value variable))))
-  (modify-file-local-variable-prop-line variable value 'add-or-replace))
+     (list variable (read-file-local-variable-value variable) t)))
+  (modify-file-local-variable-prop-line variable value 'add-or-replace interactive))
 
 ;;;###autoload
-(defun delete-file-local-variable-prop-line (variable)
+(defun delete-file-local-variable-prop-line (variable &optional interactive)
   "Delete all settings of file-local VARIABLE from the -*- line."
   (interactive
-   (list (read-file-local-variable "Delete -*- file-local variable")))
-  (modify-file-local-variable-prop-line variable nil 'delete))
+   (list (read-file-local-variable "Delete -*- file-local variable") t))
+  (modify-file-local-variable-prop-line variable nil 'delete interactive))
 
 (defvar auto-insert) ; from autoinsert.el
 
@@ -437,7 +476,7 @@ from the MODE alist ignoring the input argument VALUE."
 
       ;; Insert modified alist of directory-local variables.
       (insert ";;; Directory Local Variables\n")
-      (insert ";;; See Info node `(emacs) Directory Variables' for more information.\n\n")
+      (insert ";;; For more information see (info \"(emacs) Directory Variables\")\n\n")
       (pp (sort variables
                (lambda (a b)
                  (cond