emacs-diffs
[Top][All Lists]
Advanced

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

master 1d2aa130cae 8/9: Revive erc-command-indicator as new module


From: F. Jason Park
Subject: master 1d2aa130cae 8/9: Revive erc-command-indicator as new module
Date: Sun, 12 Nov 2023 23:56:30 -0500 (EST)

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

    Revive erc-command-indicator as new module
    
    * doc/misc/erc.texi: Add entry for `command-indicator' to Modules
    chapter.
    * etc/ERC-NEWS: Mention new module `command-indicator'.
    * lisp/erc/erc-goodies.el (erc-noncommands-list): Replace the
    nonexistent `erc-cmd-SMV' with function `erc-cmd-SAY'.
    (erc-noncommands-mode, erc-noncommands-enable,
    erc-noncommands-disable): Deprecate this module because it's a no-op.
    (erc-command-indicator-face, erc-command-indicator): Migrate from main
    library.
    (erc-command-indicator-mode, erc-command-indicator-enable,
    erc-command-indicator-disable): New module to take the spiritual place
    of `noncommands'.
    (erc-command-indicator): Move function here from main library, along
    with option namesake mentioned above.
    (erc-command-indicator-toggle-hidden): New command to toggle echoed
    command-line visibility.
    (erc--command-indicator-permit-insertion): New function.
    (erc--command-indicator-display): New function, a slightly revised
    version of the old `erc-display-command' from the main library.  Its
    only call site was removed back in d1036d288de "backport: erc
    bugfixes".  However, references were left behind to associated assets,
    like `erc-command-indicator', etc.  The function was later commented
    out in 0c599ee2e2c "* lisp/erc/erc.el: Use `run-hook-with-args` for
    `erc-pre-send-functions`", and then removed by a63ed6f78a6 "Remove
    duplicate ERC prompt on reconnect".
    * lisp/erc/erc-match.el (erc-match-toggle-hidden-fools): Use new
    non-module-specific name for `erc-match--toggle-hidden'.
    (erc-match--toggle-hidden): Move to main library for shared use by
    other modules.
    * lisp/erc/erc.el (erc-hide-prompt): Leave note explaining updated
    role.
    (erc-command-indicator): Move option and function of same name to
    erc-goodies.
    (erc-command-indicator-face): Move to erc-goodies.
    (erc-modules): Remove module `noncommands' from standard value and
    Custom set.  Add `command-indicator' to set.
    (erc--toggle-hidden): "New" function, a rebranded version of the
    utility `erc-match--toggle-hidden' from erc-match.
    (erc--send-input-lines): Accommodate modules wanting alternate
    insertion functions.
    (erc-load-irc-script-lines): Account for `erc-command-indicator' no
    longer being defined in this library.
    * test/lisp/erc/erc-scenarios-base-send-message.el
    (erc-scenarios-base-send-message--command-indicator): New test.
    * test/lisp/erc/erc-tests.el (erc-tests--modules): Remove
    deprecated module `noncommands' from manifest.  (Bug#67031)
---
 doc/misc/erc.texi                                |   5 +
 etc/ERC-NEWS                                     |  13 +++
 lisp/erc/erc-goodies.el                          | 121 +++++++++++++++++++++--
 lisp/erc/erc-match.el                            |  14 +--
 lisp/erc/erc.el                                  |  63 ++++++------
 test/lisp/erc/erc-scenarios-base-send-message.el |  54 ++++++++++
 test/lisp/erc/erc-tests.el                       |   3 +-
 7 files changed, 217 insertions(+), 56 deletions(-)

diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 10902eac33f..44e82084b90 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -450,6 +450,11 @@ Buttonize URLs, nicknames, and other text
 @item capab-identify
 Mark unidentified users on freenode and other servers supporting CAPAB.
 
+@cindex modules, command-indicator
+@item command-indicator
+Echo command lines for ``slash commands'', like @kbd{/JOIN #erc} and
+@kbd{/HELP join}
+
 @cindex modules, completion
 @cindex modules, pcomplete
 @item completion (aka pcomplete)
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index f59023eae62..cd4a283ef1c 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -157,6 +157,19 @@ asking users who've customized this option to switch to
 that some other solution, like automatic migration, is justified,
 please make that known on the bug list.
 
+** Module 'noncommands' deprecated, replaced by 'command-indicator'.
+Command-line echoing has returned to ERC after a near decade-long
+hiatus.  This means you can elect to have ERC leave a trail of (most)
+slash-command input submitted at the prompt, in a manner resembling
+that of a shell or a REPL.  The particulars are likely of little
+interest to most users, but the gist is that this functionality was
+removed in 5.3.x (Emacs 24.5) without mention in this document or a
+change log.  Everything's mostly been restored, except that the
+feature is now opt-in.  The only real gotcha is that related faces and
+options, like 'erc-command-indicator', have moved to the 'erc-goodies'
+library, although their Custom groups remain the same.  Add
+'command-indicator' to 'erc-modules' to get started.
+
 ** 'erc-button-alist' and 'erc-nick-popup-alist' have evolved slightly.
 It's no secret that the 'buttons' module treats potential nicknames
 specially.  This is perhaps most evident in its treatment of the
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 4cc81dd9378..1482c21e931 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -471,21 +471,26 @@ For use with `keep-place-indicator' module."
                                erc-cmd-COUNTRY
                                erc-cmd-SV
                                erc-cmd-SM
