1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-12 22:40:46 -08:00

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 d1036d288d "backport: erc
bugfixes".  However, references were left behind to associated assets,
like `erc-command-indicator', etc.  The function was later commented
out in 0c599ee2e2 "* lisp/erc/erc.el: Use `run-hook-with-args` for
`erc-pre-send-functions`", and then removed by a63ed6f78a "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)
This commit is contained in:
F. Jason Park 2023-11-10 13:34:31 -08:00
parent 583d73e9a0
commit 1d2aa130ca
7 changed files with 217 additions and 56 deletions

View file

@ -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)

View file

@ -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

View file

@ -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."

View file

@ -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)

View file

@ -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)))

View file

@ -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

View file

@ -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