branch: elpa/flycheck
commit 83cf0cc743a712726de9e36de203ebc9cd96f9fb
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
Make the mode-line error counts clickable
mouse-1 on the counts pops up the error list, like Flymake's clickable
indicator. The truncation marker keeps its own tooltip explaining how
many errors were suppressed.
---
CHANGES.rst | 2 ++
flycheck.el | 59 ++++++++++++++++++++++++++++++--------------
test/specs/test-mode-line.el | 34 ++++++++++++++++++++++++-
3 files changed, 76 insertions(+), 19 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index 340770e74c..7c56797791 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -18,6 +18,8 @@
``flycheck-display-errors-function`` to
``flycheck-display-error-messages``; custom display functions and
extensions like flycheck-posframe keep working unchanged.
+- The error counts in the mode line are clickable: ``mouse-1`` pops up
+ the error list.
- [#1787]: Add the ``:handle-suspicious`` property to command checkers.
It lets a checker translate a "suspicious state" (a non-zero exit
status with no parsable errors, e.g. a missing dependency) into
diff --git a/flycheck.el b/flycheck.el
index 45c434e4ef..9f09a5bcde 100644
--- a/flycheck.el
+++ b/flycheck.el
@@ -4362,6 +4362,26 @@ refresh the mode line."
(run-hook-with-args 'flycheck-status-changed-functions status)
(force-mode-line-update))
+(defun flycheck-mode-line-list-errors (&optional event)
+ "Pop up the error list for the buffer of EVENT's window.
+
+Without a mouse EVENT, e.g. when invoked from the keyboard, pop
+up the error list for the current buffer."
+ (interactive (list last-nonmenu-event))
+ (let ((window (and (eventp event)
+ (posn-window (event-start event)))))
+ ;; `posn-window' may return a frame for frame-relative positions
+ (with-selected-window (if (windowp window) window (selected-window))
+ (flycheck-list-errors))))
+
+(defvar flycheck-mode-line-counts-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1] #'flycheck-mode-line-list-errors)
+ ;; Some setups render the mode-line construct in the header line
+ (define-key map [header-line mouse-1] #'flycheck-mode-line-list-errors)
+ map)
+ "Keymap for the error counts in the mode line.")
+
(defun flycheck-mode-line-status-text (&optional status)
"Get a text describing STATUS for use in the mode line.
@@ -4375,17 +4395,27 @@ nil."
(`errored "!")
(`finished
(let-alist (flycheck-count-errors
flycheck-current-errors)
- (concat
- (if (or .error .warning .info)
- (format ":%s|%s|%s" (or .error 0) (or .warning 0)
- (or .info 0))
- flycheck-mode-success-indicator)
- ;; Signal that some errors were suppressed over
- ;; `flycheck-checker-error-threshold', even when
- ;; the kept errors have no built-in level
- (if (> flycheck--suppressed-error-count 0)
- "+"
- ""))))
+ (propertize
+ (concat
+ (if (or .error .warning .info)
+ (format ":%s|%s|%s" (or .error 0) (or .warning
0)
+ (or .info 0))
+ flycheck-mode-success-indicator)
+ ;; Signal that some errors were suppressed over
+ ;; `flycheck-checker-error-threshold', even when
+ ;; the kept errors have no built-in level
+ (if (> flycheck--suppressed-error-count 0)
+ "+"
+ ""))
+ 'local-map flycheck-mode-line-counts-map
+ 'mouse-face 'mode-line-highlight
+ 'help-echo
+ (concat
+ (when (> flycheck--suppressed-error-count 0)
+ (format "%d more errors not shown\
+ (see flycheck-checker-error-threshold)\n"
+ flycheck--suppressed-error-count))
+ "mouse-1: list errors"))))
(`interrupted ".")
(`suspicious "?")))
(face (when flycheck-mode-line-color
@@ -4397,13 +4427,6 @@ nil."
(text (format " %s%s" flycheck-mode-line-prefix indicator)))
(when face
(setq text (propertize text 'face face)))
- (when (and (eq current-status 'finished)
- (> flycheck--suppressed-error-count 0))
- (setq text (propertize
- text 'help-echo
- (format "%d more errors not shown\
- (see flycheck-checker-error-threshold)"
- flycheck--suppressed-error-count))))
text))
diff --git a/test/specs/test-mode-line.el b/test/specs/test-mode-line.el
index 83aa79d16a..4ed739dda1 100644
--- a/test/specs/test-mode-line.el
+++ b/test/specs/test-mode-line.el
@@ -45,6 +45,38 @@
(it "includes the prefix"
(let ((flycheck-mode-line-prefix "foobar")
flycheck-current-errors)
- (expect (flycheck-mode-line-status-text 'finished) :to-equal "
foobar:0"))))
+ (expect (flycheck-mode-line-status-text 'finished) :to-equal "
foobar:0")))
+
+ (it "makes the error counts clickable"
+ (let* ((flycheck-current-errors
+ (list (flycheck-error-new-at 1 1 'error "boom")))
+ (text (flycheck-mode-line-status-text 'finished))
+ (counts-start (string-match ":" text)))
+ (expect (get-text-property counts-start 'local-map text)
+ :to-be flycheck-mode-line-counts-map)
+ (expect (get-text-property counts-start 'help-echo text)
+ :to-equal "mouse-1: list errors")))
+
+ (it "binds mouse-1 to the error list"
+ (expect (lookup-key flycheck-mode-line-counts-map [mode-line mouse-1])
+ :to-be 'flycheck-mode-line-list-errors)
+ (expect (lookup-key flycheck-mode-line-counts-map [header-line mouse-1])
+ :to-be 'flycheck-mode-line-list-errors))
+
+ (it "explains suppressed errors in the tooltip of the whole indicator"
+ (flycheck-buttercup-with-temp-buffer
+ (setq flycheck--suppressed-error-count 7)
+ (let* ((flycheck-current-errors
+ (list (flycheck-error-new-at 1 1 'error "boom")))
+ (text (flycheck-mode-line-status-text 'finished))
+ (counts-start (string-match ":" text))
+ (plus-pos (string-match (rx "+" eos) text)))
+ ;; The truncation marker is part of the clickable segment
+ (expect (get-text-property plus-pos 'local-map text)
+ :to-be flycheck-mode-line-counts-map)
+ ;; The tooltip explains the suppression anywhere on the counts
+ (dolist (pos (list counts-start plus-pos))
+ (expect (get-text-property pos 'help-echo text)
+ :to-match "7 more errors not shown"))))))
;;; test-mode-line.el ends here