flymake-collection icon indicating copy to clipboard operation
flymake-collection copied to clipboard

Collection of checkers for flymake

#+TITLE: flymake-collection #+AUTHOR: Mohsin Kaleem

#+html:

#+html: #+html: #+html: MELPA #+html:

~flymake-collection~ tries to provide a comprehensive list of diagnostic-functions for use with flymake, give users the tools to easily define new syntax checkers and help selectively enable or disable diagnostic-functions based on major-modes.

The goal of this project is to make the transition from flycheck to flymake as easy as possible, and to act as a catching ground for all the checkers that don't already have a flymake backend available.

  • Table of Contents :TOC:
  • [[#installation][Installation]]
    • [[#manually][Manually]]
    • [[#from-melpa][From MELPA]]
    • [[#configurations][Configurations]]
  • [[#contributing][Contributing]]
  • [[#related-packages][Related Packages]]
    • [[#flymake-flycheck][flymake-flycheck]]
    • [[#flymake-quickdef][flymake-quickdef]]
    • [[#flymake-proselint-flymake-shellcheck-etc][flymake-proselint, flymake-shellcheck, etc.]]
  • [[#appendix][Appendix]]
  • Installation ** Manually
    1. Clone the repo
    2. Add the cloned repo path and the ~checkers~ sub-directory to the load path.
    3. Configure the package to your liking.

** From MELPA This package is on [[https://github.com/melpa/melpa][MELPA]]. You can add this to your ~package-archives~ variable and then install through ~M-x package-install~.

#+begin_src emacs-lisp (push '("melpa" . "https://melpa.org/packages/") package-archives) (package-refresh-contents) (package-install 'flymake-collection) #+end_src

** Configurations *** Enabling Diagnostic Functions This package comes with several diagnostic-functions out of the box, these can be used by simply hooking them into ~flymake-diagnostic-functions~ for whatever buffer you've enabled flymake in.

For example
#+begin_src emacs-lisp
  (add-hook 'python-mode-hook
            (defun python-mode-setup-flymake ()
              (add-hook 'flymake-diagnostic-functions 'flymake-collection-pycodestyle nil t)
              (flymake-mode +1)))
#+end_src

For a list of supported syntax-checkers see [[file:src/checkers/][./src/checkers/]]. All of the defined
checkers are auto-loaded and have no other dependencies than ~flymake-collection~
so once you've installed and compiled ~flymake-collection~ you can hook them into
~flymake-diagnostic-functions~ without any extra configuration or loading being
needed.

*** Associating Checkers with Major Modes ~flymake-collection~ provides a special configuration variable to let you associate diagnostic functions with major-modes. This can be useful both for automatically enabling diagnostic functions and for interactively toggling them based on your configuration.

The ~flymake-collection-config~ config variable is an alist with the ~key~ being the
major-mode and the ~cdr~ being the list of diagnostic functions for that mode.
Each diagnostic function can be defined as the function symbol, or an alist with
the ~car~ of the symbol being the function symbol and the ~cdr~ being a plist of
options for that function.
Currently the supported options include ~:depth~ for the ~DEPTH~ property passed to
~add-hook~, a predicate function which is called to determine whether to enable
this diagnostic-function and a boolean field ~:disabled~ to indicate whether or not
this checker shouldn't be added to ~flymake-diagnostic-functions~.

Here is an example configuration for python-mode:
#+begin_src emacs-lisp
  (push
   '(python-mode
     flymake-collection-mypy                      ; Always added to diagnostic functions.
     (flymake-collection-pycodestyle :disabled t) ; Never added.
     (flymake-collection-pylint                   ; Added when predicate is true.
      :predicate (lambda ()
                   (executable-find "pylint"))))
   flymake-collection-config)
#+end_src

*Note*: The ~executable-find~ predicate example here is redundant, each checker will
already make sure any dependent executables are installed before being run.

Lastly there's also a ~use-package~ keyword you can use to define config
entries. This is just syntax sugar over pushing these values into
~flymake-collection-config~ as shown above.

#+begin_src emacs-lisp
  (use-package python-mode
    :flymake-hook
    (python-mode
     flymake-collection-mypy                      ; Always added to diagnostic functions.
     (flymake-collection-pycodestyle :disabled t) ; Never added.
     (flymake-collection-pylint                   ; Added when predicate is true.
      :predicate (lambda ()
                   (executable-find "pylint"))))))
#+end_src

**** Automatically Enabling Syntax Checkers To automatically enable diagnostic functions based on ~flymake-collection-config~ you have to call the ~flymake-collection-hook-setup~ function. This can be done through ~use-package~, for example: #+begin_src emacs-lisp (use-package flymake-collection :hook (after-init . flymake-collection-hook-setup)) #+end_src

 You can also interactively enable or disable a diagnostic-function from
 ~flymake-collection-config~ using the ~flymake-collection-change-checker~ command.
  • Contributing Please do!. There are more checkers out there than I have the time to explore, if you'd like to add support for a new checker or contribute improvements to an existing one, we'd be more than happy to accept.

    Tests can be found in [[file:tests/checkers/]]. The [[file:tests/checkers/installers/][installers]] directory is where bash scripts are setup to install the checker on ~ubuntu:20.04~. Actual [[file:tests/checkers/test-cases/][test-cases]] are declarative YAML configurations that run a given checker function on a given file with the latest version of flymake and your local ~flymake-collection~ repository and then examines the results. See [[file:tests/checkers/test-cases/pylint.yml][pylint.yml]] for an example. Please supply installer and test-cases for any contributed checkers as well.

    To run locally you can use the supplied Makefile with ~make lint~ compiling all your local elisp files and ~make test~ running the test-cases within docker. If you do not have docker setup the CI/CD pipeline on this repo will automatically lint and test when you open a PR.

  • Related Packages ** [[https://github.com/purcell/flymake-flycheck][flymake-flycheck]] Provides a bridge between flymake and flycheck. It allows you to use all of the checker functions already exposed through flycheck with flymake. This would be useful if you're intent on using both flycheck and flymake or need to use flymake but require a checker that's only available with flycheck.

    ~flymake-collection~ doesn't bridge flycheck and flymake, it re-implements several flycheck checkers as flymake compatible ones. It also provides helpers to allow defining checkers as easily as flycheck does (for example flymake-collection provides a parallel to the convenient ~:error-patterns~ option of ~flycheck-define-checker~). In the end ~flymake-collection~ has no dependency on flycheck where as ~flymake-flycheck~ does.

** [[https://github.com/karlotness/flymake-quickdef][flymake-quickdef]] This was the initial package I adapted into ~flymake-collection-define~ because I needed extra functionality for pylint. It provides a helper macro to define backend functions for various checkers. If you prefer a more fine grained configuration or just need a standalone checker for your own use-cases it may be easier to define one using this instead of installing ~flymake-collection~.

Note: All the features of ~flymake-quickdef~ (as of version 1.0.0) is also supported by ~flymake-collection~. We also support some extra features such as linting a file in the same directory as an existing file.

** [[https://git.sr.ht/~manuel-uberti/flycheck-proselint][flymake-proselint]], [[https://github.com/federicotdn/flymake-shellcheck][flymake-shellcheck]], etc. These packages provide standalone backend functions for specific checkers. This lets you have a more modular, /what-you-need is what-you-install/ setup where you only install flymake backends for the checkers you actually intend to use. If you believe ~flymake-collection~ to be too large for your liking I'd recommend deferring to one of these existing packages.

~flymake-collection~ exists because I didn't want to have to setup and configure all of these different backends for all the languages I use. If you'd prefer to install one package and have linting work across a /collection/ of different languages and possible checkers then ~flymake-collection~ may be more what you're looking for.

  • Appendix :ARCHIVE:

LocalWords: flymake linter flycheck

Local Variables:

eval: (toc-org-mode 1)

End: