Skip to content

Commit

Permalink
Add a defcustom to control default diagnostic severity.
Browse files Browse the repository at this point in the history
Previously, there was a Flycheck specific defcustom, which was used to
select a default error level for Flycheck.  However, there was nothing
for Flymake.  Additionally, there were numerous other places in
lsp-mode which query the severity attribute of the diagnostic, such as
for statistics, modeline, headerline, etc.  All of these were being
handled inconsistently, either not at all (causing an error when the
attribute was not sent by the server), ignoring it when it was
missing (causing statistics to be inaccurate) or assuming a default of
error, which might have been different than the Flycheck specific
configuration, therefore causing an inconsistency in the modeline
statistics vs what Flycheck would report.

This change creates a common defcustom which is then used anywhere the
diagnostic severity is needed, but was not provided by the server.
This should create consistent statistics between the modeline and the
back-end checkers.  Additionally, the mapping between this defcustom
and the checker specific values happens in the diagnostic package.

Since this defcustom is used outside of the lsp-diagnostic package, it
resides in the lsp-mode package and renamed more generally.
Additionally, the Flycheck specific defcustom has been obsoleted.
  • Loading branch information
brownts committed Apr 23, 2024
1 parent 5a20661 commit a686a77
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 32 deletions.
51 changes: 24 additions & 27 deletions lsp-diagnostics.el
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,9 @@
(define-obsolete-variable-alias 'lsp-flycheck-default-level
'lsp-diagnostics-flycheck-default-level "lsp-mode 7.0.1")

(defcustom lsp-diagnostics-flycheck-default-level 'error
"Error level to use when the server does not report back a diagnostic level."
:type '(choice
(const error)
(const warning)
(const info))
:group 'lsp-diagnostics)
;;;###autoload
(define-obsolete-variable-alias 'lsp-diagnostics-flycheck-default-level
'lsp-diagnostics-default-severity "lsp-mode 9.0.1")

(defcustom lsp-diagnostics-attributes
`((unnecessary :foreground "gray")
Expand Down Expand Up @@ -131,18 +127,19 @@ g. `error', `warning') and list of LSP TAGS."

(defun lsp-diagnostics--flycheck-calculate-level (severity tags)
"Calculate flycheck level by SEVERITY and TAGS."
(let ((level (pcase severity
(1 'error)
(2 'warning)
(3 'info)
(4 'info)
(_ lsp-flycheck-default-level)))
;; materialize only first tag.
(tags (seq-map (lambda (tag)
(cond
((= tag lsp/diagnostic-tag-unnecessary) 'unnecessary)
((= tag lsp/diagnostic-tag-deprecated) 'deprecated)))
tags)))
(let* ((severity (or severity
(lsp-diagnostics-severity->numeric
lsp-diagnostics-default-severity)))
(level (cond ((= severity lsp/diagnostic-severity-error) 'error)
((= severity lsp/diagnostic-severity-warning) 'warning)
((= severity lsp/diagnostic-severity-information) 'info)
((= severity lsp/diagnostic-severity-hint) 'info)))
;; materialize only first tag.
(tags (seq-map (lambda (tag)
(cond
((= tag lsp/diagnostic-tag-unnecessary) 'unnecessary)
((= tag lsp/diagnostic-tag-deprecated) 'deprecated)))
tags)))
(if tags
(lsp-diagnostics--flycheck-level level tags)
level)))
Expand Down Expand Up @@ -305,14 +302,14 @@ See https://github.com/emacs-lsp/lsp-mode."
(goto-char (point-min))
(setq start (line-beginning-position (1+ start-line))
end (line-end-position (1+ end-line))))))
(flymake-make-diagnostic (current-buffer)
start
end
(cl-case severity?
(1 :error)
(2 :warning)
(t :note))
message))))
(let* ((severity (or severity?
(lsp-diagnostics-severity->numeric
lsp-diagnostics-default-severity)))
(type (cond ((= severity lsp/diagnostic-severity-error) :error)
((= severity lsp/diagnostic-severity-warning) :warning)
((= severity lsp/diagnostic-severity-information) :note)
((= severity lsp/diagnostic-severity-hint) :note))))
(flymake-make-diagnostic (current-buffer) start end type message)))))
;; This :region keyword forces flymake to delete old diagnostics in
;; case the buffer hasn't changed since the last call to the report
;; function. See https://github.com/joaotavora/eglot/issues/159
Expand Down
6 changes: 5 additions & 1 deletion lsp-headerline.el
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,11 @@ PATH is the current folder to be checked."
(let ((range-severity 10))
(mapc (-lambda ((&Diagnostic :range (&Range :start) :severity?))
(when (lsp-point-in-range? start range)
(setq range-severity (min range-severity severity?))))
(setq range-severity
(min range-severity
(or severity?
(lsp-diagnostics-severity->numeric
lsp-diagnostics-default-severity))))))
(lsp--get-buffer-diagnostics))
range-severity))

Expand Down
25 changes: 23 additions & 2 deletions lsp-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,15 @@ diagnostics have changed."
:type 'hook
:group 'lsp-mode)

(defcustom lsp-diagnostics-default-severity 'error
"Error level to use when the server does not report one."
:type '(choice (const :tag "Error" error)
(const :tag "Warning" warning)
(const :tag "Information" info)
(const :tag "Hint" hint))
:group 'lsp-mode
:package-version '(lsp-mode . "9.0.1"))

(define-obsolete-variable-alias 'lsp-workspace-folders-changed-hook
'lsp-workspace-folders-changed-functions "lsp-mode 6.3")

Expand Down Expand Up @@ -2277,6 +2286,14 @@ Common usecase are:
result)))
(ht)))

(defun lsp-diagnostics-severity->numeric (severity)
"Determine numeric severity from symbolic SEVERITY."
(pcase severity
('error lsp/diagnostic-severity-error)
('warning lsp/diagnostic-severity-warning)
('info lsp/diagnostic-severity-information)
('hint lsp/diagnostic-severity-hint)))

(defun lsp-diagnostics-stats-for (path)
"Get diagnostics statistics for PATH.
The result format is vector [_ errors warnings infos hints] or nil."
Expand All @@ -2296,11 +2313,15 @@ The result format is vector [_ errors warnings infos hints] or nil."
(let ((path (lsp--fix-path-casing (lsp--uri-to-path uri)))
(new-stats (make-vector 5 0)))
(mapc (-lambda ((&Diagnostic :severity?))
(cl-incf (aref new-stats (or severity? 1))))
(cl-incf (aref new-stats (or severity?
(lsp-diagnostics-severity->numeric
lsp-diagnostics-default-severity)))))
diagnostics)
(when-let ((old-diags (gethash path (lsp--workspace-diagnostics workspace))))
(mapc (-lambda ((&Diagnostic :severity?))
(cl-decf (aref new-stats (or severity? 1))))
(cl-decf (aref new-stats (or severity?
(lsp-diagnostics-severity->numeric
lsp-diagnostics-default-severity)))))
old-diags))
(lsp-diagnostics--update-path path new-stats)
(while (not (string= path (setf path (file-name-directory
Expand Down
6 changes: 4 additions & 2 deletions lsp-modeline.el
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,10 @@ The `:global' workspace is global one.")
(mapc (lambda (buf-diags)
(mapc (lambda (diag)
(-let [(&Diagnostic? :severity?) diag]
(when severity?
(cl-incf (aref stats severity?)))))
(cl-incf (aref stats
(or severity?
(lsp-diagnostics-severity->numeric
lsp-diagnostics-default-severity))))))
buf-diags))
diagnostics)
(while (< i lsp/diagnostic-severity-max)
Expand Down

0 comments on commit a686a77

Please sign in to comment.