-                               erc-cmd-SMV
+                               erc-cmd-SAY
                                erc-cmd-LASTLOG)
-  "List of commands that are aliases for CTCP ACTION or for ERC messages.
-
-If a command's function symbol is in this list, the typed command
-does not appear in the ERC buffer after the user presses ENTER.")
+  "List of client \"slash commands\" that perform their own buffer I/O.
+The `command-indicator' module forgoes echoing these commands,
+most of which aren't actual interactive lisp commands.")
 
 ;;;###autoload(autoload 'erc-noncommands-mode "erc-goodies" nil t)
 (define-erc-module noncommands nil
-  "This mode distinguishes non-commands.
-Commands listed in `erc-insert-this' know how to display
-themselves."
+  "Treat commands that display themselves specially.
+This module has been a no-op since ERC 5.3 and has likely only
+ever made sense in the context of `erc-command-indicator'.  It
+was deprecated in ERC 5.6."
   ((add-hook 'erc--input-review-functions #'erc-send-distinguish-noncommands))
   ((remove-hook 'erc--input-review-functions
                 #'erc-send-distinguish-noncommands)))
+(make-obsolete-variable 'erc-noncommand-mode
+                        'erc-command-indicator-mode "30.1")
+(make-obsolete 'erc-noncommand-mode 'erc-command-indicator-mode "30.1")
+(make-obsolete 'erc-noncommand-enable 'erc-command-indicator-enable "30.1")
+(make-obsolete 'erc-noncommand-disable 'erc-command-indicator-disable "30.1")
 
 (defun erc-send-distinguish-noncommands (state)
   "If STR is an ERC non-command, set `insertp' in STATE to nil."
@@ -499,6 +504,106 @@ themselves."
       ;; Inhibit sending this string.
       (setf (erc-input-insertp state) nil))))
 
