]> code.delx.au - gnu-emacs/blobdiff - lisp/electric.el
* lisp/electric.el (electric-indent-local-mode): New minor mode.
[gnu-emacs] / lisp / electric.el
index 351468fd75d5da6ae346b73aac8887a1a6fb7c25..9a89587ff93fde2781c3518f2d96c6dec904c567 100644 (file)
@@ -78,8 +78,6 @@
       (setq last-command-event (aref cmd (1- (length cmd)))
            this-command (key-binding cmd t)
            cmd this-command)
-      ;; This makes universal-argument-other-key work.
-      (setq universal-argument-num-events 0)
       (if (or (prog1 quit-flag (setq quit-flag nil))
              (eq last-input-event ?\C-g))
          (progn (setq unread-command-events nil
@@ -189,7 +187,7 @@ Returns nil when we can't find this char."
                            (eq (char-before) last-command-event)))))
       pos)))
 
-;; Electric indentation.
+;;; Electric indentation.
 
 ;; Autoloading variables is generally undesirable, but major modes
 ;; should usually set this variable by adding elements to the default
@@ -204,6 +202,20 @@ Each function is called with one argument (the inserted char), with
 point right after that char, and it should return t to cause indentation,
 `no-indent' to prevent indentation or nil to let other functions decide.")
 
+(defvar-local electric-indent-inhibit nil
+  "If non-nil, reindentation is not appropriate for this buffer.
+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
@@ -231,12 +243,12 @@ point right after that char, and it should return t to cause indentation,
                     (unless (eq act 'do-indent) (nth 8 (syntax-ppss))))))))
       ;; For newline, we want to reindent both lines and basically behave like
       ;; reindent-then-newline-and-indent (whose code we hence copied).
-      (when (< (1- pos) (line-beginning-position))
+      (when (<= pos (line-beginning-position))
         (let ((before (copy-marker (1- pos) t)))
           (save-excursion
-            (unless (memq indent-line-function
-                          '(indent-relative indent-to-left-margin
-                                            indent-relative-maybe))
+            (unless (or (memq indent-line-function
+                              electric-indent-functions-without-reindent)
+                        electric-indent-inhibit)
               ;; Don't reindent the previous line if the indentation function
               ;; is not a real one.
               (goto-char before)
@@ -247,10 +259,12 @@ point right after that char, and it should return t to cause indentation,
             ;; whereas we need `move after insertion', so we do the
             ;; save/restore by hand.
             (goto-char before)
-            ;; Remove the trailing whitespace after indentation because
-            ;; indentation may (re)introduce the whitespace.
-            (delete-horizontal-space t))))
-      (unless (memq indent-line-function '(indent-to-left-margin))
+           (when (eolp)
+             ;; Remove the trailing whitespace after indentation because
+             ;; indentation may (re)introduce the whitespace.
+             (delete-horizontal-space t)))))
+      (unless (and electric-indent-inhibit
+                   (> pos (line-beginning-position)))
         (indent-according-to-mode)))))
 
 ;;;###autoload
@@ -264,7 +278,6 @@ This is a global minor mode.  When enabled, it reindents whenever
 the hook `electric-indent-functions' returns non-nil, or you
 insert a character from `electric-indent-chars'."
   :global t
-  :group 'electricity
   (if (not electric-indent-mode)
       (remove-hook 'post-self-insert-hook
                    #'electric-indent-post-self-insert-function)
@@ -283,12 +296,24 @@ insert a character from `electric-indent-chars'."
                          (delq #'electric-indent-post-self-insert-function
                                (cdr bp))))))))
 
-;; Electric pairing.
+;;;###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
   '((?\" . ?\"))
   "Alist of pairs that should be used regardless of major mode."
-  :group 'electricity
   :version "24.1"
   :type '(repeat (cons character character)))
 
@@ -298,7 +323,6 @@ When inserting a closing paren character right before the same character,
 just skip that character instead, so that hitting ( followed by ) results
 in \"()\" rather than \"())\".
 This can be convenient for people who find it easier to hit ) than C-f."
-  :group 'electricity
   :version "24.1"
   :type 'boolean)
 
@@ -404,7 +428,6 @@ closing parenthesis.  \(Likewise for brackets, etc.)
 
 See options `electric-pair-pairs' and `electric-pair-skip-self'."
   :global t
-  :group 'electricity
   (if electric-pair-mode
       (progn
        (add-hook 'post-self-insert-hook
@@ -416,7 +439,7 @@ See options `electric-pair-pairs' and `electric-pair-skip-self'."
     (remove-hook 'self-insert-uses-region-functions
                  #'electric-pair-will-use-region)))
 
-;; Automatically add newlines after/before/around some chars.
+;;; Electric newlines after/before/around some chars.
 
 (defvar electric-layout-rules '()
   "List of rules saying where to automatically insert newlines.
@@ -457,7 +480,6 @@ positive, and disable it otherwise.  If called from Lisp, enable
 the mode if ARG is omitted or nil.
 The variable `electric-layout-rules' says when and how to insert newlines."
   :global t
-  :group 'electricity
   (if electric-layout-mode
       (add-hook 'post-self-insert-hook
                 #'electric-layout-post-self-insert-function)