1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Add replacement-text field to erc-input struct

* etc/ERC-NEWS: Promote `refoldp' slot from simulated to real.
Mention new `substxt' slot of `erc-input' struct.
* 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 overloading `insertp'.
(erc--command-indicator-display): Accept extra lines for
compatibility.
* lisp/erc/erc.el (erc-pre-send-functions): Revise doc.
(erc--input-ensure-hook-context, erc-input-refoldp): Remove unused
functions, originally meant to be new in ERC 5.6.
(erc--run-send-hooks): Copy data from additional fields of `erc-input'
object to `erc--input-split' workspace object.
(erc--send-input-lines): Handle `substxt' field of `erc-input' object
when it's non-nil.  (Bug#68265)
This commit is contained in:
F. Jason Park 2024-01-01 06:37:25 -08:00
parent aae131b8dd
commit d6be068ffe
4 changed files with 74 additions and 55 deletions

View file

@ -581,9 +581,17 @@ ERC now adjusts input lines to fall within allowed length limits
before showing hook members the result. For compatibility, before showing hook members the result. For compatibility,
third-party code can request that the final input be adjusted again third-party code can request that the final input be adjusted again
prior to being sent. To facilitate this, the 'erc-input' object prior to being sent. To facilitate this, the 'erc-input' object
shared among hook members has gained a "phony" 'refoldp' slot that's shared among hook members has gained a 'refoldp' slot. See doc string
only accessible from 'erc-pre-send-functions'. See doc string for for details.
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. *** ERC's prompt survives the insertion of user input and messages.
Previously, ERC's prompt and its input marker disappeared while Previously, ERC's prompt and its input marker disappeared while

View file

@ -50,7 +50,23 @@
(declare-function widget-type "wid-edit" (widget)) (declare-function widget-type "wid-edit" (widget))
(cl-defstruct erc-input (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 (cl-defstruct (erc--input-split (:include erc-input
(string "" :read-only t) (string "" :read-only t)
@ -58,7 +74,6 @@
(sendp (with-suppressed-warnings (sendp (with-suppressed-warnings
((obsolete erc-send-this)) ((obsolete erc-send-this))
erc-send-this)))) erc-send-this))))
(refoldp nil :type boolean)
(lines nil :type (list-of string)) (lines nil :type (list-of string))
(abortp nil :type (list-of symbol)) (abortp nil :type (list-of symbol))
(cmdp nil :type boolean)) (cmdp nil :type boolean))

View file

