summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/subr-x.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/subr-x.el')
-rw-r--r--lisp/emacs-lisp/subr-x.el54
1 files changed, 43 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 15c9a824d39..bb2bf3dd5fa 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -152,14 +152,15 @@ are non-nil, then the result is non-nil."
(let (res)
(if varlist
`(let* ,(setq varlist (internal--build-bindings varlist))
- (if ,(setq res (caar (last varlist)))
- ,@(or body `(,res))))
+ (when ,(setq res (caar (last varlist)))
+ ,@(or body `(,res))))
`(let* () ,@(or body '(t))))))
(defmacro if-let (spec then &rest else)
"Bind variables according to SPEC and evaluate THEN or ELSE.
-Evaluate each binding in turn, stopping if a binding value is nil.
-If all are non-nil return the value of THEN, otherwise the last form in ELSE.
+Evaluate each binding in turn, as in `let*', stopping if a
+binding value is nil. If all are non-nil return the value of
+THEN, otherwise the last form in ELSE.
Each element of SPEC is a list (SYMBOL VALUEFORM) that binds
SYMBOL to the value of VALUEFORM. An element can additionally be
@@ -208,7 +209,7 @@ The variable list SPEC is the same as in `if-let'."
(defsubst string-join (strings &optional separator)
"Join all STRINGS using SEPARATOR."
- (mapconcat 'identity strings separator))
+ (mapconcat #'identity strings separator))
(define-obsolete-function-alias 'string-reverse 'reverse "25.1")
@@ -216,17 +217,17 @@ The variable list SPEC is the same as in `if-let'."
"Trim STRING of leading string matching REGEXP.
REGEXP defaults to \"[ \\t\\n\\r]+\"."
- (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string)
- (replace-match "" t t string)
+ (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string)
+ (substring string (match-end 0))
string))
(defsubst string-trim-right (string &optional regexp)
"Trim STRING of trailing string matching REGEXP.
REGEXP defaults to \"[ \\t\\n\\r]+\"."
- (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string)
- (replace-match "" t t string)
- string))
+ (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'")
+ string)))
+ (if i (substring string 0 i) string)))
(defsubst string-trim (string &optional trim-left trim-right)
"Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT.
@@ -235,7 +236,9 @@ TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"."
(string-trim-left (string-trim-right string trim-right) trim-left))
(defsubst string-blank-p (string)
- "Check whether STRING is either empty or only whitespace."
+ "Check whether STRING is either empty or only whitespace.
+The following characters count as whitespace here: space, tab, newline and
+carriage return."
(string-match-p "\\`[ \t\n\r]*\\'" string))
(defsubst string-remove-prefix (prefix string)
@@ -250,6 +253,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