diff options
author | João Távora <joaotavora@gmail.com> | 2023-03-02 22:55:31 +0000 |
---|---|---|
committer | João Távora <joaotavora@gmail.com> | 2023-04-13 17:42:37 +0100 |
commit | d45f450cff757ed520a7ee36c632ab62387c7bc9 (patch) | |
tree | 7ce124c795aa77a80780c741de48ce36855ffbe5 /lisp | |
parent | d590af749f18ea3b82e46bb498568c77a2640d29 (diff) | |
download | emacs-d45f450cff757ed520a7ee36c632ab62387c7bc9.tar.gz |
Flymake: add new flymake-show-diagnostics-at-end-of-line option
Some editors have this. Depending on your preference, this can either
be wildly distracting and easily confused with actual code, or a
significant early aid that relieves you from moving around or reaching
for the mouse to consult an error message. To be safe, hide this
behind a customization variable and keep it disabled.
Personally, I find it less obstrusive and more helpful than expected.
* lisp/progmodes/flymake.el (flymake--delete-overlay): New helper.
(flymake--highlight-line): Handle flymake-show-diagnostics-at-end-of-line.
(flymake--clear-foreign-diags): Use flymake--delete-overlay.
(flymake--publish-diagnostics): Use flymake--delete-overlay.
(flymake-mode): Use flymake--delete-overlay.
(flymake-error-echo)
(flymake-warning-echo, flymake-note-echo): New faces.
(flymake-show-diagnostics-at-end-of-line): New option.
(Version): Bump to 1.3.4
* doc/misc/flymake.texi:
(Finding diagnostics): Mention flymake-show-diagnostics-at-end-of-line.
(Customizable variables): Mention
flymake-show-diagnostics-at-end-of-line and a few more relevant faces.
* etc/NEWS (Flymake): Mention flymake-show-diagnostics-at-end-of-line.
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/progmodes/flymake.el | 89 |
1 files changed, 76 insertions, 13 deletions
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index c751e5bd432..f2fe97cb773 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -4,7 +4,7 @@ ;; Author: Pavel Kobyakov <pk_at_work@yahoo.com> ;; Maintainer: João Távora <joaotavora@gmail.com> -;; Version: 1.3.3 +;; Version: 1.3.4 ;; Keywords: c languages tools ;; Package-Requires: ((emacs "26.1") (eldoc "1.14.0") (project "0.7.1")) @@ -431,6 +431,26 @@ verify FILTER, a function, and sort them by COMPARE (using KEY)." "Face used for marking note regions." :version "26.1") +(defface flymake-error-echo + '((t :inherit compilation-error)) + "Face used for showing summarized descriptions of errors." + :package-version '("Flymake" . "1.3.4")) + +(defface flymake-warning-echo + '((t :inherit compilation-warning)) + "Face used for showing summarized descriptions of warnings." + :package-version '("Flymake" . "1.3.4")) + +(defface flymake-note-echo + '((t :inherit flymake-note)) + "Face used for showing summarized descriptions of notes." + :package-version '("Flymake" . "1.3.4")) + +(defcustom flymake-show-diagnostics-at-end-of-line nil + "If non-nil, add diagnostic summary messages at end-of-line." + :type 'boolean + :package-version '("Flymake" . "1.3.4")) + (define-obsolete-face-alias 'flymake-warnline 'flymake-warning "26.1") (define-obsolete-face-alias 'flymake-errline 'flymake-error "26.1") @@ -584,22 +604,25 @@ Node `(Flymake)Flymake error types'" (put 'flymake-error 'face 'flymake-error) (put 'flymake-error 'flymake-bitmap 'flymake-error-bitmap) (put 'flymake-error 'severity (warning-numeric-level :error)) -(put 'flymake-error 'mode-line-face 'compilation-error) -(put 'flymake-error 'echo-face 'error) +(put 'flymake-error 'mode-line-face 'flymake-error-echo) +(put 'flymake-error 'echo-face 'flymake-error-echo) +(put 'flymake-error 'eol-face 'flymake-error-echo) (put 'flymake-error 'flymake-type-name "error") (put 'flymake-warning 'face 'flymake-warning) (put 'flymake-warning 'flymake-bitmap 'flymake-warning-bitmap) (put 'flymake-warning 'severity (warning-numeric-level :warning)) -(put 'flymake-warning 'mode-line-face 'compilation-warning) -(put 'flymake-warning 'echo-face 'warning) +(put 'flymake-warning 'mode-line-face 'flymake-warning-echo) +(put 'flymake-warning 'echo-face 'flymake-warning-echo) +(put 'flymake-warning 'eol-face 'flymake-warning-echo) (put 'flymake-warning 'flymake-type-name "warning") (put 'flymake-note 'face 'flymake-note) (put 'flymake-note 'flymake-bitmap 'flymake-note-bitmap) (put 'flymake-note 'severity (warning-numeric-level :debug)) -(put 'flymake-note 'mode-line-face 'compilation-info) -(put 'flymake-note 'echo-face 'compilation-info) +(put 'flymake-note 'mode-line-face 'flymake-note-echo) +(put 'flymake-note 'echo-face 'flymake-note-echo) +(put 'flymake-note 'eol-face 'flymake-note-echo) (put 'flymake-note 'flymake-type-name "note") (defun flymake--lookup-type-property (type prop &optional default) @@ -656,6 +679,12 @@ associated `flymake-category' return DEFAULT." flymake-diagnostic-text) always (equal (funcall comp a) (funcall comp b))))) +(defun flymake--delete-overlay (ov) + "Like `delete-overlay', delete OV, but do some more stuff." + (let ((eolov (overlay-get ov 'eol-ov))) + (when eolov (delete-overlay eolov)) + (delete-overlay ov))) + (cl-defun flymake--highlight-line (diagnostic &optional foreign) "Attempt to overlay DIAGNOSTIC in current buffer. @@ -695,6 +724,7 @@ Return nil or the overlay created." ;; diagnostic is already registered in the same place, which only ;; happens for clashes between domestic and foreign diagnostics (cl-loop for e in (flymake-diagnostics beg end) + for eov = (flymake--diag-overlay e) when (flymake--equal-diagnostic-p e diagnostic) ;; FIXME. This is an imperfect heuristic. Ideally, we'd ;; want to delete no overlays and keep annotating the @@ -710,7 +740,7 @@ Return nil or the overlay created." (flymake--diag-orig-beg e) (flymake--diag-end e) (flymake--diag-orig-end e)) - (delete-overlay (flymake--diag-overlay e)))) + (flymake--delete-overlay eov))) (setq ov (make-overlay end beg)) (setf (flymake--diag-beg diagnostic) (overlay-start ov) (flymake--diag-end diagnostic) (overlay-end ov)) @@ -728,6 +758,37 @@ Return nil or the overlay created." (flymake--lookup-type-property type 'flymake-overlay-control)) (alist-get type flymake-diagnostic-types-alist)) do (overlay-put ov ov-prop value)) + ;; Handle `flymake-show-diagnostics-at-end-of-line' + ;; + (when-let ((eol-face (and flymake-show-diagnostics-at-end-of-line + (flymake--lookup-type-property type 'eol-face)))) + (save-excursion + (goto-char (overlay-start ov)) + (let* ((start (line-end-position)) + (end (min (1+ start) (point-max))) + (eolov (car + (cl-remove-if-not + (lambda (o) (overlay-get o 'flymake-source-ovs)) + (overlays-at start)))) + (bs (flymake-diagnostic-oneliner diagnostic t))) + (setq bs (propertize bs 'face eol-face)) + ;; FIXME: 1. no checking if there are unexpectedly more than + ;; one eolov at point. 2. The first regular source ov to + ;; die also kills the eolov (very rare this matters, but + ;; could be improved). + (cond (eolov + (overlay-put eolov 'before-string + (concat (overlay-get eolov 'before-string) " " bs)) + (overlay-put eolov 'flymake-source-ovs + (cons ov (overlay-get eolov 'flymake-source-ovs)))) + (t + (setq eolov (make-overlay start end nil t nil)) + (setq bs (concat " " bs)) + (put-text-property 0 1 'cursor t bs) + (overlay-put eolov 'before-string bs) + (overlay-put eolov 'evaporate (not (= start end))) + (overlay-put eolov 'flymake-source-ovs (list ov)) + (overlay-put ov 'eol-ov eolov)))))) ;; Now ensure some essential defaults are set ;; (cl-flet ((default-maybe @@ -743,6 +804,8 @@ Return nil or the overlay created." 'flymake-bitmap (alist-get 'bitmap (alist-get type ; backward compat flymake-diagnostic-types-alist))))) + ;; (default-maybe 'after-string + ;; (flymake--diag-text diagnostic)) (default-maybe 'help-echo (lambda (window _ov pos) (with-selected-window window @@ -873,7 +936,7 @@ report applies to that region." (maphash (lambda (_buffer diags) (cl-loop for d in diags when (flymake--diag-overlay d) - do (delete-overlay it))) + do (flymake--delete-overlay it))) (flymake--state-foreign-diags state)) (clrhash (flymake--state-foreign-diags state))) @@ -900,7 +963,7 @@ and other buffers." (flymake--intersects-p (overlay-start ov) (overlay-end ov) (car region) (cdr region))) - do (delete-overlay ov) + do (flymake--delete-overlay ov) else collect diag into surviving finally (setf (flymake--state-diags state) surviving))) @@ -909,7 +972,7 @@ and other buffers." (not (flymake--state-reported-p state)) (cl-loop for diag in (flymake--state-diags state) for ov = (flymake--diag-overlay diag) - when ov do (delete-overlay ov)) + when ov do (flymake--delete-overlay ov)) (setf (flymake--state-diags state) nil) ;; Also clear all overlays for `foreign-diags' in all other ;; buffers. @@ -1153,7 +1216,7 @@ special *Flymake log* buffer." :group 'flymake :lighter ;; existing diagnostic overlays, lest we forget them by blindly ;; reinitializing `flymake--state' in the next line. ;; See https://github.com/joaotavora/eglot/issues/223. - (mapc #'delete-overlay (flymake--overlays)) + (mapc #'flymake--delete-overlay (flymake--overlays)) (setq flymake--state (make-hash-table)) (setq flymake--recent-changes nil) @@ -1200,7 +1263,7 @@ special *Flymake log* buffer." :group 'flymake :lighter (when flymake-timer (cancel-timer flymake-timer) (setq flymake-timer nil)) - (mapc #'delete-overlay (flymake--overlays)) + (mapc #'flymake--delete-overlay (flymake--overlays)) (when flymake--state (maphash (lambda (_backend state) (flymake--clear-foreign-diags state)) |