]> git.eshelyaron.com Git - emacs.git/commitdiff
Optionally prevent sending multiline input in ERC
authorF. Jason Park <jp@neverwas.me>
Wed, 27 Apr 2022 09:27:32 +0000 (02:27 -0700)
committerF. Jason Park <jp@neverwas.me>
Thu, 30 Jun 2022 22:19:53 +0000 (15:19 -0700)
* lisp/erc/erc.el (erc-inhibit-multiline-input): Add option to cap the
number of lines to be sent before admonishing the user.
(erc-ask-about-multiline-input): Add option to ask instead of warning
user when `erc-inhibit-multiline-input' is reached.
(erc--check-prompt-input-for-excess-lines): Add validator to possibly
warn when too many lines are submitted for transmission.

* test/lisp/erc/erc-tests.el
(erc--check-prompt-input-for-excess-lines): Add test.
(Bug#54536)

lisp/erc/erc.el
test/lisp/erc/erc-tests.el

index 89ce713fe026d66c70a6716add172037e7d8266b..6f17e4ee7b7d251552f7e0588780b9ed4862fcde 100644 (file)
@@ -260,6 +260,20 @@ node `(auth) Top' and info node `(erc) Connecting'.")
   :group 'erc
   :type 'boolean)
 
+(defcustom erc-inhibit-multiline-input nil
+  "Conditionally disallow input consisting of multiple lines.
+Issue an error when the number of input lines submitted for
+sending exceeds this value."
+  :package-version '(ERC . "5.4.1") ; FIXME match to next release
+  :group 'erc
+  :type '(choice integer boolean))
+
+(defcustom erc-ask-about-multiline-input nil
+  "Ask to ignore `erc-inhibit-multiline-input' when tripped."
+  :package-version '(ERC . "5.4.1") ; FIXME match to next release
+  :group 'erc
+  :type 'boolean)
+
 (defcustom erc-prompt-hidden ">"
   "Text to show in lieu of the prompt when hidden."
   :package-version '(ERC . "5.4.1") ; FIXME increment on next ELPA release
@@ -5890,6 +5904,23 @@ is empty or consists of one or more spaces, tabs, or form-feeds."
                 (string-match (rx bot (* (in " \t\f")) eot) line))
           (throw 'return t))))))
 
+(defun erc--check-prompt-input-for-excess-lines (_ lines)
+  "Return non-nil when trying to send too many LINES."
+  (when erc-inhibit-multiline-input
+    ;; Assume `erc--discard-trailing-multiline-nulls' is set to run
+    (let ((reversed (seq-drop-while #'string-empty-p (reverse lines)))
+          (max (if (eq erc-inhibit-multiline-input t)
+                   2
+                 erc-inhibit-multiline-input))
+          (seen 0)
+          msg)
+      (while (and (pop reversed) (< (cl-incf seen) max)))
+      (when (= seen max)
+        (setq msg (format "(exceeded by %d)" (1+ (length reversed))))
+        (unless (and erc-ask-about-multiline-input
+                     (y-or-n-p (concat "Send input " msg "?")))
+          (concat "Too many lines " msg))))))
+
 (defun erc--check-prompt-input-for-multiline-blanks (_ lines)
   "Return non-nil when multiline prompt input has blank LINES."
   (when (erc--blank-in-multiline-input-p lines)
@@ -5911,7 +5942,8 @@ is empty or consists of one or more spaces, tabs, or form-feeds."
 (defvar erc--check-prompt-input-functions
   '(erc--check-prompt-input-for-point-in-bounds
     erc--check-prompt-input-for-multiline-blanks
-    erc--check-prompt-input-for-running-process)
+    erc--check-prompt-input-for-running-process
+    erc--check-prompt-input-for-excess-lines)
   "Validators for user input typed at prompt.
 Called with latest input string submitted by user and the list of
 lines produced by splitting it.  If any member function returns
index 986988a3356bcdfd20a1bd4b26c9bf9da25e293b..62bea8fb3f005c59c9a7e3d32680c92db9828fcb 100644 (file)
        (should (equal (funcall next) '("there\n" nil t)))
        (should-not (funcall next))))))
 
+(ert-deftest erc--check-prompt-input-for-excess-lines ()
+  (ert-info ("Without `erc-inhibit-multiline-input'")
+    (should-not erc-inhibit-multiline-input)
+    (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b"))))
+
+  (ert-info ("With `erc-inhibit-multiline-input' as t (2)")
+    (let ((erc-inhibit-multiline-input t))
+      (should-not (erc--check-prompt-input-for-excess-lines "" '("a")))
+      (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "")))
+      (should (erc--check-prompt-input-for-excess-lines "" '("a" "b")))))
+
+  (ert-info ("With `erc-inhibit-multiline-input' as 3")
+    (let ((erc-inhibit-multiline-input 3))
+      (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b")))
+      (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b" "")))
+      (should (erc--check-prompt-input-for-excess-lines "" '("a" "b" "c")))))
+
+  (ert-info ("With `erc-ask-about-multiline-input'")
+    (let ((erc-inhibit-multiline-input t)
+          (erc-ask-about-multiline-input t))
+      (ert-simulate-keys '(?n ?\r ?y ?\r)
+        (should (erc--check-prompt-input-for-excess-lines "" '("a" "b")))
+        (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b")))))
+    (should-not erc-ask-about-multiline-input)))
+
 ;; The point of this test is to ensure output is handled identically
 ;; regardless of whether a command handler is summoned.