emacs-diffs
[Top][All Lists]
Advanced

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

master a46789b56af 4/4: Reuse command-indicator code for script lines in


From: F. Jason Park
Subject: master a46789b56af 4/4: Reuse command-indicator code for script lines in ERC
Date: Sat, 23 Mar 2024 18:38:31 -0400 (EDT)

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

    Reuse command-indicator code for script lines in ERC
    
    * lisp/erc/erc-goodies.el (erc-load-irc-script-lines): Move here from
    main file and rework to always use `command-indicator' instead of only
    partially, when available.  Also use internal "send-action" and
    "send-message" interfaces to defer command-handler output until
    command lines have been inserted.
    * lisp/erc/erc.el (erc-process-input-line): Redo doc string.
    (erc-process-script-line): Fold exceptionally overlong line.
    (erc-load-irc-script-lines): Move to erc-goodies.el.  (Bug#67032)
---
 lisp/erc/erc-goodies.el | 42 +++++++++++++++++++++++++++++++++++
 lisp/erc/erc.el         | 58 +++++++++++++------------------------------------
 2 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 883f64d3109..fe44c3bdfcb 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -625,6 +625,48 @@ Do nothing if the variable `erc-command-indicator' is nil."
                                 erc--msg-props))))
       (erc--refresh-prompt))))
 
+;;;###autoload
+(defun erc-load-irc-script-lines (lines &optional force noexpand)
+  "Process a list of LINES as prompt input submissions.
+If optional NOEXPAND is non-nil, do not expand script-specific
+substitution sequences via `erc-process-script-line' and instead
+process LINES as literal prompt input.  With FORCE, bypass flood
+protection."
+  ;; The various erc-cmd-CMDs were designed to return non-nil when
+  ;; their command line should be echoed.  But at some point, these
+  ;; handlers began displaying their own output, which naturally
+  ;; appeared *above* the echoed command.  This tries to intercept
+  ;; these insertions, deferring them until the command has returned
+  ;; and its command line has been printed.
+  (cl-assert (eq 'erc-mode major-mode))
+  (let ((args (and erc-script-args
+                   (if (string-match "^ " erc-script-args)
+                       (substring erc-script-args 1)
+                     erc-script-args))))
+    (with-silent-modifications
+      (dolist (line lines)
+        (erc-log (concat "erc-load-script: CMD: " line))
+        (unless (string-match (rx bot (* (syntax whitespace)) eot) line)
+          (unless noexpand
+            (setq line (erc-process-script-line line args)))
+          (let ((erc--current-line-input-split (erc--make-input-split line))
+                calls insertp)
+            (add-function :around (local 'erc--send-message-nested-function)
+                          (lambda (&rest args) (push args calls))
+                          '((name . erc-script-lines-fn) (depth . -80)))
+            (add-function :around (local 'erc--send-action-function)
+                          (lambda (&rest args) (push args calls))
+                          '((name . erc-script-lines-fn) (depth . -80)))
+            (setq insertp
+                  (unwind-protect (erc-process-input-line line force)
+                    (remove-function (local 'erc--send-action-function)
+                                     'erc-script-lines-fn)
+                    (remove-function (local 'erc--send-message-nested-function)
+                                     'erc-script-lines-fn)))
+            (when (and insertp erc-script-echo)
+              (erc--command-indicator-display line)
+              (dolist (call calls)
+                (apply (car call) (cdr call))))))))))
 
 ;;; IRC control character processing.
 (defgroup erc-control-characters nil
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 3cc9bd54228..0750463a4e7 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -4004,17 +4004,19 @@ erc-cmd-FOO, this returns a string /FOO."
       command-name)))
 
 (defun erc-process-input-line (line &optional force no-command)
-  "Translate LINE to an RFC1459 command and send it based.
-Returns non-nil if the command is actually sent to the server, and nil
-otherwise.
-
-If the command in the LINE is not bound as a function `erc-cmd-<COMMAND>',
-it is passed to `erc-cmd-default'.  If LINE is not a command (i.e. doesn't
-start with /<COMMAND>) then it is sent as a message.
-
-An optional FORCE argument forces sending the line when flood
-protection is in effect.  The optional NO-COMMAND argument prohibits
-this function from interpreting the line as a command."
+  "Dispatch a slash-command or chat-input handler from user-input LINE.
+If simplistic validation fails, print an error and return nil.
+Otherwise, defer to an appropriate handler.  For \"slash\" commands,
+like \"/JOIN\", expect a handler, like `erc-cmd-JOIN', to return non-nil
+if LINE is fit for echoing as a command line when executing scripts.
+For normal chat input, expect a handler to return non-nil if a message
+was successfully processed as an outgoing \"PRIVMSG\".  If LINE is a
+slash command, and ERC can't find a corresponding handler of the form
+`erc-cmd-<COMMAND>', pass LINE to `erc-cmd-default', treating it as a
+catch-all handler.  Otherwise, for normal chat input, pass LINE and the
+boolean argument FORCE to `erc-send-input-line-function'.  With a
+non-nil NO-COMMAND, always treat LINE as normal chat input rather than a
+slash command."
   (let ((command-list (erc-extract-command-from-line line)))
     (if (and command-list
              (not no-command))
@@ -8512,7 +8514,8 @@ and so on."
                     ((string-match "^%[Ss]$" esc) server)
                     ((string-match "^%[Nn]$" esc) nick)
                     ((string-match "^%\\(.\\)$" esc) (match-string 1 esc))
-                    (t (erc-log (format "BUG in erc-process-script-line: bad 
escape sequence: %S\n" esc))
+                    (t (erc-log (format "Bad escape sequence in %s: %S\n"
+                                        'erc-process-script-line esc))
                        (message "BUG IN ERC: esc=%S" esc)
                        "")))
         (setq line tail)
@@ -8531,37 +8534,6 @@ and so on."
                (buffer-string))))
     (erc-load-irc-script-lines (erc-split-multiline-safe str) force)))
 
-(defun erc-load-irc-script-lines (lines &optional force noexpand)
-  "Load IRC script LINES (a list of strings).
-
-If optional NOEXPAND is non-nil, do not expand script-specific
-sequences, process the lines verbatim.  Use this for multiline
-user input."
-  (let* ((cb (current-buffer))
-         (s "")
-         (sp (or (and (bound-and-true-p erc-command-indicator-mode)
-                      (fboundp 'erc-command-indicator)
-                      (erc-command-indicator))
-                 (erc-prompt)))
-         (args (and (boundp 'erc-script-args) erc-script-args)))
-    (if (and args (string-match "^ " args))
-        (setq args (substring args 1)))
-    ;; prepare the prompt string for echo
-    (erc-put-text-property 0 (length sp)
-                           'font-lock-face 'erc-command-indicator-face sp)
-    (while lines
-      (setq s (car lines))
-      (erc-log (concat "erc-load-script: CMD: " s))
-      (unless (string-match "^\\s-*$" s)
-        (let ((line (if noexpand s (erc-process-script-line s args))))
-          (if (and (erc-process-input-line line force)
-                   erc-script-echo)
-              (progn
-                (erc-put-text-property 0 (length line)
-                                       'font-lock-face 'erc-input-face line)
-                (erc-display-line (concat sp line) cb)))))
-      (setq lines (cdr lines)))))
-
 ;; authentication
 
 (defun erc--unfun (maybe-fn)



reply via email to

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