mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
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.
This commit is contained in:
parent
578aeedbe9
commit
2a782c8d28
1 changed files with 73 additions and 5 deletions
|
|
@ -192,6 +192,29 @@ Returns nil when we can't find this char."
|
|||
|
||||
;;; Electric indentation.
|
||||
|
||||
(defcustom electric-indent-actions nil
|
||||
"List of actions to indent.
|
||||
|
||||
The valid elements of this list can be:
|
||||
- yank: Indent the yanked text only if point is not in a string or
|
||||
comment and yanked region is longer than 1 line.
|
||||
- save: Indent the whole buffer before saving it.
|
||||
|
||||
The indentation will not happen when the major mode is unable to
|
||||
reindent code reliably, such as in buffers where indentation is
|
||||
significant."
|
||||
:type '(repeat (choice (const :tag "After yanking" yank)
|
||||
(const :tag "Before saving" before-save)))
|
||||
:set (lambda (var val)
|
||||
(set-default var val)
|
||||
(when electric-indent-mode
|
||||
(electric-indent-mode -1)
|
||||
(electric-indent-mode +1)))
|
||||
:safe (lambda (v)
|
||||
(and (proper-list-p v)
|
||||
(null (seq-filter (lambda (e) (not (symbolp e)) ) v))))
|
||||
:version "31.1")
|
||||
|
||||
;; Autoloading variables is generally undesirable, but major modes
|
||||
;; should usually set this variable by adding elements to the default
|
||||
;; 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
|
|||
not try to reindent lines. It is normally better to make the major
|
||||
mode set `electric-indent-inhibit', but this can be used as a workaround.")
|
||||
|
||||
(defun electric-indent-can-reindent-p ()
|
||||
"Return t if `electric-indent-mode' can performs reindentation."
|
||||
(not (or (memq indent-line-function
|
||||
electric-indent-functions-without-reindent)
|
||||
electric-indent-inhibit)))
|
||||
|
||||
(defun electric-indent--yank-advice (fn &rest r)
|
||||
(let ((p (point))
|
||||
(end (line-beginning-position)))
|
||||
(apply fn r)
|
||||
(when (and electric-indent-mode
|
||||
(memq 'yank electric-indent-actions)
|
||||
(electric-indent-can-reindent-p)
|
||||
;; Ensure yanked text is longer than 1 line
|
||||
(> (point) p)
|
||||
(not (= end (line-beginning-position))))
|
||||
(undo-boundary)
|
||||
(save-excursion
|
||||
(with-demoted-errors "Error reindenting: %S"
|
||||
(indent-region p (point)))))))
|
||||
|
||||
(defun electric-indent-save-hook ()
|
||||
(when (and electric-indent-mode
|
||||
;; Ensure this hook is called interactively
|
||||
(memq real-this-command '(save-buffer basic-save-buffer))
|
||||
(memq 'before-save electric-indent-actions)
|
||||
(not buffer-read-only)
|
||||
(electric-indent-can-reindent-p))
|
||||
(save-excursion
|
||||
(with-demoted-errors "Error reindenting: %S"
|
||||
(indent-region (point-min) (point-max))))))
|
||||
|
||||
(defun electric-indent-toggle-indent-actions (enable)
|
||||
"Enable the actions specified in `electric-indent-actions'."
|
||||
(cond
|
||||
((memq 'yank electric-indent-actions)
|
||||
(if enable
|
||||
(advice-add #'yank :around #'electric-indent--yank-advice)
|
||||
(advice-remove #'yank #'electric-indent--yank-advice)))
|
||||
((memq 'before-save electric-indent-actions)
|
||||
(if enable
|
||||
(add-hook 'before-save-hook #'electric-indent-save-hook)
|
||||
(remove-hook 'before-save-hook #'electric-indent-save-hook)))))
|
||||
|
||||
(defun electric-indent-post-self-insert-function ()
|
||||
"Function that `electric-indent-mode' adds to `post-self-insert-hook'.
|
||||
This indents if the hook `electric-indent-functions' returns non-nil,
|
||||
|
|
@ -256,10 +323,7 @@ or comment."
|
|||
(when at-newline
|
||||
(let ((before (copy-marker (1- pos) t)))
|
||||
(save-excursion
|
||||
(unless
|
||||
(or (memq indent-line-function
|
||||
electric-indent-functions-without-reindent)
|
||||
electric-indent-inhibit)
|
||||
(when (electric-indent-can-reindent-p)
|
||||
;; Don't reindent the previous line if the
|
||||
;; indentation function is not a real one.
|
||||
(goto-char before)
|
||||
|
|
@ -331,9 +395,13 @@ use `electric-indent-local-mode'."
|
|||
(if electric-indent-mode (throw 'found t)))))
|
||||
(remove-hook 'post-self-insert-hook
|
||||
#'electric-indent-post-self-insert-function))
|
||||
|
||||
(add-hook 'post-self-insert-hook
|
||||
#'electric-indent-post-self-insert-function
|
||||
60)))
|
||||
60))
|
||||
|
||||
;; Toggle the reindentation on actions
|
||||
(electric-indent-toggle-indent-actions electric-indent-mode))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode electric-indent-local-mode
|
||||
|
|
|
|||
Loading…
Reference in a new issue