summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorTassilo Horn <tsdh@gnu.org>2019-02-23 21:18:36 +0100
committerTassilo Horn <tsdh@gnu.org>2019-02-23 21:31:15 +0100
commite96923c188a2a38d09917c5b7f606187a1413a96 (patch)
tree6ad7b9a1549bf520747db72e36eb62ceb6fcc720 /lisp/emacs-lisp
parent5f640bfdf84753322763be23ebaa8ded92dc1c5d (diff)
downloademacs-e96923c188a2a38d09917c5b7f606187a1413a96.tar.gz
emacs-e96923c188a2a38d09917c5b7f606187a1413a96.tar.bz2
emacs-e96923c188a2a38d09917c5b7f606187a1413a96.zip
Improve replace-buffer-contents/replace-region-contents
* src/editfns.c (Freplace_buffer_contents): Add two optional arguments for mitigating performance issues. * lisp/emacs-lisp/subr-x.el (replace-region-contents): Move from subr.el. Add the same two arguments as for replace-buffer-contents. * lisp/json.el (json-pretty-print-max-secs): New variable holding the default MAX-SECS value json-pretty-print passes to replace-buffer-contents. (json-pretty-print): Use it. * doc/lispref/text.texi (Replacing): Add documentation for replace-buffer-contents two new optional arguments. Document replace-region-contents.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/subr-x.el29
1 files changed, 29 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 7d9f0bba4c7..b9ffe6a6fc6 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -250,6 +250,35 @@ TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"."
(substring string 0 (- (length string) (length suffix)))
string))
+(defun replace-region-contents (beg end replace-fn
+ &optional max-secs max-costs)
+ "Replace the region between BEG and END using REPLACE-FN.
+REPLACE-FN runs on the current buffer narrowed to the region. It
+should return either a string or a buffer replacing the region.
+
+The replacement is performed using `replace-buffer-contents'
+which also describes the MAX-SECS and MAX-COSTS arguments and the
+return value.
+
+Note: If the replacement is a string, it'll be placed in a
+temporary buffer so that `replace-buffer-contents' can operate on
+it. Therefore, if you already have the replacement in a buffer,
+it makes no sense to convert it to a string using
+`buffer-substring' or similar."
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (let ((repl (funcall replace-fn)))
+ (if (bufferp repl)
+ (replace-buffer-contents repl max-secs max-costs)
+ (let ((source-buffer (current-buffer)))
+ (with-temp-buffer
+ (insert repl)
+ (let ((tmp-buffer (current-buffer)))
+ (set-buffer source-buffer)
+ (replace-buffer-contents tmp-buffer max-secs max-costs)))))))))
+
(provide 'subr-x)
;;; subr-x.el ends here