├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── README.org └── consult-flycheck.el /.gitignore: -------------------------------------------------------------------------------- 1 | *-autoloads.el 2 | *-pkg.el 3 | *.elc 4 | *.info 5 | *.texi 6 | *~ 7 | \#*\# 8 | /README-elpa 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 3 | name: 🐞 Bug report 4 | about: Report a bug. Do not use this for questions, support or feature requests. 5 | --- 6 | Thank you for reporting a bug. 7 | 8 | Please use the latest stable release of Emacs 30.1 and start with `emacs -Q` or 9 | `package-isolate` in order to only load a minimal set of packages. This way your 10 | Emacs configuration is not loaded. 11 | 12 | Make sure that you install the newest versions of the involved packages. Please 13 | also reinstall and recompile the involved packages, ideally remove all and 14 | reinstall all packages, to exclude compilation issues due to outdated 15 | dependencies. 16 | 17 | Please provide precise information, stack traces and the exact steps to 18 | reproduce the issue. This is important to ensure that your problem can be 19 | reproduced on a different machine. 20 | 21 | If you are not really sure if your issue is a bug, please open a discussion 22 | instead. 23 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+title: consult-flycheck.el - Consult integration for Flycheck 2 | #+author: Daniel Mendler 3 | #+language: en 4 | 5 | #+html: GNU Emacs 6 | #+html: NonGNU ELPA 7 | #+html: NonGNU-devel ELPA 8 | #+html: MELPA 9 | #+html: MELPA Stable 10 | 11 | This package provides the =consult-flycheck= command, which integrates [[https://github.com/minad/consult][Consult]] 12 | with [[https://github.com/flycheck/flycheck][Flycheck]]. Take a look at the [[https://github.com/minad/consult/blob/main/README.org][Consult README]] for an extensive documentation. 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: "🙏 Please support my work on Consult and my other Emacs projects" 4 | url: https://github.com/sponsors/minad 5 | about: Thanks! Your support helps dedicating time to project maintenance and development. 6 | - name: "💡 Suggest a feature ➞ Please create a discussion" 7 | url: https://github.com/minad/consult/discussions/categories/ideas 8 | about: Start a new discussion suggesting an improvement or a feature. 9 | - name: "🧑‍🤝‍🧑 Ask the community for support" 10 | url: https://www.reddit.com/r/emacs 11 | about: Please be kind and support others. 12 | - name: "🤓 Ask the maintainer for support ➞ Please create a discussion" 13 | url: https://github.com/minad/consult/discussions/categories/q-a 14 | about: Please keep in mind that my bandwidth is limited. 15 | - name: "🔍 Search through old issues or discussions" 16 | url: https://github.com/search?q=repo%3Aminad%2Fconsult&type=issues 17 | about: The same question may have been asked before. 18 | - name: "📝 Consult wiki" 19 | url: https://github.com/minad/consult/wiki 20 | about: Additional configuration tips are covered there. Feel free to edit! 21 | - name: "📖 Consult manual" 22 | url: https://github.com/minad/consult/blob/main/README.org 23 | about: The manual covers the basic setup and workflow. 24 | -------------------------------------------------------------------------------- /consult-flycheck.el: -------------------------------------------------------------------------------- 1 | ;;; consult-flycheck.el --- Provides the command `consult-flycheck' -*- lexical-binding: t -*- 2 | 3 | ;; Copyright (C) 2021-2025 Daniel Mendler 4 | 5 | ;; Author: Daniel Mendler and Consult contributors 6 | ;; Maintainer: Daniel Mendler 7 | ;; Created: 2020 8 | ;; Version: 1.0 9 | ;; Package-Requires: ((emacs "29.1") (consult "2.8") (flycheck "35")) 10 | ;; URL: https://github.com/minad/consult-flycheck 11 | ;; Keywords: languages, tools, completion 12 | 13 | ;; This file is not part of GNU Emacs. 14 | 15 | ;; This program is free software: you can redistribute it and/or modify 16 | ;; it under the terms of the GNU General Public License as published by 17 | ;; the Free Software Foundation, either version 3 of the License, or 18 | ;; (at your option) any later version. 19 | 20 | ;; This program is distributed in the hope that it will be useful, 21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | ;; GNU General Public License for more details. 24 | 25 | ;; You should have received a copy of the GNU General Public License 26 | ;; along with this program. If not, see . 27 | 28 | ;;; Commentary: 29 | 30 | ;; Provides the command `consult-flycheck'. This is an extra package, 31 | ;; since the consult.el package only depends on Emacs core components. 32 | 33 | ;;; Code: 34 | 35 | (require 'consult) 36 | (require 'flycheck) 37 | 38 | (defconst consult-flycheck--narrow 39 | '((?e . "Error") 40 | (?w . "Warning") 41 | (?i . "Info"))) 42 | 43 | (defun consult-flycheck--sort-predicate (x y) 44 | "Compare X and Y by filename, severity, then by location. 45 | In contrast to `flycheck-error-level-<' sort errors first." 46 | (let* ((lx (flycheck-error-level x)) 47 | (ly (flycheck-error-level y)) 48 | (sx (flycheck-error-level-severity lx)) 49 | (sy (flycheck-error-level-severity ly)) 50 | (fx (if-let ((file (flycheck-error-filename x))) 51 | (file-name-nondirectory file) 52 | (buffer-name (flycheck-error-buffer x)))) 53 | (fy (if-let ((file (flycheck-error-filename y))) 54 | (file-name-nondirectory file) 55 | (buffer-name (flycheck-error-buffer y))))) 56 | (if (string= fx fy) 57 | (if (= sx sy) 58 | (if (string= lx ly) 59 | (flycheck-error-< x y) 60 | (string< lx ly)) 61 | (> sx sy)) 62 | (string< fx fy)))) 63 | 64 | (defun consult-flycheck--candidates () 65 | "Return flycheck errors as alist." 66 | (consult--forbid-minibuffer) 67 | (unless flycheck-current-errors 68 | (user-error "No flycheck errors (Status: %s)" flycheck-last-status-change)) 69 | (let* ((errors (mapcar 70 | (lambda (err) 71 | (list 72 | (if-let (file (flycheck-error-filename err)) 73 | (file-name-nondirectory file) 74 | (buffer-name (flycheck-error-buffer err))) 75 | (number-to-string (flycheck-error-line err)) 76 | (symbol-name (flycheck-error-level err)) 77 | err)) 78 | (seq-sort #'consult-flycheck--sort-predicate flycheck-current-errors))) 79 | (file-width (apply #'max (mapcar (lambda (x) (length (car x))) errors))) 80 | (line-width (apply #'max (mapcar (lambda (x) (length (cadr x))) errors))) 81 | (level-width (apply #'max (mapcar (lambda (x) (length (caddr x))) errors))) 82 | (fmt (format "%%%ds %%%ds %%-%ds\t%%s\t(%%s)" file-width line-width level-width))) 83 | (mapcar 84 | (pcase-lambda (`(,file ,line ,level-name ,err)) 85 | (let* ((level (flycheck-error-level err)) 86 | (filename (flycheck-error-filename err)) 87 | (err-copy (copy-flycheck-error err)) 88 | (buffer (if filename 89 | (find-file-noselect filename 'nowarn) 90 | (flycheck-error-buffer err)))) 91 | (when (buffer-live-p buffer) 92 | ;; Update buffer in case the source of the error resides in 93 | ;; a different file from where it was detected (i.e., the 94 | ;; filename field of the error is different than the 95 | ;; buffer). 96 | (setf (flycheck-error-buffer err-copy) buffer)) 97 | (propertize 98 | (format fmt 99 | (propertize file 'face 'flycheck-error-list-filename) 100 | (propertize line 'face 'flycheck-error-list-line-number) 101 | (propertize level-name 'face (flycheck-error-level-error-list-face level)) 102 | (propertize (subst-char-in-string ?\n ?\s 103 | (flycheck-error-message err)) 104 | 'face 'flycheck-error-list-error-message) 105 | (propertize (symbol-name (flycheck-error-checker err)) 106 | 'face 'flycheck-error-list-checker-name)) 107 | 'consult--candidate 108 | (let* ((range (flycheck-error-region-for-mode 109 | err-copy 110 | (or flycheck-highlighting-mode 'lines))) 111 | (beg (car range)) 112 | (end (cdr range))) 113 | (list (set-marker (make-marker) beg buffer) 114 | (cons 0 (- end beg)))) 115 | 'consult--type 116 | (pcase level-name 117 | ((rx (and (0+ nonl) 118 | "error" 119 | (0+ nonl))) 120 | ?e) 121 | ((rx (and (0+ nonl) 122 | "warning" 123 | (0+ nonl))) 124 | ?w) 125 | (_ ?i))))) 126 | errors))) 127 | 128 | ;;;###autoload 129 | (defun consult-flycheck () 130 | "Jump to flycheck error." 131 | (interactive) 132 | (consult--read 133 | (consult--with-increased-gc (consult-flycheck--candidates)) 134 | :prompt "Flycheck error: " 135 | :category 'consult-flycheck-error 136 | :history t ;; disable history 137 | :require-match t 138 | :sort nil 139 | :group (consult--type-group consult-flycheck--narrow) 140 | :narrow (consult--type-narrow consult-flycheck--narrow) 141 | :lookup #'consult--lookup-candidate 142 | :state (consult--jump-state))) 143 | 144 | (provide 'consult-flycheck) 145 | ;;; consult-flycheck.el ends here 146 | --------------------------------------------------------------------------------