mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 09:14:18 +00:00
Define ERC message-formatting templates with defvar
* etc/ERC-NEWS: Mention convenience macro being preferred means of defining message templates. Mention renaming of `notify' formatting templates. * lisp/erc/erc-common.el (erc--define-catalog, erc-define-message-format-catalog): New macro and internal variant to replace `erc-define-catalog-entry'. The internal variant allows us to defer reindenting existing definitions until meaningfully edited. * lisp/erc/erc-dcc.el (erc-message-english-dcc-chat-discarded, erc-message-english-dcc-chat-ended, erc-message-english-dcc-chat-no-request, erc-message-english-dcc-chat-offered, erc-message-english-dcc-chat-offer, erc-message-english-dcc-chat-accept, erc-message-english-dcc-chat-privmsg, erc-message-english-dcc-closed, erc-message-english-dcc-command-undefined, erc-message-english-dcc-ctcp-errmsg, erc-message-english-dcc-ctcp-unknown, erc-message-english-dcc-get-bytes-received, erc-message-english-dcc-get-complete, erc-message-english-dcc-get-failed, erc-message-english-dcc-get-cmd-aborted, erc-message-english-dcc-get-file-too-long, erc-message-english-dcc-get-notfound, erc-message-english-dcc-list-head, erc-message-english-dcc-list-line, erc-message-english-dcc-list-item, erc-message-english-dcc-list-end, erc-message-english-dcc-malformed, erc-message-english-dcc-privileged-port, erc-message-english-dcc-request-bogus, erc-message-english-dcc-send-finished, erc-message-english-dcc-send-offered, erc-message-english-dcc-send-offer): Define at top level using `defvar'. * lisp/erc/erc-netsplit.el (erc-netsplit-mode, erc-netsplit-enable): Don't call `erc-netsplit-install-message-catalogs'. (erc-netsplit-install-message-catalogs): Deprecate function. (erc-message-english-netsplit, erc-message-english-netjoin, erc-message-english-netjoin-done, erc-message-english-netsplit-none, erc-message-english-netsplit-wholeft): Define at top level using `defvar'. * lisp/erc/erc-notify.el (erc-notify-install-message-catalogs): Deprecate, and rename all format templates with hyphens instead of underscores. (erc-notify-timer, erc-notify-JOIN, erc-notify-NICK, erc-notify-QUIT): Use hyphenated template names. (erc-cmd-NOTIFY): Use hyphenated template names. Load the module when necessary and emit a warning. Otherwise, people who discover this autoloaded command without being aware of the module's existence may think it's "broken". (pcomplete/erc-mode/NOTIFY): Replace top-level autoload with `require' in function body. Include `erc-notify-list' in list of completions, which makes removal easier if you don't share any channels with a person, and they're not in `erc-server-users'. A better long-term solution might be to WHOIS folks we're unsure about when they're listed in a 303. (erc-message-english-notify_current, erc-message-english-notify_list, erc-message-english-notify_on, erc-message-english-notify_off): Define at top level using `defvar'. Replace nonstandard underscores with hyphens. Alias obsolete names. * lisp/erc/erc-page.el (erc-message-english-CTCP-PAGE): Define at top level using `defvar'. * lisp/erc/erc-sasl.el (erc-message-english-s902, erc-message-english-s904, erc-message-english-s905, erc-message-english-s906, erc-message-english-s907, erc-message-english-s908): Define at top level using `defvar'. * lisp/erc/erc-sound.el (erc-message-english-CTCP-SOUND): Define using `defvar'. * lisp/erc/erc.el (erc--make-message-variable-name): New function to replace `erc-make-message-variable-name' internally, where most uses previously checked whether the returned variable was bound. This helper now does that conditionally, when asked. (erc-make-message-variable-name): Defer to internal variant, `erc--make-message-variable-name'. (erc-define-catalog-entry, erc-define-catalog): Deprecate. (erc-retrieve-catalog-entry): Refactor to favor `default-toplevel-value' of `erc-current-message-catalog' before falling back to `english'. Not doing this was arguably a bug. (erc-message-english-bad-ping-response, erc-message-english-bad-syntax, erc-message-english-incorrect-args, erc-message-english-cannot-find-file, erc-message-english-cannot-read-file, erc-message-english-connect, erc-message-english-country, erc-message-english-country-unknown, erc-message-english-ctcp-empty, erc-message-english-ctcp-request, erc-message-english-ctcp-request-to, erc-message-english-ctcp-too-many, erc-message-english-flood-ctcp-off, erc-message-english-flood-strict-mode, erc-message-english-disconnected, erc-message-english-disconnected-noreconnect, erc-message-english-reconnecting, erc-message-english-reconnect-canceled, erc-message-english-finished, erc-message-english-terminated, erc-message-english-login, erc-message-english-nick-in-use, erc-message-english-nick-too-long, erc-message-english-no-default-channel, erc-message-english-no-invitation, erc-message-english-no-target, erc-message-english-ops, erc-message-english-ops-none, erc-message-english-undefined-ctcp, erc-message-english-user-mode-redundant-add, erc-message-english-user-mode-redundant-drop, erc-message-english-variable-not-bound, erc-message-english-ACTION, erc-message-english-CTCP-CLIENTINFO, erc-message-english-CTCP-ECHO, erc-message-english-CTCP-FINGER, erc-message-english-CTCP-PING, erc-message-english-CTCP-TIME, erc-message-english-CTCP-UNKNOWN, erc-message-english-CTCP-VERSION, erc-message-english-ERROR, erc-message-english-INVITE, erc-message-english-JOIN, erc-message-english-JOIN-you, erc-message-english-KICK, erc-message-english-KICK-you, erc-message-english-KICK-by-you, erc-message-english-MODE, erc-message-english-MODE-nick, erc-message-english-NICK, erc-message-english-NICK-you, erc-message-english-PART, erc-message-english-PING, erc-message-english-PONG, erc-message-english-QUIT, erc-message-english-TOPIC, erc-message-english-WALLOPS, erc-message-english-s004, erc-message-english-s221, erc-message-english-s252, erc-message-english-s253, erc-message-english-s254, erc-message-english-s275, erc-message-english-s301, erc-message-english-s303, erc-message-english-s305, erc-message-english-s306, erc-message-english-s307, erc-message-english-s311, erc-message-english-s312, erc-message-english-s313, erc-message-english-s314, erc-message-english-s317, erc-message-english-s317-on-since, erc-message-english-s319, erc-message-english-s320, erc-message-english-s321, erc-message-english-s322, erc-message-english-s324, erc-message-english-s328, erc-message-english-s329, erc-message-english-s330, erc-message-english-s331, erc-message-english-s332, erc-message-english-s333, erc-message-english-s341, erc-message-english-s352, erc-message-english-s353, erc-message-english-s367, erc-message-english-s367-set-by, erc-message-english-s368, erc-message-english-s379, erc-message-english-s391, erc-message-english-s396, erc-message-english-s401, erc-message-english-s402, erc-message-english-s403, erc-message-english-s404, erc-message-english-s405, erc-message-english-s406, erc-message-english-s412, erc-message-english-s421, erc-message-english-s431, erc-message-english-s432, erc-message-english-s442, erc-message-english-s445, erc-message-english-s446, erc-message-english-s451, erc-message-english-s461, erc-message-english-s462, erc-message-english-s463, erc-message-english-s464, erc-message-english-s465, erc-message-english-s471, erc-message-english-s473, erc-message-english-s474, erc-message-english-s475, erc-message-english-s481, erc-message-english-s482, erc-message-english-s483, erc-message-english-s484, erc-message-english-s485, erc-message-english-s491, erc-message-english-s501, erc-message-english-s502, erc-message-english-s671): Define at top level using `defvar'. * test/lisp/erc/erc-tests.el (erc-tests--string-to-propertized-parts, erc-tests-pp-propertized-parts, erc--make-message-variable-name, erc-retrieve-catalog-entry): New tests along with utility functions and a convenience command for manipulating catalogs. (Bug#67677)
This commit is contained in:
parent
7c2e02e6d7
commit
b5da8ba807
10 changed files with 259 additions and 60 deletions
12
etc/ERC-NEWS
12
etc/ERC-NEWS
|
|
@ -425,6 +425,13 @@ Built-in modules can now provide more detailed help for a particular
|
|||
subcommand by telling ERC to defer to a specialized handler. This
|
||||
facility can be opened up to third parties should any one request it.
|
||||
|
||||
*** Message-formatting templates in 'notify' renamed.
|
||||
All templates beginning with the prefix "erc-message-english-notify_"
|
||||
have been renamed to begin with "erc-message-english-notify-". For
|
||||
example, the variable 'erc-message-english-notify_current' is now
|
||||
'erc-message-english-notify_current'. The old names have been
|
||||
preserved as obsolete aliases.
|
||||
|
||||
*** Longtime quasi modules made proper.
|
||||
The 'fill' module is now defined by 'define-erc-module'. The same
|
||||
goes for ERC's imenu integration, which has 'imenu' now appearing in
|
||||
|
|
@ -510,6 +517,11 @@ handling specific "MODE" types and letters in coming releases. If
|
|||
you'd like a say in shaping how this transpires, please share your
|
||||
ideas and use cases on the tracker.
|
||||
|
||||
*** A better way to define message-formatting templates.
|
||||
The functions 'erc-define-catalog-entry' and 'erc-define-catalog' have
|
||||
been deprecated in favor of 'erc-define-message-format-catalog', a new
|
||||
macro for defining template "catalogs" at the top level of libraries.
|
||||
|
||||
*** Miscellaneous changes
|
||||
Two helper macros from GNU ELPA's Compat library are now available to
|
||||
third-party modules as 'erc-compat-call' and 'erc-compat-function'.
|
||||
|
|
|
|||
|
|
@ -506,6 +506,41 @@ Use the CASEMAPPING ISUPPORT parameter to determine the style."
|
|||
(,(widget-get (widget-convert type) :match) w v))
|
||||
',(cdr type)))
|
||||
|
||||
;; This internal variant exists as a transition aid to avoid
|
||||
;; immediately having to reflow lengthy definition lists, like the one
|
||||
;; in erc.el. These sites should switch to using the public macro
|
||||
;; when undergoing their next major edit.
|
||||
(defmacro erc--define-catalog (name entries)
|
||||
"Define `erc-display-message' formatting templates for NAME, a symbol.
|
||||
|
||||
See `erc-define-message-format-catalog' for the meaning of
|
||||
ENTRIES, an alist. Also see `erc-tests-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."
|
||||
(declare (indent 1))
|
||||
(let (out)
|
||||
(dolist (e entries (cons 'progn (nreverse out)))
|
||||
(push `(defvar ,(intern (format "erc-message-%s-%s" name (car e)))
|
||||
,(cdr e)
|
||||
,(let* ((first (format "Message template for key `%s'" (car e)))
|
||||
(last (format "catalog `%s'." name))
|
||||
(combined (concat first " in " last)))
|
||||
(if (< (length combined) 80)
|
||||
combined
|
||||
(concat first ".\nFor use with " last))))
|
||||
out))))
|
||||
|
||||
(defmacro erc-define-message-format-catalog (language &rest entries)
|
||||
"Define message-formatting templates for LANGUAGE, a symbol.
|
||||
Expect ENTRIES to be pairs of (KEY . FORMAT), where KEY is a
|
||||
symbol, and FORMAT evaluates to a format string compatible with
|
||||
`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))
|
||||
`(erc--define-catalog ,language ,entries))
|
||||
|
||||
(provide 'erc-common)
|
||||
|
||||
;;; erc-common.el ends here
|
||||
|
|
|
|||
|
|
@ -131,9 +131,8 @@ Looks like:
|
|||
(open-network-stream procname buffer addr port
|
||||
:type (and (plist-get entry :secure) 'tls))))
|
||||
|
||||
(erc-define-catalog
|
||||
'english
|
||||
'((dcc-chat-discarded
|
||||
(erc--define-catalog english
|
||||
((dcc-chat-discarded
|
||||
. "DCC: previous chat request from %n (%u@%h) discarded")
|
||||
(dcc-chat-ended . "DCC: chat with %n ended %t: %e")
|
||||
(dcc-chat-no-request . "DCC: chat request from %n not found")
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ netsplits, so that it can filter the JOIN messages on a netjoin too."
|
|||
;;;###autoload(autoload 'erc-netsplit-mode "erc-netsplit")
|
||||
(define-erc-module netsplit nil
|
||||
"This mode hides quit/join messages if a netsplit occurs."
|
||||
((erc-netsplit-install-message-catalogs)
|
||||
( ; FIXME delete newline on next edit
|
||||
(add-hook 'erc-server-JOIN-functions #'erc-netsplit-JOIN)
|
||||
(add-hook 'erc-server-MODE-functions #'erc-netsplit-MODE)
|
||||
(add-hook 'erc-server-QUIT-functions #'erc-netsplit-QUIT)
|
||||
|
|
@ -85,13 +85,22 @@ where FIRST-JOIN is t or nil, depending on whether or not the first
|
|||
join from that split has been detected or not.")
|
||||
|
||||
(defun erc-netsplit-install-message-catalogs ()
|
||||
(declare (obsolete "defined at top level in erc-netsplit.el" "30.1"))
|
||||
(with-suppressed-warnings ((obsolete erc-define-catalog)) ; indentation
|
||||
(erc-define-catalog
|
||||
'english
|
||||
'((netsplit . "netsplit: %s")
|
||||
(netjoin . "netjoin: %s, %N were split")
|
||||
(netjoin-done . "netjoin: All lost souls are back!")
|
||||
(netsplit-none . "No netsplits in progress")
|
||||
(netsplit-wholeft . "split: %s missing: %n %t"))))
|
||||
(netsplit-wholeft . "split: %s missing: %n %t"))))) ; indentation
|
||||
|
||||
(erc-define-message-format-catalog english
|
||||
(netsplit . "netsplit: %s")
|
||||
(netjoin . "netjoin: %s, %N were split")
|
||||
(netjoin-done . "netjoin: All lost souls are back!")
|
||||
(netsplit-none . "No netsplits in progress")
|
||||
(netsplit-wholeft . "split: %s missing: %n %t"))
|
||||
|
||||
(defun erc-netsplit-JOIN (proc parsed)
|
||||
"Show/don't show rejoins."
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
;;; Code:
|
||||
|
||||
(require 'erc)
|
||||
(require 'erc-networks)
|
||||
(eval-when-compile (require 'pcomplete))
|
||||
|
||||
;;;; Customizable variables
|
||||
|
|
@ -78,12 +77,14 @@ strings."
|
|||
;;;; Setup
|
||||
|
||||
(defun erc-notify-install-message-catalogs ()
|
||||
(erc-define-catalog
|
||||
'english
|
||||
'((notify_current . "Notified people online: %l")
|
||||
(notify_list . "Current notify list: %l")
|
||||
(notify_on . "Detected %n on IRC network %m")
|
||||
(notify_off . "%n has left IRC network %m"))))
|
||||
(declare (obsolete "defined at top level in erc-notify.el" "30.1"))
|
||||
(with-suppressed-warnings ((obsolete erc-define-catalog))
|
||||
(erc-define-catalog
|
||||
'english
|
||||
'((notify-current . "Notified people online: %l")
|
||||
(notify-list . "Current notify list: %l")
|
||||
(notify-on . "Detected %n on IRC network %m")
|
||||
(notify-off . "%n has left IRC network %m")))))
|
||||
|
||||
;;;###autoload(autoload 'erc-notify-mode "erc-notify" nil t)
|
||||
(define-erc-module notify nil
|
||||
|
|
@ -119,14 +120,14 @@ changes."
|
|||
(run-hook-with-args 'erc-notify-signon-hook server (car new-list))
|
||||
(erc-display-message
|
||||
parsed 'notice proc
|
||||
'notify_on ?n (car new-list) ?m (erc-network-name)))
|
||||
'notify-on ?n (car new-list) ?m (erc-network-name)))
|
||||
(setq new-list (cdr new-list)))
|
||||
(while old-list
|
||||
(when (not (erc-member-ignore-case (car old-list) ison-list))
|
||||
(run-hook-with-args 'erc-notify-signoff-hook server (car old-list))
|
||||
(erc-display-message
|
||||
parsed 'notice proc
|
||||
'notify_off ?n (car old-list) ?m (erc-network-name)))
|
||||
'notify-off ?n (car old-list) ?m (erc-network-name)))
|
||||
(setq old-list (cdr old-list)))
|
||||
(setq erc-last-ison ison-list)
|
||||
t)))
|
||||
|
|
@ -136,8 +137,8 @@ changes."
|
|||
|
||||
(defun erc-notify-JOIN (proc parsed)
|
||||
"Check if channel joiner is on `erc-notify-list' and not on `erc-last-ison'.
|
||||
If this condition is satisfied, produce a notify_on message and add the nick
|
||||
to `erc-last-ison' to prevent any further notifications."
|
||||
When that's the case, produce a `notify-on' message and add the
|
||||
nick to `erc-last-ison' to prevent any further notifications."
|
||||
(let ((nick (erc-extract-nick (erc-response.sender parsed))))
|
||||
(when (and (erc-member-ignore-case nick erc-notify-list)
|
||||
(not (erc-member-ignore-case nick erc-last-ison)))
|
||||
|
|
@ -147,13 +148,13 @@ to `erc-last-ison' to prevent any further notifications."
|
|||
nick)
|
||||
(erc-display-message
|
||||
parsed 'notice proc
|
||||
'notify_on ?n nick ?m (erc-network-name)))
|
||||
'notify-on ?n nick ?m (erc-network-name)))
|
||||
nil))
|
||||
|
||||
(defun erc-notify-NICK (proc parsed)
|
||||
"Check if new nick is on `erc-notify-list' and not on `erc-last-ison'.
|
||||
If this condition is satisfied, produce a notify_on message and add the nick
|
||||
to `erc-last-ison' to prevent any further notifications."
|
||||
When that's the case, produce a `notify-on' message and add the
|
||||
nick to `erc-last-ison' to prevent any further notifications."
|
||||
(let ((nick (erc-response.contents parsed)))
|
||||
(when (and (erc-member-ignore-case nick erc-notify-list)
|
||||
(not (erc-member-ignore-case nick erc-last-ison)))
|
||||
|
|
@ -163,13 +164,13 @@ to `erc-last-ison' to prevent any further notifications."
|
|||
nick)
|
||||
(erc-display-message
|
||||
parsed 'notice proc
|
||||
'notify_on ?n nick ?m (erc-network-name)))
|
||||
'notify-on ?n nick ?m (erc-network-name)))
|
||||
nil))
|
||||
|
||||
(defun erc-notify-QUIT (proc parsed)
|
||||
"Check if quitter is on `erc-notify-list' and on `erc-last-ison'.
|
||||
If this condition is satisfied, produce a notify_off message and remove the
|
||||
nick from `erc-last-ison' to prevent any further notifications."
|
||||
When that's the case, insert a `notify-off' message and remove
|
||||
the nick from `erc-last-ison' to prevent further notifications."
|
||||
(let ((nick (erc-extract-nick (erc-response.sender parsed))))
|
||||
(when (and (erc-member-ignore-case nick erc-notify-list)
|
||||
(erc-member-ignore-case nick erc-last-ison))
|
||||
|
|
@ -183,7 +184,7 @@ nick from `erc-last-ison' to prevent any further notifications."
|
|||
nick)
|
||||
(erc-display-message
|
||||
parsed 'notice proc
|
||||
'notify_off ?n nick ?m (erc-network-name)))
|
||||
'notify-off ?n nick ?m (erc-network-name)))
|
||||
nil))
|
||||
|
||||
;;;; User level command
|
||||
|
|
@ -193,6 +194,12 @@ nick from `erc-last-ison' to prevent any further notifications."
|
|||
"Change `erc-notify-list' or list current notify-list members online.
|
||||
Without args, list the current list of notified people online,
|
||||
with args, toggle notify status of people."
|
||||
(unless erc-notify-mode
|
||||
(erc-notify-mode +1)
|
||||
(erc-button--display-error-notice-with-keys
|
||||
(current-buffer)
|
||||
"Command /NOTIFY requires the `notify' module. Enabling now. Add `notify'"
|
||||
" to `erc-modules' before next starting ERC to silence this message."))
|
||||
(cond
|
||||
((null args)
|
||||
;; Print current notified people (online)
|
||||
|
|
@ -202,11 +209,12 @@ with args, toggle notify status of people."
|
|||
nil 'notice 'active "No ison-list yet!")
|
||||
(erc-display-message
|
||||
nil 'notice 'active
|
||||
'notify_current ?l ison))))
|
||||
'notify-current ?l ison))))
|
||||
((string= (car args) "-l")
|
||||
(erc-display-message nil 'notice 'active
|
||||
'notify_list ?l (mapconcat #'identity erc-notify-list
|
||||
" ")))
|
||||
(let ((list (if erc-notify-list
|
||||
(mapconcat #'identity erc-notify-list " ")
|
||||
"(empty)")))
|
||||
(erc-display-message nil 'notice 'active 'notify-list ?l list)))
|
||||
(t
|
||||
(while args
|
||||
(if (erc-member-ignore-case (car args) erc-notify-list)
|
||||
|
|
@ -225,23 +233,34 @@ with args, toggle notify status of people."
|
|||
(setq erc-notify-list (cons (erc-string-no-properties (car args))
|
||||
erc-notify-list)))
|
||||
(setq args (cdr args)))
|
||||
(erc-display-message
|
||||
nil 'notice 'active
|
||||
'notify_list ?l (mapconcat #'identity erc-notify-list " "))))
|
||||
(erc-cmd-NOTIFY "-l")))
|
||||
t)
|
||||
|
||||
(autoload 'pcomplete-erc-all-nicks "erc-pcomplete")
|
||||
|
||||
;; "--" is not a typo.
|
||||
(declare-function pcomplete--here "pcomplete"
|
||||
(&optional form stub paring form-only))
|
||||
(declare-function pcomplete-erc-all-nicks "erc-pcomplete"
|
||||
(&optional postfix))
|
||||
|
||||
;;;###autoload
|
||||
(defun pcomplete/erc-mode/NOTIFY ()
|
||||
(require 'pcomplete)
|
||||
(pcomplete-here (pcomplete-erc-all-nicks)))
|
||||
(require 'erc-pcomplete)
|
||||
(pcomplete-here (append erc-notify-list (pcomplete-erc-all-nicks))))
|
||||
|
||||
(erc-notify-install-message-catalogs)
|
||||
(define-obsolete-variable-alias 'erc-message-english-notify_on
|
||||
'erc-message-english-notify-on "30.1")
|
||||
(define-obsolete-variable-alias 'erc-message-english-notify_off
|
||||
'erc-message-english-notify-off "30.1")
|
||||
(define-obsolete-variable-alias 'erc-message-english-notify_list
|
||||
'erc-message-english-notify-list "30.1")
|
||||
(define-obsolete-variable-alias 'erc-message-english-notify_current
|
||||
'erc-message-english-notify-current "30.1")
|
||||
|
||||
(erc-define-message-format-catalog english
|
||||
(notify-current . "Notified people online: %l")
|
||||
(notify-list . "Current notify list: %l")
|
||||
(notify-on . "Detected %n on IRC network %m")
|
||||
(notify-off . "%n has left IRC network %m"))
|
||||
|
||||
(provide 'erc-notify)
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@
|
|||
"Process CTCP PAGE requests from IRC."
|
||||
nil nil)
|
||||
|
||||
(erc-define-catalog-entry 'english 'CTCP-PAGE "Page from %n (%u@%h): %m")
|
||||
(defvar erc-message-english-CTCP-PAGE "Page from %n (%u@%h): %m"
|
||||
"English template for a CTCP PAGE message.")
|
||||
|
||||
(defcustom erc-page-function nil
|
||||
"A function to process a \"page\" request.
|
||||
|
|
|
|||
|
|
@ -305,9 +305,8 @@ If necessary, pass PROMPT to `read-passwd'."
|
|||
(| eot ",")))
|
||||
(downcase offered)))
|
||||
|
||||
(erc-define-catalog
|
||||
'english
|
||||
'((s902 . "ERR_NICKLOCKED nick %n unavailable: %s")
|
||||
(erc--define-catalog english
|
||||
((s902 . "ERR_NICKLOCKED nick %n unavailable: %s")
|
||||
(s904 . "ERR_SASLFAIL (authentication failed) %s")
|
||||
(s905 . "ERR SASLTOOLONG (credentials too long) %s")
|
||||
(s906 . "ERR_SASLABORTED (authentication aborted) %s")
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ and play sound files as requested."
|
|||
((remove-hook 'erc-ctcp-query-SOUND-hook #'erc-ctcp-query-SOUND)
|
||||
(define-key erc-mode-map "\C-c\C-s" #'undefined)))
|
||||
|
||||
(erc-define-catalog-entry 'english 'CTCP-SOUND "%n (%u@%h) plays %s:%m")
|
||||
(defvar erc-message-english-CTCP-SOUND "%n (%u@%h) plays %s:%m"
|
||||
"English template for a CTCP SOUND message.")
|
||||
|
||||
(defcustom erc-play-sound t
|
||||
"Play sounds when you receive CTCP SOUND requests."
|
||||
|
|
|
|||
|
|
@ -8690,24 +8690,38 @@ All windows are opened in the current frame."
|
|||
|
||||
;;; Message catalog
|
||||
|
||||
(define-inline erc--make-message-variable-name (catalog key softp)
|
||||
"Return variable name conforming to ERC's message-catalog interface.
|
||||
Given a CATALOG symbol `mycat' and format-string KEY `mykey',
|
||||
also a symbol, return the symbol `erc-message-mycat-mykey'. With
|
||||
SOFTP, only do so when defined as a variable."
|
||||
(inline-quote
|
||||
(let* ((catname (symbol-name ,catalog))
|
||||
(prefix (if (eq ?- (aref catname 0)) "erc--message" "erc-message-"))
|
||||
(name (concat prefix catname "-" (symbol-name ,key))))
|
||||
(if ,softp
|
||||
(and-let* ((s (intern-soft name)) ((boundp s))) s)
|
||||
(intern name)))))
|
||||
|
||||
(defun erc-make-message-variable-name (catalog entry)
|
||||
"Create a variable name corresponding to CATALOG's ENTRY."
|
||||
(intern (concat "erc-message-"
|
||||
(symbol-name catalog) "-" (symbol-name entry))))
|
||||
(erc--make-message-variable-name catalog entry nil))
|
||||
|
||||
(defun erc-define-catalog-entry (catalog entry format-spec)
|
||||
"Set CATALOG's ENTRY to FORMAT-SPEC."
|
||||
(declare (obsolete "define manually using `defvar' instead" "30.1"))
|
||||
(set (erc-make-message-variable-name catalog entry)
|
||||
format-spec))
|
||||
|
||||
(defun erc-define-catalog (catalog entries)
|
||||
"Define a CATALOG according to ENTRIES."
|
||||
(dolist (entry entries)
|
||||
(erc-define-catalog-entry catalog (car entry) (cdr entry))))
|
||||
(declare (obsolete erc-define-message-format-catalog "30.1"))
|
||||
(with-suppressed-warnings ((obsolete erc-define-catalog-entry))
|
||||
(dolist (entry entries)
|
||||
(erc-define-catalog-entry catalog (car entry) (cdr entry)))))
|
||||
|
||||
(erc-define-catalog
|
||||
'english
|
||||
'((bad-ping-response . "Unexpected PING response from %n (time %t)")
|
||||
(erc--define-catalog english
|
||||
((bad-ping-response . "Unexpected PING response from %n (time %t)")
|
||||
(bad-syntax . "Error occurred - incorrect usage?\n%c %u\n%d")
|
||||
(incorrect-args . "Incorrect arguments. Usage:\n%c %u\n%d")
|
||||
(cannot-find-file . "Cannot find file %f")
|
||||
|
|
@ -8764,7 +8778,7 @@ All windows are opened in the current frame."
|
|||
(MODE-nick . "%n has changed mode for %t to %m")
|
||||
(NICK . "%n (%u@%h) is now known as %N")
|
||||
(NICK-you . "Your new nickname is %N")
|
||||
(PART . erc-message-english-PART)
|
||||
(PART . #'erc-message-english-PART)
|
||||
(PING . "PING from server (last: %s sec. ago)")
|
||||
(PONG . "PONG from %h (%i second%s)")
|
||||
(QUIT . "%n (%u@%h) has quit: %r")
|
||||
|
|
@ -8861,19 +8875,20 @@ functions."
|
|||
|
||||
(defvar-local erc-current-message-catalog 'english)
|
||||
|
||||
(defun erc-retrieve-catalog-entry (entry &optional catalog)
|
||||
"Retrieve ENTRY from CATALOG.
|
||||
|
||||
If CATALOG is nil, `erc-current-message-catalog' is used.
|
||||
|
||||
If ENTRY is nil in CATALOG, it is retrieved from the fallback,
|
||||
english, catalog."
|
||||
(defun erc-retrieve-catalog-entry (key &optional catalog)
|
||||
"Retrieve `format-spec' entry for symbol KEY in CATALOG.
|
||||
Without symbol CATALOG, use `erc-current-message-catalog'. If
|
||||
lookup fails, try the latter's `default-toplevel-value' if it's
|
||||
not the same as CATALOG. Failing that, try the `english' catalog
|
||||
if yet untried."
|
||||
(unless catalog (setq catalog erc-current-message-catalog))
|
||||
(let ((var (erc-make-message-variable-name catalog entry)))
|
||||
(if (boundp var)
|
||||
(symbol-value var)
|
||||
(when (boundp (erc-make-message-variable-name 'english entry))
|
||||
(symbol-value (erc-make-message-variable-name 'english entry))))))
|
||||
(symbol-value
|
||||
(or (erc--make-message-variable-name catalog key 'softp)
|
||||
(let ((default (default-toplevel-value 'erc-current-message-catalog)))
|
||||
(or (and (not (eq default catalog))
|
||||
(erc--make-message-variable-name default key 'softp))
|
||||
(and (not (memq 'english (list default catalog)))
|
||||
(erc--make-message-variable-name 'english key 'softp)))))))
|
||||
|
||||
(defun erc-format-message (msg &rest args)
|
||||
"Format MSG according to ARGS.
|
||||
|
|
|
|||
|
|
@ -3262,4 +3262,113 @@ connection."
|
|||
(put 'erc-mname-enable 'definition-name 'mname)
|
||||
(put 'erc-mname-disable 'definition-name 'mname))))))
|
||||
|
||||
(defun erc-tests--string-to-propertized-parts (string)
|
||||
"Return a sequence of `propertize' forms for generating STRING.
|
||||
Expect maintainers manipulating template catalogs to use this
|
||||
with `pp-eval-last-sexp' or similar to convert back and forth
|
||||
between literal strings."
|
||||
`(concat
|
||||
,@(mapcar
|
||||
(pcase-lambda (`(,beg ,end ,plist))
|
||||
;; At the time of writing, `propertize' produces a string
|
||||
;; with the order of the input plist reversed.
|
||||
`(propertize ,(substring-no-properties string beg end)
|
||||
,@(let (out)
|
||||
(while-let ((plist)
|
||||
(k (pop plist))
|
||||
(v (pop plist)))
|
||||
(push (if (or (consp v) (symbolp v)) `',v v) out)
|
||||
(push `',k out))
|
||||
out)))
|
||||
(object-intervals string))))
|
||||
|
||||
(defun erc-tests-pp-propertized-parts (arg)
|
||||
"Convert literal string before point into a `propertize'd form.
|
||||
For simplicity, assume string evaluates to itself."
|
||||
(interactive "P")
|
||||
(let ((sexp (erc-tests--string-to-propertized-parts (pp-last-sexp))))
|
||||
(if arg (insert (pp-to-string sexp)) (pp-eval-expression sexp))))
|
||||
|
||||
(ert-deftest erc-tests--string-to-propertized-parts ()
|
||||
:tags '(:unstable) ; only run this locally
|
||||
(unless (>= emacs-major-version 28) (ert-skip "Missing `object-intervals'"))
|
||||
|
||||
(should (equal (erc-tests--string-to-propertized-parts
|
||||
#("abc"
|
||||
0 1 (face default foo 1)
|
||||
1 3 (face (default italic) bar "2")))
|
||||
'(concat (propertize "a" 'foo 1 'face 'default)
|
||||
(propertize "bc" 'bar "2" 'face '(default italic)))))
|
||||
(should (equal #("abc"
|
||||
0 1 (face default foo 1)
|
||||
1 3 (face (default italic) bar "2"))
|
||||
(concat (propertize "a" 'foo 1 'face 'default)
|
||||
(propertize "bc" 'bar "2" 'face '(default italic))))))
|
||||
|
||||
(ert-deftest erc--make-message-variable-name ()
|
||||
(should (erc--make-message-variable-name 'english 'QUIT 'softp))
|
||||
(should (erc--make-message-variable-name 'english 'QUIT nil))
|
||||
|
||||
(let ((obarray (obarray-make)))
|
||||
(should-not (erc--make-message-variable-name 'testcat 'testkey 'softp))
|
||||
(should (erc--make-message-variable-name 'testcat 'testkey nil))
|
||||
(should (intern-soft "erc-message-testcat-testkey" obarray))
|
||||
(should-not (erc--make-message-variable-name 'testcat 'testkey 'softp))
|
||||
(set (intern "erc-message-testcat-testkey" obarray) "hello world")
|
||||
(should (equal (symbol-value
|
||||
(erc--make-message-variable-name 'testcat 'testkey nil))
|
||||
"hello world")))
|
||||
|
||||
;; Hyphenated (internal catalog).
|
||||
(let ((obarray (obarray-make)))
|
||||
(should-not (erc--make-message-variable-name '-testcat 'testkey 'softp))
|
||||
(should (erc--make-message-variable-name '-testcat 'testkey nil))
|
||||
(should (intern-soft "erc--message-testcat-testkey" obarray))
|
||||
(should-not (erc--make-message-variable-name '-testcat 'testkey 'softp))
|
||||
(set (intern "erc--message-testcat-testkey" obarray) "hello world")
|
||||
(should (equal (symbol-value
|
||||
(erc--make-message-variable-name '-testcat 'testkey nil))
|
||||
"hello world"))))
|
||||
|
||||
(ert-deftest erc-retrieve-catalog-entry ()
|
||||
(should (eq 'english erc-current-message-catalog))
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "User modes for %n: %m"))
|
||||
|
||||
;; Local binding.
|
||||
(with-temp-buffer
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "User modes for %n: %m"))
|
||||
(setq erc-current-message-catalog 'test)
|
||||
;; No catalog named `test'.
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "User modes for %n: %m"))
|
||||
|
||||
(let ((obarray (obarray-make)))
|
||||
(set (intern "erc-message-test-s221") "test 221 val")
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "test 221 val"))
|
||||
(set (intern "erc-message-english-s221") "eng 221 val")
|
||||
|
||||
(let ((erc-current-message-catalog 'english))
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "eng 221 val")))
|
||||
|
||||
(with-temp-buffer
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "eng 221 val"))
|
||||
(let ((erc-current-message-catalog 'test))
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "test 221 val"))))
|
||||
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "test 221 val")))
|
||||
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "User modes for %n: %m"))
|
||||
(should (equal erc-current-message-catalog 'test)))
|
||||
|
||||
;; Default top-level value.
|
||||
(set-default-toplevel-value 'erc-current-message-catalog 'test-top)
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "User modes for %n: %m"))
|
||||
(set (intern "erc-message-test-top-s221") "test-top 221 val")
|
||||
(should (equal (erc-retrieve-catalog-entry 's221) "test-top 221 val"))
|
||||
|
||||
(setq erc-current-message-catalog 'test-local)
|
||||
(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))
|
||||
|
||||
;;; erc-tests.el ends here
|
||||
|
|
|
|||
Loading…
Reference in a new issue