@ -583,15 +583,18 @@ Do nothing if the variable `erc-command-indicator' is nil."
"Insert `erc-input' STATE's message if it's an echoed command." "Insert `erc-input' STATE's message if it's an echoed command."
(cl-assert erc-command-indicator-mode) (cl-assert erc-command-indicator-mode)
(when (erc--input-split-cmdp state) (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))) (erc-send-distinguish-noncommands state)))
;; This function used to be called `erc-display-command'. It was ;; 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 ;; neutered in ERC 5.3.x (Emacs 24.5), commented out in 5.4, removed
;; in 5.5, and restored in 5.6. ;; 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." "Insert command LINE as echoed input resembling that of REPLs and shells."
(when erc-insert-this (when erc-insert-this
(when rest
(setq line (string-join (cons line rest) "\n")))
(save-excursion (save-excursion
(erc--assert-input-bounds) (erc--assert-input-bounds)
(let ((insert-position (marker-position (goto-char erc-insert-marker))) (let ((insert-position (marker-position (goto-char erc-insert-marker)))

View file

@ -1235,30 +1235,30 @@ anyway."
(make-obsolete-variable 'erc-send-pre-hook 'erc-pre-send-functions "27.1") (make-obsolete-variable 'erc-send-pre-hook 'erc-pre-send-functions "27.1")
(defcustom erc-pre-send-functions nil (defcustom erc-pre-send-functions nil
"Special hook run to possibly alter the string that is sent. "Special hook to possibly alter the string to send and insert.
The functions are called with one argument, an `erc-input' struct, ERC calls the member functions with one argument, an `erc-input'
and should alter that struct. struct instance to modify as needed.
The struct has three slots: The struct has five slots:
`string': The current input string. `string': String to send, originally from prompt input.
`insertp': Whether the string should be inserted into the erc buffer. `insertp': Whether a string should be inserted in the buffer.
`sendp': Whether the string should be sent to the irc server. `sendp': Whether `string' should be sent to the IRC server.
`substxt': String to display (but not send) instead of `string'.
And one \"phony\" slot only accessible by hook members at runtime: `refoldp': Whether to re-split `string' per protocol limits.
`refoldp': Whether the string should be re-split per protocol limits.
This hook runs after protocol line splitting has taken place, so This hook runs after protocol line splitting has taken place, so
the value of `string' is originally \"pre-filled\". If you need the value of `string' comes \"pre-split\" according to the option
ERC to refill the entire payload before sending it, set the phony `erc-split-line-length'. If you need ERC to refill the entire
`refoldp' slot to a non-nil value. Note that this refilling is payload before sending it, set the `refoldp' slot to a non-nil
only a convenience, and modules with special needs, such as value. Note that this refilling is only a convenience, and
preserving \"preformatted\" text or encoding for subprotocol modules with special needs, such as preserving \"preformatted\"
\"tunneling\", should handle splitting manually." text or encoding for subprotocol \"tunneling\", should handle
:group 'erc splitting manually and possibly also specify replacement text to
:type 'hook display via the `substxt' slot."
:version "27.1") :package-version '(ERC . "5.3")
:group 'erc-hooks
:type 'hook)
(define-obsolete-variable-alias 'erc--pre-send-split-functions (define-obsolete-variable-alias 'erc--pre-send-split-functions
'erc--input-review-functions "30.1") 'erc--input-review-functions "30.1")
@ -7899,22 +7899,6 @@ When all lines are empty, remove all but the first."
(setf (erc--input-split-lines state) (setf (erc--input-split-lines state)
(mapcan #'erc--split-line (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) (defun erc--run-send-hooks (lines-obj)
"Run send-related hooks that operate on the entire prompt input. "Run send-related hooks that operate on the entire prompt input.
Sequester some of the back and forth involved in honoring old Sequester some of the back and forth involved in honoring old
@ -7932,12 +7916,17 @@ queue. Expect LINES-OBJ to be an `erc--input-split' object."
(state (progn (state (progn
;; This may change `str' and `erc-*-this'. ;; This may change `str' and `erc-*-this'.
(run-hook-with-args 'erc-send-pre-hook str) (run-hook-with-args 'erc-send-pre-hook str)
(make-erc-input :string str (make-erc-input
:insertp erc-insert-this :string str
:sendp erc-send-this)))) :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) (run-hook-with-args 'erc-pre-send-functions state)
(setf (erc--input-split-sendp lines-obj) (erc-input-sendp 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-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. ;; See note in test of same name re trailing newlines.
(erc--input-split-lines lines-obj) (erc--input-split-lines lines-obj)
(let ((lines (split-string (erc-input-string state) (let ((lines (split-string (erc-input-string state)
@ -7955,15 +7944,19 @@ queue. Expect LINES-OBJ to be an `erc--input-split' object."
(defun erc--send-input-lines (lines-obj) (defun erc--send-input-lines (lines-obj)
"Send lines in `erc--input-split-lines' object LINES-OBJ." "Send lines in `erc--input-split-lines' object LINES-OBJ."
(when (erc--input-split-sendp lines-obj) (when (erc--input-split-sendp lines-obj)
(dolist (line (erc--input-split-lines lines-obj)) (let ((insertp (erc--input-split-insertp lines-obj))
(when (erc--input-split-insertp lines-obj) (substxt (erc--input-split-substxt lines-obj)))
(if (eq (erc--input-split-insertp lines-obj) (when (and insertp substxt)
'erc--command-indicator-display) (setq insertp nil)
(funcall (erc--input-split-insertp lines-obj) line) (if (functionp substxt)
(erc-display-msg line))) (apply substxt (erc--input-split-lines lines-obj))
(erc-process-input-line (concat line "\n") (erc-display-msg substxt)))
(null erc-flood-protect) (dolist (line (erc--input-split-lines lines-obj))
(not (erc--input-split-cmdp 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) (defun erc-send-input (input &optional skip-ws-chk)
"Treat INPUT as typed in by the user. "Treat INPUT as typed in by the user.