Simplify erc-button movement commands
* etc/ERC-NEWS: Mention TAB being bound to new command `erc-tab' and `erc-previous-button' now stopping at the start of buttons. * lisp/erc/erc-button.el (erc-button-mode, erc-button-enable, erc-button-disable): Add and remove `erc-button-next' to `erc--tab-functions' hook, which is tantamount to binding the command in the read-only area of an ERC buffer. (erc-button-next-function): Deprecate and remove from client code path because this module doesn't concern itself with prompt input and thus no longer needs to conform to the `completion-at-point-functions' interface. (erc-button--prev-next-predicate-functions): New variable, a hook to determine whether to continue searching for a button. Other modules should utilize this as needed. (erc-button--end-of-button-p): Add function to serve as default value for `erc-button--continue-predicate'. (erc--button-next): Add generalized button-movement function. (erc-button-next, erc-button-previous): Make `erc-button-previous' behave more predictably by having it land at the beginning of buttons. And remove roundabout appeal to HOF in `erc-button-next'. (erc-button-previous-of-nick): New command to jump to previous appearance of nick at point. * lisp/erc/erc-fill.el (erc-fill-wrap, erc-fill-wrap-enable, erc-fill-wrap-disable): Add and remove merge-related hookee from `erc-button--prev-next-predicate-functions'. (erc-fill--wrap-merged-button-p): New function to detect redundant speakers. * lisp/erc/erc.el (erc-complete-functions): Quote TAB in doc string. (erc-mode-map): Bind `erc-tab' to TAB. (erc--tab-functions, erc-tab): Add new command and hook to serve as unified dispatch for TAB-related operations. It calls `c-a-p' in the input area and defers to module code in the read-only message area. * test/lisp/erc/erc-button-tests.el: New file. * test/lisp/erc/erc-fill-tests.el (erc-fill-tests--wrap-populate): Run finalizer for transient keymap timer. * test/lisp/erc/erc-tests.el (erc-button--display-error-notice-with-keys): Move to new dedicated test file for erc-button and fix expected behavior of `erc-button-previous'. (Bug#62834)
This commit is contained in:
parent
2641dfd4b4
commit
2e18ba6302
7 changed files with 283 additions and 93 deletions
18
etc/ERC-NEWS
18
etc/ERC-NEWS
|
@ -128,9 +128,10 @@ renamed 'erc-ensure-target-buffer-on-privmsg'.
|
|||
Some minor quality-of-life niceties have finally made their way to
|
||||
ERC. For example, the function 'erc-echo-timestamp' is now
|
||||
interactive and can be invoked on any message to view its timestamp in
|
||||
the echo area. Also, the 'irccontrols' module now supports additional
|
||||
colors and special handling for "spoilers" (hidden text). And issuing
|
||||
an "/MOTD" now dispatches a purpose-built command handler.
|
||||
the echo area. The command 'erc-button-previous' now moves to the
|
||||
beginning instead of the end of buttons. And the 'irccontrols' module
|
||||
now supports additional colors and special handling for "spoilers"
|
||||
(hidden text).
|
||||
|
||||
** Changes in the library API.
|
||||
|
||||
|
@ -199,10 +200,13 @@ example, requiring the use of 'insert-before-markers' instead of
|
|||
changes are encouraged to voice their concerns on the bug list.
|
||||
|
||||
*** Miscellaneous changes
|
||||
For autoloading purposes, 'Info-goto-node' has been supplanted by
|
||||
plain old 'info' in 'erc-button-alist', and two helper macros from GNU
|
||||
ELPA's Compat library are now available to third-party modules as
|
||||
'erc-compat-call' and 'erc-compat-function'.
|
||||
Two helper macros from GNU ELPA's Compat library are now available to
|
||||
third-party modules as 'erc-compat-call' and 'erc-compat-function'.
|
||||
In the area of buttons, 'Info-goto-node' has been supplanted by plain
|
||||
old 'info' in 'erc-button-alist', primarily for autoloading purposes.
|
||||
And the "TAB" key is now bound to a new command, 'erc-tab', that only
|
||||
calls 'completion-at-point' when point is in the input area and
|
||||
module-specific commands, like 'erc-button-next', otherwise.
|
||||
|
||||
|
||||
* Changes in ERC 5.5
|
||||
|
|
|
@ -55,11 +55,11 @@
|
|||
((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--tab-functions #'erc-button-next)
|
||||
(erc--modify-local-map t "<backtab>" #'erc-button-previous))
|
||||
((remove-hook 'erc-insert-modify-hook #'erc-button-add-buttons)
|
||||
(remove-hook 'erc-send-modify-hook #'erc-button-add-buttons)
|
||||
(remove-hook 'erc-complete-functions #'erc-button-next-function)
|
||||
(remove-hook 'erc--tab-functions #'erc-button-next)
|
||||
(erc--modify-local-map nil "<backtab>" #'erc-button-previous)))
|
||||
|
||||
;;; Variables
|
||||
|
@ -529,6 +529,7 @@ call it with the value of the `erc-data' text property."
|
|||
(defun erc-button-next-function ()
|
||||
"Pseudo completion function that actually jumps to the next button.
|
||||
For use on `completion-at-point-functions'."
|
||||
(declare (obsolete erc-nickserv-identify "30.1"))
|
||||
;; FIXME: This is an abuse of completion-at-point-functions.
|
||||
(when (< (point) (erc-beg-of-input-line))
|
||||
(let ((start (point)))
|
||||
|
@ -546,27 +547,73 @@ For use on `completion-at-point-functions'."
|
|||
(error "No next button"))
|
||||
t)))))
|
||||
|
||||
(defun erc-button-next ()
|
||||
"Go to the next button in this buffer."
|
||||
(interactive)
|
||||
(let ((f (erc-button-next-function)))
|
||||
(if f (funcall f))))
|
||||
(defvar erc-button--prev-next-predicate-functions
|
||||
'(erc-button--end-of-button-p)
|
||||
"Abnormal hook whose members can return non-nil to continue searching.
|
||||
Otherwise, if all members return nil, point will stay at the
|
||||
current button. Called with a single arg, a buffer position
|
||||
greater than `point-min' with a text property of `erc-callback'.")
|
||||
|
||||
(defun erc-button-previous ()
|
||||
"Go to the previous button in this buffer."
|
||||
(interactive)
|
||||
(let ((here (point)))
|
||||
(when (< here (erc-beg-of-input-line))
|
||||
(while (and (get-text-property here 'erc-callback)
|
||||
(not (= here (point-min))))
|
||||
(setq here (1- here)))
|
||||
(while (and (not (get-text-property here 'erc-callback))
|
||||
(not (= here (point-min))))
|
||||
(setq here (1- here)))
|
||||
(if (> here (point-min))
|
||||
(goto-char here)
|
||||
(error "No previous button"))
|
||||
t)))
|
||||
(defun erc-button--end-of-button-p (point)
|
||||
(get-text-property (1- point) 'erc-callback))
|
||||
|
||||
(defun erc--button-next (arg)
|
||||
(let* ((nextp (prog1 (>= arg 1) (setq arg (max 1 (abs arg)))))
|
||||
(search-fn (if nextp
|
||||
#'next-single-char-property-change
|
||||
#'previous-single-char-property-change))
|
||||
(start (point))
|
||||
(p start))
|
||||
(while (progn
|
||||
;; Break out of current search context.
|
||||
(when-let ((low (max (point-min) (1- (pos-bol))))
|
||||
(high (min (point-max) (1+ (pos-eol))))
|
||||
(prop (get-text-property p 'erc-callback))
|
||||
(q (if nextp
|
||||
(text-property-not-all p high
|
||||
'erc-callback prop)
|
||||
(funcall search-fn p 'erc-callback nil low)))
|
||||
((< low q high)))
|
||||
(setq p q))
|
||||
;; Assume that buttons occur frequently enough that
|
||||
;; omitting LIMIT is acceptable.
|
||||
(while
|
||||
(and (setq p (funcall search-fn p 'erc-callback))
|
||||
(if nextp (< p erc-insert-marker) (/= p (point-min)))
|
||||
(run-hook-with-args-until-success
|
||||
'erc-button--prev-next-predicate-functions p)))
|
||||
(and arg
|
||||
(< (point-min) p erc-insert-marker)
|
||||
(goto-char p)
|
||||
(not (zerop (cl-decf arg))))))
|
||||
(when (= (point) start)
|
||||
(user-error (if nextp "No next button" "No previous button")))
|
||||
t))
|
||||
|
||||
(defun erc-button-next (&optional arg)
|
||||
"Go to the ARGth next button."
|
||||
(declare (advertised-calling-convention (arg) "30.1"))
|
||||
(interactive "p")
|
||||
(setq arg (pcase arg ((pred listp) (prefix-numeric-value arg)) (_ arg)))
|
||||
(erc--button-next arg))
|
||||
|
||||
(defun erc-button-previous (&optional arg)
|
||||
"Go to ARGth previous button."
|
||||
(declare (advertised-calling-convention (arg) "30.1"))
|
||||
(interactive "p")
|
||||
(setq arg (pcase arg ((pred listp) (prefix-numeric-value arg)) (_ arg)))
|
||||
(erc--button-next (- arg)))
|
||||
|
||||
(defun erc-button-previous-of-nick (arg)
|
||||
"Go to ARGth previous button for nick at point."
|
||||
(interactive "p")
|
||||
(if-let* ((prop (get-text-property (point) 'erc-data))
|
||||
(erc-button--prev-next-predicate-functions
|
||||
(cons (lambda (p)
|
||||
(not (equal (get-text-property p 'erc-data) prop)))
|
||||
erc-button--prev-next-predicate-functions)))
|
||||
(erc--button-next (- arg))
|
||||
(user-error "No nick at point")))
|
||||
|
||||
(defun erc-browse-emacswiki (thing)
|
||||
"Browse to THING in the emacs-wiki."
|
||||
|
|
|
@ -300,7 +300,9 @@ of the minor-mode toggles as usual."
|
|||
(setq msg (concat msg (and msg " ")
|
||||
(erc-fill--make-module-dependency-msg "button"))))
|
||||
(erc-with-server-buffer
|
||||
(erc-button-mode +1))))
|
||||
(erc-button-mode +1)))
|
||||
(add-hook 'erc-button--prev-next-predicate-functions
|
||||
#'erc-fill--wrap-merged-button-p nil t))
|
||||
;; Set local value of user option (can we avoid this somehow?)
|
||||
(unless (eq erc-fill-function #'erc-fill-wrap)
|
||||
(setq-local erc-fill-function #'erc-fill-wrap))
|
||||
|
@ -328,6 +330,8 @@ of the minor-mode toggles as usual."
|
|||
(kill-local-variable 'erc-fill--wrap-value)
|
||||
(kill-local-variable 'erc-fill-function)
|
||||
(kill-local-variable 'erc-fill--wrap-visual-keys)
|
||||
(remove-hook 'erc-button--prev-next-predicate-functions
|
||||
#'erc-fill--wrap-merged-button-p t)
|
||||
(remove-function (local 'erc-stamp--insert-date-function)
|
||||
#'erc-fill--wrap-stamp-insert-prefixed-date)
|
||||
(visual-line-mode -1))
|
||||
|
@ -414,6 +418,10 @@ See `erc-fill-wrap-mode' for details."
|
|||
`((space :width (- erc-fill--wrap-value ,len))
|
||||
(space :width erc-fill--wrap-value))))))
|
||||
|
||||
;; FIXME use own text property to avoid false positives.
|
||||
(defun erc-fill--wrap-merged-button-p (point)
|
||||
(equal "" (get-text-property point 'display)))
|
||||
|
||||
;; This is an experimental helper for third-party modules. You could,
|
||||
;; for example, use this to automatically resize the prefix to a
|
||||
;; fraction of the window's width on some event change. Another use
|
||||
|
|
|
@ -354,7 +354,7 @@ simply because we do not necessarily receive the QUIT event."
|
|||
:type 'hook)
|
||||
|
||||
(defcustom erc-complete-functions nil
|
||||
"These functions get called when the user hits TAB in ERC.
|
||||
"These functions get called when the user hits \\`TAB' in ERC.
|
||||
Each function in turn is called until one returns non-nil to
|
||||
indicate it has handled the input."
|
||||
:group 'erc-hooks
|
||||
|
@ -1231,7 +1231,7 @@ which the local user typed."
|
|||
(define-key map "\C-c\C-u" #'erc-kill-input)
|
||||
(define-key map "\C-c\C-x" #'erc-quit-server)
|
||||
(define-key map "\M-\t" #'ispell-complete-word)
|
||||
(define-key map "\t" #'completion-at-point)
|
||||
(define-key map "\t" #'erc-tab)
|
||||
|
||||
;; Suppress `font-lock-fontify-block' key binding since it
|
||||
;; destroys face properties.
|
||||
|
@ -4675,6 +4675,19 @@ This places `point' just after the prompt, or at the beginning of the line."
|
|||
(setq erc-input-ring-index nil))
|
||||
(kill-line)))
|
||||
|
||||
(defvar erc--tab-functions nil
|
||||
"Functions to try when user hits \\`TAB' outside of input area.
|
||||
Called with a numeric prefix arg.")
|
||||
|
||||
(defun erc-tab (&optional arg)
|
||||
"Call `completion-at-point' when typing in the input area.
|
||||
Otherwise call members of `erc--tab-functions' with raw prefix
|
||||
ARG until one of them returns non-nil."
|
||||
(interactive "P")
|
||||
(if (>= (point) erc-input-marker)
|
||||
(completion-at-point)
|
||||
(run-hook-with-args-until-success 'erc--tab-functions arg)))
|
||||
|
||||
(defun erc-complete-word-at-point ()
|
||||
(run-hook-with-args-until-success 'erc-complete-functions))
|
||||
|
||||
|
|
177
test/lisp/erc/erc-button-tests.el
Normal file
177
test/lisp/erc/erc-button-tests.el
Normal file
|
@ -0,0 +1,177 @@
|
|||
;;; erc-button-tests.el --- Tests for erc-button -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
;;
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published
|
||||
;; by the Free Software Foundation, either version 3 of the License,
|
||||
;; or (at your option) any later version.
|
||||
;;
|
||||
;; GNU Emacs is distributed in the hope that it will be useful, but
|
||||
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;; General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'erc-button)
|
||||
|
||||
(defun erc-button-tests--insert-privmsg (speaker &rest msg-parts)
|
||||
(declare (indent 1))
|
||||
(let ((msg (erc-format-privmessage speaker
|
||||
(apply #'concat msg-parts) nil t)))
|
||||
(erc-display-message nil nil (current-buffer) msg)))
|
||||
|
||||
(defun erc-button-tests--populate (test)
|
||||
(let ((inhibit-message noninteractive)
|
||||
erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
|
||||
|
||||
(with-current-buffer
|
||||
(cl-letf
|
||||
(((symbol-function 'erc-server-connect)
|
||||
(lambda (&rest _)
|
||||
(setq erc-server-process
|
||||
(start-process "sleep" (current-buffer) "sleep" "1"))
|
||||
(set-process-query-on-exit-flag erc-server-process nil))))
|
||||
|
||||
(erc-open "localhost" 6667 "tester" "Tester" 'connect
|
||||
nil nil nil nil nil "tester" 'foonet))
|
||||
|
||||
(with-current-buffer (erc--open-target "#chan")
|
||||
(erc-update-channel-member
|
||||
"#chan" "alice" "alice" t nil nil nil nil nil "fake" "~u" nil nil t)
|
||||
|
||||
(erc-update-channel-member
|
||||
"#chan" "bob" "bob" t nil nil nil nil nil "fake" "~u" nil nil t)
|
||||
|
||||
(erc-display-message
|
||||
nil 'notice (current-buffer)
|
||||
(concat "This server is in debug mode and is logging all user I/O. "
|
||||
"Blah alice (1) bob (2) blah."))
|
||||
|
||||
(funcall test))
|
||||
|
||||
(when noninteractive
|
||||
(kill-buffer "#chan")
|
||||
(kill-buffer)))))
|
||||
|
||||
(ert-deftest erc-button-next ()
|
||||
(erc-button-tests--populate
|
||||
(lambda ()
|
||||
(erc-button-tests--insert-privmsg "alice"
|
||||
"(3) bob (4) come, you are a tedious fool: to the purpose.")
|
||||
|
||||
(erc-button-tests--insert-privmsg "bob"
|
||||
"(5) alice (6) Come me to what was done to her.")
|
||||
|
||||
(should (= erc-input-marker (point)))
|
||||
|
||||
;; Break out of input area
|
||||
(erc-button-previous 1)
|
||||
(should (looking-at (rx "alice (6)")))
|
||||
|
||||
;; No next button
|
||||
(should-error (erc-button-next 1) :type 'user-error)
|
||||
(should (looking-at (rx "alice (6)")))
|
||||
|
||||
;; Next with negative arg is equivalent to previous
|
||||
(erc-button-next -1)
|
||||
(should (looking-at (rx "bob> (5)")))
|
||||
|
||||
;; One past end of button
|
||||
(forward-char 3)
|
||||
(should (looking-at (rx "> (5)")))
|
||||
(should-not (get-text-property (point) 'erc-callback))
|
||||
(erc-button-previous 1)
|
||||
(should (looking-at (rx "bob> (5)")))
|
||||
|
||||
;; At end of button
|
||||
(forward-char 2)
|
||||
(should (looking-at (rx "b> (5)")))
|
||||
(erc-button-previous 1)
|
||||
(should (looking-at (rx "bob (4)")))
|
||||
|
||||
;; Skip multiple buttons back
|
||||
(erc-button-previous 2)
|
||||
(should (looking-at (rx "bob (2)")))
|
||||
|
||||
;; Skip multiple buttons forward
|
||||
(erc-button-next 2)
|
||||
(should (looking-at (rx "bob (4)")))
|
||||
|
||||
;; No error as long as some progress made
|
||||
(erc-button-previous 100)
|
||||
(should (looking-at (rx "alice (1)")))
|
||||
|
||||
;; Error when no progress made
|
||||
(should-error (erc-button-previous 1) :type 'user-error)
|
||||
(should (looking-at (rx "alice (1)"))))))
|
||||
|
||||
;; 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)
|
||||
(setq erc-server-process
|
||||
(start-process "sleep" (current-buffer) "sleep" "1"))
|
||||
(set-process-query-on-exit-flag erc-server-process nil)
|
||||
(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 1)
|
||||
(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 1)
|
||||
;; End of interval correct
|
||||
(erc-button-previous 1)
|
||||
(should (looking-at "C-a fails")))
|
||||
|
||||
(ert-info ("Extended command mapping succeeds")
|
||||
(erc-button-next 1)
|
||||
(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 1)
|
||||
(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
|
||||
|
||||
(ert-info ("Format when trailing args include non-strings")
|
||||
(should (equal (erc-button--display-error-notice-with-keys
|
||||
"abc" " %d def" " 45%s" 123 '\6)
|
||||
"*** abc 123 def 456")))
|
||||
|
||||
(when noninteractive
|
||||
(unless mode
|
||||
(erc-button-mode -1))
|
||||
(kill-buffer "*Help*")
|
||||
(kill-buffer)))))
|
||||
|
||||
;;; erc-button-tests.el ends here
|
|
@ -94,6 +94,8 @@
|
|||
;; Defend against non-local exits from `ert-skip'
|
||||
(unwind-protect
|
||||
(funcall test)
|
||||
(when set-transient-map-timer
|
||||
(timer-event-handler set-transient-map-timer))
|
||||
(set-window-buffer (selected-window) original-window-buffer)
|
||||
(when noninteractive
|
||||
(while-let ((buf (pop erc-fill-tests--buffers)))
|
||||
|
|
|
@ -2110,65 +2110,4 @@ connection."
|
|||
(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
|
||||
|
||||
(ert-info ("Format when trailing args include non-strings")
|
||||
(should (equal (erc-button--display-error-notice-with-keys
|
||||
"abc" " %d def" " 45%s" 123 '\6)
|
||||
"*** abc 123 def 456")))
|
||||
|
||||
(when noninteractive
|
||||
(unless mode
|
||||
(erc-button-mode -1))
|
||||
(kill-buffer "*Help*")
|
||||
(kill-buffer)))))
|
||||
|
||||
;;; erc-tests.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue