[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 951b115c2ac 06/19: Make erc-input's refoldp slot conditionally av

From: F. Jason Park
Subject: master 951b115c2ac 06/19: Make erc-input's refoldp slot conditionally available
Date: Sun, 17 Dec 2023 23:21:37 -0500 (EST)

branch: master
commit 951b115c2ac9b60007eef6a13a25c618a69c7e0f
Author: F. Jason Park <jp@neverwas.me>
Commit: F. Jason Park <jp@neverwas.me>

    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--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               |  5 +++--
 lisp/erc/erc-common.el     |  3 ++-
 lisp/erc/erc.el            | 31 +++++++++++++++++++++++++------
 test/lisp/erc/erc-tests.el |  7 ++++---
 4 files changed, 34 insertions(+), 12 deletions(-)

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 
 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
 *** 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))
+  (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' 
                       (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' 
                 (if erc--allow-empty-outgoing-lines-p
                   (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 @@
               (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))
-           (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))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]