|
7 | 7 | ;; Description: Management for indentation level. |
8 | 8 | ;; Keyword: control indent tab generic level |
9 | 9 | ;; Version: 0.1.0 |
10 | | -;; Package-Requires: ((emacs "24.3")) |
| 10 | +;; Package-Requires: ((emacs "26.1")) |
11 | 11 | ;; URL: https://github.com/jcs-elpa/indent-control |
12 | 12 |
|
13 | 13 | ;; This file is NOT part of GNU Emacs. |
|
44 | 44 | (c++-mode . 4) |
45 | 45 | (csharp-mode . 4) |
46 | 46 | (css-mode . 2) |
| 47 | + (dockerfile-mode . 2) |
47 | 48 | (elisp-mode . 2) |
48 | 49 | (emacs-lisp-mode . 2) |
| 50 | + (go-mode . 4) |
| 51 | + (groovy-mode . 4) |
49 | 52 | (java-mode . 4) |
50 | | - (js-mode . 4) |
51 | | - (js2-mode . 4) |
52 | | - (json-mode . 4) |
| 53 | + (jayces-mode . 4) |
| 54 | + (js-mode . 2) |
| 55 | + (js2-mode . 2) |
| 56 | + (json-mode . 2) |
| 57 | + (kotlin-mode . 4) |
| 58 | + (less-css-mode . 2) |
53 | 59 | (lisp-mode . 2) |
54 | 60 | (lisp-interaction-mode . 2) |
55 | 61 | (lua-mode . 4) |
56 | 62 | (nasm-mode . 4) |
| 63 | + (nix-mode . 2) |
57 | 64 | (nxml-mode . 2) |
58 | 65 | (objc-mode . 4) |
59 | 66 | (python-mode . 4) |
| 67 | + (rjsx-mode . 2) |
60 | 68 | (ruby-mode . 4) |
61 | 69 | (rust-mode . 4) |
| 70 | + (scss-mode . 2) |
62 | 71 | (shader-mode . 4) |
| 72 | + (ssass-mode . 2) |
63 | 73 | (sql-mode . 1) |
64 | 74 | (typescript-mode . 4) |
65 | 75 | (web-mode . 2) |
|
83 | 93 | :type 'integer |
84 | 94 | :group 'indent-control) |
85 | 95 |
|
86 | | -(defun indent-control--is-current-major-mode-p (mns) |
87 | | - "Check if this major modes MNS." |
88 | | - (cond ((stringp mns) |
89 | | - (string= (symbol-name major-mode) mns)) |
| 96 | +;; |
| 97 | +;; (@* "Util" ) |
| 98 | +;; |
| 99 | + |
| 100 | +(defmacro indent-control--mute-apply (&rest body) |
| 101 | + "Execute BODY without message." |
| 102 | + (declare (indent 0) (debug t)) |
| 103 | + `(let ((message-log-max nil)) |
| 104 | + (with-temp-message (or (current-message) nil) |
| 105 | + (let ((inhibit-message t)) (progn ,@body))))) |
| 106 | + |
| 107 | +(defmacro indent-control--no-log-apply (&rest body) |
| 108 | + "Execute BODY without write it to message buffer." |
| 109 | + (declare (indent 0) (debug t)) |
| 110 | + `(let ((message-log-max nil)) (progn ,@body))) |
| 111 | + |
| 112 | +(defun indent-control--clamp-integer (in-val in-min in-max) |
| 113 | + "Make sure the IN-VAL is between IN-MIN and IN-MAX." |
| 114 | + (cond ((<= in-val in-min) (setq in-val in-min)) |
| 115 | + ((>= in-val in-max) (setq in-val in-max))) |
| 116 | + in-val) |
| 117 | + |
| 118 | +(defun indent-control--major-mode-p (mns) |
| 119 | + "Check if this major mode MNS." |
| 120 | + (cond ((stringp mns) (string= (symbol-name major-mode) mns)) |
90 | 121 | ((listp mns) |
91 | | - (let ((index 0) |
92 | | - (current-mode-name nil) |
93 | | - (found nil)) |
94 | | - (while (and (< index (length mns)) |
95 | | - (not found)) |
96 | | - (setq current-mode-name (nth index mns)) |
97 | | - (setq found (indent-control--is-current-major-mode-p current-mode-name)) |
98 | | - (setq index (1+ index))) |
| 122 | + (let ((index 0) (len (length mns)) current-mode-name found) |
| 123 | + (while (and (not found) (< index len)) |
| 124 | + (setq current-mode-name (nth index mns) |
| 125 | + found (indent-control--major-mode-p current-mode-name) |
| 126 | + index (1+ index))) |
99 | 127 | found)) |
100 | | - ((symbolp mns) |
101 | | - (equal major-mode mns)) |
| 128 | + ((symbolp mns) (equal major-mode mns)) |
102 | 129 | (t nil))) |
103 | 130 |
|
104 | | -(defun indent-control--set-tab-width-by-mode (tw) |
105 | | - "Set the tab width TW for current major mode." |
106 | | - (cond |
107 | | - ((indent-control--is-current-major-mode-p '("actionscript-mode")) |
108 | | - (setq actionscript-indent-level tw)) |
109 | | - ((indent-control--is-current-major-mode-p '("cc-mode" |
110 | | - "c-mode" |
111 | | - "c++-mode" |
112 | | - "csharp-mode" |
113 | | - "java-mode" |
114 | | - "jayces-mode" |
115 | | - "objc-mode")) |
116 | | - (setq c-basic-offset tw)) |
117 | | - ((indent-control--is-current-major-mode-p '("css-mode" |
118 | | - "scss-mode")) |
119 | | - (setq css-indent-offset tw)) |
120 | | - ((indent-control--is-current-major-mode-p '("js-mode" |
121 | | - "json-mode")) |
122 | | - (setq js-indent-level tw)) |
123 | | - ((indent-control--is-current-major-mode-p '("js2-mode")) |
124 | | - (setq js2-basic-offset tw)) |
125 | | - ((indent-control--is-current-major-mode-p '("lisp-mode" |
126 | | - "lisp-interaction-mode" |
127 | | - "emacs-lisp-mode")) |
128 | | - (setq lisp-body-indent tw)) |
129 | | - ((indent-control--is-current-major-mode-p '("lua-mode")) |
130 | | - (setq lua-indent-level tw)) |
131 | | - ((indent-control--is-current-major-mode-p '("lua-mode")) |
132 | | - (setq lua-indent-level tw)) |
133 | | - ((indent-control--is-current-major-mode-p '("nasm-mode")) |
134 | | - (setq nasm-basic-offset tw)) |
135 | | - ((indent-control--is-current-major-mode-p '("nxml-mode")) |
136 | | - (setq nxml-child-indent tw)) |
137 | | - ((indent-control--is-current-major-mode-p '("python-mode")) |
138 | | - (setq py-indent-offset tw)) |
139 | | - ((indent-control--is-current-major-mode-p '("ruby-mode")) |
140 | | - (setq ruby-indent-level tw)) |
141 | | - ((indent-control--is-current-major-mode-p '("rust-mode")) |
142 | | - (setq rust-indent-offset tw)) |
143 | | - ((indent-control--is-current-major-mode-p '("shader-mode")) |
144 | | - (setq shader-indent-offset tw)) |
145 | | - ((indent-control--is-current-major-mode-p '("sql-mode")) |
146 | | - (setq sql-indent-offset tw)) |
147 | | - ((indent-control--is-current-major-mode-p '("typescript-mode")) |
148 | | - (setq typescript-indent-level tw)) |
149 | | - ((indent-control--is-current-major-mode-p '("web-mode")) |
150 | | - (setq web-mode-markup-indent-offset tw)) |
151 | | - ((indent-control--is-current-major-mode-p '("yaml-mode")) |
152 | | - (setq yaml-indent-offset tw)) |
153 | | - (t |
154 | | - (setq tab-width tw))) |
155 | | - (if tw |
156 | | - (progn |
157 | | - (indent-control--set-tab-width-record-by-mode tw) |
158 | | - (message "Current indent level: %s" tw)) |
159 | | - (message "No indent offset defined in major mode: %s" major-mode))) |
| 131 | +;; |
| 132 | +;; (@* "Core" ) |
| 133 | +;; |
160 | 134 |
|
161 | | -(defun indent-control--get-tab-width-by-mode () |
162 | | - "Get indentation level by mode." |
| 135 | +(defun indent-control--indent-level-by-mode () |
| 136 | + "Return indentation level variable as symbol depends on current major mode." |
163 | 137 | (cond |
164 | | - ((indent-control--is-current-major-mode-p '("actionscript-mode")) |
165 | | - actionscript-indent-level) |
166 | | - ((indent-control--is-current-major-mode-p '("cc-mode" |
167 | | - "c-mode" |
168 | | - "c++-mode" |
169 | | - "csharp-mode" |
170 | | - "java-mode" |
171 | | - "jayces-mode" |
172 | | - "objc-mode")) |
173 | | - c-basic-offset) |
174 | | - ((indent-control--is-current-major-mode-p '("css-mode")) |
175 | | - css-indent-offset) |
176 | | - ((indent-control--is-current-major-mode-p '("js-mode" |
177 | | - "json-mode")) |
178 | | - js-indent-level) |
179 | | - ((indent-control--is-current-major-mode-p '("js2-mode")) |
180 | | - js2-basic-offset) |
181 | | - ((indent-control--is-current-major-mode-p '("lisp-mode" |
182 | | - "lisp-interaction-mode" |
183 | | - "emacs-lisp-mode")) |
184 | | - lisp-body-indent) |
185 | | - ((indent-control--is-current-major-mode-p '("lua-mode")) |
186 | | - lua-indent-level) |
187 | | - ((indent-control--is-current-major-mode-p '("nasm-mode")) |
188 | | - nasm-basic-offset) |
189 | | - ((indent-control--is-current-major-mode-p '("nxml-mode")) |
190 | | - nxml-child-indent) |
191 | | - ((indent-control--is-current-major-mode-p '("python-mode")) |
192 | | - py-indent-offset) |
193 | | - ((indent-control--is-current-major-mode-p '("ruby-mode")) |
194 | | - ruby-indent-level) |
195 | | - ((indent-control--is-current-major-mode-p '("rust-mode")) |
196 | | - rust-indent-offset) |
197 | | - ((indent-control--is-current-major-mode-p '("shader-mode")) |
198 | | - shader-indent-offset) |
199 | | - ((indent-control--is-current-major-mode-p '("sql-mode")) |
200 | | - sql-indent-offset) |
201 | | - ((indent-control--is-current-major-mode-p '("typescript-mode")) |
202 | | - typescript-indent-level) |
203 | | - ((indent-control--is-current-major-mode-p '("web-mode")) |
204 | | - web-mode-markup-indent-offset) |
205 | | - ((indent-control--is-current-major-mode-p '("yaml-mode")) |
206 | | - yaml-indent-offset) |
207 | | - (t tab-width))) |
| 138 | + ((indent-control--major-mode-p '("actionscript-mode")) (quote actionscript-indent-level)) |
| 139 | + ((indent-control--major-mode-p '("cc-mode" |
| 140 | + "c-mode" |
| 141 | + "c++-mode" |
| 142 | + "csharp-mode" |
| 143 | + "java-mode" |
| 144 | + "jayces-mode" |
| 145 | + "objc-mode")) (quote c-basic-offset)) |
| 146 | + ((indent-control--major-mode-p '("css-mode" |
| 147 | + "less-css-mode" |
| 148 | + "scss-mode")) (quote css-indent-offset)) |
| 149 | + ((indent-control--major-mode-p '("ssass-mode")) (quote ssass-tab-width)) |
| 150 | + ((indent-control--major-mode-p '("groovy-mode")) (quote groovy-indent-offset)) |
| 151 | + ((indent-control--major-mode-p '("js-mode")) (quote js-indent-level)) |
| 152 | + ((indent-control--major-mode-p '("js2-mode")) (quote js2-basic-offset)) |
| 153 | + ((indent-control--major-mode-p '("lisp-mode" |
| 154 | + "lisp-interaction-mode" |
| 155 | + "emacs-lisp-mode")) (quote lisp-body-indent)) |
| 156 | + ((indent-control--major-mode-p '("lua-mode")) (quote lua-indent-level)) |
| 157 | + ((indent-control--major-mode-p '("nasm-mode")) (quote nasm-basic-offset)) |
| 158 | + ((indent-control--major-mode-p '("nxml-mode")) (quote nxml-child-indent)) |
| 159 | + ((indent-control--major-mode-p '("python-mode")) (quote py-indent-offset)) |
| 160 | + ((indent-control--major-mode-p '("rjsx-mode")) (quote js-indent-level)) |
| 161 | + ((indent-control--major-mode-p '("ruby-mode")) (quote ruby-indent-level)) |
| 162 | + ((indent-control--major-mode-p '("rust-mode")) (quote rust-indent-offset)) |
| 163 | + ((indent-control--major-mode-p '("shader-mode")) (quote shader-indent-offset)) |
| 164 | + ((indent-control--major-mode-p '("sql-mode")) (quote sql-indent-offset)) |
| 165 | + ((indent-control--major-mode-p '("typescript-mode")) (quote typescript-indent-level)) |
| 166 | + ((indent-control--major-mode-p '("web-mode")) |
| 167 | + (quote (web-mode-markup-indent-offset |
| 168 | + web-mode-css-indent-offset |
| 169 | + web-mode-code-indent-offset))) |
| 170 | + ((indent-control--major-mode-p '("yaml-mode")) (quote yaml-indent-offset)) |
| 171 | + (t (quote tab-width)))) |
| 172 | + |
| 173 | +(defun indent-control-set-indent-level-by-mode (tw) |
| 174 | + "Set the tab width (TW) for current major mode." |
| 175 | + (let ((var-symbol (indent-control--indent-level-by-mode))) |
| 176 | + (cond ((listp var-symbol) (dolist (indent-var var-symbol) (set indent-var tw))) |
| 177 | + (t (set var-symbol tw)))) |
| 178 | + (when (integerp tw) |
| 179 | + (indent-control--set-indent-level-record-by-mode tw) |
| 180 | + (indent-control--no-log-apply |
| 181 | + (message "[INFO] Current indent level: %s" tw)))) |
| 182 | + |
| 183 | +(defun indent-control-get-indent-level-by-mode () |
| 184 | + "Get indentation level by mode." |
| 185 | + (let ((var-symbol (indent-control--indent-level-by-mode))) |
| 186 | + (when (listp var-symbol) (setq var-symbol (nth 0 var-symbol))) |
| 187 | + (symbol-value var-symbol))) |
| 188 | + |
| 189 | +(defun indent-control--delta-ensure-valid-tab-width (cv dv) |
| 190 | + "Change tab width by current value CV and delta value (DV)." |
| 191 | + (indent-control--clamp-integer |
| 192 | + (+ cv dv) indent-control-min-indentation-level indent-control-max-indentation-level)) |
| 193 | + |
| 194 | +(defun indent-control--delta-tab-width (dv) |
| 195 | + "Increase/Decrease tab width by delta value (DV)." |
| 196 | + (let ((indent-level (indent-control-get-indent-level-by-mode))) |
| 197 | + (indent-control-set-indent-level-by-mode |
| 198 | + (indent-control--delta-ensure-valid-tab-width indent-level dv)))) |
208 | 199 |
|
209 | | -(defun indent-control--set-tab-width-record-by-mode (tw &optional mn) |
210 | | - "Set the tab width record by MN with tab width TW." |
| 200 | +(defun indent-control--set-indent-level-record-by-mode (tw &optional mn) |
| 201 | + "Set the tab width record by mode name MN with tab width TW." |
211 | 202 | (unless mn (setq mn major-mode)) |
212 | | - (let ((index 0) |
213 | | - (break-it nil)) |
214 | | - (while (and (< index (length indent-control-records)) |
215 | | - (not break-it)) |
216 | | - (let ((record-mode-name (car (nth index indent-control-records)))) |
| 203 | + (let ((index 0) (len (length indent-control-records)) break-it) |
| 204 | + (while (and (not break-it) (< index len)) |
| 205 | + (let* ((record (nth index indent-control-records)) |
| 206 | + (record-mode-name (car record))) |
217 | 207 | (when (equal mn record-mode-name) |
218 | 208 | (setf (cdr (nth index indent-control-records)) tw) |
219 | 209 | (setq break-it t))) |
220 | 210 | (setq index (1+ index))) |
221 | 211 | (unless break-it |
222 | | - (message "Tab width record not found: %s" mn)))) |
| 212 | + (message "[WARNING] Indentation level record not found: %s" mn)))) |
223 | 213 |
|
224 | | -(defun indent-control--get-tab-width-record-by-mode (&optional mn) |
225 | | - "Get the tab width record by MN." |
| 214 | +(defun indent-control--get-indent-level-record-by-mode (&optional mn) |
| 215 | + "Get the tab width record by mode name, MN." |
226 | 216 | (unless mn (setq mn major-mode)) |
227 | | - (let ((index 0) |
228 | | - (break-it nil) |
229 | | - (target-tab-width nil)) |
230 | | - (while (and (< index (length indent-control-records)) |
231 | | - (not break-it)) |
232 | | - (let ((record-mode-name (car (nth index indent-control-records))) |
233 | | - (record-tab-width (cdr (nth index indent-control-records)))) |
| 217 | + (let ((index 0) (len (length indent-control-records)) break-it |
| 218 | + ;; Have default to `tab-width'. |
| 219 | + (target-tab-width tab-width)) |
| 220 | + (while (and (not break-it) (< index len)) |
| 221 | + (let* ((record (nth index indent-control-records)) |
| 222 | + (record-mode-name (car record)) (record-tab-width (cdr record))) |
234 | 223 | (when (equal mn record-mode-name) |
235 | | - (setq target-tab-width record-tab-width) |
236 | | - (setq break-it t))) |
| 224 | + (setq target-tab-width record-tab-width |
| 225 | + break-it t))) |
237 | 226 | (setq index (1+ index))) |
238 | 227 | target-tab-width)) |
239 | 228 |
|
240 | | - |
241 | | -(defun indent-control--clamp-integer (in-val in-min in-max) |
242 | | - "Make sure the IN-VAL is between IN-MIN and IN-MAX." |
243 | | - (let ((out-result in-val)) |
244 | | - (cond ((<= in-val in-min) (progn (setq out-result in-min))) |
245 | | - ((>= in-val in-max) (progn (setq out-result in-max)))) |
246 | | - out-result)) |
247 | | - |
248 | | -(defun indent-control--ensure-valid-tab-width (cv dv) |
249 | | - "Change tab width by current value CV and delta value DV." |
250 | | - (indent-control--clamp-integer (+ cv dv) |
251 | | - indent-control-min-indentation-level |
252 | | - indent-control-max-indentation-level)) |
253 | | - |
254 | | -(defun indent-control--delta-tab-width (dv) |
255 | | - "Increase/Decrease tab width by delta value DV." |
256 | | - (indent-control--set-tab-width-by-mode (indent-control--ensure-valid-tab-width (indent-control--get-tab-width-by-mode) dv))) |
257 | | - |
258 | 229 | (defun indent-control--prog-mode-hook () |
259 | 230 | "Programming language mode hook." |
260 | | - (let ((inhibit-message t) |
261 | | - (message-log-max nil)) |
| 231 | + (indent-control--mute-apply |
262 | 232 | (indent-control-continue-with-tab-width-record))) |
263 | 233 | (add-hook 'prog-mode-hook #'indent-control--prog-mode-hook) |
264 | 234 |
|
265 | 235 | ;;;###autoload |
266 | 236 | (defun indent-control-inc-indent-level () |
267 | | - "Increase tab width by 2." |
| 237 | + "Increase indent level by one level, default is 2." |
268 | 238 | (interactive) |
269 | 239 | (indent-control--delta-tab-width indent-control-delta) |
270 | 240 | (indent-for-tab-command)) |
271 | 241 |
|
272 | 242 | ;;;###autoload |
273 | 243 | (defun indent-control-dec-indent-level () |
274 | | - "Decrease tab width by 2." |
| 244 | + "Decrease indent level by one level, default is 2." |
275 | 245 | (interactive) |
276 | 246 | (indent-control--delta-tab-width (- 0 indent-control-delta)) |
277 | 247 | (indent-for-tab-command)) |
278 | 248 |
|
279 | 249 | ;;;###autoload |
280 | 250 | (defun indent-control-continue-with-tab-width-record () |
281 | 251 | "Keep the tab width the same as last time modified." |
282 | | - (indent-control--set-tab-width-by-mode (indent-control--get-tab-width-record-by-mode))) |
| 252 | + (indent-control-set-indent-level-by-mode (indent-control--get-indent-level-record-by-mode))) |
283 | 253 |
|
284 | 254 | (provide 'indent-control) |
285 | 255 | ;;; indent-control.el ends here |
0 commit comments