From: "J.P." <jp@neverwas.me>
To: 60933@debbugs.gnu.org
Cc: emacs-erc@gnu.org
Subject: bug#60933: 30.0.50; ERC >5.5: Make buttonizing more extensible
Date: Thu, 09 Mar 2023 06:42:07 -0800 [thread overview]
Message-ID: <87fsaekmv4.fsf__39101.0304259666$1678373014$gmane$org@neverwas.me> (raw)
In-Reply-To: <878rhzc3gk.fsf@neverwas.me> (J. P.'s message of "Wed, 18 Jan 2023 06:38:51 -0800")
[-- Attachment #1: Type: text/plain, Size: 137 bytes --]
v3. Expand `erc-button-alist' pattern to recognize inline (info "...")
forms. Autoload button helpers (locally, in ERC's own loaddefs).
[-- Attachment #2: 0000-v2-v3.diff --]
[-- Type: text/x-patch, Size: 3269 bytes --]
From 28517cf23b5ed65f8a421dddcffec6a0aecd7fe5 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 9 Mar 2023 06:28:53 -0800
Subject: [PATCH 0/3] *** NOT A PATCH ***
*** BLURB HERE ***
F. Jason Park (3):
[5.6] Replace Info-goto-node with info in erc-button-alist
[5.6] Add erc-button helper for substituting command keys
[5.6] Allow erc-button-add-face to take an object
lisp/erc/erc-button.el | 172 +++++++++++++++++++++++++++++++++----
lisp/erc/erc-networks.el | 22 ++---
test/lisp/erc/erc-tests.el | 56 ++++++++++++
3 files changed, 220 insertions(+), 30 deletions(-)
Interdiff:
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 49e3caf49a1..c94a412eea8 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -134,7 +134,7 @@ erc-button-alist
("[`‘]\\([a-zA-Z][-a-zA-Z_0-9!*<=>+]+\\)['’]"
1 t erc-button-describe-symbol 1)
;; pseudo links
- ("\\bInfo:[\"]\\([^\"]+\\)[\"]" 0 t info 1)
+ ("\\(?:\\bInfo: ?\\|(info \\)[\"]\\(([^\"]+\\)[\"])?" 0 t info 1)
("\\b\\(Ward\\|Wiki\\|WardsWiki\\|TheWiki\\):\\([A-Z][a-z]+\\([A-Z][a-z]+\\)+\\)"
0 t (lambda (page)
(browse-url (concat "http://c2.com/cgi-bin/wiki?" page)))
@@ -600,25 +600,39 @@ erc-button--substitute-command-keys-in-region
(insert s))
(cons beg (point)))
-(defun erc-button--display-error-notice-with-keys (parsed &rest strings)
- "Add help keys to STRINGS for corner-case admonishments.
-Return inserted result."
+;;;###autoload
+(defun erc-button--display-error-notice-with-keys (&optional parsed buffer
+ &rest strings)
+ "Add help keys to STRINGS for configuration-related admonishments.
+Return inserted result. PARSED can be an `erc-response' object,
+a string, or nil. BUFFER can be a buffer, a string, or nil. As
+a special case, PARSED can also be a buffer as long as BUFFER is
+a string or nil."
+ (when (stringp buffer)
+ (push buffer strings)
+ (setq buffer nil))
(when (stringp parsed)
(push parsed strings)
(setq parsed nil))
+ (when (bufferp parsed)
+ (cl-assert (null buffer))
+ (setq buffer parsed
+ parsed nil))
(let* ((string (apply #'concat strings))
(erc-insert-post-hook
(cons (lambda ()
- (setq string (buffer-substring (point-min) (1- (point-max)))))
+ (setq string (buffer-substring (point-min)
+ (1- (point-max)))))
erc-insert-post-hook))
(erc-button-alist
`((,(rx "\\[" (group (+ (not "]"))) "]") 0
erc-button--substitute-command-keys-in-region
erc-button-describe-symbol 1)
,@erc-button-alist)))
- (erc-display-error-notice parsed string)
+ (erc-display-message parsed '(notice error) (or buffer 'active) string)
string))
+;;;###autoload
(defun erc-button--display-error-notice-with-keys-and-warn (&rest args)
"Like `erc-button--display-error-notice-with-keys' but also warn."
(let ((string (apply #'erc-button--display-error-notice-with-keys args)))
--
2.39.2
[-- Attachment #3: 0001-5.6-Replace-Info-goto-node-with-info-in-erc-button-a.patch --]
[-- Type: text/x-patch, Size: 2345 bytes --]
From f61bd6bb6129571327cdb9e68b38e8221b72d91e Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Sun, 18 Dec 2022 19:01:40 -0800
Subject: [PATCH 1/3] [5.6] Replace Info-goto-node with info in
erc-button-alist
* lisp/erc/erc-button.el (erc-button-alist): Replace `Info-goto-node'
with plain `info', which is autoloaded. Expand regexp to recognize
inline `info' function calls.
* lisp/erc/erc-networks.el (erc-networks--set-name,
erc-networks--warn-on-connect): Don't require `info'. (Bug#60933.)
---
lisp/erc/erc-button.el | 2 +-
lisp/erc/erc-networks.el | 2 --
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index c28dddefa0e..891b453466f 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -133,7 +133,7 @@ erc-button-alist
("[`‘]\\([a-zA-Z][-a-zA-Z_0-9!*<=>+]+\\)['’]"
1 t erc-button-describe-symbol 1)
;; pseudo links
- ("\\bInfo:[\"]\\([^\"]+\\)[\"]" 0 t Info-goto-node 1)
+ ("\\(?:\\bInfo: ?\\|(info \\)[\"]\\(([^\"]+\\)[\"])?" 0 t info 1)
("\\b\\(Ward\\|Wiki\\|WardsWiki\\|TheWiki\\):\\([A-Z][a-z]+\\([A-Z][a-z]+\\)+\\)"
0 t (lambda (page)
(browse-url (concat "http://c2.com/cgi-bin/wiki?" page)))
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index 95fd8990c99..4337d633cfa 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -1292,7 +1292,6 @@ erc-networks--set-name
erc-server-announced-name "\" in `erc-networks-alist'"
" or consider calling `erc-tls' with the keyword `:id'."
" See Info:\"(erc) Network Identifier\" for more.")))
- (require 'info)
(erc-display-error-notice parsed m)
(if erc-networks--allow-unknown-network
(progn
@@ -1514,7 +1513,6 @@ erc-networks--warn-on-connect
"Emit warning when the `networks' module hasn't been loaded.
Ideally, do so upon opening the network process."
(unless (or erc--target erc-networks-mode)
- (require 'info nil t)
(let ((m (concat "Required module `networks' not loaded. If this "
" was unexpected, please add it to `erc-modules'.")))
;; Assume the server buffer has been marked as active.
--
2.39.2
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0002-5.6-Add-erc-button-helper-for-substituting-command-k.patch --]
[-- Type: text/x-patch, Size: 16850 bytes --]
From 5fb14bbc6535acfabcec5afe89613528e1b405b5 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Sun, 18 Dec 2022 19:01:40 -0800
Subject: [PATCH 2/3] [5.6] Add erc-button helper for substituting command keys
TODO: add ERC-NEWS entry for `erc-button-alist' field-type deprecation
once ERC 5.5 is released and a new section for 5.6 is added.
* lisp/erc/erc-button.el (erc-button-mode, erc-button-enable): Warn if
`erc-button-alist' contains deprecated FORM field in `nicknames'
entry.
(erc-button-alist): Deprecate arbitrary sexp form for third item of
entries and offer more useful bounds-modifying function in its place.
Mention that anything other than `erc-button-buttonize-nicks' is
deprecated as the FORM field in a `nicknames' entry.
(erc-button--maybe-warn-arbitrary-sexp): Add helper for validating
third `erc-button-alist' field.
(erc-button--check-nicknames-entry): Add helper to check for
deprecated items in `erc-button-alist'.
(erc-button--modify-nick-function): Add new variable to hold a
function that filters nickname bounds when buttonizing.
(erc-button--preserve-bounds): Add function to serve as default value
for `erc-button--modify-nick-function).
(erc-button-add-nickname-buttons): Accommodate function variant for
"form" field of `erc-button-alist' entries. Minor optimizations.
(erc-button-add-buttons-1): Show warning when arbitrary sexp for third
"form" field encountered. Accommodate binary function instead.
(erc-button--substitute-command-keys-in-region): Add new function to
serve as default key-substitution function item in `erc-button-alist'.
(erc-button--display-error-notice-with-keys): Add new helper function
for displaying ad hoc warnings that possibly require key substitution.
* lisp/erc/erc-networks.el (erc-networks--ensure-announced,
erc-networks--on-MOTD-end): Use new key-substitutions helper from
erc-button.
(erc-button--display-error-notice-with-keys-and-warn): Add new
function to both display an ERC error message and show a warning.
* test/lisp/erc/erc-tests.el
(erc-button--display-error-notice-with-keys): New test. (Bug#60933.)
---
lisp/erc/erc-button.el | 151 ++++++++++++++++++++++++++++++++++---
lisp/erc/erc-networks.el | 20 ++---
test/lisp/erc/erc-tests.el | 56 ++++++++++++++
3 files changed, 207 insertions(+), 20 deletions(-)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 891b453466f..eca3df44892 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -52,7 +52,8 @@ erc-button
;;;###autoload(autoload 'erc-button-mode "erc-button" nil t)
(define-erc-module button nil
"This mode buttonizes all messages according to `erc-button-alist'."
- ((add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append)
+ ((erc-button--check-nicknames-entry)
+ (add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append)
(add-hook 'erc-send-modify-hook #'erc-button-add-buttons 'append)
(add-hook 'erc-complete-functions #'erc-button-next-function)
(add-hook 'erc-mode-hook #'erc-button-setup))
@@ -165,8 +166,17 @@ erc-button-alist
BUTTON is the number of the regexp grouping actually matching the
button. This is ignored if REGEXP is `nicknames'.
-FORM is a Lisp expression which must eval to true for the button to
- be added.
+FORM is a Lisp symbol for a special variable whose value must be
+ true for the button to be added. Alternatively, when REGEXP is
+ not `nicknames', FORM can be a function whose arguments are BEG
+ and END, the bounds of the button in the current buffer. It's
+ expected to return a cons of (possibly identical) bounds or
+ nil, to deny. For the extent of the call, all face options
+ defined for the button module are re-bound, shadowing
+ themselves, so the function is free to change their values.
+ When regexp is the special symbol `nicknames', FORM must be the
+ symbol `erc-button-buttonize-nicks'. Specifying anything else
+ is deprecated.
CALLBACK is the function to call when the user push this button.
CALLBACK can also be a symbol. Its variable value will be used
@@ -176,7 +186,7 @@ erc-button-alist
CALLBACK. There can be several PAR arguments. If REGEXP is
`nicknames', these are ignored, and CALLBACK will be called with
the nickname matched as the argument."
- :package-version '(ERC . "5.5")
+ :package-version '(ERC . "5.6") ; FIXME sync on release
:type '(repeat
(list :tag "Button"
(choice :tag "Matches"
@@ -275,22 +285,79 @@ erc-button-add-buttons
(concat "\\<" (regexp-quote (car elem)) "\\>")
entry)))))))))))
+(defun erc-button--maybe-warn-arbitrary-sexp (form)
+ (if (and (symbolp form) (special-variable-p form))
+ (symbol-value form)
+ (unless (get 'erc-button--maybe-warn-arbitrary-sexp 'warned-arbitrary-sexp)
+ (put 'erc-button--maybe-warn-arbitrary-sexp 'warned-arbitrary-sexp t)
+ (lwarn 'erc :warning
+ (concat "Arbitrary sexps for the third FORM"
+ " slot of `erc-button-alist' entries"
+ " have been deprecated.")))
+ (eval form t)))
+
+(defun erc-button--check-nicknames-entry ()
+ ;; This helper exists because the module is defined after its options.
+ (when-let (((eq major-mode 'erc-mode))
+ (entry (alist-get 'nicknames erc-button-alist)))
+ (unless (eq 'erc-button-buttonize-nicks (nth 1 entry))
+ (erc-button--display-error-notice-with-keys-and-warn
+ "Values other than `erc-button-buttonize-nicks' in the third slot of "
+ "the `nicknames' entry of `erc-button-alist' are deprecated."))))
+
+(defun erc-button--preserve-bounds (bounds _ _ _)
+ "Return BOUNDS.\n\n(fn BOUNDS NICKNAME SERVER-USER CHANNEL-USER)"
+ bounds)
+
+;; This variable is intended to serve as a "core" to be wrapped by
+;; (built-in) modules during setup. It's unclear whether
+;; `add-function's practice of removing existing advice before
+;; re-adding it is desirable when integrating modules since we're
+;; mostly concerned with ensuring one "piece" precedes or follows
+;; another (specific piece), which may not yet (or ever) be present.
+
+(defvar erc-button--modify-nick-function #'erc-button--preserve-bounds
+ "Function to possibly modify aspects of nick being buttonized.
+Called with four args: BOUNDS NICKNAME SERVER-USER CHANNEL-USER.
+BOUNDS is a cons of (BEG . END) marking the position of the nick
+in the current message, which occupies the whole of the narrowed
+buffer. NICKNAME is a case-mapped string without text
+properties. SERVER-USER and CHANNEL-USER are the nick's
+`erc-server-users' entry and its associated (though possibly nil)
+`erc-channel-user' object. The function should return BOUNDS or
+a suitable replacement to indicate that buttonizing ought to
+proceed, and nil if it should be inhibited.")
+
(defun erc-button-add-nickname-buttons (entry)
"Search through the buffer for nicknames, and add buttons."
(let ((form (nth 2 entry))
(fun (nth 3 entry))
bounds word)
- (when (or (eq t form)
- (eval form t))
+ (when (eq form 'erc-button-buttonize-nicks)
+ (setq form (and (symbol-value form) erc-button--modify-nick-function)))
+ (when (or (functionp form)
+ (eq t form)
+ (and form (erc-button--maybe-warn-arbitrary-sexp form)))
(goto-char (point-min))
(while (erc-forward-word)
(when (setq bounds (erc-bounds-of-word-at-point))
(setq word (buffer-substring-no-properties
(car bounds) (cdr bounds)))
- (when (or (and (erc-server-buffer-p) (erc-get-server-user word))
- (and erc-channel-users (erc-get-channel-user word)))
- (erc-button-add-button (car bounds) (cdr bounds)
- fun t (list word))))))))
+ (let* ((erc-button-face erc-button-face)
+ (erc-button-mouse-face erc-button-mouse-face)
+ (erc-button-nickname-face erc-button-nickname-face)
+ (down (erc-downcase word))
+ (cuser (and erc-channel-users
+ (gethash down erc-channel-users)))
+ (user (or (and cuser (car cuser))
+ (and erc-server-users
+ (gethash down erc-server-users)))))
+ (when (and user
+ (or (not (functionp form))
+ (setq bounds
+ (funcall form bounds down user (cdr cuser)))))
+ (erc-button-add-button (car bounds) (cdr bounds)
+ fun t (list word)))))))))
(defun erc-button-add-buttons-1 (regexp entry)
"Search through the buffer for matches to ENTRY and add buttons."
@@ -302,7 +369,14 @@ erc-button-add-buttons-1
(fun (nth 3 entry))
(data (mapcar #'match-string-no-properties (nthcdr 4 entry))))
(when (or (eq t form)
- (eval form t))
+ (and (functionp form)
+ (let* ((erc-button-face erc-button-face)
+ (erc-button-mouse-face erc-button-mouse-face)
+ (erc-button-nickname-face erc-button-nickname-face)
+ (rv (funcall form start end)))
+ (when rv
+ (setq end (cdr rv) start (car rv)))))
+ (erc-button--maybe-warn-arbitrary-sexp form))
(erc-button-add-button start end fun nil data regexp)))))
(defun erc-button-remove-old-buttons ()
@@ -511,6 +585,61 @@ erc-button-beats-to-time
(message "@%s is %d:%02d local time"
beats hours minutes)))
+(defun erc-button--substitute-command-keys-in-region (beg end)
+ "Replace command in region with keys and return new bounds"
+ (let* ((o (buffer-substring beg end))
+ (s (substitute-command-keys o)))
+ (unless (equal o s)
+ (setq erc-button-face nil))
+ (delete-region beg end)
+ (insert s))
+ (cons beg (point)))
+
+;;;###autoload
+(defun erc-button--display-error-notice-with-keys (&optional parsed buffer
+ &rest strings)
+ "Add help keys to STRINGS for configuration-related admonishments.
+Return inserted result. PARSED can be an `erc-response' object,
+a string, or nil. BUFFER can be a buffer, a string, or nil. As
+a special case, PARSED can also be a buffer as long as BUFFER is
+a string or nil."
+ (when (stringp buffer)
+ (push buffer strings)
+ (setq buffer nil))
+ (when (stringp parsed)
+ (push parsed strings)
+ (setq parsed nil))
+ (when (bufferp parsed)
+ (cl-assert (null buffer))
+ (setq buffer parsed
+ parsed nil))
+ (let* ((string (apply #'concat strings))
+ (erc-insert-post-hook
+ (cons (lambda ()
+ (setq string (buffer-substring (point-min)
+ (1- (point-max)))))
+ erc-insert-post-hook))
+ (erc-button-alist
+ `((,(rx "\\[" (group (+ (not "]"))) "]") 0
+ erc-button--substitute-command-keys-in-region
+ erc-button-describe-symbol 1)
+ ,@erc-button-alist)))
+ (erc-display-message parsed '(notice error) (or buffer 'active) string)
+ string))
+
+;;;###autoload
+(defun erc-button--display-error-notice-with-keys-and-warn (&rest args)
+ "Like `erc-button--display-error-notice-with-keys' but also warn."
+ (let ((string (apply #'erc-button--display-error-notice-with-keys args)))
+ (with-temp-buffer
+ (insert string)
+ (goto-char (point-min))
+ (with-syntax-table lisp-mode-syntax-table
+ (skip-syntax-forward "^-"))
+ (forward-char)
+ (display-warning
+ 'erc (buffer-substring-no-properties (point) (point-max))))))
+
(provide 'erc-button)
;;; erc-button.el ends here
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index 4337d633cfa..dd481032e7e 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -67,6 +67,9 @@ erc-session-server
(declare-function erc-server-process-alive "erc-backend" (&optional buffer))
(declare-function erc-set-active-buffer "erc" (buffer))
+(declare-function erc-button--display-error-notice-with-keys
+ (parsed &rest strings))
+
;; Variables
(defgroup erc-networks nil
@@ -1310,12 +1313,11 @@ erc-networks--ensure-announced
Copy source (prefix) from MOTD-ish message as a last resort."
;; The 004 handler never ran; see 2004-03-10 Diane Murray in change log
(unless erc-server-announced-name
- (setq erc-server-announced-name (erc-response.sender parsed))
- (erc-display-error-notice
- parsed (concat "Failed to determine server name. Using \""
- erc-server-announced-name "\" instead."
- " If this was unexpected, consider reporting it via "
- (substitute-command-keys "\\[erc-bug]") ".")))
+ (require 'erc-button)
+ (erc-button--display-error-notice-with-keys
+ parsed "Failed to determine server name. Using \""
+ (setq erc-server-announced-name (erc-response.sender parsed)) "\" instead"
+ ". If this was unexpected, consider reporting it via \\[erc-bug]" "."))
nil)
(defun erc-unset-network-name (_nick _ip _reason)
@@ -1493,9 +1495,9 @@ erc-networks-on-MOTD-end
(memq (erc--target-symbol erc--target)
erc-networks--bouncer-targets)))
proc)
- (let ((m (concat "Unexpected state detected. Please report via "
- (substitute-command-keys "\\[erc-bug]") ".")))
- (erc-display-error-notice parsed m))))
+ (require 'erc-button)
+ (erc-button--display-error-notice-with-keys
+ parsed "Unexpected state detected. Please report via \\[erc-bug].")))
;; For now, retain compatibility with erc-server-NNN-functions.
(or (erc-networks--ensure-announced proc parsed)
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index d6c63934163..05f0de6b195 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1370,4 +1370,60 @@ define-erc-module--local
(put 'erc-mname-enable 'definition-name 'mname)
(put 'erc-mname-disable 'definition-name 'mname))))))
+
+;; XXX move erc-button tests to new file if more added.
+(require 'erc-button)
+
+;; See also `erc-scenarios-networks-announced-missing' in
+;; erc-scenarios-misc.el for a more realistic example.
+(ert-deftest erc-button--display-error-notice-with-keys ()
+ (with-current-buffer (get-buffer-create "*fake*")
+ (let ((mode erc-button-mode)
+ (inhibit-message noninteractive)
+ erc-modules
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+ (erc-mode)
+ (erc-tests--set-fake-server-process "sleep" "1")
+ (erc--initialize-markers (point) nil)
+ (erc-button-mode +1)
+ (should (equal (erc-button--display-error-notice-with-keys
+ "If \\[erc-bol] fails, "
+ "see \\[erc-bug] or `erc-mode-map'.")
+ "*** If C-a fails, see M-x erc-bug or `erc-mode-map'."))
+ (goto-char (point-min))
+
+ (ert-info ("Keymap substitution succeeds")
+ (erc-button-next)
+ (should (looking-at "C-a"))
+ (should (eq (get-text-property (point) 'mouse-face) 'highlight))
+ (erc-button-press-button)
+ (with-current-buffer "*Help*"
+ (goto-char (point-min))
+ (should (search-forward "erc-bol" nil t)))
+ (erc-button-next)
+ (erc-button-previous) ; end of interval correct
+ (should (looking-at "a fails")))
+
+ (ert-info ("Extended command mapping succeeds")
+ (erc-button-next)
+ (should (looking-at "M-x erc-bug"))
+ (erc-button-press-button)
+ (should (eq (get-text-property (point) 'mouse-face) 'highlight))
+ (with-current-buffer "*Help*"
+ (goto-char (point-min))
+ (should (search-forward "erc-bug" nil t))))
+
+ (ert-info ("Symbol-description face preserved") ; mutated by d-e-n-w-k
+ (erc-button-next)
+ (should (equal (get-text-property (point) 'font-lock-face)
+ '(erc-button erc-error-face)))
+ (should (eq (get-text-property (point) 'mouse-face) 'highlight))
+ (should (eq erc-button-face 'erc-button))) ; extent evaporates
+
+ (when noninteractive
+ (unless mode
+ (erc-button-mode -1))
+ (kill-buffer "*Help*")
+ (kill-buffer)))))
+
;;; erc-tests.el ends here
--
2.39.2
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0003-5.6-Allow-erc-button-add-face-to-take-an-object.patch --]
[-- Type: text/x-patch, Size: 3448 bytes --]
From 28517cf23b5ed65f8a421dddcffec6a0aecd7fe5 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 13 Jan 2023 05:13:06 -0800
Subject: [PATCH 3/3] [5.6] Allow erc-button-add-face to take an object
* lisp/erc/erc-button.el
(erc-button--add-nickname-face-function): New internal var.
(erc-button-add-button): Call `erc-button--add-nickname-face-function'
when it's a function for applying `erc-button-nickname-face'.
(erc-button-add-face): Add optional `object' param. (Bug#60933.)
---
lisp/erc/erc-button.el | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index eca3df44892..c94a412eea8 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -391,6 +391,8 @@ erc-button-remove-old-buttons
mouse-face nil
keymap nil)))
+(defvar erc-button--add-nickname-face-function nil)
+
(defun erc-button-add-button (from to fun nick-p &optional data regexp)
"Create a button between FROM and TO with callback FUN and data DATA.
NICK-P specifies if this is a nickname button.
@@ -417,7 +419,10 @@ erc-button-add-button
(move-marker pos (point))))))
(if nick-p
(when erc-button-nickname-face
- (erc-button-add-face from to erc-button-nickname-face))
+ (if erc-button--add-nickname-face-function
+ (funcall erc-button--add-nickname-face-function
+ from to erc-button-nickname-face)
+ (erc-button-add-face from to erc-button-nickname-face)))
(when erc-button-face
(erc-button-add-face from to erc-button-face)))
(add-text-properties
@@ -429,16 +434,16 @@ erc-button-add-button
(list 'rear-nonsticky t)
(and data (list 'erc-data data)))))
-(defun erc-button-add-face (from to face)
+(defun erc-button-add-face (from to face &optional object)
"Add FACE to the region between FROM and TO."
;; If we just use `add-text-property', then this will overwrite any
;; face text property already used for the button. It will not be
;; merged correctly. If we use overlays, then redisplay will be
;; very slow with lots of buttons. This is why we manually merge
;; face text properties.
- (let ((old (erc-list (get-text-property from 'font-lock-face)))
+ (let ((old (erc-list (get-text-property from 'font-lock-face object)))
(pos from)
- (end (next-single-property-change from 'font-lock-face nil to))
+ (end (next-single-property-change from 'font-lock-face object to))
new)
;; old is the face at pos, in list form. It is nil if there is no
;; face at pos. If nil, the new face is FACE. If not nil, the
@@ -446,10 +451,10 @@ erc-button-add-face
;; where this face changes.
(while (< pos to)
(setq new (if old (cons face old) face))
- (put-text-property pos end 'font-lock-face new)
+ (put-text-property pos end 'font-lock-face new object)
(setq pos end
- old (erc-list (get-text-property pos 'font-lock-face))
- end (next-single-property-change pos 'font-lock-face nil to)))))
+ old (erc-list (get-text-property pos 'font-lock-face object))
+ end (next-single-property-change pos 'font-lock-face object to)))))
;; widget-button-click calls with two args, we ignore the first.
;; Since Emacs runs this directly, rather than with
--
2.39.2
next prev parent reply other threads:[~2023-03-09 14:42 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-18 14:38 bug#60933: 30.0.50; ERC >5.5: Make buttonizing more extensible J.P.
2023-02-19 15:04 ` J.P.
2023-03-09 14:42 ` J.P. [this message]
[not found] ` <87fsaekmv4.fsf@neverwas.me>
2023-04-18 14:11 ` J.P.
[not found] ` <877cu9qnyo.fsf@neverwas.me>
2023-04-29 15:56 ` J.P.
2023-05-23 13:35 ` J.P.
2023-06-02 14:07 ` J.P.
2023-09-13 14:09 ` J.P.
[not found] ` <87wmwuyxjh.fsf@neverwas.me>
2023-09-19 13:28 ` J.P.
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='87fsaekmv4.fsf__39101.0304259666$1678373014$gmane$org@neverwas.me' \
--to=jp@neverwas.me \
--cc=60933@debbugs.gnu.org \
--cc=emacs-erc@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).