Function: flymake--highlight-line

flymake--highlight-line is a byte-compiled function defined in flymake.el.gz.

Signature

(flymake--highlight-line DIAGNOSTIC &optional FOREIGN)

Documentation

Attempt to overlay DIAGNOSTIC in current buffer.

FOREIGN says if DIAGNOSTIC is "foreign" to the current buffer, i.e. managed by another buffer where flymake-mode(var)/flymake-mode(fun) is also active.

This function mayskip overlay creation if a diagnostic which is the same as DIAGNOSTIC is already highlighted
(in the sense of flymake--equal-diagnostic-p). In that case
the action to take depends on FOREIGN. If nil the existing overlay is deleted, else no overlay is created.

Return nil or the overlay created.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/flymake.el.gz
(cl-defun flymake--highlight-line (diagnostic &optional foreign)
  "Attempt to overlay DIAGNOSTIC in current buffer.

FOREIGN says if DIAGNOSTIC is \"foreign\" to the current buffer,
i.e. managed by another buffer where `flymake-mode' is also
active.

This function mayskip overlay creation if a diagnostic which is
the same as DIAGNOSTIC is already highlighted
(in the sense of `flymake--equal-diagnostic-p').  In that case
the action to take depends on FOREIGN.  If nil the existing
overlay is deleted, else no overlay is created.

Return nil or the overlay created."
  (let* ((type (or (flymake-diagnostic-type diagnostic)
                   :error))
         (beg (flymake--diag-beg diagnostic))
         (end (flymake--diag-end diagnostic))
         (convert (lambda (cell)
                    (flymake-diag-region (current-buffer)
                                         (car cell)
                                         (cdr cell))))
         ov)
    ;; Convert (LINE . COL) forms of `flymake--diag-beg' and
    ;; `flymake--diag-end'.  Record the converted positions.
    ;;
    (cond ((and (consp beg) (not (null end)))
           (setq beg (car (funcall convert beg)))
           (when (consp end)
             (setq end (car (funcall convert end)))))
          ((consp beg)
           (cl-destructuring-bind (a . b) (funcall convert beg)
             (setq beg a end b))))
    (setf (flymake--diag-beg diagnostic) beg
          (flymake--diag-end diagnostic) end)
    ;; Try to remedy the situation if the same diagnostic is already
    ;; registered in the same place.  This 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
             ;; superseded foreign in an overlay but hide it from most
             ;; `flymake-diagnostics' calls.  If the target buffer is
             ;; killed we can keep the "latent" state of the foreign
             ;; diagnostic (with filename and updated line/col info).
             ;; If it is revisited the foreign diagnostic can be
             ;; revived again.
             do (if foreign
                    (cl-return-from flymake--highlight-line nil)
                  (setf (flymake--diag-beg e)
                        (flymake--diag-orig-beg e)
                        (flymake--diag-end e)
                        (flymake--diag-orig-end e))
                  (flymake--delete-overlay eov)))
    (setq ov (make-overlay beg end))
    (setf (flymake--diag-overlay diagnostic) ov)
    (when (= (overlay-start ov) (overlay-end ov))
      ;; Some backends report diagnostics with invalid bounds.  Don't
      ;; bother.
      (delete-overlay ov)
      (cl-return-from flymake--highlight-line nil))
    (setf (flymake--diag-beg diagnostic) (overlay-start ov)
          (flymake--diag-end diagnostic) (overlay-end ov))
    ;; First set `category' in the overlay
    ;;
    (overlay-put ov 'category
                 (flymake--lookup-type-property type 'flymake-category))
    ;; Now "paint" the overlay with all the other non-category
    ;; properties.
    (cl-loop
     for (ov-prop . value) in
     (append (reverse
              (flymake--diag-overlay-properties diagnostic))
             (reverse ; ensure earlier props override later ones
              (flymake--lookup-type-property type 'flymake-overlay-control))
             (alist-get type flymake-diagnostic-types-alist))
     do (overlay-put ov ov-prop value))
    ;; Now ensure some essential defaults are set
    ;;
    (cl-flet ((default-maybe
                (prop value)
                (unless (plist-member (overlay-properties ov) prop)
                  (overlay-put ov prop (flymake--lookup-type-property
                                        type prop value)))))
      (default-maybe 'face 'flymake-error)
      (default-maybe 'before-string
        (flymake--indicator-overlay-spec
         (flymake--lookup-type-property
          type
          (cond ((eq flymake-indicator-type 'fringes)
                 'flymake-bitmap)
                ((eq flymake-indicator-type 'margins)
                 'flymake-margin-string))
          (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
            (mapconcat
             #'flymake-diagnostic-oneliner
             (flymake-diagnostics pos)
             "\n"))))
      (default-maybe 'severity (warning-numeric-level :error))
      ;; Use (PRIMARY . SECONDARY) priority, to avoid clashing with
      ;; `region' face, for example (bug#34022).
      (default-maybe 'priority (cons nil (+ 40 (overlay-get ov 'severity)))))
    ;; Some properties can't be overridden.
    ;;
    (overlay-put ov 'evaporate t)
    (overlay-put ov 'flymake-overlay t)
    (overlay-put ov 'flymake-diagnostic diagnostic)
    ;; Handle `flymake-show-diagnostics-at-end-of-line'
    ;;
    (when flymake-show-diagnostics-at-end-of-line
      (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-eol-source-overlays))
                        (overlays-in start end)))))
          ;; FIXME: 1. no checking if there are unexpectedly more than
          ;; one eolov at point.
          (if eolov
              (push ov (overlay-get eolov 'flymake-eol-source-overlays))
            (setq eolov (make-overlay start end nil t nil))
            (overlay-put eolov 'flymake-overlay t)
            (overlay-put eolov 'flymake--eol-overlay t)
            (overlay-put eolov 'flymake-eol-source-overlays (list ov))
            (overlay-put eolov 'evaporate (not (= start end)))) ; FIXME: fishy
          (overlay-put ov 'eol-ov eolov))))
    ov))