+
+;;; Command-indicator
+
+(defface erc-command-indicator-face
+  '((t :inherit (erc-input-face fixed-pitch-serif)))
+  "Face for echoed command lines, including the prompt.
+See option `erc-command-indicator'."
+  :package-version '(ERC . "5.6") ; standard value, from bold
+  :group 'erc-faces)
+
+(defcustom erc-command-indicator 'erc-prompt
+  "Pseudo prompt for echoed command lines.
+An analog of the option `erc-prompt' that replaces the \"speaker
+label\" for echoed \"slash\" commands submitted at the prompt.  A
+value of nil means ERC only inserts the command-line portion
+alone, without the prompt, which may trick certain modules, like
+`fill', into treating the leading slash command itself as the
+message's speaker."
+  :package-version '(ERC . "5.6")
+  :group 'erc-display
+  :type '(choice (const :tag "Defer to `erc-prompt'" erc-prompt)
+                 (const :tag "Print command lines without a prompt" nil)
+                 (string :tag "User-provided string")
+                 (function :tag "User-provided function")))
+
+;;;###autoload(autoload 'erc-command-indicator-mode "erc-goodies" nil t)
+(define-erc-module command-indicator nil
+  "Echo command lines for \"slash commands,\" like /JOIN, /HELP, etc.
+Skip those appearing in `erc-noncommands-list'.
+
+Users can run \\[erc-command-indicator-toggle-hidden] to hide and
+reveal echoed command lines after they've been inserted."
+  ((add-hook 'erc--input-review-functions
+             #'erc--command-indicator-permit-insertion 80 t)
+   (erc-command-indicator-toggle-hidden -1))
+  ((remove-hook 'erc--input-review-functions
+                #'erc--command-indicator-permit-insertion t)
+   (erc-command-indicator-toggle-hidden +1))
+  'local)
+
+(defun erc-command-indicator ()
+  "Return the command-indicator prompt as a string.
+Do nothing if the variable `erc-command-indicator' is nil."
+  (and erc-command-indicator
+       (let ((prompt (if (functionp erc-command-indicator)
+                         (funcall erc-command-indicator)
+                       erc-command-indicator)))
+         (concat prompt (and (not (string-empty-p prompt))
+                             (not (string-suffix-p " " prompt))
+                             " ")))))
+
+(defun erc-command-indicator-toggle-hidden (arg)
+  "Toggle whether echoed \"slash commands\" are visible."
+  (interactive "P")
+  (erc--toggle-hidden 'command-indicator arg))
+
+(defun erc--command-indicator-permit-insertion (state)
+  "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)
+    (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)
+  "Insert command LINE as echoed input resembling that of REPLs and shells."
+  (when erc-insert-this
+    (save-excursion
+      (erc--assert-input-bounds)
+      (let ((insert-position (marker-position (goto-char erc-insert-marker)))
+            (erc--msg-props (or erc--msg-props
+                                (let ((ovs erc--msg-prop-overrides))
+                                  (map-into `((erc-msg . slash-cmd)
+                                              ,@(reverse ovs))
+                                            'hash-table)))))
+        (when-let ((string (erc-command-indicator))
+                   (erc-input-marker (copy-marker erc-input-marker)))
+          (erc-display-prompt nil nil string 'erc-command-indicator-face)
+          (remove-text-properties insert-position (point)
+                                  '(field nil erc-prompt nil))
+          (set-marker erc-input-marker nil))
+        (let ((beg (point)))
+          (insert line)
+          (erc-put-text-property beg (point)
+                                 'font-lock-face 'erc-command-indicator-face)
+          (insert "\n"))
+        (save-restriction
+          (narrow-to-region insert-position (point))
+          (run-hooks 'erc-send-modify-hook)
+          (run-hooks 'erc-send-post-hook)
+          (cl-assert (> (- (point-max) (point-min)) 1))
+          (erc--hide-message 'command-indicator)
+          (add-text-properties (point-min) (1+ (point-min))
+                               (erc--order-text-properties-from-hash
+                                erc--msg-props))))
+      (erc--refresh-prompt))))
+
+
 ;;; IRC control character processing.
 (defgroup erc-control-characters nil
   "Dealing with control characters."
diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el
index 8644e61106f..6fff54d3cf4 100644
--- a/lisp/erc/erc-match.el
+++ b/lisp/erc/erc-match.el
@@ -695,19 +695,7 @@ This function is meant to be called from 
`erc-text-matched-hook'."
 Expect the function `erc-hide-fools' or similar to be present in
 `erc-text-matched-hook'."
   (interactive "P")
-  (erc-match--toggle-hidden 'match-fools arg))
-
-(defun erc-match--toggle-hidden (prop arg)
-  "Toggle invisibility for spec member PROP.
-Treat ARG in a manner similar to mode toggles defined by
-`define-minor-mode'."
-  (when arg
-    (setq arg (prefix-numeric-value arg)))
-  (if (memq prop (ensure-list buffer-invisibility-spec))
-      (unless (natnump arg)
-        (remove-from-invisibility-spec prop))
-    (when (or (not arg) (natnump arg))
-      (add-to-invisibility-spec prop))))
+  (erc--toggle-hidden 'match-fools arg))
 
 (provide 'erc-match)
 
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 6a110f7ca77..cd1c925a757 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -346,8 +346,13 @@ with a value of 2 and means disallow more than 1 line of 
input."
   "If non-nil, hide input prompt upon disconnecting.
 To unhide, type something in the input area.  Once revealed, a
 prompt remains unhidden until the next disconnection.  Channel
-prompts are unhidden upon rejoining.  See
-`erc-unhide-query-prompt' for behavior concerning query prompts."
+prompts are unhidden upon rejoining.  For behavior concerning
+query prompts, see `erc-unhide-query-prompt'.  Longtime ERC users
+should note that this option was repurposed in ERC 5.5 because it
+had lain dormant for years after being sidelined in 5.3 when its
+only use in the interactive client was removed.  Before then, its
+role was controlling whether `erc-command-indicator' would appear
+alongside echoed slash-command lines."
   :package-version '(ERC . "5.5")
   :group 'erc-display
   :type '(choice (const :tag "Always hide prompt" t)
@@ -759,28 +764,6 @@ See also the variable `erc-prompt'."
         (concat prompt " ")
       prompt)))
 
-(defcustom erc-command-indicator nil
-  "Indicator used by ERC for showing commands.
-
-If non-nil, this will be used in the ERC buffer to indicate
-commands (i.e., input starting with a `/').
-
-If nil, the prompt will be constructed from the variable `erc-prompt'."
-  :group 'erc-display
-  :type '(choice (const nil) string function))
-
-(defun erc-command-indicator ()
-  "Return the command indicator prompt as a string.
-
-This only has any meaning if the variable `erc-command-indicator' is non-nil."
-  (and erc-command-indicator
-       (let ((prompt (if (functionp erc-command-indicator)
-                         (funcall erc-command-indicator)
-                       erc-command-indicator)))
-         (if (> (length prompt) 0)
-             (concat prompt " ")
-           prompt))))
-
 (defcustom erc-notice-prefix "*** "
   "Prefix for all notices."
   :group 'erc-display
@@ -1364,12 +1347,6 @@ This will only be used if `erc-header-line-face-method' 
is non-nil."
   "ERC face for the prompt."
   :group 'erc-faces)
 
-(defface erc-command-indicator-face
-  '((t :weight bold))
-  "ERC face for the command indicator.
-See the variable `erc-command-indicator'."
-  :group 'erc-faces)
-
 (defface erc-notice-face
   '((default :weight bold)
     (((class color) (min-colors 88) (supports :weight semi-bold))
@@ -2077,7 +2054,7 @@ buffer rather than a server buffer.")
 
 (defcustom erc-modules '( autojoin button completion fill imenu irccontrols
                           list match menu move-to-prompt netsplit
-                          networks noncommands readonly ring stamp track)
+                          networks readonly ring stamp track)
   "A list of modules which ERC should enable.
 If you set the value of this without using `customize' remember to call
 \(erc-update-modules) after you change it.  When using `customize', modules
@@ -2127,6 +2104,7 @@ removed from the list will be disabled."
     (const :tag "button: Buttonize URLs, nicknames, and other text" button)
     (const :tag "capab: Mark unidentified users on servers supporting CAPAB"
            capab-identify)
+    (const :tag "command-indicator: Echo command lines." command-indicator)
     (const :tag "completion: Complete nicknames and commands (programmable)"
            completion)
     (const :tag "dcc: Provide Direct Client-to-Client support" dcc)
@@ -2146,7 +2124,7 @@ removed from the list will be disabled."
     (const :tag "networks: Provide data about IRC networks" networks)
     (const :tag "nickbar: Show nicknames in a dyamic side window" nickbar)
     (const :tag "nicks: Uniquely colorize nicknames in target buffers" nicks)
-    (const :tag "noncommands: Don't display non-IRC commands after evaluation"
+    (const :tag "noncommands: Deprecated. See module `command-indicator'."
            noncommands)
     (const :tag "notifications: Desktop alerts on PRIVMSG or mentions"
            notifications)
@@ -3328,6 +3306,18 @@ don't bother including the preceding newline."
           (cl-incf beg))
         (erc--merge-prop (1- beg) (1- end) 'invisible value)))))
 
+(defun erc--toggle-hidden (prop arg)
+  "Toggle invisibility for spec member PROP.
+Treat ARG in a manner similar to mode toggles defined by
+`define-minor-mode'."
+  (when arg
+    (setq arg (prefix-numeric-value arg)))
+  (if (memq prop (ensure-list buffer-invisibility-spec))
+      (unless (natnump arg)
+        (remove-from-invisibility-spec prop))
+    (when (or (not arg) (natnump arg))
+      (add-to-invisibility-spec prop))))
+
 (defun erc--delete-inserted-message (beg-or-point &optional end)
   "Remove message between BEG and END.
 Expect BEG and END to match bounds as returned by the macro
@@ -7051,7 +7041,9 @@ queue.  Expect LINES-OBJ to be an `erc--input-split' 
object."
   (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))
+        (if (functionp (erc--input-split-insertp lines-obj))
+            (funcall (erc--input-split-insertp lines-obj) line)
+          (erc-display-msg line)))
       (erc-process-input-line (concat line "\n")
                               (null erc-flood-protect)
                               (not (erc--input-split-cmdp lines-obj))))))
@@ -7557,7 +7549,10 @@ sequences, process the lines verbatim.  Use this for 
multiline
 user input."
   (let* ((cb (current-buffer))
          (s "")
-         (sp (or (erc-command-indicator) (erc-prompt)))
+         (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)))
diff --git a/test/lisp/erc/erc-scenarios-base-send-message.el 
b/test/lisp/erc/erc-scenarios-base-send-message.el
index 904381abe6a..bf9e0f5ae3a 100644
--- a/test/lisp/erc/erc-scenarios-base-send-message.el
+++ b/test/lisp/erc/erc-scenarios-base-send-message.el
@@ -69,4 +69,58 @@
           (funcall expect 10 "<alice> No, not till Thursday;"))))))
 
 
+;; This asserts that the `command-indicator' module only inserts
+;; prompt-like prefixes for normal slash commands, like /JOIN.
+
+(ert-deftest erc-scenarios-base-send-message--command-indicator ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/send-message")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'noncommands))
+       (erc-modules `(command-indicator fill-wrap ,@erc-modules))
+       (expect (erc-d-t-make-expecter)))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port (process-contact dumb-server :service)
+                                :nick "tester"
+                                :full-name "tester")
+        (funcall expect 5 "debug mode")
+        (erc-scenarios-common-say "/join #chan")
+        (funcall expect 10 "ERC> /join #chan")))
+
+    (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+      (ert-info ("Prompt absent for CTCP ACTION")
+        (funcall expect 10 "<bob> alice: For hands, to do Rome")
+        (erc-scenarios-common-say "/me sad")
+        (funcall expect -0.1 "ERC> /me sad")
+        (funcall expect 10 "* tester sad"))
+
+      (ert-info ("Prompt absent for literal command")
+        (funcall expect 10 "<alice> bob: Spotted, detested")
+        (erc-scenarios-common-say "/say /me sad")
+        (funcall expect -0.1 "ERC> /say /me sad")
+        (funcall expect 10 "<tester> /me sad"))
+
+      (ert-info ("Prompt absent for /SV")
+        (funcall expect 10 "<bob> Marcus, my brother!")
+        (erc-scenarios-common-say "/sv")
+        (funcall expect -0.1 "ERC> /sv")
+        (funcall expect 10 "<tester> I'm using ERC"))
+
+      (ert-info ("Prompt absent module list via /SM")
+        (funcall expect 10 "<bob> alice: You still wrangle")
+        (erc-scenarios-common-say "/sm")
+        (funcall expect -0.1 "ERC> /sm")
+        (funcall expect 10 "<tester> I'm using the following modules: ")
+        (funcall expect 10 "<alice> No, not till Thursday;"))
+
+      (ert-info ("Prompt present for /QUIT in issuing buffer")
+        (erc-scenarios-common-say "/quit")
+        (funcall expect 10 "ERC> /quit"))
+
+      (with-current-buffer "foonet"
+        (funcall expect 10 "ERC finished")))))
+
 ;;; erc-scenarios-base-send-message.el ends here
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 2898ca7be75..e7422d330c0 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -2543,7 +2543,8 @@
     (kill-buffer "#chan")))
 
 (defconst erc-tests--modules
-  '( autoaway autojoin bufbar button capab-identify completion dcc fill identd
+  '( autoaway autojoin bufbar button capab-identify
+     command-indicator completion dcc fill identd
      imenu irccontrols keep-place list log match menu move-to-prompt netsplit
      networks nickbar nicks noncommands notifications notify page readonly
      replace ring sasl scrolltobottom services smiley sound



reply via email to

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