From: F. Jason Park Date: Fri, 1 Dec 2023 21:54:12 +0000 (-0800) Subject: Make erc-input's refoldp slot conditionally available X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=951b115c2ac9b60007eef6a13a25c618a69c7e0f;p=emacs.git Make erc-input's refoldp slot conditionally available * etc/ERC-NEWS: Fix entry regarding `erc-input-refoldp'. * lisp/erc/erc-common.el (erc-input): Remove `refoldp' slot, which was to be new in 5.6, in order to reduce churn in the extremely unlikely event that third-party code uses the read-syntax of these objects or ones subclassed from it for some other purpose, outside of `erc-pre-send-functions'. (erc--input-split) Add `refoldp' slot here instead. * lisp/erc/erc.el (erc-pre-send-functions): Amend doc string to stress that `refoldp' is not a real slot. (erc--input-ensure-hook-context, erc-input-refoldp): New function, an impostor accessor for the nonexistent `refoldp' slot of `erc-input', and a helper function for asserting a valid context at runtime. (erc--run-send-hooks): Don't copy over `refoldp' from the `erc--input-lines' object to the working `erc-insert' object. Check the insertion context's `erc--input-split' object instead of the hook's `erc-insert' object when deciding whether to resplit. * test/lisp/erc/erc-tests.el: Adjust test environment to satisfy assertion. (Bug#62947) --- diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 93437431289..3bb302e1dd2 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -464,8 +464,9 @@ ERC now adjusts input lines to fall within allowed length limits before showing hook members the result. For compatibility, third-party code can request that the final input be adjusted again prior to being sent. To facilitate this, the 'erc-input' object -shared among hook members has gained a new 'refoldp' slot, making this -a breaking change, if only in theory. See doc string for details. +shared among hook members has gained a "phony" 'refoldp' slot that's +only accessible from 'erc-pre-send-functions'. See doc string for +details. *** ERC's prompt survives the insertion of user input and messages. Previously, ERC's prompt and its input marker disappeared while diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index fd6ad476641..ce0831709c7 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el @@ -49,7 +49,7 @@ (declare-function widget-type "wid-edit" (widget)) (cl-defstruct erc-input - string insertp sendp refoldp) + string insertp sendp) (cl-defstruct (erc--input-split (:include erc-input (string :read-only) @@ -57,6 +57,7 @@ (sendp (with-suppressed-warnings ((obsolete erc-send-this)) erc-send-this)))) + (refoldp nil :type boolean) (lines nil :type (list-of string)) (abortp nil :type (list-of symbol)) (cmdp nil :type boolean)) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 4d027f0e6c4..7982c23f4a1 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1195,13 +1195,18 @@ The struct has three slots: `string': The current input string. `insertp': Whether the string should be inserted into the erc buffer. `sendp': Whether the string should be sent to the irc server. + +And one \"phony\" slot only accessible by hook members at runtime: + `refoldp': Whether the string should be re-split per protocol limits. This hook runs after protocol line splitting has taken place, so the value of `string' is originally \"pre-filled\". If you need -ERC to refill the entire payload before sending it, set the -`refoldp' slot to a non-nil value. Preformatted text and encoded -subprotocols should probably be handled manually." +ERC to refill the entire payload before sending it, set the phony +`refoldp' slot to a non-nil value. Note that this refilling is +only a convenience, and modules with special needs, such as +preserving \"preformatted\" text or encoding for subprotocol +\"tunneling\", should handle splitting manually." :group 'erc :type 'hook :version "27.1") @@ -7405,6 +7410,22 @@ When all lines are empty, remove all but the first." (setf (erc--input-split-lines state) (mapcan #'erc--split-line (erc--input-split-lines state))))) +(defun erc--input-ensure-hook-context () + (unless (erc--input-split-p erc--current-line-input-split) + (error "Invoked outside of `erc-pre-send-functions'"))) + +(defun erc-input-refoldp (_) + "Impersonate accessor for phony `erc-input' `refoldp' slot. +This function only works inside `erc-pre-send-functions' members." + (declare (gv-setter (lambda (v) + `(progn + (erc--input-ensure-hook-context) + (setf (erc--input-split-refoldp + erc--current-line-input-split) + ,v))))) + (erc--input-ensure-hook-context) + (erc--input-split-refoldp erc--current-line-input-split)) + (defun erc--run-send-hooks (lines-obj) "Run send-related hooks that operate on the entire prompt input. Sequester some of the back and forth involved in honoring old @@ -7424,8 +7445,6 @@ queue. Expect LINES-OBJ to be an `erc--input-split' object." (run-hook-with-args 'erc-send-pre-hook str) (make-erc-input :string str :insertp erc-insert-this - :refoldp (erc--input-split-refoldp - lines-obj) :sendp erc-send-this)))) (run-hook-with-args 'erc-pre-send-functions state) (setf (erc--input-split-sendp lines-obj) (erc-input-sendp state) @@ -7437,7 +7456,7 @@ queue. Expect LINES-OBJ to be an `erc--input-split' object." (if erc--allow-empty-outgoing-lines-p lines (cl-nsubst " " "" lines :test #'equal)))) - (when (erc-input-refoldp state) + (when (erc--input-split-refoldp lines-obj) (erc--split-lines lines-obj))))) (when (and (erc--input-split-cmdp lines-obj) (cdr (erc--input-split-lines lines-obj))) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 361e12c2a91..ceb5d86c19c 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -2254,10 +2254,11 @@ erc-pre-send-functions (lambda (o) (setf (erc-input-string o) "foo bar baz" (erc-input-refoldp o) t))) - (let ((erc-split-line-length 8)) + (let* ((split (make-erc--input-split :string "foo" :lines '("foo"))) + (erc--current-line-input-split split) + (erc-split-line-length 8)) (should - (pcase (erc--run-send-hooks (make-erc--input-split - :string "foo" :lines '("foo"))) + (pcase (erc--run-send-hooks split) ((cl-struct erc--input-split (string "foo") (sendp 't) (insertp 't) (lines '("foo bar " "baz")) (cmdp 'nil))