;; Copyright (C) 2014 Free Software Foundation, Inc.
;; Author: Artur Malabarba <emacs@endlessparentheses.com>
-;; URL: http://github.com/Malabarba/aggressive-indent-mode
-;; Version: 1.3
+;; URL: https://github.com/Malabarba/aggressive-indent-mode
+;; Version: 1.5.2
;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
;; Keywords: indent lisp maint tools
;; Prefix: aggressive-indent
;; GNU General Public License for more details.
;;
-;;; Change Log:
-;; 0.3.1 - 2014/10/30 - Define new delete-backward bound to backspace.
-;; 0.3 - 2014/10/23 - Implement a smarter engine for non-lisp modes.
-;; 0.2 - 2014/10/20 - Reactivate `electric-indent-mode'.
-;; 0.2 - 2014/10/19 - Add variable `aggressive-indent-dont-indent-if', so the user can prevent indentation.
-;; 0.1 - 2014/10/15 - Release.
;;; Code:
(require 'cl-lib)
(defgroup aggressive-indent nil
"Customization group for aggressive-indent."
:prefix "aggressive-indent-"
+ :group 'electricity
:group 'indent)
(defun aggressive-indent-bug-report ()
(require 'lisp-mnt)
(lm-version)))
emacs-version)
- (browse-url "https://github.com/Bruce-Connor/aggressive-indent-mode/issues/new"))
+ (browse-url "https://github.com/Malabarba/aggressive-indent-mode/issues/new"))
(defvar aggressive-indent-mode)
jabber-chat-mode
haml-mode
haskell-mode
+ haskell-interactive-mode
image-mode
makefile-mode
makefile-gmake-mode
:type '(repeat symbol)
:package-version '(aggressive-indent . "0.3.1"))
-(defcustom aggressive-indent-protected-commands '(undo undo-tree-undo undo-tree-redo)
+(defcustom aggressive-indent-protected-commands '(undo undo-tree-undo undo-tree-redo whitespace-cleanup)
"Commands after which indentation will NOT be performed.
Aggressive indentation could break things like `undo' by locking
the user in a loop, so this variable is used to control which
(null (buffer-modified-p))
(and (boundp 'smerge-mode) smerge-mode)
(let ((line (thing-at-point 'line)))
- (when (stringp line)
- (or (string-match "\\`[[:blank:]]*\n?\\'" line)
- ;; If the user is starting to type a comment.
- (and (stringp comment-start)
- (string-match (concat "\\`[[:blank:]]*"
- (substring comment-start 0 1)
- "[[:blank:]]*$")
- line)))))
+ (and (stringp line)
+ ;; If the user is starting to type a comment.
+ (stringp comment-start)
+ (string-match (concat "\\`[[:blank:]]*"
+ (substring comment-start 0 1)
+ "[[:blank:]]*$")
+ line)))
(let ((sp (syntax-ppss)))
;; Comments.
(or (and (not aggressive-indent-comments-too) (elt sp 4))
'(when (boundp 'iedit-mode)
(add-to-list 'aggressive-indent--internal-dont-indent-if
'iedit-mode)))
+(eval-after-load 'evil
+ '(when (boundp 'iedit-mode)
+ (add-to-list 'aggressive-indent--internal-dont-indent-if
+ 'iedit-mode)))
(eval-after-load 'coq
'(add-to-list 'aggressive-indent--internal-dont-indent-if
'(and (derived-mode-p 'coq-mode)
(set-marker-insertion-type p t)
(unwind-protect
(progn
- (goto-char r)
- (setq was-begining-of-line
- (= r (line-beginning-position)))
+ (unless (= l r)
+ (when (= (char-before r) ?\n)
+ (cl-decf r)))
;; If L is at the end of a line, skip that line.
(unless (= l r)
- (goto-char l)
- (when (= l (line-end-position))
+ (when (= (char-after l) ?\n)
(cl-incf l)))
;; Indent the affected region.
+ (goto-char r)
(unless (= l r) (indent-region l r))
- ;; `indent-region' doesn't do anything if R was the beginning of a line, so we indent manually there.
- (when was-begining-of-line
- (indent-according-to-mode))
;; And then we indent each following line until nothing happens.
(forward-line 1)
- (skip-chars-forward "[:blank:]\n")
+ (skip-chars-forward "[:blank:]\n\r\xc")
(let* ((eod (ignore-errors
(save-excursion (end-of-defun)
(point-marker))))
;; not at all, stop at the limit.
(< (point) point-limit))))
(forward-line 1)
- (skip-chars-forward "[:blank:]\n"))))
+ (skip-chars-forward "[:blank:]\n\r\f"))))
(goto-char p))))
(defun aggressive-indent--softly-indent-region-and-on (l r &rest _)
;;; Tracking changes
(defvar aggressive-indent--changed-list nil
"List of (left right) limit of regions changed in the last command loop.")
+(make-variable-buffer-local 'aggressive-indent--changed-list)
(defun aggressive-indent--indent-if-changed ()
"Indent any region that changed in the last command loop."
(when aggressive-indent--changed-list
- (unless (or (run-hook-wrapped 'aggressive-indent--internal-dont-indent-if #'eval)
- (aggressive-indent--run-user-hooks))
- (while-no-input
- (let ((inhibit-modification-hooks t)
- (inhibit-point-motion-hooks t)
- (indent-function
- (if (cl-member-if #'derived-mode-p aggressive-indent-modes-to-prefer-defun)
- #'aggressive-indent--softly-indent-defun #'aggressive-indent--softly-indent-region-and-on)))
- (while aggressive-indent--changed-list
- (apply indent-function (car aggressive-indent--changed-list))
- (setq aggressive-indent--changed-list
- (cdr aggressive-indent--changed-list))))))))
+ (save-excursion
+ (save-selected-window
+ (unless (or (run-hook-wrapped 'aggressive-indent--internal-dont-indent-if #'eval)
+ (aggressive-indent--run-user-hooks))
+ (while-no-input
+ (redisplay)
+ (let ((inhibit-modification-hooks t)
+ (inhibit-point-motion-hooks t)
+ (indent-function
+ (if (cl-member-if #'derived-mode-p aggressive-indent-modes-to-prefer-defun)
+ #'aggressive-indent--softly-indent-defun #'aggressive-indent--softly-indent-region-and-on)))
+ (while aggressive-indent--changed-list
+ (apply indent-function (car aggressive-indent--changed-list))
+ (setq aggressive-indent--changed-list
+ (cdr aggressive-indent--changed-list))))))))))
+
+(defvar-local aggressive-indent--balanced-parens t
+ "Non-nil if the current-buffer has balanced parens.")
+
+(defun aggressive-indent--check-parens ()
+ "Check if parens are balanced in the current buffer.
+Store result in `aggressive-indent--balanced-parens'."
+ (setq aggressive-indent--balanced-parens
+ (ignore-errors
+ (save-restriction
+ (narrow-to-defun)
+ (check-parens)
+ t))))
(defun aggressive-indent--keep-track-of-changes (l r &rest _)
"Store the limits (L and R) of each change in the buffer."
(when aggressive-indent-mode
- (push (list l r) aggressive-indent--changed-list)))
+ (push (list l r) aggressive-indent--changed-list)
+ (aggressive-indent--check-parens)))
;;; Minor modes
;;;###autoload
(define-minor-mode aggressive-indent-mode
nil nil " =>"
- '(("\ 3\11" . aggressive-indent-indent-defun)
+ `((,(kbd "C-c C-q") . aggressive-indent-indent-defun)
([backspace]
menu-item "maybe-delete-indentation" ignore :filter
(lambda (&optional _)
(memq major-mode '(text-mode fundamental-mode))
buffer-read-only))
(aggressive-indent-mode -1)
- ;; Should electric indent be ON or OFF?
+ ;; Should electric indent be ON or OFF?
(if (or (eq aggressive-indent-dont-electric-modes t)
(cl-member-if #'derived-mode-p aggressive-indent-dont-electric-modes))
(aggressive-indent--local-electric nil)
(aggressive-indent--local-electric t))
+ (aggressive-indent--check-parens)
(add-hook 'after-change-functions #'aggressive-indent--keep-track-of-changes nil 'local)
(add-hook 'post-command-hook #'aggressive-indent--indent-if-changed nil 'local))
;; Clean the hooks