: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
(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)
(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
(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.