diff options
-rw-r--r-- | doc/misc/flymake.texi | 150 | ||||
-rw-r--r-- | etc/NEWS | 7 | ||||
-rw-r--r-- | lisp/progmodes/flymake-proc.el | 13 | ||||
-rw-r--r-- | lisp/progmodes/flymake.el | 223 | ||||
-rw-r--r-- | lisp/progmodes/python.el | 7 |
5 files changed, 228 insertions, 172 deletions
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index 9260f4f22ba..e7f4da75bb9 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -275,54 +275,61 @@ The following sections discuss each approach in detail. @cindex customizing error types @cindex error types, customization -@vindex flymake-diagnostic-types-alist -The variable @code{flymake-diagnostic-types-alist} is looked up by -Flymake every time an annotation for a diagnostic is created in the -buffer. Specifically, this variable holds a table of correspondence -between symbols designating diagnostic types and an additional -sub-table of properties pertaining to each diagnostic type. - -Both tables are laid out in association list (@pxref{Association -Lists,,, elisp, The Emacs Lisp Reference Manual}) format, and thus can -be conveniently accessed with the functions of the @code{assoc} -family. - -You can use any symbol-value association in the properties sub-table, -but some symbols have special meaning as to where and how Flymake -presents the diagnostic: +To customize the appearance of error types, set properties on the +symbols associated with each diagnostic type. The standard diagnostic +symbols are @code{:error}, @code{:warning} and @code{:note} (though +the backend may define more, @pxref{Backend functions}). + +The following properties can be set: @itemize @item @cindex bitmap of diagnostic -@code{bitmap}, an image displayed in the fringe according to +@code{flymake-bitmap}, an image displayed in the fringe according to @code{flymake-fringe-indicator-position}. The value actually follows the syntax of @code{flymake-error-bitmap} (@pxref{Customizable variables}). It is overridden by any @code{before-string} overlay property. @item -@cindex severity of diagnostic -@code{severity} is a non-negative integer specifying the diagnostic's -severity. The higher the value, the more serious is the error. If -the overlay property @code{priority} is not specified, @code{severity} -is used to set it and help sort overlapping overlays. +@code{flymake-overlay-control}, an alist ((@var{OVPROP} . @var{VALUE}) +@var{...}) of further properties used to affect the appearance of +Flymake annotations. With the exception of @code{category} and +@code{evaporate}, these properties are applied directly to the created +overlay (@pxref{Overlay Properties,,, elisp, The Emacs Lisp Reference +Manual}). -@item -Every property pertaining to overlays (@pxref{Overlay Properties,,, -elisp, The Emacs Lisp Reference Manual}), except @code{category} and -@code{evaporate}. These properties are used to affect the appearance -of Flymake annotations. +As an example, here's how to make diagnostics of the type @code{:note} +stand out more prominently: -As an example, here's how to make errors (diagnostics of the type -@code{:error}) stand out even more prominently in the buffer, by -raising the characters using a @code{display} overlay property. +@example +(push '(face . highlight) (get :note 'flymake-overlay-control)) +@end example + +If you push another alist entry in front, it overrides the previous +one. So this effectively removes the face from @code{:note} +diagnostics: @example -(push '(display . (raise 1.2)) - (cdr (assoc :error flymake-diagnostic-types-alist))) +(push '(face . nil) (get :note 'flymake-overlay-control)) @end example +To restore the original look for @code{:note} types, empty or remove +its @code{flymake-overlay-control} property: + +@example +(put :note 'flymake-overlay-control '()) +@end example + +@item +@cindex severity of diagnostic +@code{flymake-severity} is a non-negative integer specifying the +diagnostic's severity. The higher the value, the more serious is the +error. If the overlay property @code{priority} is not specified in +@code{flymake-overlay-control}, @code{flymake-severity} is used to set +it and help sort overlapping overlays. + @item @vindex flymake-category @code{flymake-category} is a symbol whose property list is considered @@ -333,32 +340,29 @@ the default for missing values of any other properties. @vindex flymake-error @vindex flymake-warning @vindex flymake-note -Three default diagnostic types, @code{:error}, @code{:warning} and -@code{:note} are predefined in -@code{flymake-diagnostic-types-alist}. By default each lists a single +Three default diagnostic types are predefined: @code{:error}, +@code{:warning}, and @code{:note}. By default, each one of them has a @code{flymake-category} property whose value is, respectively, the -symbols @code{flymake-error}, @code{flymake-warning} and +category symbol @code{flymake-error}, @code{flymake-warning} and @code{flymake-note}. -These category symbols' plists is where the values of customizable -variables and faces such as @code{flymake-error-bitmap} are found. -Thus, if you change their plists, Flymake may stop honoring these -user customizations. +These category symbols' plist is where the values of customizable +variables and faces (such as @code{flymake-error-bitmap}) are found. +Thus, if you change their plists, Flymake may stop honoring these user +customizations. -The @code{flymake-category} special property is also especially useful -for backends which create diagnostics objects with non-default -types that differ from an existing type by only a few properties -(@pxref{Flymake utility functions}). +The @code{flymake-category} special property is especially useful for +backends which create diagnostics objects with non-default types that +differ from an existing type by only a few properties (@pxref{Flymake +utility functions}). As an example, consider configuring a new diagnostic type -@code{:low-priority-note} that behaves much like the @code{:note} -priority but without an overlay face. +@code{:low-priority-note} that behaves much like @code{:note}, but +without an overlay face. @example -(add-to-list - 'flymake-diagnostic-types-alist - `(:low-priority-note . ((face . nil) - (flymake-category . flymake-note)))) +(put :low-priority-note 'flymake-overlay-control '((face . nil))) +(put :low-priority-note 'flymake-category 'flymake-note) @end example @vindex flymake-diagnostics @@ -389,20 +393,17 @@ Internet search for the text of a @code{:warning} or @code{:error}. (eww-browse-url (concat "https://duckduckgo.com/?q=" - (replace-regexp-in-string " " - "+" - (flymake-diagnostic-text topmost-diag))) + (replace-regexp-in-string + " " "+" (flymake-diagnostic-text topmost-diag))) t))) (dolist (type '(:warning :error)) - (let ((a (assoc type flymake-diagnostic-types-alist))) - (setf (cdr a) - (append `((mouse-face . highlight) - (keymap . ,(let ((map (make-sparse-keymap))) - (define-key map [mouse-2] - 'my-search-for-message) - map))) - (cdr a))))) + (push '(mouse-face . highlight) (get type 'flymake-overlay-control)) + (push `(keymap . ,(let ((map (make-sparse-keymap))) + (define-key map [mouse-2] + 'my-search-for-message) + map)) + (get type 'flymake-overlay-control))) @end example @node Backend functions @@ -436,10 +437,10 @@ the first argument is always @var{report-fn}, a callback function detailed below; @item -the remaining arguments are keyword-value pairs of the -form @w{@code{(@var{:key} @var{value} @var{:key2} @var{value2}...)}}. Currently, -Flymake provides no such arguments, but backend functions must be -prepared to accept (and possibly ignore) any number of them. +the remaining arguments are keyword-value pairs of the form +@w{@code{(@var{:key} @var{value} @var{:key2} @var{value2}...)}}. +Currently, Flymake provides no such arguments, but backend functions +must be prepared to accept (and possibly ignore) any number of them. @end itemize Whenever Flymake or the user decide to re-check the buffer, backend @@ -512,9 +513,9 @@ by calling the function @code{flymake-make-diagnostic}. @deffn Function flymake-make-diagnostic buffer beg end type text Make a Flymake diagnostic for @var{buffer}'s region from @var{beg} to -@var{end}. @var{type} is a key to -@code{flymake-diagnostic-types-alist} and @var{text} is a description -of the problem detected in this region. +@var{end}. @var{type} is a diagnostic symbol (@pxref{Flymake error +types}), and @var{text} is a description of the problem detected in +this region. @end deffn @cindex access diagnostic object @@ -715,14 +716,13 @@ Patterns for error/warning messages in the form @code{(regexp file-idx line-idx col-idx err-text-idx)}. @xref{Parsing the output}. @item flymake-proc-diagnostic-type-pred -A function to classify a diagnostic text as particular type of -error. Should be a function taking an error text and returning one of -the symbols indexing @code{flymake-diagnostic-types-alist}. If non-nil -is returned but there is no such symbol in that table, a warning is -assumed. If nil is returned, an error is assumed. Can also be a -regular expression that should match only warnings. This variable -replaces the old @code{flymake-warning-re} and -@code{flymake-warning-predicate}. +A function to classify a diagnostic text as particular type of error. +Should be a function taking an error text and returning a diagnostic +symbol (@pxref{Flymake error types}). If non-nil is returned but +there is no such symbol in that table, a warning is assumed. If nil +is returned, an error is assumed. Can also be a regular expression +that should match only warnings. This variable replaces the old +@code{flymake-warning-re} and @code{flymake-warning-predicate}. @item flymake-proc-compilation-prevents-syntax-check A flag indicating whether compilation and syntax check of the same @@ -176,6 +176,13 @@ interface that's more like functions like @code{search-forward}. It now treats the optional 2nd argument to mean that the URL should be shown in the currently selected window. +** Flymake + ++++ +*** The variable 'flymake-diagnostic-types-alist' is obsolete +You should instead set properties on known diagnostic symbols, like +':error' and ':warning', as demonstrated in the Flymake manual. + ** Package *** New 'package-quickstart' feature When 'package-quickstart' is non-nil, package.el precomputes a big autoloads diff --git a/lisp/progmodes/flymake-proc.el b/lisp/progmodes/flymake-proc.el index e38e4a75d45..8600be9b97c 100644 --- a/lisp/progmodes/flymake-proc.el +++ b/lisp/progmodes/flymake-proc.el @@ -196,11 +196,10 @@ from compile.el") 'flymake-proc-default-guess "Predicate matching against diagnostic text to detect its type. Takes a single argument, the diagnostic's text and should return -a value suitable for indexing -`flymake-diagnostic-types-alist' (which see). If the returned -value is nil, a type of `:error' is assumed. For some backward -compatibility, if a non-nil value is returned that doesn't -index that alist, a type of `:warning' is assumed. +a diagnostic symbol naming a type. If the returned value is nil, +a type of `:error' is assumed. For some backward compatibility, +if a non-nil value is returned that doesn't name a type, +`:warning' is assumed. Instead of a function, it can also be a string, a regular expression. A match indicates `:warning' type, otherwise @@ -516,8 +515,8 @@ Create parent directories as needed." :error)) ((functionp pred) (let ((probe (funcall pred message))) - (cond ((assoc-default probe - flymake-diagnostic-types-alist) + (cond ((and (symbolp probe) + (get probe 'flymake-category)) probe) (probe :warning) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index ec933ad16ba..27bf1bd17a9 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -34,13 +34,77 @@ ;; results produced by these backends, as well as entry points for ;; backends to hook on to. ;; -;; The main entry points are `flymake-mode' and `flymake-start' +;; The main interactive entry point is the `flymake-mode' minor mode, +;; which periodically and automatically initiates checks as the user +;; is editing the buffer. The variables `flymake-no-changes-timeout', +;; `flymake-start-syntax-check-on-newline' and +;; `flymake-start-on-flymake-mode' give finer control over the events +;; triggering a check, as does the interactive command +;; `flymake-start', which immediately starts a check. ;; -;; The docstrings of these variables are relevant to understanding how -;; Flymake works for both the user and the backend programmer: +;; Shortly after each check, a summary of collected diagnostics should +;; appear in the mode-line. If it doesn't, there might not be a +;; suitable Flymake backend for the current buffer's major mode, in +;; which case Flymake will indicate this in the mode-line. The +;; indicator will be `!' (exclamation mark), if all the configured +;; backends errored (or decided to disable themselves) and `?' +;; (question mark) if no backends were even configured. ;; -;; * `flymake-diagnostic-functions' -;; * `flymake-diagnostic-types-alist' +;; For programmers interested in writing a new Flymake backend, the +;; docstring of `flymake-diagnostic-functions', the Flymake manual, +;; and the code of existing backends are probably a good starting +;; point. +;; +;; The user wishing to customize the appearance of error types should +;; set properties on the symbols associated with each diagnostic type. +;; The standard diagnostic symbols are `:error', `:warning' and +;; `:note' (though a specific backend may define and use more). The +;; following properties can be set: +;; +;; * `flymake-bitmap', an image displayed in the fringe according to +;; `flymake-fringe-indicator-position'. The value actually follows +;; the syntax of `flymake-error-bitmap' (which see). It is overridden +;; by any `before-string' overlay property. +;; +;; * `flymake-severity', a non-negative integer specifying the +;; diagnostic's severity. The higher, the more serious. If the +;; overlay property `priority' is not specified, `severity' is used to +;; set it and help sort overlapping overlays. +;; +;; * `flymake-overlay-control', an alist ((OVPROP . VALUE) ...) of +;; further properties used to affect the appearance of Flymake +;; annotations. With the exception of `category' and `evaporate', +;; these properties are applied directly to the created overlay. See +;; Info Node `(elisp)Overlay Properties'. +;; +;; * `flymake-category', a symbol whose property list is considered a +;; default for missing values of any other properties. This is useful +;; to backend authors when creating new diagnostic types that differ +;; from an existing type by only a few properties. The category +;; symbols `flymake-error', `flymake-warning' and `flymake-note' make +;; good candidates for values of this property. +;; +;; For instance, to omit the fringe bitmap displayed for the standard +;; `:note' type, set its `flymake-bitmap' property to nil: +;; +;; (put :note 'flymake-bitmap nil) +;; +;; To change the face for `:note' type, add a `face' entry to its +;; `flymake-overlay-control' property. +;; +;; (push '(face . highlight) (get :note 'flymake-overlay-control)) +;; +;; If you push another alist entry in front, it overrides the previous +;; one. So this effectively removes the face from `:note' +;; diagnostics. +;; +;; (push '(face . nil) (get :note 'flymake-overlay-control)) +;; +;; To erase customizations and go back to the original look for +;; `:note' types: +;; +;; (cl-remf (symbol-plist :note) 'flymake-overlay-control) +;; (cl-remf (symbol-plist :note) 'flymake-bitmap) ;; ;;; Code: @@ -232,10 +296,9 @@ generated it." text &optional data) "Make a Flymake diagnostic for BUFFER's region from BEG to END. -TYPE is a key to `flymake-diagnostic-types-alist' and TEXT is a -description of the problem detected in this region. DATA is any -object that the caller wishes to attach to the created diagnostic -for later retrieval." +TYPE is a key to symbol and TEXT is a description of the problem +detected in this region. DATA is any object that the caller +wishes to attach to the created diagnostic for later retrieval." (flymake--diag-make :buffer buffer :beg beg :end end :type type :text text :data data)) @@ -426,74 +489,56 @@ Currently accepted REPORT-KEY arguments are: (put 'flymake-diagnostic-functions 'safe-local-variable #'null) -(defvar flymake-diagnostic-types-alist - `((:error - . ((flymake-category . flymake-error))) - (:warning - . ((flymake-category . flymake-warning))) - (:note - . ((flymake-category . flymake-note)))) - "Alist ((KEY . PROPS)*) of properties of Flymake diagnostic types. -KEY designates a kind of diagnostic can be anything passed as -`:type' to `flymake-make-diagnostic'. - -PROPS is an alist of properties that are applied, in order, to -the diagnostics of the type designated by KEY. The recognized -properties are: - -* Every property pertaining to overlays, except `category' and - `evaporate' (see Info Node `(elisp)Overlay Properties'), used - to affect the appearance of Flymake annotations. - -* `bitmap', an image displayed in the fringe according to - `flymake-fringe-indicator-position'. The value actually - follows the syntax of `flymake-error-bitmap' (which see). It - is overridden by any `before-string' overlay property. - -* `severity', a non-negative integer specifying the diagnostic's - severity. The higher, the more serious. If the overlay - property `priority' is not specified, `severity' is used to set - it and help sort overlapping overlays. - -* `flymake-category', a symbol whose property list is considered - a default for missing values of any other properties. This is - useful to backend authors when creating new diagnostic types - that differ from an existing type by only a few properties.") +(put :error 'flymake-category 'flymake-error) +(put :warning 'flymake-category 'flymake-warning) +(put :note 'flymake-category 'flymake-note) + +(defvar flymake-diagnostic-types-alist `() "") +(make-obsolete-variable + 'flymake-diagnostic-types-alist + "Set properties on the diagnostic symbols instead. See Info +Node `(Flymake)Flymake error types'" + "27.1") (put 'flymake-error 'face 'flymake-error) -(put 'flymake-error 'bitmap 'flymake-error-bitmap) +(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-warning 'face 'flymake-warning) -(put 'flymake-warning 'bitmap 'flymake-warning-bitmap) +(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-note 'face 'flymake-note) -(put 'flymake-note 'bitmap 'flymake-note-bitmap) +(put 'flymake-note 'flymake-bitmap 'flymake-note-bitmap) (put 'flymake-note 'severity (warning-numeric-level :debug)) (put 'flymake-note 'mode-line-face 'compilation-info) (defun flymake--lookup-type-property (type prop &optional default) - "Look up PROP for TYPE in `flymake-diagnostic-types-alist'. -If TYPE doesn't declare PROP in either -`flymake-diagnostic-types-alist' or in the symbol of its + "Look up PROP for diagnostic TYPE. +If TYPE doesn't declare PROP in its plist or in the symbol of its associated `flymake-category' return DEFAULT." - (let ((alist-probe (assoc type flymake-diagnostic-types-alist))) - (cond (alist-probe - (let* ((alist (cdr alist-probe)) - (prop-probe (assoc prop alist))) - (if prop-probe - (cdr prop-probe) - (if-let* ((cat (assoc-default 'flymake-category alist)) - (plist (and (symbolp cat) - (symbol-plist cat))) - (cat-probe (plist-member plist prop))) - (cadr cat-probe) - default)))) - (t - default)))) + ;; This function also consults `flymake-diagnostic-types-alist' for + ;; backward compatibility. + ;; + (if (plist-member (symbol-plist type) prop) + ;; allow nil values to survive + (get type prop) + (let (alist) + (or + (alist-get + prop (setq + alist + (alist-get type flymake-diagnostic-types-alist))) + (when-let* ((cat (or + (get type 'flymake-category) + (alist-get 'flymake-category alist))) + (plist (and (symbolp cat) + (symbol-plist cat))) + (cat-probe (plist-member plist prop))) + (cadr cat-probe)) + default)))) (defun flymake--fringe-overlay-spec (bitmap &optional recursed) (if (and (symbolp bitmap) @@ -510,34 +555,38 @@ associated `flymake-category' return DEFAULT." (list bitmap))))))) (defun flymake--highlight-line (diagnostic) - "Highlight buffer with info in DIAGNOSTIC." - (when-let* ((ov (make-overlay + "Highlight buffer with info in DIGNOSTIC." + (when-let* ((type (flymake--diag-type diagnostic)) + (ov (make-overlay (flymake--diag-beg diagnostic) (flymake--diag-end diagnostic)))) - ;; First set `category' in the overlay, then copy over every other - ;; property. + ;; First set `category' in the overlay ;; - (let ((alist (assoc-default (flymake--diag-type diagnostic) - flymake-diagnostic-types-alist))) - (overlay-put ov 'category (assoc-default 'flymake-category alist)) - (cl-loop for (k . v) in alist - unless (eq k 'category) - do (overlay-put ov k v))) + (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 ; ensure ealier 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 (or (plist-member (overlay-properties ov) prop) - (let ((cat (overlay-get ov - 'flymake-category))) - (and cat - (plist-member (symbol-plist cat) prop)))) - (overlay-put ov prop value)))) - (default-maybe 'bitmap 'flymake-error-bitmap) + (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--fringe-overlay-spec - (overlay-get ov 'bitmap))) + (flymake--lookup-type-property + type + 'flymake-bitmap + (alist-get 'bitmap (alist-get type ; backward compat + flymake-diagnostic-types-alist))))) (default-maybe 'help-echo (lambda (window _ov pos) (with-selected-window window @@ -825,7 +874,9 @@ The commands `flymake-goto-next-error' and diagnostics annotated in the buffer. The visual appearance of each type of diagnostic can be changed -in the variable `flymake-diagnostic-types-alist'. +by setting properties `flymake-overlay-control', `flymake-bitmap' +and `flymake-severity' on the symbols of diagnostic types (like +`:error', `:warning' and `:note'). Activation or deactivation of backends used by Flymake in each buffer happens via the special hook @@ -929,9 +980,8 @@ arg, skip any diagnostics with a severity less than `:warning'. If `flymake-wrap-around' is non-nil and no more next diagnostics, resumes search from top. -FILTER is a list of diagnostic types found in -`flymake-diagnostic-types-alist', or nil, if no filter is to be -applied." +FILTER is a list of diagnostic types, or nil, if no filter is to +be applied." ;; TODO: let filter be a number, a severity below which diags are ;; skipped. (interactive (list 1 @@ -985,9 +1035,8 @@ prefix arg, skip any diagnostics with a severity less than If `flymake-wrap-around' is non-nil and no more previous diagnostics, resumes search from bottom. -FILTER is a list of diagnostic types found in -`flymake-diagnostic-types-alist', or nil, if no filter is to be -applied." +FILTER is a list of diagnostic types found in, or nil, if no +filter is to be applied." (interactive (list 1 (if current-prefix-arg '(:error :warning)) t)) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index a09ca2f2f29..6f4a343310c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -5209,9 +5209,10 @@ be used." (defcustom python-flymake-msg-alist '(("\\(^redefinition\\|.*unused.*\\|used$\\)" . :warning)) "Alist used to associate messages to their types. -Each element should be a cons-cell (REGEXP . TYPE), where TYPE must be -one defined in the variable `flymake-diagnostic-types-alist'. -For example, when using `flake8' a possible configuration could be: +Each element should be a cons-cell (REGEXP . TYPE), where TYPE +should be a diagnostic type symbol like `:error', `:warning' or +`:note'. For example, when using `flake8' a possible +configuration could be: ((\"\\(^redefinition\\|.*unused.*\\|used$\\)\" . :warning) (\"^E999\" . :error) |