mini-echo.el icon indicating copy to clipboard operation
mini-echo.el copied to clipboard

Error thrown by flycheck segment

Open oscarfv opened this issue 8 months ago • 5 comments

I'm not sure if it is a change on flycheck or a change on Emacs (I'm using the master branch) but the segment started failing with:

propertize: Wrong type argument: numberp, nil

I think that the problematic part is:

(al (push (cons 'success (alist-get 'info errors 0)) errors))

If I try to message the contents of al I get errors like:

string-join: Lisp nesting exceeds ‘max-lisp-eval-depth’: 1601

For now, I'm using this patch:

--- a/singles/mini-echo-segments.el
+++ b/singles/mini-echo-segments.el
@@ -821,13 +821,16 @@ (mini-echo-define-segment "flycheck"
                         ('running "*")
                         ('finished nil))))
        (propertize ind 'face 'compilation-mode-line-run))
-     (let* ((errors (flycheck-count-errors flycheck-current-errors))
-            (al (push (cons 'success (alist-get 'info errors 0)) errors)))
-       (mapconcat
-        (lambda (s)
-          (propertize (number-to-string (alist-get s al)) 'face s))
-        '(error warning success)
-        "/")))))
+     (let-alist (flycheck-count-errors flycheck-current-errors)
+       (concat
+	(propertize (number-to-string (or .error 0))
+		    'face (if .error 'error 'success))
+	"/"
+	(propertize (number-to-string (or .warning 0))
+		    'face (if .warning 'warning 'success))
+	"/"
+	(propertize (number-to-string (or .info 0))
+		    'face (if .warning 'info 'success)))))))
 
 (mini-echo-define-segment "meow"
   "Return the meow status of current buffer."

oscarfv avatar May 10 '25 13:05 oscarfv

please update and test again.

eki3z avatar May 17 '25 04:05 eki3z

Your change fixes a bug, but that's not enough. There are two remaining issues:

  1. At least here, flycheck-count-errors only returns elements for error, warning and info if there are non-zero counts for them. flycheck-count-errors may return an empty list.
  2. You can't rely on the return value of push.

So the complete fix is:

--- a/singles/mini-echo-segments.el
+++ b/singles/mini-echo-segments.el
@@ -821,11 +821,11 @@ (mini-echo-define-segment "flycheck"
                         ('running "*")
                         ('finished nil))))
        (propertize ind 'face 'compilation-mode-line-run))
-     (let* ((errors (flycheck-count-errors flycheck-current-errors))
-            (al (push (cons 'success (alist-get 'info errors 0)) errors)))
+     (let* ((errors (flycheck-count-errors flycheck-current-errors)))
+       (push (cons 'success (or (alist-get 'info errors) 0)) errors)
        (mapconcat
         (lambda (s)
-          (propertize (number-to-string (alist-get s al)) 'face s))
+          (propertize (number-to-string (or (alist-get s errors) 0)) 'face s))
         '(error warning success)
         "/")))))

oscarfv avatar May 17 '25 11:05 oscarfv

As an aside, that segment uses the error and warning faces even when the error and warning count are zero. As those faces are designed to stand out from the rest, the effect is that you see something in error face and need to read the number to notice that there are no errors. I would prefer a success face on that case, as the patch on my initial message. I can make a PR if you wish. My original patch contains a mistake, this is the corrected one:

--- a/singles/mini-echo-segments.el
+++ b/singles/mini-echo-segments.el
@@ -821,13 +821,16 @@ (mini-echo-define-segment "flycheck"
                         ('running "*")
                         ('finished nil))))
        (propertize ind 'face 'compilation-mode-line-run))
-     (let* ((errors (flycheck-count-errors flycheck-current-errors))
-            (al (push (cons 'success (alist-get 'info errors 0)) errors)))
-       (mapconcat
-        (lambda (s)
-          (propertize (number-to-string (alist-get s al)) 'face s))
-        '(error warning success)
-        "/")))))
+     (let-alist (flycheck-count-errors flycheck-current-errors)
+       (concat
+	(propertize (number-to-string (or .error 0))
+		    'face (if .error 'error 'success))
+	"/"
+	(propertize (number-to-string (or .warning 0))
+		    'face (if .warning 'warning 'success))
+	"/"
+	(propertize (number-to-string (or .info 0))
+		    'face (if .info 'info 'success)))))))
 
 (mini-echo-define-segment "meow"
   "Return the meow status of current buffer."

oscarfv avatar May 17 '25 11:05 oscarfv

another fix for all possible nil value, test is again.

eki3z avatar May 25 '25 15:05 eki3z

another fix for all possible nil value, test is again.

Thanks!

I see that you still do

(setq errors (push ...

As mentioned before, push is not meant to return an useful value. At best, is like writing

(setq errors (setq errors (cons ...

because push modifies the variable (when you pass a variable).

At worst, things can break now or in the future. I got recursive lists while trying to inspect the contents of errors. I don't know why, but they dissapeared after removing the (setq before (push.

oscarfv avatar May 25 '25 17:05 oscarfv