Function: projectile-replace--apply-file
projectile-replace--apply-file is a byte-compiled function defined in
projectile.el.
Signature
(projectile-replace--apply-file FILE MATCHES REPLACEMENT LITERAL)
Documentation
Apply MATCHES in FILE and return its undo edits, or the symbol skipped.
Edits run from the highest buffer position downwards so earlier edits
don't shift later matches. The live buffer visiting FILE (if any) is
re-resolved now rather than trusted from scan time, so a file opened
since the scan is edited in its buffer instead of being clobbered on
disk, and a scan-time buffer that has since been killed is handled. In
either case the recorded positions are verified to still span the matched
text; if not (the file or buffer changed since the scan) the file is
skipped rather than corrupted. A clean buffer is saved; a buffer with
unsaved changes is edited but left for the user to save. The returned
edits describe what was really written, and feed projectile-replace-undo.
Source Code
;; Defined in ~/.emacs.d/elpa/projectile-20260820.1509/projectile.el
(defun projectile-replace--apply-file (file matches replacement literal)
"Apply MATCHES in FILE and return its undo edits, or the symbol `skipped'.
Edits run from the highest buffer position downwards so earlier edits
don't shift later matches. The live buffer visiting FILE (if any) is
re-resolved now rather than trusted from scan time, so a file opened
since the scan is edited in its buffer instead of being clobbered on
disk, and a scan-time buffer that has since been killed is handled. In
either case the recorded positions are verified to still span the matched
text; if not (the file or buffer changed since the scan) the file is
skipped rather than corrupted. A clean buffer is saved; a buffer with
unsaved changes is edited but left for the user to save. The returned
edits describe what was really written, and feed `projectile-replace-undo'."
(let* ((descending (sort (copy-sequence matches)
(lambda (a b)
(> (projectile-replace--match-beg a)
(projectile-replace--match-beg b)))))
(buffer (get-file-buffer file)))
(if (buffer-live-p buffer)
(with-current-buffer buffer
(if (not (projectile-replace--positions-valid-p descending))
(projectile-replace--skip (buffer-name buffer) "changed since scan")
(let ((was-modified (buffer-modified-p)))
(save-excursion
(save-restriction
(widen)
(atomic-change-group
(dolist (m descending)
(projectile-replace--do-one m replacement literal)))))
;; don't silently save a buffer that already had unsaved edits
(unless was-modified
(let ((require-final-newline nil))
(save-buffer)))
(projectile-replace--undo-edits matches replacement literal))))
(with-temp-buffer
(insert-file-contents file)
(let ((coding last-coding-system-used))
(if (not (projectile-replace--positions-valid-p descending))
(projectile-replace--skip (file-name-nondirectory file)
"changed on disk since scan")
(dolist (m descending)
(projectile-replace--do-one m replacement literal))
(let ((coding-system-for-write coding))
(write-region (point-min) (point-max) file nil 'no-message))
(projectile-replace--undo-edits matches replacement literal)))))))