dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

aggressive-indent.el (22463B)


      1 ;;; aggressive-indent.el --- Minor mode to aggressively keep your code always indented  -*- lexical-binding:t -*-
      2 
      3 ;; Copyright (C) 2014-2021 Free Software Foundation, Inc
      4 
      5 ;; Author: Artur Malabarba <emacs@endlessparentheses.com>
      6 ;; URL: https://github.com/Malabarba/aggressive-indent-mode
      7 ;; Version: 1.10.0
      8 ;; Package-Requires: ((emacs "24.3"))
      9 ;; Keywords: indent lisp maint tools
     10 ;; Prefix: aggressive-indent
     11 ;; Separator: -
     12 
     13 ;;; Commentary:
     14 ;;
     15 ;; `electric-indent-mode' is enough to keep your code nicely aligned when
     16 ;; all you do is type.  However, once you start shifting blocks around,
     17 ;; transposing lines, or slurping and barfing sexps, indentation is bound
     18 ;; to go wrong.
     19 ;;
     20 ;; `aggressive-indent-mode' is a minor mode that keeps your code always
     21 ;; indented.  It reindents after every change, making it more reliable
     22 ;; than `electric-indent-mode'.
     23 ;;
     24 ;; ### Instructions ###
     25 ;;
     26 ;; This package is available fom Melpa, you may install it by calling
     27 ;;
     28 ;;     M-x package-install RET aggressive-indent
     29 ;;
     30 ;; Then activate it with
     31 ;;
     32 ;;     (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
     33 ;;     (add-hook 'css-mode-hook #'aggressive-indent-mode)
     34 ;;
     35 ;; You can use this hook on any mode you want, `aggressive-indent' is not
     36 ;; exclusive to emacs-lisp code.  In fact, if you want to turn it on for
     37 ;; every programming mode, you can do something like:
     38 ;;
     39 ;;     (global-aggressive-indent-mode 1)
     40 ;;     (add-to-list 'aggressive-indent-excluded-modes 'html-mode)
     41 ;;
     42 ;; ### Manual Installation ###
     43 ;;
     44 ;; If you don't want to install from Melpa, you can download it manually,
     45 ;; place it in your `load-path' and require it with
     46 ;;
     47 ;;     (require 'aggressive-indent)
     48 
     49 ;;; Instructions:
     50 ;;
     51 ;; INSTALLATION
     52 ;;
     53 ;; This package is available fom Melpa, you may install it by calling
     54 ;; M-x package-install RET aggressive-indent.
     55 ;;
     56 ;; Then activate it with
     57 ;;     (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
     58 ;;
     59 ;; You can also use an equivalent hook for another mode,
     60 ;; `aggressive-indent' is not exclusive to emacs-lisp code.
     61 ;;
     62 ;; Alternatively, you can download it manually, place it in your
     63 ;; `load-path' and require it with
     64 ;;
     65 ;;     (require 'aggressive-indent)
     66 
     67 ;;; License:
     68 ;;
     69 ;; This file is NOT part of GNU Emacs.
     70 ;;
     71 ;; This program is free software; you can redistribute it and/or
     72 ;; modify it under the terms of the GNU General Public License
     73 ;; as published by the Free Software Foundation; either version 3
     74 ;; of the License, or (at your option) any later version.
     75 ;;
     76 ;; This program is distributed in the hope that it will be useful,
     77 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     78 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     79 ;; GNU General Public License for more details.
     80 ;;
     81 
     82 ;;; Code:
     83 
     84 (require 'cl-lib)
     85 
     86 (defgroup aggressive-indent nil
     87   "Customization group for aggressive-indent."
     88   :prefix "aggressive-indent-"
     89   :group 'electricity
     90   :group 'indent)
     91 
     92 (defun aggressive-indent-bug-report ()
     93   "Opens github issues page in a web browser.  Please send any bugs you find.
     94 Please include your Emacs and `aggressive-indent' versions."
     95   (interactive)
     96   (message "Your `aggressive-indent-version' is: %s, and your emacs version is: %s.
     97 Please include this in your report!"
     98            (eval-when-compile
     99              (ignore-errors
    100                (require 'lisp-mnt)
    101                (lm-version)))
    102            emacs-version)
    103   (browse-url "https://github.com/Malabarba/aggressive-indent-mode/issues/new"))
    104 
    105 (defvar aggressive-indent-mode)
    106 
    107 ;;; Configuring indentation
    108 (defcustom aggressive-indent-dont-electric-modes nil
    109   "List of major-modes where `electric-indent' should be disabled."
    110   :type '(choice
    111           (const :tag "Never use `electric-indent-mode'." t)
    112           (repeat :tag "List of major-modes to avoid `electric-indent-mode'." symbol))
    113   :package-version '(aggressive-indent . "0.3.1"))
    114 
    115 (defcustom aggressive-indent-excluded-modes
    116   '(elm-mode
    117     haskell-mode
    118     inf-ruby-mode
    119     makefile-mode
    120     makefile-gmake-mode
    121     python-mode
    122     sql-interactive-mode
    123     text-mode
    124     yaml-mode)
    125   "Modes in which `aggressive-indent-mode' should not be activated.
    126 This variable is only used if `global-aggressive-indent-mode' is
    127 active.  If the minor mode is turned on with the local command,
    128 `aggressive-indent-mode', this variable is ignored."
    129   :type '(repeat symbol)
    130   :package-version '(aggressive-indent . "1.8.4"))
    131 
    132 (defcustom aggressive-indent-protected-commands '(undo undo-tree-undo undo-tree-redo whitespace-cleanup)
    133   "Commands after which indentation will NOT be performed.
    134 Aggressive indentation could break things like `undo' by locking
    135 the user in a loop, so this variable is used to control which
    136 commands will NOT be followed by a re-indent."
    137   :type '(repeat symbol)
    138   :package-version '(aggressive-indent . "0.1"))
    139 
    140 (defcustom aggressive-indent-protected-current-commands
    141   '(query-replace-regexp query-replace)
    142   "Like `aggressive-indent-protected-commands', but for the current command.
    143 For instance, with the default value, this variable prevents
    144 indentation during `query-replace' (but not after)."
    145   :type '(repeat symbol)
    146   :package-version '(aggressive-indent . "1.8.4"))
    147 
    148 (defcustom aggressive-indent-comments-too nil
    149   "If non-nil, aggressively indent in comments as well."
    150   :type 'boolean
    151   :package-version '(aggressive-indent . "0.3"))
    152 
    153 (defcustom aggressive-indent-modes-to-prefer-defun
    154   '(emacs-lisp-mode lisp-mode scheme-mode clojure-mode)
    155   "List of major-modes in which indenting defun is preferred.
    156 Add here any major modes with very good definitions of
    157 `end-of-defun' and `beginning-of-defun', or modes which bug out
    158 if you have `after-change-functions' (such as paredit).
    159 
    160 If current major mode is derived from one of these,
    161 `aggressive-indent' will call `aggressive-indent-indent-defun'
    162 after every command.  Otherwise, it will call
    163 `aggressive-indent-indent-region-and-on' after every buffer
    164 change."
    165   :type '(repeat symbol)
    166   :package-version '(aggressive-indent . "0.3"))
    167 
    168 ;;; Preventing indentation
    169 (defconst aggressive-indent--internal-dont-indent-if
    170   '((memq last-command aggressive-indent-protected-commands)
    171     (memq this-command aggressive-indent-protected-current-commands)
    172     (region-active-p)
    173     buffer-read-only
    174     undo-in-progress
    175     (null (buffer-modified-p))
    176     (and (boundp 'smerge-mode) smerge-mode)
    177     (equal (buffer-name) "*ediff-merge*")
    178     (let ((line (thing-at-point 'line)))
    179       (and (stringp line)
    180            ;; If the user is starting to type a comment.
    181            (stringp comment-start)
    182            (string-match (concat "\\`[[:blank:]]*"
    183                                  (substring comment-start 0 1)
    184                                  "[[:blank:]]*$")
    185                          line)))
    186     (let ((sp (syntax-ppss)))
    187       ;; Comments.
    188       (or (and (not aggressive-indent-comments-too) (elt sp 4))
    189           ;; Strings.
    190           (elt sp 3))))
    191   "List of forms which prevent indentation when they evaluate to non-nil.
    192 This is for internal use only.  For user customization, use
    193 `aggressive-indent-dont-indent-if' instead.")
    194 
    195 (eval-after-load 'yasnippet
    196   '(when (boundp 'yas--active-field-overlay)
    197      (add-to-list 'aggressive-indent--internal-dont-indent-if
    198                   '(and
    199                     (overlayp yas--active-field-overlay)
    200                     (overlay-end yas--active-field-overlay))
    201                   'append)))
    202 (eval-after-load 'company
    203   '(when (boundp 'company-candidates)
    204      (add-to-list 'aggressive-indent--internal-dont-indent-if
    205                   'company-candidates)))
    206 (eval-after-load 'auto-complete
    207   '(when (boundp 'ac-completing)
    208      (add-to-list 'aggressive-indent--internal-dont-indent-if
    209                   'ac-completing)))
    210 (eval-after-load 'multiple-cursors-core
    211   '(when (boundp 'multiple-cursors-mode)
    212      (add-to-list 'aggressive-indent--internal-dont-indent-if
    213                   'multiple-cursors-mode)))
    214 (eval-after-load 'iedit
    215   '(when (boundp 'iedit-mode)
    216      (add-to-list 'aggressive-indent--internal-dont-indent-if
    217                   'iedit-mode)))
    218 (eval-after-load 'evil
    219   '(when (boundp 'iedit-mode)
    220      (add-to-list 'aggressive-indent--internal-dont-indent-if
    221                   'iedit-mode)))
    222 (eval-after-load 'coq
    223   '(add-to-list 'aggressive-indent--internal-dont-indent-if
    224                 '(and (derived-mode-p 'coq-mode)
    225                       (not (string-match "\\.[[:space:]]*$"
    226                                          (thing-at-point 'line))))))
    227 (eval-after-load 'ruby-mode
    228   '(add-to-list 'aggressive-indent--internal-dont-indent-if
    229                 '(when (derived-mode-p 'ruby-mode)
    230                    (let ((line (thing-at-point 'line)))
    231                      (and (stringp line)
    232                           (string-match "\\b\\(begin\\|case\\|d\\(?:ef\\|o\\)\\|if\\) *$" line))))))
    233 
    234 (defcustom aggressive-indent-dont-indent-if '()
    235   "List of variables and functions to prevent aggressive indenting.
    236 This variable is a list where each element is a Lisp form.
    237 As long as any one of these forms returns non-nil,
    238 aggressive-indent will not perform any indentation.
    239 
    240 See `aggressive-indent--internal-dont-indent-if' for usage examples.
    241 
    242 Note that this is only used once, and only on the line where the
    243 point is when we're about to start indenting.  In order to
    244 prevent indentation of further lines, see
    245 `aggressive-indent-stop-here-hook'."
    246   :type '(repeat sexp)
    247   :package-version '(aggressive-indent . "0.2"))
    248 
    249 (defcustom aggressive-indent-stop-here-hook nil
    250   "A hook that runs on each line before it is indented.
    251 If any function on this hook returns non-nil, it immediately
    252 prevents indentation of the current line and any further
    253 lines.
    254 
    255 Note that aggressive-indent does indentation in two stages.  The
    256 first stage indents the entire edited region, while the second
    257 stage keeps indenting further lines until its own logic decide to
    258 stop.  This hook only affects the second stage.  That is, it
    259 effectly lets you add your own predicates to the logic that
    260 decides when to stop.
    261 
    262 In order to prevent indentation before the first stage, see
    263 `aggressive-indent-dont-indent-if' instead."
    264   :type 'hook)
    265 
    266 (defvar aggressive-indent--error-message "One of the forms in `aggressive-indent-dont-indent-if' had the following error, I've disabled it until you fix it: %S"
    267   "Error message thrown by `aggressive-indent-dont-indent-if'.")
    268 
    269 (defvar aggressive-indent--has-errored nil
    270   "Keep track of whether `aggressive-indent-dont-indent-if' is throwing.
    271 This is used to prevent an infinite error loop on the user.")
    272 
    273 (defun aggressive-indent--run-user-hooks ()
    274   "Safely run forms in `aggressive-indent-dont-indent-if'.
    275 If any of them errors out, we only report it once until it stops
    276 erroring again."
    277   (and aggressive-indent-dont-indent-if
    278        (condition-case er
    279            (prog1 (eval (cons 'or aggressive-indent-dont-indent-if))
    280              (setq aggressive-indent--has-errored nil))
    281          (error (unless aggressive-indent--has-errored
    282                   (setq aggressive-indent--has-errored t)
    283                   (message aggressive-indent--error-message er))))))
    284 
    285 ;;; Indenting defun
    286 (defcustom aggressive-indent-region-function #'indent-region
    287   "Function called to indent a region.
    288 It is called with two arguments, the region beginning and end."
    289   :risky t
    290   :type 'function)
    291 
    292 ;;;###autoload
    293 (defun aggressive-indent-indent-defun (&optional l r)
    294   "Indent current defun.
    295 Throw an error if parentheses are unbalanced.
    296 If L and R are provided, use them for finding the start and end of defun."
    297   (interactive)
    298   (let ((p (point-marker)))
    299     (set-marker-insertion-type p t)
    300     (funcall aggressive-indent-region-function
    301              (save-excursion
    302                (when l (goto-char l))
    303                (beginning-of-defun 1) (point))
    304              (save-excursion
    305                (when r (goto-char r))
    306                (end-of-defun 1) (point)))
    307     (goto-char p)))
    308 
    309 (defun aggressive-indent--softly-indent-defun (&optional l r)
    310   "Indent current defun unobstrusively.
    311 Like `aggressive-indent-indent-defun', but without errors or
    312 messages.  L and R passed to `aggressive-indent-indent-defun'."
    313   (cl-letf (((symbol-function 'message) #'ignore))
    314     (ignore-errors (aggressive-indent-indent-defun l r))))
    315 
    316 ;;; Indenting region
    317 (defun aggressive-indent--indent-current-balanced-line (column)
    318   "Indent current balanced line, if it starts at COLUMN.
    319 Balanced line means anything contained in a sexp that starts at
    320 the current line, or starts at the same line that one of these
    321 sexps ends.
    322 
    323 Return non-nil only if the line's indentation actually changed."
    324   (when (= (current-column) column)
    325     (unless (= (point)
    326                (progn (indent-according-to-mode)
    327                       (point)))
    328       (let ((line-end (line-end-position)))
    329         (forward-sexp 1)
    330         (comment-forward (point-max))
    331         ;; We know previous sexp finished on a previous line when
    332         ;; there's only be whitespace behind point.
    333         (while (progn
    334                  (skip-chars-backward "[:blank:]")
    335                  (not (looking-at "^")))
    336           (forward-sexp 1)
    337           (comment-forward (point-max)))
    338         (when (looking-at "^")
    339           (funcall aggressive-indent-region-function line-end (1- (point))))
    340         (skip-chars-forward "[:blank:]")))))
    341 
    342 (defun aggressive-indent--extend-end-to-whole-sexps (beg end)
    343   "Return a point >= END, so that it covers whole sexps from BEG."
    344   (save-excursion
    345     (goto-char beg)
    346     (while (and (< (point) end)
    347                 (not (eobp)))
    348       (forward-sexp 1))
    349     (point)))
    350 
    351 ;;;###autoload
    352 (defun aggressive-indent-indent-region-and-on (l r)
    353   "Indent region between L and R, and then some.
    354 Call `aggressive-indent-region-function' between L and R, and
    355 then keep indenting until nothing more happens."
    356   (interactive "r")
    357   (let ((p (point-marker)))
    358     (set-marker-insertion-type p t)
    359     (unwind-protect
    360         (progn
    361           (unless (= l r)
    362             (when (= (char-before r) ?\n)
    363               (cl-decf r)))
    364           ;; If L is at the end of a line, skip that line.
    365           (unless (= l r)
    366             (when (= (char-after l) ?\n)
    367               (cl-incf l)))
    368           ;; Indent the affected region.
    369           (goto-char r)
    370           (unless (= l r) (funcall aggressive-indent-region-function l r))
    371           ;; And then we indent each following line until nothing happens.
    372           (forward-line 1)
    373           (skip-chars-forward "[:blank:]\n\r\xc")
    374           (let ((base-column (current-column)))
    375             (while (and (not (eobp))
    376                         (not (run-hook-with-args-until-success 'aggressive-indent-stop-here-hook))
    377                         (aggressive-indent--indent-current-balanced-line base-column)))))
    378       (goto-char p))))
    379 
    380 (defun aggressive-indent--softly-indent-region-and-on (l r &rest _)
    381   "Indent region between L and R, and a bit more.
    382 Like `aggressive-indent-indent-region-and-on', but without errors
    383 or messages."
    384   (cl-letf (((symbol-function 'message) #'ignore))
    385     (ignore-errors (aggressive-indent-indent-region-and-on l r))))
    386 
    387 ;;; Tracking changes
    388 (defvar aggressive-indent--changed-list nil
    389   "List of (left right) limit of regions changed in the last command loop.")
    390 (make-variable-buffer-local 'aggressive-indent--changed-list)
    391 
    392 (defun aggressive-indent--process-changed-list-and-indent ()
    393   "Indent the regions in `aggressive-indent--changed-list'."
    394   (unless (or (run-hook-wrapped 'aggressive-indent--internal-dont-indent-if #'eval)
    395               (aggressive-indent--run-user-hooks))
    396     (let ((after-change-functions (remove 'aggressive-indent--keep-track-of-changes after-change-functions))
    397           (inhibit-point-motion-hooks t)
    398           (indent-function
    399            (if (cl-member-if #'derived-mode-p aggressive-indent-modes-to-prefer-defun)
    400                #'aggressive-indent--softly-indent-defun #'aggressive-indent--softly-indent-region-and-on)))
    401       ;; Take the 10 most recent changes.
    402       (let ((cell (nthcdr 10 aggressive-indent--changed-list)))
    403         (when cell (setcdr cell nil)))
    404       ;; (message "----------")
    405       (while aggressive-indent--changed-list
    406         ;; (message "%S" (car aggressive-indent--changed-list))
    407         (apply indent-function (car aggressive-indent--changed-list))
    408         (setq aggressive-indent--changed-list
    409               (cdr aggressive-indent--changed-list))))))
    410 
    411 (defun aggressive-indent--clear-change-list ()
    412   "Clear cache of all changed regions. "
    413   (setq aggressive-indent--changed-list nil))
    414 
    415 (defcustom aggressive-indent-sit-for-time 0.05
    416   "Time, in seconds, to wait before indenting.
    417 If you feel aggressive-indent is causing Emacs to hang while
    418 typing, try tweaking this number."
    419   :type 'float)
    420 
    421 (defvar-local aggressive-indent--idle-timer nil
    422   "Idle timer used for indentation")
    423 
    424 ;; Ripped from Emacs 27.0 subr.el.
    425 ;; See Github Issue#111 and Emacs bug#31692.
    426 (defmacro aggressive-indent--while-no-input (&rest body)
    427   "Execute BODY only as long as there's no pending input.
    428 If input arrives, that ends the execution of BODY,
    429 and `while-no-input' returns t.  Quitting makes it return nil.
    430 If BODY finishes, `while-no-input' returns whatever value BODY produced."
    431   (declare (debug t) (indent 0))
    432   (let ((catch-sym (make-symbol "input")))
    433     `(with-local-quit
    434        (catch ',catch-sym
    435 	 (let ((throw-on-input ',catch-sym)
    436                val)
    437            (setq val (or (input-pending-p)
    438 	                 (progn ,@body)))
    439            (cond
    440             ;; When input arrives while throw-on-input is non-nil,
    441             ;; kbd_buffer_store_buffered_event sets quit-flag to the
    442             ;; value of throw-on-input.  If, when BODY finishes,
    443             ;; quit-flag still has the same value as throw-on-input, it
    444             ;; means BODY never tested quit-flag, and therefore ran to
    445             ;; completion even though input did arrive before it
    446             ;; finished.  In that case, we must manually simulate what
    447             ;; 'throw' in process_quit_flag would do, and we must
    448             ;; reset quit-flag, because leaving it set will cause us
    449             ;; quit to top-level, which has undesirable consequences,
    450             ;; such as discarding input etc.  We return t in that case
    451             ;; because input did arrive during execution of BODY.
    452             ((eq quit-flag throw-on-input)
    453              (setq quit-flag nil)
    454              t)
    455             ;; This is for when the user actually QUITs during
    456             ;; execution of BODY.
    457             (quit-flag
    458              nil)
    459             (t val)))))))
    460 
    461 (defun aggressive-indent--maybe-cancel-timer ()
    462   "Cancel and remove the timer if it is set."
    463   (when (timerp aggressive-indent--idle-timer)
    464     (cancel-timer aggressive-indent--idle-timer)
    465     (setq aggressive-indent--idle-timer nil)))
    466 
    467 (defun aggressive-indent--indent-if-changed (buffer)
    468   "Indent any region that changed in BUFFER in the last command loop."
    469   (if (not (buffer-live-p buffer))
    470       (aggressive-indent--maybe-cancel-timer)
    471     (with-current-buffer buffer
    472       (when (and aggressive-indent-mode aggressive-indent--changed-list)
    473         (save-excursion
    474           (save-selected-window
    475             (aggressive-indent--while-no-input
    476               (aggressive-indent--process-changed-list-and-indent))))
    477         (aggressive-indent--maybe-cancel-timer)))))
    478 
    479 (defun aggressive-indent--keep-track-of-changes (l r &rest _)
    480   "Store the limits (L and R) of each change in the buffer."
    481   (when aggressive-indent-mode
    482     (push (list l r) aggressive-indent--changed-list)
    483     (aggressive-indent--maybe-cancel-timer)
    484     (setq aggressive-indent--idle-timer
    485           (run-with-idle-timer aggressive-indent-sit-for-time t #'aggressive-indent--indent-if-changed (current-buffer)))))
    486 
    487 ;;; Minor modes
    488 ;;;###autoload
    489 (define-minor-mode aggressive-indent-mode
    490   nil nil " =>"
    491   `((,(kbd "C-c C-q") . aggressive-indent-indent-defun)
    492     ([backspace]
    493      menu-item "maybe-delete-indentation" ignore :filter
    494      (lambda (&optional _)
    495        (when (and (looking-back "^[[:blank:]]+")
    496                   ;; Wherever we don't want to indent, we probably also
    497                   ;; want the default backspace behavior.
    498                   (not (run-hook-wrapped 'aggressive-indent--internal-dont-indent-if #'eval))
    499                   (not (aggressive-indent--run-user-hooks)))
    500          #'delete-indentation))))
    501   (if aggressive-indent-mode
    502       (if (and global-aggressive-indent-mode
    503                (or (cl-member-if #'derived-mode-p aggressive-indent-excluded-modes)
    504                    (equal indent-line-function #'indent-relative)
    505                    (derived-mode-p 'text-mode)
    506                    (eq major-mode 'fundamental-mode)
    507                    buffer-read-only))
    508           (aggressive-indent-mode -1)
    509         ;; Should electric indent be ON or OFF?
    510         (if (or (eq aggressive-indent-dont-electric-modes t)
    511                 (cl-member-if #'derived-mode-p aggressive-indent-dont-electric-modes))
    512             (aggressive-indent--local-electric nil)
    513           (aggressive-indent--local-electric t))
    514         (add-hook 'after-change-functions #'aggressive-indent--keep-track-of-changes nil 'local)
    515         (add-hook 'after-revert-hook #'aggressive-indent--clear-change-list nil 'local)
    516         (add-hook 'before-save-hook #'aggressive-indent--process-changed-list-and-indent nil 'local)
    517         (add-hook 'kill-buffer-hook #'aggressive-indent--maybe-cancel-timer nil 'local))
    518     ;; Clean the hooks
    519     (aggressive-indent--maybe-cancel-timer)
    520     (remove-hook 'after-change-functions #'aggressive-indent--keep-track-of-changes 'local)
    521     (remove-hook 'after-revert-hook #'aggressive-indent--clear-change-list 'local)
    522     (remove-hook 'before-save-hook #'aggressive-indent--process-changed-list-and-indent 'local)
    523     (remove-hook 'post-command-hook #'aggressive-indent--softly-indent-defun 'local)
    524     (remove-hook 'kill-buffer-hook #'aggressive-indent--maybe-cancel-timer 'local)))
    525 
    526 (defun aggressive-indent--local-electric (on)
    527   "Turn variable `electric-indent-mode' on or off locally, as per boolean ON."
    528   (if (fboundp 'electric-indent-local-mode)
    529       (electric-indent-local-mode (if on 1 -1))
    530     (set (make-local-variable 'electric-indent-mode) on)))
    531 
    532 ;;;###autoload
    533 (define-globalized-minor-mode global-aggressive-indent-mode
    534   aggressive-indent-mode aggressive-indent-mode)
    535 
    536 ;;;###autoload
    537 (defalias 'aggressive-indent-global-mode
    538   #'global-aggressive-indent-mode)
    539 
    540 (provide 'aggressive-indent)
    541 ;;; aggressive-indent.el ends here