]> code.delx.au - gnu-emacs-elpa/blob - aggressive-indent.el
Readme
[gnu-emacs-elpa] / aggressive-indent.el
1 ;;; aggressive-indent.el --- Minor mode to keep your code always indented. More aggressive than electric-indent-mode.
2
3 ;; Copyright (C) 2014 Artur Malabarba <bruce.connor.am@gmail.com>
4
5 ;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
6 ;; URL: http://github.com/Bruce-Connor/aggressive-indent-mode
7 ;; Version: 0.1
8 ;; Package-Requires: ((emacs "24.1") (names "0.5") (cl-lib "0.5"))
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 command, 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 2
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 ;;; Change Log:
83 ;; 0.1 - 2014/10/15 - Release.
84 ;;; Code:
85
86 (require 'cl-lib)
87 (require 'names)
88
89 ;;;###autoload
90 (define-namespace aggressive-indent- :group indent
91
92 (defconst version "0.1" "Version of the aggressive-indent.el package.")
93 (defun bug-report ()
94 "Opens github issues page in a web browser. Please send any bugs you find.
95 Please include your emacs and aggressive-indent versions."
96 (interactive)
97 (message "Your `aggressive-indent-version' is: %s, and your emacs version is: %s.
98 Please include this in your report!"
99 aggressive-indent-version emacs-version)
100 (browse-url "https://github.com/Bruce-Connor/aggressive-indent-mode/issues/new"))
101
102 \f
103 ;;; Start of actual Code:
104 (defcustom excluded-modes '(text-mode tabulated-list-mode special-mode)
105 "Modes in which `aggressive-indent-mode' should not be activated.
106 This variable is only used if `global-aggressive-indent-mode' is
107 active. If the minor mode is turned on with the local command,
108 `aggressive-indent-mode', this variable is ignored."
109 :type '(repeat symbol)
110 :package-version '(aggressive-indent . "0.1"))
111
112 (defcustom protected-commands '(undo undo-tree-undo undo-tree-redo)
113 "Commands after which indentation will NOT be performed.
114 Aggressive indentation could break things like `undo' by locking
115 the user in a loop, so this variable is used to control which
116 commands will NOT be followed by a re-indent."
117 :type '(repeat symbol)
118 :package-version '(aggressive-indent . "0.1"))
119
120 (defun -softly-indent-defun ()
121 "Indent current defun unobstrusively.
122 Like `aggressive-indent-indent-defun', except do nothing if
123 mark is active (to avoid deactivaing it), or if buffer is not
124 modified (to avoid creating accidental modifications).
125 Also, never throw errors nor messages.
126
127 Meant for use in hooks. Interactively, use the other one."
128 (unless (or (region-active-p)
129 buffer-read-only
130 (null (buffer-modified-p))
131 (memq last-command protected-commands))
132 (ignore-errors
133 (cl-letf (((symbol-function 'message) #'ignore))
134 (indent-defun)))))
135
136 :autoload
137 (defun indent-defun ()
138 "Indent current defun.
139 Throw an error if parentheses are unbalanced."
140 (interactive)
141 (indent-region
142 (save-excursion (beginning-of-defun 1) (point))
143 (save-excursion (end-of-defun 1) (point))))
144
145 \f
146 ;;; Minor modes
147 :autoload
148 (define-minor-mode mode nil nil " ->"
149 '(("\C-c\C-q" . aggressive-indent-indent-defun))
150 (if mode
151 (if (and global-aggressive-indent-mode
152 (cl-member-if #'derived-mode-p excluded-modes))
153 (mode -1)
154 (setq-local electric-indent-mode nil)
155 (add-hook 'post-command-hook #'-softly-indent-defun nil 'local))
156 (remove-hook 'post-command-hook #'-softly-indent-defun 'local)))
157
158 :autoload
159 (define-globalized-minor-mode global-aggressive-indent-mode
160 mode mode)
161
162 :autoload
163 (defalias #'aggressive-indent-global-mode
164 #'global-aggressive-indent-mode)
165 )
166
167 (provide 'aggressive-indent)
168 ;;; aggressive-indent.el ends here.