Function: analyze-text-conversion
analyze-text-conversion is an interactive and byte-compiled function
defined in simple.el.gz.
Signature
(analyze-text-conversion)
Documentation
Analyze the results of the previous text conversion event.
For each insertion:
- Look for the insertion of a string starting or ending with a
character inside auto-fill-chars, and fill the text around
it if auto-fill-mode is enabled.
- Look for the insertion of a new line, and cause automatic
line breaking of the previous line when auto-fill-mode is
enabled.
- Look for the deletion of a single electric pair character,
and delete the adjacent pair if
electric-pair-delete-adjacent-pairs.
- Run post-self-insert-hook for the last character of
any inserted text so that modes such as electric-pair-mode(var)/electric-pair-mode(fun)
can work.
- Run post-text-conversion-hook with last-command-event set
to the last character of any inserted text to finish up.
Finally, amalgamate recent changes to the undo list with previous
ones, unless a new line has been inserted or auto-fill has taken
place. If undo information is being recorded, make sure
undo-auto-current-boundary-timer will run within the next 5
seconds.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/simple.el.gz
(defun analyze-text-conversion ()
"Analyze the results of the previous text conversion event.
For each insertion:
- Look for the insertion of a string starting or ending with a
character inside `auto-fill-chars', and fill the text around
it if `auto-fill-mode' is enabled.
- Look for the insertion of a new line, and cause automatic
line breaking of the previous line when `auto-fill-mode' is
enabled.
- Look for the deletion of a single electric pair character,
and delete the adjacent pair if
`electric-pair-delete-adjacent-pairs'.
- Run `post-self-insert-hook' for the last character of
any inserted text so that modes such as `electric-pair-mode'
can work.
- Run `post-text-conversion-hook' with `last-command-event' set
to the last character of any inserted text to finish up.
Finally, amalgamate recent changes to the undo list with previous
ones, unless a new line has been inserted or auto-fill has taken
place. If undo information is being recorded, make sure
`undo-auto-current-boundary-timer' will run within the next 5
seconds."
(interactive)
;; One important consideration to bear in mind when adjusting this
;; code is to _never_ move point in reaction to an edit so long as
;; the additional processing undertaken by this function does not
;; also edit the buffer text.
(let ((any-nonephemeral nil)
point-moved)
;; The list must be processed in reverse.
(dolist (edit (reverse text-conversion-edits))
;; Filter out ephemeral edits and deletions after point. Here, we
;; are only interested in insertions or deletions whose contents
;; can be identified.
(when (stringp (nth 3 edit))
(with-current-buffer (car edit)
;; Record that the point hasn't been moved by the execution
;; of a post command or text conversion hook.
(setq point-moved nil)
(if (not (eq (nth 1 edit) (nth 2 edit)))
;; Process this insertion. (nth 3 edit) is the text which
;; was inserted.
(let* ((inserted (nth 3 edit))
;; Get the first and last characters.
(start (aref inserted 0))
(end (aref inserted (1- (length inserted))))
;; Figure out whether or not to auto-fill.
(auto-fill-p (or (aref auto-fill-chars start)
(aref auto-fill-chars end)))
;; Figure out whether or not a newline was inserted.
(newline-p (string-search "\n" inserted))
;; Save the current undo list to figure out
;; whether or not auto-fill has actually taken
;; place.
(old-undo-list buffer-undo-list)
;; Save the point position to return it there
;; later.
(old-point (point)))
(save-excursion
(if (and auto-fill-function newline-p)
(progn (goto-char (nth 2 edit))
(previous-logical-line)
(funcall auto-fill-function)
(setq old-point (point)))
(when (and auto-fill-function auto-fill-p)
(goto-char (nth 2 edit))
(funcall auto-fill-function)
(setq old-point (point))))
;; Record whether or not this edit should result in
;; an undo boundary being added.
(setq any-nonephemeral
(or any-nonephemeral newline-p
;; See if auto-fill has taken place by
;; comparing the current undo list with
;; the saved head.
(not (eq old-undo-list
buffer-undo-list)))))
(goto-char (nth 2 edit))
(let ((last-command-event end)
(point (point)))
(unless (run-hook-with-args-until-success
'post-text-conversion-hook)
(run-hooks 'post-self-insert-hook))
(when (not (eq (point) point))
(setq point-moved t)))
;; If post-self-insert-hook doesn't move the point,
;; restore it to its previous location. Generally,
;; the call to goto-char upon processing the last edit
;; recorded text-conversion-edit will see to this, but
;; if the input method sets point expressly, no edit
;; will be recorded, and point will wind up away from
;; where the input method believes it is.
(unless point-moved
(goto-char old-point)))
;; Process this deletion before point. (nth 2 edit) is the
;; text which was deleted. Input methods typically prefer
;; to edit words instead of deleting characters off their
;; ends, but they seem to always send proper requests for
;; deletion for punctuation.
(when (and (boundp 'electric-pair-delete-adjacent-pairs)
(symbol-value 'electric-pair-delete-adjacent-pairs)
;; Make sure elec-pair is loaded.
(fboundp 'electric-pair-analyze-conversion)
;; Only do this if only a single edit happened.
text-conversion-edits)
(save-excursion
(goto-char (nth 2 edit))
(electric-pair-analyze-conversion (nth 3 edit))))))))
;; If all edits were ephemeral, make this an amalgamating command.
;; Then, make sure that an undo boundary is placed within the next
;; five seconds.
(unless any-nonephemeral
(undo-auto-amalgamate)
(let ((timer undo-auto-current-boundary-timer))
(if timer
;; The timer is already running. See if it's due to expire
;; within the next five seconds.
(let ((time (timer--time timer)))
(unless (<= (time-convert (time-subtract time nil)
'integer)
5)
;; It's not, so make it run in 5 seconds.
(timer-set-time undo-auto-current-boundary-timer
(time-add nil 5))))
;; Otherwise, start it for five seconds from now.
(setq undo-auto-current-boundary-timer
(run-at-time 5 nil #'undo-auto--boundary-timer)))))))