[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master b088222ec9f 3/5: Simplify ISUPPORT-derived data wrangling in ERC
From: |
F. Jason Park |
Subject: |
master b088222ec9f 3/5: Simplify ISUPPORT-derived data wrangling in ERC |
Date: |
Sat, 18 Nov 2023 15:40:47 -0500 (EST) |
branch: master
commit b088222ec9f0cff720ca366bdef448d392731f94
Author: F. Jason Park <jp@neverwas.me>
Commit: F. Jason Park <jp@neverwas.me>
Simplify ISUPPORT-derived data wrangling in ERC
* lisp/erc/erc-backend.el (erc--get-isupport-entry): Check server
buffer for `erc-server-parameters' when (re)initializing value. This
function was previously unreliable from a target buffer on cache
misses.
(erc--with-isupport-data): New macro for accessing and caching data
derived from an ISUPPORT parameter. Late-arriving params break the
cache.
(erc-server-005): Rewrite pattern as `rx' form, factoring out bol/eol.
* lisp/erc/erc-common.el (erc--isupport-data): New struct to be
subclassed for storing cached ISUPPORT-derived data.
* test/lisp/erc/erc-scenarios-display-message.el: Remove stray
`require'. (Bug#67220)
---
lisp/erc/erc-backend.el | 27 +++++++++++++++++++++++---
lisp/erc/erc-common.el | 5 +++++
test/lisp/erc/erc-scenarios-display-message.el | 2 --
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 66ac9057d75..8ebc10501c2 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -2098,7 +2098,9 @@ primitive value."
(erc-with-server-buffer erc--isupport-params)))
(value (with-memoization (gethash key table)
(when-let ((v (assoc (symbol-name key)
- erc-server-parameters)))
+ (or erc-server-parameters
+ (erc-with-server-buffer
+ erc-server-parameters)))))
(if (cdr v)
(erc--parse-isupport-value (cdr v))
'--empty--)))))
@@ -2108,6 +2110,22 @@ primitive value."
(when table
(remhash key table))))
+;; While it's better to depend on interfaces than specific types,
+;; using `cl-struct-slot-value' or similar to extract a known slot at
+;; runtime would incur a small "ducktyping" tax, which should probably
+;; be avoided when running dozens of times per incoming message.
+(defmacro erc--with-isupport-data (param var &rest body)
+ "Return structured data stored in VAR for \"ISUPPORT\" PARAM.
+Expect VAR's value to be an instance of `erc--isupport-data'. If
+VAR is uninitialized or stale, evaluate BODY and assign the
+result to VAR."
+ (declare (indent defun))
+ `(erc-with-server-buffer
+ (pcase-let (((,@(list '\` (list param '\, 'key)))
+ (erc--get-isupport-entry ',param)))
+ (or (and ,var (eq key (erc--isupport-data-key ,var)) ,var)
+ (setq ,var (progn ,@body))))))
+
(define-erc-response-handler (005)
"Set the variable `erc-server-parameters' and display the received message.
@@ -2128,8 +2146,11 @@ A server may send more than one 005 message."
key
value
negated)
- (when (string-match "^\\([A-Z]+\\)=\\(.*\\)$\\|^\\(-\\)?\\([A-Z]+\\)$"
- section)
+ (when (string-match
+ (rx bot (| (: (group (+ (any "A-Z"))) "=" (group (* nonl)))
+ (: (? (group "-")) (group (+ (any "A-Z")))))
+ eot)
+ section)
(setq key (or (match-string 1 section) (match-string 4 section))
value (match-string 2 section)
negated (and (match-string 3 section) '-))
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el
index 930e8032f6d..b020c612b7d 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -101,6 +101,11 @@
(contents "" :type string)
(tags '() :type list))
+(cl-defstruct erc--isupport-data
+ "Abstract \"class\" for parsed ISUPPORT data.
+For use with the macro `erc--with-isupport-data'."
+ (key nil :type (or null cons)))
+
;; After dropping 28, we can use prefixed "erc-autoload" cookies.
(defun erc--normalize-module-symbol (symbol)
"Return preferred SYMBOL for `erc--modules'."
diff --git a/test/lisp/erc/erc-scenarios-display-message.el
b/test/lisp/erc/erc-scenarios-display-message.el
index 51bdf305ad5..5751a32212d 100644
--- a/test/lisp/erc/erc-scenarios-display-message.el
+++ b/test/lisp/erc/erc-scenarios-display-message.el
@@ -59,6 +59,4 @@
(erc-cmd-QUIT "")))
-(eval-when-compile (require 'erc-join))
-
;;; erc-scenarios-display-message.el ends here