diff options
| author | F. Jason Park | 2023-06-01 22:07:03 -0700 |
|---|---|---|
| committer | F. Jason Park | 2023-06-11 19:18:14 -0700 |
| commit | 67f7ac2bbee2f58d919232682f6ea9e7039eb5f3 (patch) | |
| tree | f18940773162a6e8d6b51584b1425e1221b734d3 | |
| parent | bd969326e96584249b6c140d972f7b27ab3274f6 (diff) | |
| download | emacs-67f7ac2bbee2f58d919232682f6ea9e7039eb5f3.tar.gz emacs-67f7ac2bbee2f58d919232682f6ea9e7039eb5f3.zip | |
Deprecate nicknames entry in erc-button-alist
* lisp/erc/erc-button.el (erc-button-mode, erc-button-enable,
erc-button-disable): Restore running `erc-button-setup' on
`erc-mode-hook' and also do so immediately in all ERC buffers.
Do this instead of calling `erc-button--check-nicknames-entry.
(erc-button-buttonize-nicks): Mention that this option's value must be
non-nil for all but the most basic client functionality.
(erc-button-alist): Remove `nicknames' entry entirely. Describe
deprecation, replacement behavior, and available escape hatches in doc
string. Update and improve custom type definition, in particular, by
including long supported but never mentioned variants for the "REGEXP"
field.
(erc-button-keys-added): Deprecate because unused and misleading: keys
are bound during module init and remain so while module is enabled.
(erc-button--has-nickname-entry): New variable to indicate whether to
follow legacy code path when a `nicknames' entry exists in
`erc-button-alist'.
(erc-button-setup): Rewrite to provide warnings about deprecated
values for `erc-button-alist'.
(erc-button-nickname-callback-function): Add escape hatch for those
needing a custom callback for what was the default `nickname' entry in
`erc-button-alist'.
(erc-button-add-buttons): Always run `erc-button-add-nickname-buttons'
unless `erc-button--has-nickname-entry' is non-nil.
(erc-button--maybe-warn-arbitrary-sexp, erc-button--extract-form):
Rename former to latter and abstain from emitting a warning.
(erc-button--check-nicknames-entry): Remove unused function.
(erc-button-add-nickname-buttons): Defer to `erc-button--extract-form'
for determining value of third FORM slot of entry.
(erc-button-add-buttons-1): Call renamed version of
`erc-button--maybe-warn-arbitrary-sexp'. (Bug#60933)
| -rw-r--r-- | lisp/erc/erc-button.el | 137 |
1 files changed, 81 insertions, 56 deletions
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index 33b93ff6744..3045bb44889 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el | |||
| @@ -52,13 +52,15 @@ | |||
| 52 | ;;;###autoload(autoload 'erc-button-mode "erc-button" nil t) | 52 | ;;;###autoload(autoload 'erc-button-mode "erc-button" nil t) |
| 53 | (define-erc-module button nil | 53 | (define-erc-module button nil |
| 54 | "This mode buttonizes all messages according to `erc-button-alist'." | 54 | "This mode buttonizes all messages according to `erc-button-alist'." |
| 55 | ((erc-button--check-nicknames-entry) | 55 | ((add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append) |
| 56 | (add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append) | ||
| 57 | (add-hook 'erc-send-modify-hook #'erc-button-add-buttons 'append) | 56 | (add-hook 'erc-send-modify-hook #'erc-button-add-buttons 'append) |
| 57 | (add-hook 'erc-mode-hook #'erc-button-setup 91) | ||
| 58 | (unless erc--updating-modules-p (erc-buffer-do #'erc-button-setup)) | ||
| 58 | (add-hook 'erc--tab-functions #'erc-button-next) | 59 | (add-hook 'erc--tab-functions #'erc-button-next) |
| 59 | (erc--modify-local-map t "<backtab>" #'erc-button-previous)) | 60 | (erc--modify-local-map t "<backtab>" #'erc-button-previous)) |
| 60 | ((remove-hook 'erc-insert-modify-hook #'erc-button-add-buttons) | 61 | ((remove-hook 'erc-insert-modify-hook #'erc-button-add-buttons) |
| 61 | (remove-hook 'erc-send-modify-hook #'erc-button-add-buttons) | 62 | (remove-hook 'erc-send-modify-hook #'erc-button-add-buttons) |
| 63 | (remove-hook 'erc-mode-hook #'erc-button-setup) | ||
| 62 | (remove-hook 'erc--tab-functions #'erc-button-next) | 64 | (remove-hook 'erc--tab-functions #'erc-button-next) |
| 63 | (erc--modify-local-map nil "<backtab>" #'erc-button-previous))) | 65 | (erc--modify-local-map nil "<backtab>" #'erc-button-previous))) |
| 64 | 66 | ||
| @@ -103,7 +105,10 @@ longer than `erc-fill-column'." | |||
| 103 | :type '(choice integer boolean)) | 105 | :type '(choice integer boolean)) |
| 104 | 106 | ||
| 105 | (defcustom erc-button-buttonize-nicks t | 107 | (defcustom erc-button-buttonize-nicks t |
| 106 | "Flag indicating whether nicks should be buttonized or not." | 108 | "Flag indicating whether nicks should be buttonized. |
| 109 | Note that beginning in ERC 5.6, some functionality provided by | ||
| 110 | other modules, such as `fill-wrap', may depend on this option | ||
| 111 | being non-nil." | ||
| 107 | :type 'boolean) | 112 | :type 'boolean) |
| 108 | 113 | ||
| 109 | (defcustom erc-button-rfc-url "https://tools.ietf.org/html/rfc%s" | 114 | (defcustom erc-button-rfc-url "https://tools.ietf.org/html/rfc%s" |
| @@ -126,8 +131,7 @@ longer than `erc-fill-column'." | |||
| 126 | ;; a button, it makes no sense to optimize performance by | 131 | ;; a button, it makes no sense to optimize performance by |
| 127 | ;; bytecompiling lambdas in this alist. On the other hand, it makes | 132 | ;; bytecompiling lambdas in this alist. On the other hand, it makes |
| 128 | ;; things hard to maintain. | 133 | ;; things hard to maintain. |
| 129 | '((nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0) | 134 | '((erc-button-url-regexp 0 t browse-url-button-open-url 0) |
| 130 | (erc-button-url-regexp 0 t browse-url-button-open-url 0) | ||
| 131 | ;; ("<URL: *\\([^<> ]+\\) *>" 0 t browse-url-button-open-url 1) | 135 | ;; ("<URL: *\\([^<> ]+\\) *>" 0 t browse-url-button-open-url 1) |
| 132 | ;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3) | 136 | ;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3) |
| 133 | ;; emacs internal | 137 | ;; emacs internal |
| @@ -159,41 +163,45 @@ REGEXP is the string matching text around the button or a symbol | |||
| 159 | strings, or an alist with the strings in the car. Note that | 163 | strings, or an alist with the strings in the car. Note that |
| 160 | entries in lists or alists are considered to be nicks or other | 164 | entries in lists or alists are considered to be nicks or other |
| 161 | complete words. Therefore they are enclosed in \\< and \\> | 165 | complete words. Therefore they are enclosed in \\< and \\> |
| 162 | while searching. REGEXP can also be the symbol | 166 | while searching. Also, use of the special symbol `nicknames' |
| 163 | `nicknames', which matches the nickname of any user on the | 167 | for this slot was deprecated in ERC 5.6, but users can still |
| 164 | current server. | 168 | use `erc-button-buttonize-nicks' to control whether nicks get |
| 169 | buttonized. And because customizing a corresponding CALLBACK | ||
| 170 | is no longer possible, an escape hatch has been provided via | ||
| 171 | the variable `erc-button-nickname-callback-function'. | ||
| 165 | 172 | ||
| 166 | BUTTON is the number of the regexp grouping actually matching the | 173 | BUTTON is the number of the regexp grouping actually matching the |
| 167 | button. This is ignored if REGEXP is `nicknames'. | 174 | button. |
| 168 | 175 | ||
| 169 | FORM is either a boolean or a special variable whose value must | 176 | FORM is either a boolean or a special variable whose value must |
| 170 | be non-nil for the button to be added. When REGEXP is the | 177 | be non-nil for the button to be added. It can also be a |
| 171 | special symbol `nicknames', FORM must be the symbol | 178 | function to call in place of `erc-button-add-button' with the |
| 172 | `erc-button-buttonize-nicks'. Anything else is deprecated. | 179 | exact same arguments. When FORM is also a special variable, |
| 173 | For all other entries, FORM can also be a function to call in | 180 | ERC disregards the variable and calls the function. Note that |
| 174 | place of `erc-button-add-button' with the exact same arguments. | 181 | arbitrary s-expressions were deprecated in ERC 5.6 and may not |
| 175 | When FORM is also a special variable, ERC disregards the | 182 | be respected in the future. If necessary, users can instead |
| 176 | variable and calls the function. | 183 | supply a function that calls `erc-button-add-button' when such |
| 184 | an expression is non-nil. | ||
| 177 | 185 | ||
| 178 | CALLBACK is the function to call when the user push this button. | 186 | CALLBACK is the function to call when the user push this button. |
| 179 | CALLBACK can also be a symbol. Its variable value will be used | 187 | CALLBACK can also be a symbol. Its variable value will be used |
| 180 | as the callback function. | 188 | as the callback function. |
| 181 | 189 | ||
| 182 | PAR is a number of a regexp grouping whose text will be passed to | 190 | PAR is a number of a regexp grouping whose text will be passed to |
| 183 | CALLBACK. There can be several PAR arguments. If REGEXP is | 191 | CALLBACK. There can be several PAR arguments." |
| 184 | `nicknames', these are ignored, and CALLBACK will be called with | ||
| 185 | the nickname matched as the argument." | ||
| 186 | :package-version '(ERC . "5.6") ; FIXME sync on release | 192 | :package-version '(ERC . "5.6") ; FIXME sync on release |
| 187 | :type '(repeat | 193 | :type '(repeat |
| 188 | (list :tag "Button" | 194 | (list :tag "Button" |
| 189 | (choice :tag "Matches" | 195 | (choice :tag "Matches" |
| 190 | regexp | 196 | regexp |
| 191 | (variable :tag "Variable containing regexp") | 197 | (variable :tag "Variable containing regexp") |
| 192 | (const :tag "Nicknames" nicknames)) | 198 | (repeat :tag "List of words" string) |
| 199 | (alist :key-type string :value-type sexp)) | ||
| 193 | (integer :tag "Number of the regexp section that matches") | 200 | (integer :tag "Number of the regexp section that matches") |
| 194 | (choice :tag "When to buttonize" | 201 | (choice :tag "When to buttonize" |
| 195 | (const :tag "Always" t) | 202 | (const :tag "Always" t) |
| 196 | (sexp :tag "Only when this evaluates to non-nil")) | 203 | (function :tag "Alternative buttonizing function") |
| 204 | (variable :tag "Var with value treated as boolean")) | ||
| 197 | (function :tag "Function to call when button is pressed") | 205 | (function :tag "Function to call when button is pressed") |
| 198 | (repeat :tag "Sections of regexp to send to the function" | 206 | (repeat :tag "Sections of regexp to send to the function" |
| 199 | :inline t | 207 | :inline t |
| @@ -239,15 +247,40 @@ constituents.") | |||
| 239 | (defvar erc-button-keys-added nil | 247 | (defvar erc-button-keys-added nil |
| 240 | "Internal variable used to keep track of whether we've added the | 248 | "Internal variable used to keep track of whether we've added the |
| 241 | global-level ERC button keys yet.") | 249 | global-level ERC button keys yet.") |
| 250 | (make-obsolete-variable 'erc-button-keys-added "no longer relevant" "30.1") | ||
| 251 | |||
| 252 | (defvar-local erc-button--has-nickname-entry nil | ||
| 253 | "Whether `erc-button-alist' contains a legacy `nicknames' entry.") | ||
| 242 | 254 | ||
| 243 | ;; Maybe deprecate this function and `erc-button-keys-added' if they | ||
| 244 | ;; continue to go unused for a another version (currently 5.6). | ||
| 245 | (defun erc-button-setup () | 255 | (defun erc-button-setup () |
| 246 | "Add ERC mode-level button movement keys. This is only done once." | 256 | "Perform major-mode setup for ERC's button module. |
| 247 | ;; Add keys. | 257 | Note that prior to ERC 5.6, this function used to modify |
| 248 | (unless erc-button-keys-added | 258 | `erc-mode-map', but that's now handled by the mode toggles |
| 249 | (define-key erc-mode-map (kbd "<backtab>") #'erc-button-previous) | 259 | themselves." |
| 250 | (setq erc-button-keys-added t))) | 260 | (setq erc-button-keys-added t) |
| 261 | (cl-assert (derived-mode-p 'erc-mode)) | ||
| 262 | ;; It would probably suffice to run this in server buffers alone, | ||
| 263 | ;; even though buttonizing happens in all ERC buffers and users have | ||
| 264 | ;; been known to set `erc-button-alist' locally. | ||
| 265 | (dolist (entry erc-button-alist) | ||
| 266 | (pcase entry | ||
| 267 | ((or `(nicknames ,_ ,sym . ,_) `('nicknames ,_ ,sym . ,_)) | ||
| 268 | (setq erc-button--has-nickname-entry t) | ||
| 269 | (unless (eq sym 'erc-button-buttonize-nicks) | ||
| 270 | (erc--warn-once-before-connect 'erc-button-mode | ||
| 271 | "The legacy `nicknames' entry in `erc-button-alist'" | ||
| 272 | " is deprecated. See doc string for details."))) | ||
| 273 | ((and `(,_ ,_ ,form . ,_) | ||
| 274 | (guard (not (or (and (symbolp form) | ||
| 275 | (special-variable-p form)) | ||
| 276 | (functionp form))))) | ||
| 277 | (erc--warn-once-before-connect 'erc-button-mode | ||
| 278 | "Arbitrary sexps for the third, FORM slot of `erc-button-alist'" | ||
| 279 | " entries are deprecated. Either use a variable or a function" | ||
| 280 | " that conditionally calls `erc-button-add-button'."))))) | ||
| 281 | |||
| 282 | (defvar erc-button-nickname-callback-function #'erc-nick-popup | ||
| 283 | "Escape hatch for those needing a different nickname callback.") | ||
| 251 | 284 | ||
| 252 | (defun erc-button-add-buttons () | 285 | (defun erc-button-add-buttons () |
| 253 | "Find external references in the current buffer and make buttons of them. | 286 | "Find external references in the current buffer and make buttons of them. |
| @@ -261,6 +294,11 @@ specified by `erc-button-alist'." | |||
| 261 | (alist erc-button-alist) | 294 | (alist erc-button-alist) |
| 262 | regexp) | 295 | regexp) |
| 263 | (erc-button-remove-old-buttons) | 296 | (erc-button-remove-old-buttons) |
| 297 | (unless (or erc-button--has-nickname-entry | ||
| 298 | (not erc-button-buttonize-nicks)) | ||
| 299 | (erc-button-add-nickname-buttons | ||
| 300 | `(_ _ erc-button--modify-nick-function | ||
| 301 | ,erc-button-nickname-callback-function))) | ||
| 264 | (dolist (entry alist) | 302 | (dolist (entry alist) |
| 265 | (if (or (eq (car entry) 'nicknames) | 303 | (if (or (eq (car entry) 'nicknames) |
| 266 | ;; Old form retained for backward compatibility. | 304 | ;; Old form retained for backward compatibility. |
| @@ -284,28 +322,18 @@ specified by `erc-button-alist'." | |||
| 284 | (concat "\\<" (regexp-quote (car elem)) "\\>") | 322 | (concat "\\<" (regexp-quote (car elem)) "\\>") |
| 285 | entry))))))))))) | 323 | entry))))))))))) |
| 286 | 324 | ||
| 287 | (defun erc-button--maybe-warn-arbitrary-sexp (form) | 325 | (defun erc-button--extract-form (form) |
| 288 | (cl-assert (not (booleanp form))) ; covered by caller | ||
| 289 | ;; If a special-variable is also a function, favor the function. | 326 | ;; If a special-variable is also a function, favor the function. |
| 290 | (cond ((functionp form) form) | 327 | (cond ((eq t form) t) |
| 291 | ((and (symbolp form) (special-variable-p form)) (symbol-value form)) | 328 | ((functionp form) form) |
| 292 | (t (unless (get 'erc-button--maybe-warn-arbitrary-sexp | 329 | ((and (symbolp form) (special-variable-p form)) |
| 293 | 'warned-arbitrary-sexp) | 330 | (while (let ((val (symbol-value form))) |
| 294 | (put 'erc-button--maybe-warn-arbitrary-sexp | 331 | (prog1 (and (not (eq val form)) |
| 295 | 'warned-arbitrary-sexp t) | 332 | (symbolp val) |
| 296 | (lwarn 'erc :warning (concat "Arbitrary sexps for the third FORM" | 333 | (special-variable-p val)) |
| 297 | " slot of `erc-button-alist' entries" | 334 | (setq form val)))) |
| 298 | " have been deprecated."))) | 335 | form) |
| 299 | (eval form t)))) | 336 | (t (eval form t)))) |
| 300 | |||
| 301 | (defun erc-button--check-nicknames-entry () | ||
| 302 | ;; This helper exists because the module is defined after its options. | ||
| 303 | (when (eq major-mode 'erc-mode) | ||
| 304 | (unless (eq (nth 1 (alist-get 'nicknames erc-button-alist)) | ||
| 305 | 'erc-button-buttonize-nicks) | ||
| 306 | (erc-button--display-error-notice-with-keys-and-warn | ||
| 307 | "Values other than `erc-button-buttonize-nicks' in the third slot of " | ||
| 308 | "the `nicknames' entry of `erc-button-alist' are deprecated.")))) | ||
| 309 | 337 | ||
| 310 | (cl-defstruct erc-button--nick | 338 | (cl-defstruct erc-button--nick |
| 311 | ( bounds nil :type cons | 339 | ( bounds nil :type cons |
| @@ -405,12 +433,10 @@ retrieve it during buttonizing via | |||
| 405 | "Search through the buffer for nicknames, and add buttons." | 433 | "Search through the buffer for nicknames, and add buttons." |
| 406 | (let ((form (nth 2 entry)) | 434 | (let ((form (nth 2 entry)) |
| 407 | (fun (nth 3 entry)) | 435 | (fun (nth 3 entry)) |
| 436 | (erc-button-buttonize-nicks (and erc-button-buttonize-nicks | ||
| 437 | erc-button--modify-nick-function)) | ||
| 408 | bounds word) | 438 | bounds word) |
| 409 | (when (eq form 'erc-button-buttonize-nicks) | 439 | (when (and form (setq form (erc-button--extract-form form))) |
| 410 | (setq form (and (symbol-value form) erc-button--modify-nick-function))) | ||
| 411 | (when (or (functionp form) | ||
| 412 | (eq t form) | ||
| 413 | (and form (erc-button--maybe-warn-arbitrary-sexp form))) | ||
| 414 | (goto-char (point-min)) | 440 | (goto-char (point-min)) |
| 415 | (while (erc-forward-word) | 441 | (while (erc-forward-word) |
| 416 | (when (setq bounds (erc-bounds-of-word-at-point)) | 442 | (when (setq bounds (erc-bounds-of-word-at-point)) |
| @@ -456,8 +482,7 @@ retrieve it during buttonizing via | |||
| 456 | (and-let* | 482 | (and-let* |
| 457 | ((raw-form (nth 2 entry)) | 483 | ((raw-form (nth 2 entry)) |
| 458 | (res (or (eq t raw-form) | 484 | (res (or (eq t raw-form) |
| 459 | (erc-button--maybe-warn-arbitrary-sexp | 485 | (erc-button--extract-form raw-form)))) |
| 460 | raw-form)))) | ||
| 461 | (if (functionp res) res #'erc-button-add-button))))) | 486 | (if (functionp res) res #'erc-button-add-button))))) |
| 462 | (let ((start (match-beginning (nth 1 entry))) | 487 | (let ((start (match-beginning (nth 1 entry))) |
| 463 | (end (match-end (nth 1 entry))) | 488 | (end (match-end (nth 1 entry))) |