bug#68265: 30.0.50; ERC 5.6: Simplify alternate text insertion for outgoing messages
"J.P." <[email protected]> Fri, 05 Jan 2024 06:54:55 -0800
| Newsgroups | gmane.emacs.erc.general |
|---|---|
| Message-ID | <[email protected]> |
Tags: patch Spoofing messages submitted at the prompt is currently a chore. By this, I mean inserting chat content that differs from what's actually sent. For years, users have resorted to all manner of awkward finagling (typically in `erc-send-modify-hook' members) to accomplish "simple" things, like finding where the leading speaker portion ends and the message proper begins. The proposal here is to add an "alternate text" slot to the `erc-input' object passed around by `erc-pre-send-functions'. Use cases include - language translation - sub-protocol encoding - the IRCv3 multiline extension For the upcoming release, users will already have to recompile their dependent packages, so we might as well seize this opportunity to modify core schemata (if truly warranted). Demo implementation for an existing third-party package forthcoming. Thanks. In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38, cairo version 1.17.6) of 2024-01-04 built on localhost Repository revision: 1081e975c9370999df1a288b117bfd9053050d21 Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12014000 System Description: Fedora Linux 37 (Workstation Edition) Configured using: 'configure --enable-check-lisp-object-type --enable-checking=yes,glyphs 'CFLAGS=-O0 -g3' PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig' Configured features: ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB Important settings: value of $LANG: en_US.UTF-8 value of $XMODIFIERS: @im=ibus locale-coding-system: utf-8-unix Major mode: Lisp Interaction Minor modes in effect: tooltip-mode: t global-eldoc-mode: t eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t minibuffer-regexp-mode: t line-number-mode: t indent-tabs-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug message mailcap yank-media puny dired dired-loaddefs rfc822 mml mml-sec epa epg rfc6068 epg-config gnus-util time-date mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils compile text-property-search comint ansi-osc ansi-color ring comp-run comp-common erc derived auth-source eieio eieio-core password-cache json map format-spec erc-backend erc-networks easy-mmode byte-opt bytecomp byte-compile erc-common inline cl-extra help-mode erc-compat cl-seq cl-macs gv pcase rx subr-x cl-loaddefs cl-lib erc-loaddefs rmc iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic indonesian philippine cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp files window text-properties overlay sha1 md5 base64 format env code-pages mule custom widget keymap hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting cairo gtk x-toolkit xinput2 x multi-tty move-toolbar make-network-process native-compile emacs) Memory information: ((conses 16 149907 11404) (symbols 48 11361 0) (strings 32 27740 4779) (string-bytes 1 971593) (vectors 16 17647) (vector-slots 8 310679 13296) (floats 8 27 25) (intervals 56 330 0) (buffers 976 12))
0001-5.6-Make-erc-send-input-lines-a-normal-function.patch
(text/x-patch, 1.6 KB)
From 572d24e5b37cdc1a89a5ea4f328ac6446ab36a8c Mon Sep 17 00:00:00 2001 From: "F. Jason Park" <[email protected]> Date: Mon, 1 Jan 2024 00:34:53 -0800 Subject: [PATCH 1/4] [5.6] Make erc--send-input-lines a normal function * lisp/erc/erc.el (erc--send-input-lines): Revert portion of 174b3dd9bd78c662ce9fff78404dcfa02259d21b "Make nested input handling more robust in ERC" that converted this from a function to a method. Instead, defer change until it's needed, likely for bug#49860. Also, don't overload `insertp' because user code can legitimately set that to a function, which we then blindly call. --- lisp/erc/erc.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index e639a6278fc..1243a331bca 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -7878,14 +7878,12 @@ erc--run-send-hooks (user-error "Multiline command detected" )) lines-obj) -(cl-defmethod erc--send-input-lines (lines-obj) +(defun erc--send-input-lines (lines-obj) "Send lines in `erc--input-split-lines' object LINES-OBJ." (when (erc--input-split-sendp lines-obj) (dolist (line (erc--input-split-lines lines-obj)) (when (erc--input-split-insertp lines-obj) - (if (functionp (erc--input-split-insertp lines-obj)) - (funcall (erc--input-split-insertp lines-obj) line) - (erc-display-msg line))) + (erc-display-msg line)) (erc-process-input-line (concat line "\n") (null erc-flood-protect) (not (erc--input-split-cmdp lines-obj)))))) -- 2.42.0
0002-5.6-Allow-setting-erc-split-line-length-to-zero.patch
(text/x-patch, 4.1 KB)
From 980201aa92598de00a4d600dd85bc9c69e263755 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" <[email protected]> Date: Wed, 3 Jan 2024 02:00:45 -0800 Subject: [PATCH 2/4] [5.6] Allow setting `erc-split-line-length' to zero * etc/ERC-NEWS: Mention `erc-flood-protect' no longer affects line splitting. * lisp/erc/erc-backend.el (erc-split-line-length): Mention ways to suppress line splitting entirely. (erc--split-line): Exit loop instead of asserting progress has been made. * lisp/erc/erc.el (erc--split-lines): Don't split input when `erc-split-line-length is zero. * test/lisp/erc/erc-tests.el (erc--split-line): Assert behavior when `erc-split-line-length' is 0. --- etc/ERC-NEWS | 6 ++++++ lisp/erc/erc-backend.el | 9 +++++++-- lisp/erc/erc.el | 2 +- test/lisp/erc/erc-tests.el | 8 ++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index c51b6f05458..3eb929063b2 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -560,6 +560,12 @@ third-party code, the key takeaway is that more 'font-lock-face' properties encountered in the wild may be combinations of faces rather than lone ones. +*** 'erc-flood-protect' no longer influences input splitting. +This variable's role has been narrowed to affecting rate limiting +only. ERC used to suppress protocol line-splitting when its value was +nil, but that's now handled by setting 'erc-split-line-length' to +zero. + *** 'erc-pre-send-functions' visits prompt input post-split. ERC now adjusts input lines to fall within allowed length limits before showing hook members the result. For compatibility, diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 4162df00595..95207e56fd1 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -433,7 +433,11 @@ erc-server-reconnect-function (defcustom erc-split-line-length 440 "The maximum length of a single message. -If a message exceeds this size, it is broken into multiple ones. +ERC normally splits chat input submitted at its prompt into +multiple messages when the initial size exceeds this value in +bytes. Modules can tell ERC to forgo splitting entirely by +setting this to zero locally or, preferably, by binding it around +a remapped `erc-send-current-line' command. IRC allows for lines up to 512 bytes. Two of them are CR LF. And a typical message looks like this: @@ -596,7 +600,8 @@ erc--split-line (if (= (car cmp) (point-min)) (goto-char (nth 1 cmp)) (goto-char (car cmp))))) - (cl-assert (/= (point-min) (point))) + (when (= (point-min) (point)) + (goto-char (point-max))) (push (buffer-substring-no-properties (point-min) (point)) out) (delete-region (point-min) (point))) (or (nreverse out) (list ""))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 1243a331bca..abb9d3830dd 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -7821,7 +7821,7 @@ erc--split-lines "Partition non-command input into lines of protocol-compliant length." ;; Prior to ERC 5.6, line splitting used to be predicated on ;; `erc-flood-protect' being non-nil. - (unless (erc--input-split-cmdp state) + (unless (or (zerop erc-split-line-length) (erc--input-split-cmdp state)) (setf (erc--input-split-lines state) (mapcan #'erc--split-line (erc--input-split-lines state))))) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 2cd47ec3f89..a9aa255718d 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -1298,6 +1298,14 @@ erc-log-irc-protocol (should-not erc-debug-irc-protocol))) (ert-deftest erc--split-line () + (let ((erc-split-line-length 0)) + (should (equal (erc--split-line "") '(""))) + (should (equal (erc--split-line " ") '(" "))) + (should (equal (erc--split-line "1") '("1"))) + (should (equal (erc--split-line " 1") '(" 1"))) + (should (equal (erc--split-line "1 ") '("1 "))) + (should (equal (erc--split-line "abc") '("abc")))) + (let ((erc-default-recipients '("#chan")) (erc-split-line-length 10)) (should (equal (erc--split-line "") '(""))) -- 2.42.0
0003-5.6-Make-ERC-s-format-catalogs-more-extensible.patch
(text/x-patch, 5.3 KB)
From 43501ac2e921829bff21b0253fed5a17c2294b06 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" <[email protected]> Date: Wed, 3 Jan 2024 23:10:55 -0800 Subject: [PATCH 3/4] [5.6] Make ERC's format catalogs more extensible * lisp/erc/erc-common.el (erc--define-catalog): Accept a `:parent' keyword to allow for extending an existing catalog by overriding some subset of defined entries. (erc-define-message-format-catalog): Add edebug spec. * lisp/erc/erc.el (erc-retrieve-catalog-entry): Check parent for definition before `default-toplevel-value'. * test/lisp/erc/erc-tests.el (erc-retrieve-catalog-entry): Add test case for inheritance. * test/lisp/erc/resources/erc-tests-common.el (erc-tests-common-pp-propertized-parts): Fix bug in helper. (Bug#67677) --- lisp/erc/erc-common.el | 17 +++++++++++++++-- lisp/erc/erc.el | 6 ++++++ test/lisp/erc/erc-tests.el | 16 +++++++++++++++- test/lisp/erc/resources/erc-tests-common.el | 2 +- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index b8ba0673355..2581e40f850 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el @@ -554,9 +554,21 @@ erc--define-catalog ENTRIES, an alist, and `erc-tests-common-pp-propertized-parts' in tests/lisp/erc/erc-tests.el for a convenience command to convert a literal string into a sequence of `propertize' forms, which are -much easier to review and edit." +much easier to review and edit. When ENTRIES begins with a +sequence of keyword-value pairs remove them and consider their +evaluated values before processing the alist proper. + +Currently, the only recognized keyword is `:parent', which tells +ERC to search recursively for a given template key using the +keyword's associated value, another catalog symbol, if not found +in catalog NAME." (declare (indent 1)) (let (out) + (while (keywordp (car entries)) + (push (pcase-exhaustive (pop entries) + (:parent `(put ',name 'erc--base-format-catalog + ,(pop entries)))) + out)) (dolist (e entries (cons 'progn (nreverse out))) (push `(defvar ,(intern (format "erc-message-%s-%s" name (car e))) ,(cdr e) @@ -575,7 +587,8 @@ erc-define-message-format-catalog `format-spec'. Expect modules that only define a handful of entries to do so manually, instead of using this macro, so that the resulting variables will end up with more useful doc strings." - (declare (indent 1)) + (declare (indent 1) + (debug (symbolp [&rest [keywordp form]] &rest (symbolp . form)))) `(erc--define-catalog ,language ,entries)) (defmacro erc--doarray (spec &rest body) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index abb9d3830dd..1e208b8204f 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -9317,6 +9317,12 @@ erc-retrieve-catalog-entry (unless catalog (setq catalog erc-current-message-catalog)) (symbol-value (or (erc--make-message-variable-name catalog key 'softp) + (let ((parent catalog) + last) + (while (and (setq parent (get parent 'erc--base-format-catalog)) + (not (setq last (erc--make-message-variable-name + parent key 'softp))))) + last) (let ((default (default-toplevel-value 'erc-current-message-catalog))) (or (and (not (eq default catalog)) (erc--make-message-variable-name default key 'softp)) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index a9aa255718d..a71cc806f6a 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -3533,6 +3533,20 @@ erc-retrieve-catalog-entry (should (equal (erc-retrieve-catalog-entry 's221) "test-top 221 val")) (makunbound (intern "erc-message-test-top-s221")) - (unintern "erc-message-test-top-s221" obarray)) + (unintern "erc-message-test-top-s221" obarray) + + ;; Inheritance. + (let ((obarray (obarray-make))) + (set (intern "erc-message-test1-abc") "val test1 abc") + (set (intern "erc-message-test2-abc") "val test2 abc") + (set (intern "erc-message-test2-def") "val test2 def") + (put (intern "test0") 'erc--base-format-catalog (intern "test1")) + (put (intern "test1") 'erc--base-format-catalog (intern "test2")) + (should (equal (erc-retrieve-catalog-entry 'abc (intern "test0")) + "val test1 abc")) + (should (equal (erc-retrieve-catalog-entry 'def (intern "test0")) + "val test2 def")) + ;; Terminates. + (should-not (erc-retrieve-catalog-entry 'ghi (intern "test0"))))) ;;; erc-tests.el ends here diff --git a/test/lisp/erc/resources/erc-tests-common.el b/test/lisp/erc/resources/erc-tests-common.el index fc5649798b5..906aa891352 100644 --- a/test/lisp/erc/resources/erc-tests-common.el +++ b/test/lisp/erc/resources/erc-tests-common.el @@ -150,7 +150,7 @@ erc-tests-common-pp-propertized-parts For simplicity, assume string evaluates to itself." (interactive "P") (let ((sexp (erc-tests-common-string-to-propertized-parts (pp-last-sexp)))) - (if arg (insert (pp-to-string sexp)) (pp-eval-expression sexp)))) + (if arg (insert (pp-to-string sexp)) (pp-macroexpand-expression sexp)))) ;; The following utilities are meant to help prepare tests for ;; `erc--get-inserted-msg-bounds' and friends. -- 2.42.0
0004-5.6-Add-replacement-text-field-to-erc-input-struct.patch
(text/x-patch, 11.1 KB)
From 9f2f807297bf8cbab9ab507a06f3621f0fa74f8d Mon Sep 17 00:00:00 2001 From: "F. Jason Park" <[email protected]> Date: Mon, 1 Jan 2024 06:37:25 -0800 Subject: [PATCH 4/4] [5.6] Add replacement-text field to erc-input struct * etc/ERC-NEWS: Promote `refoldp' slot from simulated to real. * lisp/erc/erc-common.el (erc-input): Add `substxt' and `refoldp' slots. (erc--input-split): Move `refoldp' to "superclass". * lisp/erc/erc-goodies.el (erc--command-indicator-permit-insertion): Use `substxt' field instead of `insertp'. (erc--command-indicator-display): Accept extra lines. * lisp/erc/erc.el (erc-pre-send-functions): Revise doc. (erc--input-ensure-hook-context, erc-input-refoldp): Remove unused functions. (erc--run-send-hooks): Copy data from additional fields of `erc-input' object to `erc--input-split' object. (erc--send-input-lines): Handle `substxt' field of `erc-input' object when it's non-nil. --- etc/ERC-NEWS | 14 +++++-- lisp/erc/erc-common.el | 19 ++++++++- lisp/erc/erc-goodies.el | 7 +++- lisp/erc/erc.el | 86 ++++++++++++++++++++--------------------- 4 files changed, 74 insertions(+), 52 deletions(-) diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 3eb929063b2..416c302f16f 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -571,9 +571,17 @@ 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 "phony" 'refoldp' slot that's -only accessible from 'erc-pre-send-functions'. See doc string for -details. +shared among hook members has gained a 'refoldp' slot. See doc string +for details. + +*** More flexibility in sending and displaying prompt input. +The abnormal hook 'erc-pre-send-functions' previously married outgoing +message text to its inserted representation in an ERC target buffer. +Going forward, users can populate the new slot 'substxt' with +alternate text to insert in place of the 'string' slot's contents, +which ERC still sends to the server. This dichotomy lets users +completely avoid the often fiddly 'erc-send-modify-hook' and friends +for use cases like language translation and subprotocol encoding. *** 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 2581e40f850..80554d6d187 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el @@ -49,7 +49,23 @@ erc-session-server (declare-function widget-type "wid-edit" (widget)) (cl-defstruct erc-input - string insertp sendp) + "Object shared among members of `erc-pre-send-functions'. +Any use outside of the hook is not supported." + ( string "" :type string + :documentation "String to send and, without `substxt', insert. +ERC treats separate lines as separate messages.") + ( insertp nil :type boolean + :documentation "Whether to insert outgoing message. +When nil, ERC still sends `string'.") + ( sendp nil :type boolean + :documentation "Whether to send and (for compat reasons) insert. +To insert without sending, define a (slash) command.") + ( substxt nil :type (or function string null) + :documentation "Alternate string to insert without splitting. +The function form is for internal use.") + ( refoldp nil :type boolean + :documentation "Whether to resplit a possibly overlong `string'. +ERC only refolds `string', never `substxt'.")) (cl-defstruct (erc--input-split (:include erc-input (string :read-only) @@ -57,7 +73,6 @@ erc-input (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-goodies.el b/lisp/erc/erc-goodies.el index c5ab25bea98..38c14687a9c 100644 --- a/lisp/erc/erc-goodies.el +++ b/lisp/erc/erc-goodies.el @@ -579,15 +579,18 @@ erc--command-indicator-permit-insertion "Insert `erc-input' STATE's message if it's an echoed command." (cl-assert erc-command-indicator-mode) (when (erc--input-split-cmdp state) - (setf (erc--input-split-insertp state) #'erc--command-indicator-display) + (setf (erc--input-split-insertp state) t + (erc--input-split-substxt state) #'erc--command-indicator-display) (erc-send-distinguish-noncommands state))) ;; This function used to be called `erc-display-command'. It was ;; neutered in ERC 5.3.x (Emacs 24.5), commented out in 5.4, removed ;; in 5.5, and restored in 5.6. -(defun erc--command-indicator-display (line) +(defun erc--command-indicator-display (line &rest rest) "Insert command LINE as echoed input resembling that of REPLs and shells." (when erc-insert-this + (when rest + (setq line (string-join (cons line rest) "\n"))) (save-excursion (erc--assert-input-bounds) (let ((insert-position (marker-position (goto-char erc-insert-marker))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 1e208b8204f..00963d24a32 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1211,30 +1211,30 @@ erc-send-pre-hook (make-obsolete-variable 'erc-send-pre-hook 'erc-pre-send-functions "27.1") (defcustom erc-pre-send-functions nil - "Special hook run to possibly alter the string that is sent. -The functions are called with one argument, an `erc-input' struct, -and should alter that struct. + "Special hook to possibly alter the string to send and insert. +ERC calls the member functions with one argument, an `erc-input' +struct instance to modify as needed. -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: +The struct has five slots: - `refoldp': Whether the string should be re-split per protocol limits. + `string': String to send, originally from prompt input. + `insertp': Whether a string should be inserted in the buffer. + `sendp': Whether `string' should be sent to the IRC server. + `substxt': String to display (but not send) instead of `string'. + `refoldp': Whether to re-split `string' 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 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") +the value of `string' comes \"pre-split\" according to the option +`erc-split-line-length'. If you need ERC to refill the entire +payload before sending it, set the `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 and possibly also specify replacement text to +display via the `substxt' slot." + :package-version '(ERC . "5.3") + :group 'erc-hooks + :type 'hook) (define-obsolete-variable-alias 'erc--pre-send-split-functions 'erc--input-review-functions "30.1") @@ -7825,22 +7825,6 @@ erc--split-lines (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 @@ -7858,12 +7842,17 @@ erc--run-send-hooks (state (progn ;; This may change `str' and `erc-*-this'. (run-hook-with-args 'erc-send-pre-hook str) - (make-erc-input :string str - :insertp erc-insert-this - :sendp erc-send-this)))) + (make-erc-input + :string str + :insertp erc-insert-this + :sendp erc-send-this + :substxt (erc--input-split-substxt lines-obj) + :refoldp (erc--input-split-refoldp lines-obj))))) (run-hook-with-args 'erc-pre-send-functions state) (setf (erc--input-split-sendp lines-obj) (erc-input-sendp state) (erc--input-split-insertp lines-obj) (erc-input-insertp state) + (erc--input-split-substxt lines-obj) (erc-input-substxt state) + (erc--input-split-refoldp lines-obj) (erc-input-refoldp state) ;; See note in test of same name re trailing newlines. (erc--input-split-lines lines-obj) (let ((lines (split-string (erc-input-string state) @@ -7881,12 +7870,19 @@ erc--run-send-hooks (defun erc--send-input-lines (lines-obj) "Send lines in `erc--input-split-lines' object LINES-OBJ." (when (erc--input-split-sendp lines-obj) - (dolist (line (erc--input-split-lines lines-obj)) - (when (erc--input-split-insertp lines-obj) - (erc-display-msg line)) - (erc-process-input-line (concat line "\n") - (null erc-flood-protect) - (not (erc--input-split-cmdp lines-obj)))))) + (let ((insertp (erc--input-split-insertp lines-obj)) + (substxt (erc--input-split-substxt lines-obj))) + (when (and insertp substxt) + (setq insertp nil) + (if (functionp substxt) + (apply substxt (erc--input-split-lines lines-obj)) + (erc-display-msg substxt))) + (dolist (line (erc--input-split-lines lines-obj)) + (when insertp + (erc-display-msg line)) + (erc-process-input-line (concat line "\n") + (null erc-flood-protect) + (not (erc--input-split-cmdp lines-obj))))))) (defun erc-send-input (input &optional skip-ws-chk) "Treat INPUT as typed in by the user. -- 2.42.0