branch: elpa/flycheck
commit 43cf1fdb0ef39e8aa678108d1b2d8a07bfa0d989
Author: Jimmy Yuen Ho Wong <wyue...@gmail.com>
Commit: Bozhidar Batsov <bozhi...@batsov.dev>

    Introduce flycheck-clear-displayed-errors-function to give 
flycheck-display-error-at-point a chance to clear errors
---
 CHANGES.rst                    |  3 ++
 doc/user/error-interaction.rst | 18 ++++++++++
 flycheck.el                    | 79 +++++++++++++++++++++++++++---------------
 3 files changed, 72 insertions(+), 28 deletions(-)

diff --git a/CHANGES.rst b/CHANGES.rst
index 76c96d77c4..b95e241d03 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -14,12 +14,15 @@ New Features
 - [#2070]: Add a new syntax checker ``r`` for R with the builtin ``parse`` 
function.
 - [#2073]: Add new syntax checker ``salt-lint`` for the salt 
infrastructure-as-code language.
 - [#2071]: Add a new checker ``perl-perlimports``, for cleaning up Perl import 
statements.
+- [#1972]: New defcustom ``flycheck-clear-displayed-errors-function`` to
+  customize how error messages are to be cleared.
 
 -----------
 Bugs fixed
 -----------
 
 - [#2057]: Revert the extraction of ``flycheck-version`` with ``lm-version``.
+- [#1972]: Refine flycheck-display-errors lifecycle so error messages can be 
cleared.
 
 ----------
 Changes
diff --git a/doc/user/error-interaction.rst b/doc/user/error-interaction.rst
index 1c50e7019b..a54e6ccbd7 100644
--- a/doc/user/error-interaction.rst
+++ b/doc/user/error-interaction.rst
@@ -134,6 +134,24 @@ Flycheck provides two built-in functions for this option:
       (setq flycheck-display-errors-function
             #'flycheck-display-error-messages-unless-error-list)
 
+Along the same vein, Flycheck provides a way to customise how a error message 
is
+cleared, this is especially useful if you use a Flycheck extension to display
+error messages differently from the default.
+
+.. defcustom:: flycheck-clear-displayed-errors-function
+
+   Function to hide error message displayed by 
`flycheck-display-errors-function`.
+
+   If set to a function, it will be called with no arguments to
+   clear all displayed errors at point.
+
+By default, Flycheck only provides `flycheck-clear-displayed-error-messages` to
+clear the last Flycheck error message from the minibuffer:
+
+.. defun:: flycheck-clear-displayed-error-messages
+
+   Clear error messages displayed by `flycheck-display-error-messages`.
+
 .. seealso::
 
    :flyc:`flycheck-pos-tip`
diff --git a/flycheck.el b/flycheck.el
index fc887b4afc..1a118596a7 100644
--- a/flycheck.el
+++ b/flycheck.el
@@ -428,6 +428,18 @@ If set to nil, do not display errors at all."
   :package-version '(flycheck . "0.13")
   :risky t)
 
+(defcustom flycheck-clear-displayed-errors-function 
#'flycheck-clear-displayed-error-messages
+  "Function to hide error message displayed by 
`flycheck-display-errors-function'.
+
+If set to a function, it will be called with no arguments to
+clear all displayed errors at point."
+  :group 'flycheck
+  :type '(choice (const :tag "Clear displayed error messages"
+                        flycheck-clear-displayed-error-messages)
+                 (function :tag "Clear displayed errors function"))
+  :package-version '(flycheck . "34.2")
+  :risky t)
+
 (defcustom flycheck-help-echo-function #'flycheck-help-echo-all-error-messages
   "Function to compute the contents of the error tooltips.
 
@@ -2968,7 +2980,7 @@ Slots:
     ;; the focus hooks only work on Emacs 24.4 and upwards, but since undefined
     ;; hooks are perfectly ok we don't need a version guard here.  They'll just
     ;; not work silently.
-    (post-command-hook . flycheck-maybe-display-error-at-point-soon)
+    (post-command-hook . flycheck-display-error-at-point-soon)
     (focus-in-hook     . flycheck-display-error-at-point-soon)
     (focus-out-hook    . flycheck-cancel-error-display-error-at-point-timer)
     (post-command-hook . flycheck-hide-error-buffer)
@@ -3374,6 +3386,7 @@ current syntax check."
     (flycheck-stop))
   (flycheck-delete-all-overlays)
   (flycheck-clear-errors)
+  (flycheck-clear-displayed-error-messages)
   (flycheck-error-list-refresh)
   (flycheck-hide-error-buffer))
 
@@ -5545,6 +5558,11 @@ non-nil."
   (when flycheck-display-errors-function
     (funcall flycheck-display-errors-function errors)))
 
+(defun flycheck-clear-displayed-errors ()
+  "Clear errors using `flycheck-clear-displayed-errors-function'."
+  (when flycheck-clear-displayed-errors-function
+    (funcall flycheck-clear-displayed-errors-function)))
+
 (defvar-local flycheck-display-error-at-point-timer nil
   "Timer to automatically show errors.")
 
@@ -5554,40 +5572,27 @@ non-nil."
     (cancel-timer flycheck-display-error-at-point-timer)
     (setq flycheck-display-error-at-point-timer nil)))
 
-(defun flycheck--error-display-tick ()
-  "Return point and tick counter of current buffer."
-  (cons (point) (buffer-modified-tick)))
-
-(defvar-local flycheck--last-error-display-tick nil
-  "Value of `flycheck--error-display-tick' when errors were last displayed.")
-
 (defun flycheck-display-error-at-point ()
-  "Display all the error messages at point."
+  "Display all the error messages at point.
+
+If there are no errors, clears the error messages at point."
   (interactive)
   ;; This function runs from a timer, so we must take care to not ignore any
   ;; errors
   (with-demoted-errors "Flycheck error display error: %s"
     (flycheck-cancel-error-display-error-at-point-timer)
-    (setq flycheck--last-error-display-tick (flycheck--error-display-tick))
     (when flycheck-mode
-      (when-let (errors (flycheck-overlay-errors-at (point)))
-        (flycheck-display-errors errors)))))
+      (let ((errors (flycheck-overlay-errors-at (point))))
+        (if errors
+            (flycheck-display-errors errors)
+          (flycheck-clear-displayed-errors))))))
 
 (defun flycheck-display-error-at-point-soon ()
   "Display error messages at point, with a delay."
-  (setq flycheck--last-error-display-tick nil)
-  (flycheck-maybe-display-error-at-point-soon))
-
-(defun flycheck-maybe-display-error-at-point-soon ()
-  "Display error message at point with a delay, unless already displayed."
   (flycheck-cancel-error-display-error-at-point-timer)
-  (when (and (not (equal flycheck--last-error-display-tick
-                         (setq flycheck--last-error-display-tick
-                               (flycheck--error-display-tick))))
-             (flycheck-overlays-at (point)))
-    (setq flycheck-display-error-at-point-timer
-          (run-at-time flycheck-display-errors-delay nil
-                       'flycheck-display-error-at-point))))
+  (setq flycheck-display-error-at-point-timer
+        (run-at-time flycheck-display-errors-delay nil
+                     'flycheck-display-error-at-point)))
 
 
 ;;; Functions to display errors
@@ -5612,6 +5617,14 @@ and if the echo area is not occupied by minibuffer 
input."
   "Flycheck error messages"
   "Major mode for extended error messages.")
 
+(defvar flycheck--last-displayed-message nil
+  "Reference to the last displayed message so it can be cleared.
+
+This value is the return value from `display-message-or-buffer',
+thus it can be a string or a window.
+
+See `flycheck-clear-displayed-error-messages'.")
+
 (defun flycheck-display-error-messages (errors)
   "Display the messages of ERRORS.
 
@@ -5625,15 +5638,17 @@ information.
 In the latter case, show messages in the buffer denoted by
 variable `flycheck-error-message-buffer'."
   (when (and errors (flycheck-may-use-echo-area-p))
-    (let ((message (flycheck-help-echo-all-error-messages errors)))
-      (display-message-or-buffer
-       message flycheck-error-message-buffer 'not-this-window)
+    (let* ((message (flycheck-help-echo-all-error-messages errors))
+           (retval (display-message-or-buffer
+                    message flycheck-error-message-buffer 'not-this-window)))
       ;; We cannot rely on `display-message-or-buffer' returning the right
       ;; window. See URL `https://github.com/flycheck/flycheck/issues/1643'.
       (when-let (buf (get-buffer flycheck-error-message-buffer))
         (with-current-buffer buf
           (unless (derived-mode-p 'flycheck-error-message-mode)
-            (flycheck-error-message-mode)))))))
+            (flycheck-error-message-mode))))
+      (setq flycheck--last-displayed-message retval)
+      retval)))
 
 (defun flycheck-display-error-messages-unless-error-list (errors)
   "Show messages of ERRORS unless the error list is visible.
@@ -5656,6 +5671,14 @@ Hide the error buffer if there is no error under point."
       (save-selected-window
         (quit-window nil window)))))
 
+(defun flycheck-clear-displayed-error-messages ()
+  "Clear error messages displayed by `flycheck-display-error-messages'."
+  (when flycheck--last-displayed-message
+    (if (and (stringp flycheck--last-displayed-message)
+             (equal (current-message) flycheck--last-displayed-message))
+        (message nil)
+      (flycheck-hide-error-buffer))))
+
 
 ;;; Working with errors
 (defun flycheck-copy-errors-as-kill (pos &optional formatter)

Reply via email to