Function: combobulate-cursor--update-function
combobulate-cursor--update-function is a natively compiled function
defined in combobulate-cursor.el.
Signature
(combobulate-cursor--update-function BUF TAG)
Documentation
Return a function that updates the overlays in BUF with TAG.
This function is intended to be used in post-command-hook to
update the overlays in BUF with TAG. It is returned as a closure
that captures the minibuffer text at the time of its creation.
Overlays must be valid combobulate-refactor field overlays.
Source Code
;; Defined in /nix/store/b5fvrwzi3zvkabyzx0in6gw1cj963z46-emacs-packages-deps/share/emacs/site-lisp/combobulate-cursor.el
(defun combobulate-cursor--update-function (buf tag)
"Return a function that updates the overlays in BUF with TAG.
This function is intended to be used in `post-command-hook' to
update the overlays in BUF with TAG. It is returned as a closure
that captures the minibuffer text at the time of its creation.
Overlays must be valid `combobulate-refactor' field overlays."
(lambda ()
(let ((idx 0)
;; nab the minibuffer text here (before we change the
;; current buffer) as we return a closure that runs in
;; `post-command-hook' inside the minibuffer prompt
;; machinery, and the minibuffer contents function will,
;; despite its name, happily return the contents of
;; *whatever* buffer is the current buffer, whether it is
;; actually a minibuffer or not.
(minibuffer-text (minibuffer-contents)))
(with-current-buffer buf
(let ((ovs (combobulate--refactor-get-overlays combobulate-cursor--refactor-id)))
(mapc (lambda (ov)
(when (overlay-get ov 'combobulate-refactor-field-enabled)
;; Essential. There's a million things in here
;; that throw errors left and right that'll cause
;; `post-command-hook' to eject us from future
;; updates if it gets a signal.
(ignore-errors
(combobulate--refactor-update-field
ov tag
(let* ((to (query-replace-compile-replacement minibuffer-text t))
;; `replace-eval-replacement' and
;; `query-replace-compile-replacement'
;; rewrites `\,(...)' elisp forms and
;; detects regexp backslash groups such
;; as `\N' and rewrites them as
;; `(match-string N)' ---
;; great. However, we cannot use this
;; feature as it assumes match data is
;; set (as it ordinarily would be in a
;; normal search&replace loop) and the
;; coterie of functions that depend on
;; it.
;;
;; As we're effectively hacking up the
;; replace machinery to work with
;; Combobulate's refactoring system, we
;; either need to rewrite uses of
;; `match-string' to a custom function
;; of our own choosing; ensure match
;; data is set so it matches the field
;; overlays in the buffer, which is
;; complex; or just `cl-letf' it here
;; temporarily.
(replacement-text
(cl-letf (((symbol-function 'match-string)
(lambda (n &optional _string)
(overlay-get
(nth
;; Asking for the 0th
;; match means we want
;; the current
;; overlay's text.
(if (= n 0)
idx
;; Subtract 1 because 0
;; refers to the whole
;; match
(1- n))
ovs)
'combobulate-refactor-field-original-text))))
(or (replace-eval-replacement
(cond
((null to) "")
((stringp to)
(list 'concat to))
(t (cdr to)))
idx)
""))))
(replace-regexp-in-string
combobulate-cursor-substitute-match
(lambda (sub)
;; Avoid using any sort of matching
;; functions here that touches match
;; data. It does not work well due to
;; `replace-regexp-in-string' doing its own
;; thing with the data.
;;
;; Thankfully,
;; `combobulate-cursor-substitute-match'
;; is set to match backslash groups and
;; they are syntactically simple: the
;; first character is a backslash and the
;; rest is a number. Extracting the number
;; is as simple as the substring without
;; the backslash.
(if-let (matched-ov
(let ((num (string-to-number (substring sub 1))))
;; The number 0 is special. In
;; an ordinary search&replace
;; loop it refers to the whole
;; match. Here we repurpose it
;; to mean the original text of
;; the CURRENT field. Also,
;; subtract 1 to account for
;; the 0-based whole match
;; index.
(if (= num 0) (nth idx ovs) (nth (1- num) ovs))))
(overlay-get matched-ov 'combobulate-refactor-field-original-text)
;; No match, return the default text in the minibuffer.
minibuffer-text))
replacement-text))
;; required, as we need to ensure `default-text' is
;; set to a default value that won't cause issues
;; down the road if the eval replacement call does
;; not yield anything.
""))
(cl-incf idx)))
ovs))))))