Subject: 28.0.50; Do not require subr-x at run time

From: Tino Calancha <[email-masked]>
Date: Mon, 10 Feb 2020 14:59:42 +0100

X-Debbugs-Cc: Tassilo Horn <[email-masked]>,Michael Albinus <[email-masked]>,Lars Magne Ingebrigtsen <[email-masked]>
Severity: wishlist
tags: patch

This patch replaces
(require subr-x)
with
(eval-when-compile (require 'subr-x))

on several files using just defsubst/defmacro from subr-x.el.

In addition, it moves back replace-region-contents into subr.el: been a defun,
and documented in the manual, then it fits better inside subr.el.

--8<-----------------------------cut here---------------start------------->8---
commit 87abdb434ad892256c4a432eb86ac5628d253891
Author: Constantino Calancha <[email-masked]>
Date:   Mon Feb 10 14:19:10 2020 +0100

    Do not require subr-x at run time
    
    Move back `replace-region-contents' to subr.el according
    with the convention for subr-x.
    * calendar/time-date.el
    * net/net-utils.el
    * net/nsm.el
    * net/tramp-compat.el:
    Require subr-x at compile time.
    
    * lisp/subr.el (replace-region-contents): Move it from subr-x.el.
    
    * lisp/emacs-lisp/json.el:  Do not require subr-x since now
    `replace-region-contents' is loaded at start up.

diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index e2402de801..b4b13037bf 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -37,7 +37,7 @@
 ;;; Code:
 
 (require 'cl-lib)
-(require 'subr-x)
+(eval-when-compile (require 'subr-x))
 
 (defmacro with-decoded-time-value (varlist &rest body)
   "Decode a time value and bind it according to VARLIST, then eval BODY.
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 044c9aada0..883607a549 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -254,34 +254,6 @@ string-remove-suffix
       (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)
 
diff --git a/lisp/json.el b/lisp/json.el
index 18d7fda882..e31928e825 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -55,7 +55,6 @@
 ;;; Code:
 
 (require 'map)
-(require 'subr-x)
 
 ;; Parameters
 
diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el
index ef3651b033..780f34b028 100644
--- a/lisp/net/net-utils.el
+++ b/lisp/net/net-utils.el
@@ -44,7 +44,7 @@
 ;; days is for /sbin to be a symlink to /usr/sbin, but we still need to
 ;; search both for older systems.
 
-(require 'subr-x)
+(eval-when-compile (require 'subr-x))
 (require 'cl-lib)
 
 (defun net-utils--executable-find-sbin (command)
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el
index 2d36c5e257..f85529f726 100644
--- a/lisp/net/nsm.el
+++ b/lisp/net/nsm.el
@@ -26,7 +26,7 @@
 
 (require 'cl-lib)
 (require 'rmc)                       ; read-multiple-choice
-(require 'subr-x)
+(eval-when-compile (require 'subr-x))
 (require 'seq)
 (require 'map)
 
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index 87bcd08b85..8f74683dee 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -39,7 +39,7 @@ tramp-unload-file-name-handlers
 (require 'ls-lisp)  ;; Due to `tramp-handle-insert-directory'.
 (require 'parse-time)
 (require 'shell)
-(require 'subr-x)
+(eval-when-compile (require 'subr-x))
 
 ;; `temporary-file-directory' as function is introduced with Emacs 26.1.
 (declare-function tramp-handle-temporary-file-directory "tramp")
diff --git a/lisp/subr.el b/lisp/subr.el
index b5ec0de156..406cc50611 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -5768,6 +5768,35 @@ flatten-tree
 ;; for discoverability:
 (defalias 'flatten-list 'flatten-tree)
 
+(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)))))))))
+
 ;; The initial anchoring is for better performance in searching matches.
 (defconst regexp-unmatchable "\\`a\\`"
   "Standard regexp guaranteed not to match any string at all.")

--8<-----------------------------cut here---------------end--------------->8---

In GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, Xaw scroll bars)
 of 2020-02-10 built on localhost.example.com
Repository revision: ac9acc1864b02b92de4eb2e98db7b5b0cd03e019
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12007000
System Description: openSUSE Tumbleweed