* lisp/electric.el (electric-indent-local-mode): New minor mode.
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 6 Nov 2013 02:10:18 +0000 (21:10 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Wed, 6 Nov 2013 02:10:18 +0000 (21:10 -0500)
(electric-indent-functions-without-reindent): New var.
(electric-indent-post-self-insert-function): Use it.
* lisp/emacs-lisp/gv.el (buffer-local-value): Add setter.

lisp/ChangeLog
lisp/electric.el
lisp/emacs-lisp/gv.el

index 9d5d97b..5b4cba4 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-06  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * electric.el (electric-indent-local-mode): New minor mode.
+       (electric-indent-functions-without-reindent): New var.
+       (electric-indent-post-self-insert-function): Use it.
+       * emacs-lisp/gv.el (buffer-local-value): Add setter.
+
 2013-11-05  Eli Zaretskii  <eliz@gnu.org>
 
        * international/quail.el (quail-help): Be more explicit about the
index 1f95e68..9a89587 100644 (file)
@@ -207,6 +207,15 @@ point right after that char, and it should return t to cause indentation,
 This should be set by major modes such as `python-mode' since
 Python does not lend itself to fully automatic indentation.")
 
+(defvar electric-indent-functions-without-reindent
+  '(indent-relative indent-to-left-margin indent-relative-maybe
+    py-indent-line coffee-indent-line org-indent-line
+    haskell-indentation-indent-line haskell-indent-cycle haskell-simple-indent)
+  "List of indent functions that can't reindent.
+If `line-indent-function' is one of those, then `electric-indent-mode' will
+not try to reindent lines.  It is normally better to make the major
+mode set `electric-indent-inhibit', but this can be used as a workaround.")
+
 (defun electric-indent-post-self-insert-function ()
   ;; FIXME: This reindents the current line, but what we really want instead is
   ;; to reindent the whole affected text.  That's the current line for simple
@@ -238,8 +247,7 @@ Python does not lend itself to fully automatic indentation.")
         (let ((before (copy-marker (1- pos) t)))
           (save-excursion
             (unless (or (memq indent-line-function
-                              '(indent-relative indent-to-left-margin
-                                                indent-relative-maybe))
+                              electric-indent-functions-without-reindent)
                         electric-indent-inhibit)
               ;; Don't reindent the previous line if the indentation function
               ;; is not a real one.
@@ -255,9 +263,8 @@ Python does not lend itself to fully automatic indentation.")
              ;; Remove the trailing whitespace after indentation because
              ;; indentation may (re)introduce the whitespace.
              (delete-horizontal-space t)))))
-      (unless (or (memq indent-line-function '(indent-to-left-margin))
-                  (and electric-indent-inhibit
-                       (> pos (line-beginning-position))))
+      (unless (and electric-indent-inhibit
+                   (> pos (line-beginning-position)))
         (indent-according-to-mode)))))
 
 ;;;###autoload
@@ -289,6 +296,19 @@ insert a character from `electric-indent-chars'."
                          (delq #'electric-indent-post-self-insert-function
                                (cdr bp))))))))
 
+;;;###autoload
+(define-minor-mode electric-indent-local-mode
+  "Toggle `electric-indent-mode' only in this buffer."
+  :variable (buffer-local-value 'electric-indent-mode (current-buffer))
+  (cond
+   ((eq electric-indent-mode (default-value 'electric-indent-mode))
+    (kill-local-variable 'electric-indent-mode))
+   ((not (default-value 'electric-indent-mode))
+    ;; Locally enabled, but globally disabled.
+    (electric-indent-mode 1)                ; Setup the hooks.
+    (setq-default electric-indent-mode nil) ; But keep it globally disabled.
+    )))
+
 ;;; Electric pairing.
 
 (defcustom electric-pair-pairs
index 8a5841a..1a38005 100644 (file)
@@ -346,6 +346,10 @@ The return value is the last VAL in the list.
 (gv-define-simple-setter window-point set-window-point)
 (gv-define-simple-setter window-start set-window-start)
 
+(gv-define-setter buffer-local-value (val var buf)
+  (macroexp-let2 nil v val
+    `(with-current-buffer ,buf (set (make-local-variable ,var) ,v))))
+
 ;;; Some occasionally handy extensions.
 
 ;; While several of the "places" below are not terribly useful for direct use,