aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/electric.el
diff options
context:
space:
mode:
authorElías Gabriel Pérez2025-09-11 19:13:21 -0600
committerStefan Monnier2025-09-23 16:16:54 -0400
commit2a782c8d2803edeb01aef592c2b89fc8bcd80660 (patch)
tree28920d4f1071db2532b43b7b257cc7faf8c64b11 /lisp/electric.el
parent578aeedbe986efbae63382a7b9ba1a94372df659 (diff)
downloademacs-2a782c8d2803edeb01aef592c2b89fc8bcd80660.tar.gz
emacs-2a782c8d2803edeb01aef592c2b89fc8bcd80660.zip
Add electric-indent actions to reindent (bug#79371)
* lisp/electric.el (electric-indent-actions) (electric-indent-function): New user options. (electric-indent-should-reindent-p, electric-indent--yank-advice) (electric-indent-save-hook): New functions. (electric-indent-post-self-insert-function): Use them.
Diffstat (limited to 'lisp/electric.el')
-rw-r--r--lisp/electric.el78
1 files changed, 73 insertions, 5 deletions
diff --git a/lisp/electric.el b/lisp/electric.el
index 302fb8d08bc..7825bbe43ec 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -192,6 +192,29 @@ Returns nil when we can't find this char."
192 192
193;;; Electric indentation. 193;;; Electric indentation.
194 194
195(defcustom electric-indent-actions nil
196 "List of actions to indent.
197
198The valid elements of this list can be:
199 - yank: Indent the yanked text only if point is not in a string or
200 comment and yanked region is longer than 1 line.
201 - save: Indent the whole buffer before saving it.
202
203The indentation will not happen when the major mode is unable to
204reindent code reliably, such as in buffers where indentation is
205significant."
206 :type '(repeat (choice (const :tag "After yanking" yank)
207 (const :tag "Before saving" before-save)))
208 :set (lambda (var val)
209 (set-default var val)
210 (when electric-indent-mode
211 (electric-indent-mode -1)
212 (electric-indent-mode +1)))
213 :safe (lambda (v)
214 (and (proper-list-p v)
215 (null (seq-filter (lambda (e) (not (symbolp e)) ) v))))
216 :version "31.1")
217
195;; Autoloading variables is generally undesirable, but major modes 218;; Autoloading variables is generally undesirable, but major modes
196;; should usually set this variable by adding elements to the default 219;; should usually set this variable by adding elements to the default
197;; value, which only works well if the variable is preloaded. 220;; value, which only works well if the variable is preloaded.
@@ -218,6 +241,50 @@ If `indent-line-function' is one of those, then `electric-indent-mode' will
218not try to reindent lines. It is normally better to make the major 241not try to reindent lines. It is normally better to make the major
219mode set `electric-indent-inhibit', but this can be used as a workaround.") 242mode set `electric-indent-inhibit', but this can be used as a workaround.")
220 243
244(defun electric-indent-can-reindent-p ()
245 "Return t if `electric-indent-mode' can performs reindentation."
246 (not (or (memq indent-line-function
247 electric-indent-functions-without-reindent)
248 electric-indent-inhibit)))
249
250(defun electric-indent--yank-advice (fn &rest r)
251 (let ((p (point))
252 (end (line-beginning-position)))
253 (apply fn r)
254 (when (and electric-indent-mode
255 (memq 'yank electric-indent-actions)
256 (electric-indent-can-reindent-p)
257 ;; Ensure yanked text is longer than 1 line
258 (> (point) p)
259 (not (= end (line-beginning-position))))
260 (undo-boundary)
261 (save-excursion
262 (with-demoted-errors "Error reindenting: %S"
263 (indent-region p (point)))))))
264
265(defun electric-indent-save-hook ()
266 (when (and electric-indent-mode
267 ;; Ensure this hook is called interactively
268 (memq real-this-command '(save-buffer basic-save-buffer))
269 (memq 'before-save electric-indent-actions)
270 (not buffer-read-only)
271 (electric-indent-can-reindent-p))
272 (save-excursion
273 (with-demoted-errors "Error reindenting: %S"
274 (indent-region (point-min) (point-max))))))
275
276(defun electric-indent-toggle-indent-actions (enable)
277 "Enable the actions specified in `electric-indent-actions'."
278 (cond
279 ((memq 'yank electric-indent-actions)
280 (if enable
281 (advice-add #'yank :around #'electric-indent--yank-advice)
282 (advice-remove #'yank #'electric-indent--yank-advice)))
283 ((memq 'before-save electric-indent-actions)
284 (if enable
285 (add-hook 'before-save-hook #'electric-indent-save-hook)
286 (remove-hook 'before-save-hook #'electric-indent-save-hook)))))
287
221(defun electric-indent-post-self-insert-function () 288(defun electric-indent-post-self-insert-function ()
222 "Function that `electric-indent-mode' adds to `post-self-insert-hook'. 289 "Function that `electric-indent-mode' adds to `post-self-insert-hook'.
223This indents if the hook `electric-indent-functions' returns non-nil, 290This indents if the hook `electric-indent-functions' returns non-nil,
@@ -256,10 +323,7 @@ or comment."
256 (when at-newline 323 (when at-newline
257 (let ((before (copy-marker (1- pos) t))) 324 (let ((before (copy-marker (1- pos) t)))
258 (save-excursion 325 (save-excursion
259 (unless 326 (when (electric-indent-can-reindent-p)
260 (or (memq indent-line-function
261 electric-indent-functions-without-reindent)
262 electric-indent-inhibit)
263 ;; Don't reindent the previous line if the 327 ;; Don't reindent the previous line if the
264 ;; indentation function is not a real one. 328 ;; indentation function is not a real one.
265 (goto-char before) 329 (goto-char before)
@@ -331,9 +395,13 @@ use `electric-indent-local-mode'."
331 (if electric-indent-mode (throw 'found t))))) 395 (if electric-indent-mode (throw 'found t)))))
332 (remove-hook 'post-self-insert-hook 396 (remove-hook 'post-self-insert-hook
333 #'electric-indent-post-self-insert-function)) 397 #'electric-indent-post-self-insert-function))
398
334 (add-hook 'post-self-insert-hook 399 (add-hook 'post-self-insert-hook
335 #'electric-indent-post-self-insert-function 400 #'electric-indent-post-self-insert-function
336 60))) 401 60))
402
403 ;; Toggle the reindentation on actions
404 (electric-indent-toggle-indent-actions electric-indent-mode))
337 405
338;;;###autoload 406;;;###autoload
339(define-minor-mode electric-indent-local-mode 407(define-minor-mode electric-indent-local-mode