diff options
| author | F. Jason Park | 2023-11-13 18:24:59 -0800 |
|---|---|---|
| committer | F. Jason Park | 2023-11-18 12:34:56 -0800 |
| commit | b088222ec9f0cff720ca366bdef448d392731f94 (patch) | |
| tree | 51238af28ee75afb6272f253ceaa560b6f960ad4 | |
| parent | cc7e008dce1df9d2472338b1fc3cc766166e9e55 (diff) | |
| download | emacs-b088222ec9f0cff720ca366bdef448d392731f94.tar.gz emacs-b088222ec9f0cff720ca366bdef448d392731f94.zip | |
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)
| -rw-r--r-- | lisp/erc/erc-backend.el | 27 | ||||
| -rw-r--r-- | lisp/erc/erc-common.el | 5 | ||||
| -rw-r--r-- | 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." | |||
| 2098 | (erc-with-server-buffer erc--isupport-params))) | 2098 | (erc-with-server-buffer erc--isupport-params))) |
| 2099 | (value (with-memoization (gethash key table) | 2099 | (value (with-memoization (gethash key table) |
| 2100 | (when-let ((v (assoc (symbol-name key) | 2100 | (when-let ((v (assoc (symbol-name key) |
| 2101 | erc-server-parameters))) | 2101 | (or erc-server-parameters |
| 2102 | (erc-with-server-buffer | ||
| 2103 | erc-server-parameters))))) | ||
| 2102 | (if (cdr v) | 2104 | (if (cdr v) |
| 2103 | (erc--parse-isupport-value (cdr v)) | 2105 | (erc--parse-isupport-value (cdr v)) |
| 2104 | '--empty--))))) | 2106 | '--empty--))))) |
| @@ -2108,6 +2110,22 @@ primitive value." | |||
| 2108 | (when table | 2110 | (when table |
| 2109 | (remhash key table)))) | 2111 | (remhash key table)))) |
| 2110 | 2112 | ||
| 2113 | ;; While it's better to depend on interfaces than specific types, | ||
| 2114 | ;; using `cl-struct-slot-value' or similar to extract a known slot at | ||
| 2115 | ;; runtime would incur a small "ducktyping" tax, which should probably | ||
| 2116 | ;; be avoided when running dozens of times per incoming message. | ||
| 2117 | (defmacro erc--with-isupport-data (param var &rest body) | ||
| 2118 | "Return structured data stored in VAR for \"ISUPPORT\" PARAM. | ||
| 2119 | Expect VAR's value to be an instance of `erc--isupport-data'. If | ||
| 2120 | VAR is uninitialized or stale, evaluate BODY and assign the | ||
| 2121 | result to VAR." | ||
| 2122 | (declare (indent defun)) | ||
| 2123 | `(erc-with-server-buffer | ||
| 2124 | (pcase-let (((,@(list '\` (list param '\, 'key))) | ||
| 2125 | (erc--get-isupport-entry ',param))) | ||
| 2126 | (or (and ,var (eq key (erc--isupport-data-key ,var)) ,var) | ||
| 2127 | (setq ,var (progn ,@body)))))) | ||
| 2128 | |||
| 2111 | (define-erc-response-handler (005) | 2129 | (define-erc-response-handler (005) |
| 2112 | "Set the variable `erc-server-parameters' and display the received message. | 2130 | "Set the variable `erc-server-parameters' and display the received message. |
| 2113 | 2131 | ||
| @@ -2128,8 +2146,11 @@ A server may send more than one 005 message." | |||
| 2128 | key | 2146 | key |
| 2129 | value | 2147 | value |
| 2130 | negated) | 2148 | negated) |
| 2131 | (when (string-match "^\\([A-Z]+\\)=\\(.*\\)$\\|^\\(-\\)?\\([A-Z]+\\)$" | 2149 | (when (string-match |
| 2132 | section) | 2150 | (rx bot (| (: (group (+ (any "A-Z"))) "=" (group (* nonl))) |
| 2151 | (: (? (group "-")) (group (+ (any "A-Z"))))) | ||
| 2152 | eot) | ||
| 2153 | section) | ||
| 2133 | (setq key (or (match-string 1 section) (match-string 4 section)) | 2154 | (setq key (or (match-string 1 section) (match-string 4 section)) |
| 2134 | value (match-string 2 section) | 2155 | value (match-string 2 section) |
| 2135 | negated (and (match-string 3 section) '-)) | 2156 | 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 @@ | |||
| 101 | (contents "" :type string) | 101 | (contents "" :type string) |
| 102 | (tags '() :type list)) | 102 | (tags '() :type list)) |
| 103 | 103 | ||
| 104 | (cl-defstruct erc--isupport-data | ||
| 105 | "Abstract \"class\" for parsed ISUPPORT data. | ||
| 106 | For use with the macro `erc--with-isupport-data'." | ||
| 107 | (key nil :type (or null cons))) | ||
| 108 | |||
| 104 | ;; After dropping 28, we can use prefixed "erc-autoload" cookies. | 109 | ;; After dropping 28, we can use prefixed "erc-autoload" cookies. |
| 105 | (defun erc--normalize-module-symbol (symbol) | 110 | (defun erc--normalize-module-symbol (symbol) |
| 106 | "Return preferred SYMBOL for `erc--modules'." | 111 | "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 @@ | |||
| 59 | 59 | ||
| 60 | (erc-cmd-QUIT ""))) | 60 | (erc-cmd-QUIT ""))) |
| 61 | 61 | ||
| 62 | (eval-when-compile (require 'erc-join)) | ||
| 63 | |||
| 64 | ;;; erc-scenarios-display-message.el ends here | 62 | ;;; erc-scenarios-display-message.el ends here |