emacs-lsp / lsp-ui

UI integrations for lsp-mode
https://emacs-lsp.github.io/lsp-ui
GNU General Public License v3.0
1.04k stars 139 forks source link

Fix: `lsp-flycheck` fail to show errors due to not setting buffer. #13

Closed jiegec closed 6 years ago

jiegec commented 6 years ago

Original code:

(defun lsp-flycheck--start (checker callback)
  "Start an LSP syntax check with CHECKER.

CALLBACK is the status callback passed by Flycheck."
  ;; Turn all errors from lsp--diagnostics into flycheck-error objects and pass
  ;; them immediately to the callback
  (let ((errors))
    (maphash (lambda (file diagnostics)
               (dolist (diag diagnostics)
                 (push (flycheck-error-new
                        :checker checker
                        :filename file
                        :line (1+ (lsp-diagnostic-line diag))
                        :column (1+ (lsp-diagnostic-column diag))
                        :message (lsp-diagnostic-message diag)
                        :level (pcase (lsp-diagnostic-severity diag)
                                 (1 'error)
                                 (2 'warning)
                                 (_ 'info))
                        :id (lsp-diagnostic-code diag))
                       errors)))
             lsp--diagnostics)
    (funcall callback 'finished errors)))

The (current-buffer) is not passed to flycheck-error-new, then the error will be rejected later in flycheck-relevant-error-p:

(defun flycheck-relevant-error-p (err)
  "Determine whether ERR is relevant for the current buffer.

Return t if ERR may be shown for the current buffer, or nil
otherwise."
  (flycheck-error-with-buffer err
    (let ((file-name (flycheck-error-filename err))
          (message (flycheck-error-message err)))
      (and
       ;; The error is relevant for the current buffer if it's got no file-name
       ;; and the current buffer has no file name, too, or if it refers to the
       ;; same file as the current buffer.
       (or (and (not file-name) (not buffer-file-name))
           (and buffer-file-name file-name
                (flycheck-same-files-p file-name buffer-file-name)))
       message
       (not (string-empty-p message))
       (flycheck-error-line err)))))

In the macro flycheck-error-with-buffer, the buffer is set locally to the one bound in err, which is nil in this case. Simple fix:

(defun lsp-flycheck--start (checker callback)
  "Start an LSP syntax check with CHECKER.

CALLBACK is the status callback passed by Flycheck."
  ;; Turn all errors from lsp--diagnostics into flycheck-error objects and pass
  ;; them immediately to the callback
  (let ((errors))
    (maphash (lambda (file diagnostics)
               (dolist (diag diagnostics)
                 (push (flycheck-error-new
                        :buffer (current-buffer)
                        :checker checker
                        :filename file
                        :line (1+ (lsp-diagnostic-line diag))
                        :column (1+ (lsp-diagnostic-column diag))
                        :message (lsp-diagnostic-message diag)
                        :level (pcase (lsp-diagnostic-severity diag)
                                 (1 'error)
                                 (2 'warning)
                                 (_ 'info))
                        :id (lsp-diagnostic-code diag))
                       errors)))
             lsp--diagnostics)
    (funcall callback 'finished errors)))

Just too lazy for a pull-request because fix is trivial and shorter than explanation ;) P.S. edebug is really helpful

sebastiencs commented 6 years ago

Thank you