]> git.eshelyaron.com Git - emacs.git/commitdiff
Make erc-input's refoldp slot conditionally available
authorF. Jason Park <jp@neverwas.me>
Fri, 1 Dec 2023 21:54:12 +0000 (13:54 -0800)
committerF. Jason Park <jp@neverwas.me>
Mon, 18 Dec 2023 04:17:54 +0000 (20:17 -0800)
* 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)

etc/ERC-NEWS
lisp/erc/erc-common.el
lisp/erc/erc.el
test/lisp/erc/erc-tests.el

index 934374312891324a00062bf7d33cd7a6657bc5b1..3bb302e1dd28b0139bfad41cb282ae73b22fa1ed 100644 (file)
@@ -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
index fd6ad47664136e2992575220839acd0a94a00922..ce0831709c7035f1ef5a5799a002c9d3c463ed4d 100644 (file)
@@ -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))
index 4d027f0e6c4524af6c09b52e90bd89d04fa26762..7982c23f4a1a583b9ef766306dc0c76747963fd5 100644 (file)
@@ -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)))
index 361e12c2a91907f5ec2867e1e39928666bc81d66..ceb5d86c19ce3fea58a8af3213c15f2054f278f3 100644 (file)
               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))