| @ -0,0 +1,6 @@ | |||
| # -*- mode: conf; -*- | |||
| [flake8] | |||
| # Ignore all missing docstrings for now, until we have docstrings everywhere | |||
| ignore = D100,D101,D102,D103,D105,D401,W503 | |||
| exclude = test/resources | |||
| inline-quotes = ' | |||
| @ -0,0 +1,7 @@ | |||
| I, the contributor, agree to licence my contributions to the Flycheck project | |||
| under the terms of the [GPL 3.0][1] and any later version, and to license my | |||
| contributions to the documentation of the Flycheck project under the terms of | |||
| the [Creative Commons Attribution-ShareAlike 4.0 International][2] license. | |||
| [1]: http://www.flycheck.org/en/latest/licenses.html#flycheck-gpl | |||
| [2]: http://www.flycheck.org/en/latest/licenses.html#flycheck-cc-by-sa | |||
| @ -0,0 +1,14 @@ | |||
| =========== | |||
| Thank you | |||
| =========== | |||
| Thank you very much for your interest in contributing to Flycheck! We’d like to | |||
| warmly welcome you in the Flycheck community, and hope that you enjoy your time | |||
| with us! | |||
| Flycheck’s documentation provides a comprehensive Contributor Guide which shows | |||
| how you can contribute to Flycheck and helps you through all stages of the | |||
| contribution process. | |||
| Please read it at | |||
| <http://www.flycheck.org/en/latest/contributor/contributing.html>. | |||
| @ -0,0 +1,47 @@ | |||
| --- | |||
| name: Bug report | |||
| about: Report an unexpected Flycheck behavior | |||
| title: '' | |||
| labels: 'kind: bug' | |||
| assignees: '' | |||
| --- | |||
| Thank you for taking the time to report an issue and improve Flycheck. This template is for **actual bugs you observed**. If you have trouble setting up Flycheck, or if you have a question, please use the relevant issue template instead. | |||
| ## Checklist | |||
| - [ ] I have checked existing issues for potential duplicates before creating this one. | |||
| - [ ] I have read the [Troubleshooting guide][]. | |||
| ## Bug description | |||
| A clear and concise description of what the bug is. | |||
| ## Steps to reproduce | |||
| Steps to reproduce the behavior: | |||
| 1. Open file '...' | |||
| 2. Do '....' | |||
| 3. See error | |||
| - [ ] I have read https://emacs.stackexchange.com/questions/28429/how-do-i-troubleshoot-emacs-problems | |||
| ## Expected behavior | |||
| A clear and concise description of what you expected to happen. | |||
| ## Screenshots | |||
| If applicable, add screenshots to help explain your problem. | |||
| ## System configuration | |||
| ``` | |||
| Paste the output of `M-x flycheck-verify-setup` here. | |||
| ``` | |||
| Emacs configuration: | |||
| - [ ] Plain Emacs / Custom configuration | |||
| - [ ] Spacemacs | |||
| - [ ] Doom Emacs | |||
| - [ ] Other shared configuration | |||
| ## Additional notes | |||
| Add any other context about the problem here. | |||
| [Troubleshooting guide]: https://www.flycheck.org/en/latest/user/troubleshooting.html | |||
| @ -0,0 +1,22 @@ | |||
| --- | |||
| name: Feature request | |||
| about: Suggest an improvement to Flycheck | |||
| title: '' | |||
| labels: 'kind: feature request' | |||
| assignees: '' | |||
| --- | |||
| Thank you for taking the time to improve Flycheck. | |||
| ## Checklist | |||
| - [ ] I have checked existing issues for potential duplicates before creating this one. | |||
| ## Feature description | |||
| A clear and concise description of what you want Flycheck to do. | |||
| ## Describe alternatives you've considered | |||
| A clear and concise description of any alternative solutions or features you've considered. | |||
| ## Additional context | |||
| Add any other context or screenshots, mockups etc. | |||
| @ -0,0 +1,50 @@ | |||
| --- | |||
| name: User support | |||
| about: Trouble setting up or using Flycheck? | |||
| title: '' | |||
| labels: 'kind: user support' | |||
| assignees: '' | |||
| --- | |||
| This template is for **user support**. If you are reporting an actual Flycheck bug, please use the relevant issue template instead. | |||
| ## Checklist | |||
| - [ ] I have searched existing issues and StackOverflow for solutions. | |||
| - [ ] I have read the [Flycheck manual][]. | |||
| - [ ] I have read the [Troubleshooting Guide][]. | |||
| - [ ] I have checked my issue has not been reported yet. | |||
| ## Problem description | |||
| A clear and concise description of the problem you encounter. | |||
| ## Steps to reproduce | |||
| Steps to reproduce the behavior: | |||
| 1. Open file '...' | |||
| 2. Do '....' | |||
| 3. See error | |||
| - [ ] I have read https://emacs.stackexchange.com/questions/28429/how-do-i-troubleshoot-emacs-problems | |||
| ## Expected behavior | |||
| A clear and concise description of what you expected to happen. | |||
| ## Screenshots | |||
| If applicable, add screenshots to help explain your problem. | |||
| ## System configuration | |||
| ``` | |||
| Paste the output of `M-x flycheck-verify-setup` here. | |||
| ``` | |||
| Emacs configuration: | |||
| - [ ] Plain Emacs / Custom configuration | |||
| - [ ] Spacemacs | |||
| - [ ] Doom Emacs | |||
| - [ ] Other shared configuration | |||
| ## Additional notes | |||
| Add any other context about the problem here. | |||
| [Flycheck manual]: https://www.flycheck.org/en/latest/user/troubleshooting.html | |||
| [Troubleshooting guide]: https://www.flycheck.org/en/latest/user/troubleshooting.html | |||
| @ -0,0 +1,28 @@ | |||
| --- | |||
| name: New checker | |||
| about: Provide a new checker implementation | |||
| title: 'Add syntax checker for XXX' | |||
| labels: 'component: checkers' | |||
| assignees: '' | |||
| --- | |||
| ## Checklist | |||
| - [ ] I have read the [Contributor's guide][]. | |||
| - [ ] I have documented this checker in the [manual][]. | |||
| - [ ] I have added a test for this checker in [flycheck-test.el][]. | |||
| - [ ] (*If you have written a test*) I have created a companion PR to add the | |||
| checker tool in [flycheck/docker-tools][]. | |||
| - [ ] I have mentioned the checker in the [Changelog][]. | |||
| ## Description | |||
| Describe the checker you added. | |||
| ## Additional context | |||
| Additional relevant information about the checker and its integration into Flycheck. | |||
| [Changelog]: https://github.com/flycheck/flycheck/blob/master/CHANGES.rst | |||
| [manual]: https://www.flycheck.org/en/latest/languages.html | |||
| [flycheck-test.el]: https://github.com/flycheck/flycheck/blob/master/test/flycheck-test.el | |||
| [flycheck/docker-tools]: https://github.com/flycheck/docker-tools | |||
| [Contributor's guide]: https://www.flycheck.org/en/latest/contributor/contributing.html | |||
| @ -0,0 +1,14 @@ | |||
| *.elc | |||
| # Packages installed for development | |||
| /.cask/ | |||
| # Bundler configuration and lock file | |||
| /.bundle/ | |||
| /Gemfile.lock | |||
| # Generated distribution packages | |||
| /dist/ | |||
| # Directory local variables | |||
| .dir-locals.el | |||
| @ -0,0 +1,32 @@ | |||
| # -*- mode: conf; -*- | |||
| Biao Xie <423300@gmail.com> | |||
| Bozhidar Batsov <bozhidar@batsov.com> <bozhidar@tradeo.com> | |||
| Chao SHEN <scturtle@gmail.com> | |||
| Cristian Capdevila <capdevc@defvar.org> | |||
| Manuel Uberti <manuel@boccaperta.com> | |||
| Manuel Uberti <manuel@boccaperta.com> <manuel-uberti@users.noreply.github.com> | |||
| Mark Hellewell <mark.hellewell@icloud.com> | |||
| Mark Karpov <markkarpov@opmbx.org> | |||
| Peter Vasil <mail@petervasil.net> | |||
| Romanos Skiadas <rski@users.noreply.github.com> | |||
| # Looks as if there's different unicode normalisations for this name | |||
| Saša Jovanić <sasa@simplify.ba> | |||
| Sean Whitton <spwhitton@spwhitton.name> <spwhitton@users.noreply.github.com> | |||
| Sebastian Schueppel <s3bs@users.noreply.github.com> | |||
| Sebastian Wiesner <swiesner@lunaryorn.com> <lunaryorn@gmail.com> | |||
| Sebastian Wiesner <swiesner@lunaryorn.com> <me@lunaryorn.com> | |||
| Senda Akiha <senda.akiha@gmail.com> | |||
| Steve Purcell <steve@sanityinc.com> <steve.purcell@powershop.co.nz> | |||
| Sylvain Benner <sylvain.benner@gmail.com> | |||
| Sylvain Rousseau <thisirs@gmail.com> | |||
| Vlatko Basic <vlatko.basic@gmail.com> | |||
| Yuuki Arisawa <yuuki.ari@gmail.com> | |||
| Zhuo Yuan <yzprofiles@gmail.com> | |||
| # These contributors prefer to remain anonymous | |||
| fmdkdd <fmdkdd@gmail.com> | |||
| # The real names of these contributors are unknown | |||
| papaeye <papaeye@gmail.com> | |||
| chessman <evgeniy.a@livetex.ru> | |||
| @ -0,0 +1,96 @@ | |||
| # Use Python 3.5 for our tooling | |||
| language: python | |||
| python: | |||
| - "3.8" | |||
| # Our tests are run with Emacs in Docker | |||
| services: | |||
| - docker | |||
| matrix: | |||
| # Don’t wait for jobs that are allowed to fail | |||
| fast_finish: true | |||
| # Allow master branch to fail | |||
| allow_failures: | |||
| - env: JOB="emacs" EMACS_VERSION="master" | |||
| cache: | |||
| - pip | |||
| env: | |||
| matrix: | |||
| # Run our tests on all these Emacs versions | |||
| - JOB="emacs" EMACS_VERSION="master" | |||
| - JOB="emacs" EMACS_VERSION="27.1" | |||
| - JOB="emacs" EMACS_VERSION="26.3" | |||
| - JOB="emacs" EMACS_VERSION="25.3" | |||
| # A special job to build the manual | |||
| - JOB="build-manual" | |||
| # And another special job to lint our Python code | |||
| - JOB="lint-python" | |||
| before_install: | |||
| - if [[ $JOB == emacs ]]; then docker pull flycheck/emacs-cask:$EMACS_VERSION; fi | |||
| install: | |||
| - | | |||
| case $JOB in | |||
| emacs) | |||
| # We use separate Cask files for Emacs 25 | |||
| if [[ $EMACS_VERSION == 25.* ]]; then | |||
| cp Cask.25 Cask | |||
| fi | |||
| # Install Emacs modes for our tests | |||
| docker run --volume "$TRAVIS_BUILD_DIR":/flycheck \ | |||
| --workdir /flycheck \ | |||
| flycheck/emacs-cask:$EMACS_VERSION \ | |||
| /bin/bash -c "make init";; | |||
| build-manual) | |||
| # Install requirements of documentation | |||
| pip install -r doc/requirements.txt;; | |||
| lint-python) | |||
| # Install requirements for linting | |||
| pip install -r maint/requirements.txt;; | |||
| esac | |||
| script: | |||
| - | | |||
| # Abort if any command fails | |||
| set -e | |||
| case $JOB in | |||
| emacs) | |||
| # Check formatting | |||
| docker run --volume "$TRAVIS_BUILD_DIR":/flycheck \ | |||
| --workdir /flycheck \ | |||
| flycheck/emacs-cask:$EMACS_VERSION \ | |||
| /bin/bash -c "make check" | |||
| # Compile and run unit tests. | |||
| docker run --volume "$TRAVIS_BUILD_DIR":/flycheck \ | |||
| --workdir /flycheck \ | |||
| flycheck/emacs-cask:$EMACS_VERSION \ | |||
| /bin/bash -c "make compile && make unit && make specs" | |||
| # If the unit tests succeed, fetch the all-tools container | |||
| # and run the integration tests | |||
| docker build --build-arg EMACS_VERSION=$EMACS_VERSION \ | |||
| --tag tools-and-emacs:$EMACS_VERSION \ | |||
| --file=.travis/tools-and-emacs . | |||
| docker run --volume "$TRAVIS_BUILD_DIR":/flycheck \ | |||
| --workdir /flycheck \ | |||
| tools-and-emacs:$EMACS_VERSION \ | |||
| /bin/bash -c "check-tools && make integ" ;; | |||
| build-manual) | |||
| # Build and deploy the manual | |||
| make -C doc SPHINXOPTS=-n html;; | |||
| lint-python) | |||
| # Lint our Python code | |||
| make -C maint check;; | |||
| esac | |||
| notifications: | |||
| webhooks: | |||
| urls: | |||
| - https://webhooks.gitter.im/e/efdc5fd9433efa7c6b80 | |||
| on_success: change | |||
| @ -0,0 +1,22 @@ | |||
| # Adding this stage is a workaround because `COPY --from` does not support | |||
| # variable substitution. | |||
| # See https://github.com/moby/moby/issues/34482 | |||
| ARG EMACS_VERSION=25.3 | |||
| FROM flycheck/emacs-cask:${EMACS_VERSION} AS emacs-cask | |||
| FROM flycheck/all-tools | |||
| # We need gnutls for downloading packages from ELPA | |||
| RUN apt-get -qq update && \ | |||
| apt-get install -qq --no-install-recommends -y \ | |||
| gnutls-bin \ | |||
| make \ | |||
| && rm -rf /var/lib/apt/lists/* | |||
| # We need Emacs and Cask | |||
| ENV PATH /opt/emacs/bin:$PATH | |||
| COPY --from=emacs-cask /opt/emacs /opt/emacs | |||
| ENV PATH /root/.cask/bin:$PATH | |||
| COPY --from=emacs-cask /root/.cask /root/.cask | |||
| COPY --from=emacs-cask /root/.emacs.d /root/.emacs.d | |||
| @ -0,0 +1,412 @@ | |||
| 33-cvs (in development) | |||
| ======================= | |||
| - New features and improvements | |||
| - The ``flycheck-verify-setup`` UI now includes buttons to re-enable manually | |||
| disabled checkers and to try to re-enable automatically disabled checkers | |||
| (command checkers are automatically disabled when their executable cannot be | |||
| found). [GH-1755] | |||
| - Error explainers can now return URLs (to show a webpage) or functions (to | |||
| use custom formatting). For example, the Rust checker now renders | |||
| explanations using ``markdown-view-mode``. [GH-1753] | |||
| - **Breaking changes** | |||
| - The variable ``flycheck-current-errors`` now contains errors in the order in | |||
| which they were returned by checkers. In previous versions of Flycheck, | |||
| this list was sorted by error position and severity. [GH-1749] | |||
| 32-cvs (frozen on May 3rd, 2020) | |||
| ================================ | |||
| - Highlights | |||
| - Many checkers and compiler, such as ``ocaml``, ``rust``, ``eslint``, and | |||
| others, include end-line and end-column information. Flycheck can now | |||
| highlight the exact region that they report. Authors of checker definitions | |||
| can use the new ``:end-line`` and ``:end-column`` arguments in | |||
| ``flycheck-error-new``, or the new ``end-line`` and ``end-column`` fields in | |||
| error patterns. [GH-1400] | |||
| - Errors that checkers return for other files will now be displayed on the | |||
| first line of the current buffer instead of begin discarded. The error list | |||
| indicates which file each error came from, and navigation moves | |||
| automatically moves between files. This change helps with compiled | |||
| languages, where an error in another file may cause the current file to be | |||
| considered invalid. Variables ``flycheck-relevant-error-other-file-show`` | |||
| and ``flycheck-relevant-error-other-file-minimum-level`` control this | |||
| behavior. [GH-1427] | |||
| - Flycheck can now draw error indicators in margins in addition to fringes. | |||
| Margins can contain arbitrary characters and images, not just monochrome | |||
| bitmaps, allowing for a better experience on high-DPI screens. | |||
| ``flycheck-indication-mode`` controls this behavior, and | |||
| ``flycheck-set-indication-mode`` can be used to automatically adjust the | |||
| fringes and margins. Additionally, Flycheck's will now use high-resolution | |||
| fringe bitmaps if the fringe is wide enough [GH-1742, GH-1744] | |||
| - Error highlighting is now configurable, using the new | |||
| ``flycheck-highlighting-style`` variable: instead of applying | |||
| level-dependent faces (typically with wavy underlines), Flycheck can now | |||
| insert delimiters around errors, or mix styles depending on how many lines | |||
| an error covers. Additionally, stipples are added in the fringes to | |||
| indicate errors that span multiple lines. [GH-1743] | |||
| - New features and improvements | |||
| - Flycheck can now trigger a syntax check automatically after switching | |||
| buffers, using the ``idle-buffer-switch`` option in | |||
| ``flycheck-check-syntax-automatically``. This is useful when errors in a | |||
| file are due to problems in a separate file. Variables | |||
| ``flycheck-idle-buffer-switch-delay`` and | |||
| ``flycheck-buffer-switch-check-intermediate-buffers`` control the | |||
| functionality. [GH-1297] | |||
| - Flycheck will now use Emacs' native XML parsing when libXML fails. This | |||
| behavior can be changed by customizing ``flycheck-xml-parser``. [GH-1349] | |||
| - ``flycheck-verify-setup`` now shows more clearly which checkers | |||
| will run in the buffer, and which are misconfigured. [GH-1478] | |||
| - Flycheck now locates checker executables using a customizable function, | |||
| ``flycheck-executable-find``. The default value of this function allows | |||
| relative paths (set e.g. in file or dir-local variables) in addition to | |||
| absolute paths and executable names. [GH-1485] | |||
| - Checkers that report error positions as a single offset from the start of | |||
| the file can use the new ``flycheck-error-new-at-pos`` constructor instead | |||
| of converting that position to a line and a column. [GH-1400] | |||
| - Config-file variables can now be set to a list of file names. This is | |||
| useful for checkers like mypy which don't run correctly when called from a | |||
| subdirectory without passing an explicit config file. [GH-1711] | |||
| - Thanks to algorithmic improvements in error reporting, Flycheck is now much | |||
| faster in large buffers. [GH-1750] | |||
| - New syntax checkers: | |||
| - Awk with ``gawk`` [GH-1708] | |||
| - Bazel with ``bazel-buildifier`` [GH-1613] | |||
| - CUDA with ``cuda-nvcc`` [GH-1508] | |||
| - CWL with ``schema-salad-tool`` [GH-1361] | |||
| - Elixir with ``credo`` [GH-1062] | |||
| - JSON with ``json-jq`` [GH-1568] | |||
| - Jsonnet with ``jsonnet`` [GH-1345] | |||
| - MarkdownLint CLI with ``markdownlint`` [GH-1366] | |||
| - mypy with ``python-mypy`` [GH-1354] | |||
| - Nix with ``nix-linter`` [GH-1530] | |||
| - Opam with ``opam lint`` [GH-1532] | |||
| - protobuf-prototool with ``prototool`` [GH-1591] | |||
| - Rust with ``rust-clippy`` [GH-1385] | |||
| - Ruumba with ``eruby-ruumba`` [GH-1616] | |||
| - Staticcheck with ``go-staticheck`` [GH-1541] | |||
| - terraform with ``terraform fmt``, ``tflint`` [GH-1586] | |||
| - Tcl with ``nagelfar`` [GH-1365] | |||
| - Text prose with ``textlint`` [GH-1534] | |||
| - VHDL with ``ghdl`` [GH-1160] | |||
| - Checker improvements: | |||
| - ``python-pylint`` and ``python-flake8`` are now invoked with ``python -c``, | |||
| to make it easier to change between Python 2 and Python 3. [GH-1113] | |||
| - Add ``flycheck-perl-module-list`` to use specified modules when | |||
| syntax checking code with the ``perl`` checker. [GH-1207] | |||
| - ``rust-cargo`` now uses ``cargo check`` and ``cargo test``. [GH-1289] | |||
| - Add ``flycheck-ghc-stack-project-file`` for the | |||
| ``haskell-stack-ghc`` checker. [GH-1316] | |||
| - Add ``flycheck-cppcheck-suppressions-file`` to pass a suppressions | |||
| file to cppcheck. [GH-1329] | |||
| - Add ``--force-exclusion`` flag to ``rubocop`` command. [GH-1348] | |||
| - Flycheck now uses ESLint's JSON output instead of checkstyle XML. [GH-1350] | |||
| - Add ``flychjeck-eslint-args`` to pass arguments to ``javascript-eslint``. | |||
| [GH-1360] | |||
| - Flycheck will now execute ``rubocop`` from the directory where a ``Gemfile`` | |||
| is located. If a ``Gemfile`` does not exist, the old behaviour of running | |||
| the command from the directory where ``.rubocop.yml`` is found will be | |||
| used. [GH-1368] | |||
| - Add ``flycheck-sh-bash-args`` to pass arguments to ``sh-bash``. [GH-1439] | |||
| - ``haskell-stack-ghc`` will not try to install GHC anymore. [GH-1443] | |||
| - Add ``flycheck-ghdl-ieee-library`` to select which standard IEEE | |||
| library to use for ghdl. [GH-1547] | |||
| - The ``javascript-eslint`` checker now supports ``typescript-mode`` by | |||
| default. | |||
| - Add ``flycheck-erlang-rebar3-profile`` to select which profile to | |||
| use when compiling erlang with rebar3. [GH-1560] | |||
| - Add ``flycheck-relevant-error-other-file-show`` to avoid showing errors | |||
| from other files. [GH-1579] | |||
| - The ``nix-linter`` checker now has an error explainer. [GH-1586] | |||
| - The Emacs Lisp checker can now run in buffers not backed by files. [GH-1695] | |||
| - **Breaking changes** | |||
| - Remove the ``javascript-jscs`` checker. [GH-1024] | |||
| - Remove the ``elixir-dogma`` checker. [GH-1450] | |||
| - ``rust-cargo`` now requires Rust 1.17 or newer. [GH-1289] | |||
| - ``rust`` now requires 1.18 or newer. [GH-1501] | |||
| - Rename ``flycheck-cargo-rustc-args`` to ``flycheck-cargo-check-args``. | |||
| [GH-1289] | |||
| - ``rust-cargo`` does not use the variable ``flycheck-rust-args`` anymore. | |||
| [GH-1289] | |||
| - Improve detection of default directory for ``haskell-ghc`` to consider | |||
| ``hpack`` project files. [GH-1435] | |||
| - Replace ``go tool vet`` with ``go vet``. [GH-1548] | |||
| - Remove the deprecated ``go-megacheck`` checker, which is replaced by | |||
| ``go-staticcheck``. [GH-1583] | |||
| 31 (Oct 07, 2017) | |||
| ================= | |||
| - **Breaking changes** | |||
| - ``rust-cargo`` now requires Rust 1.15 or newer [GH-1201] | |||
| - Remove javascript-gjslint checker | |||
| - New syntax checkers: | |||
| - Protobuf with ``protoc`` [GH-1125] | |||
| - systemd-analyze with ``systemd-analyze`` [GH-1135] | |||
| - Nix with ``nix-instantiate`` [GH-1164] | |||
| - Dockerfile with ``hadolint`` [GH-1194] | |||
| - AsciiDoc with ``asciidoctor`` [GH-1167] | |||
| - CSS/SCSS/LESS with ``stylelint`` [GH-903] | |||
| - Ruby with ``reek`` [GH-1244] | |||
| - Go with ``megacheck`` [GH-1290] | |||
| - LLVM IR with ``llc`` [GH-1302] | |||
| - Text prose with ``proselint`` [GH-1304] | |||
| - New features: | |||
| - Add ``flycheck-xml-xmlstarlet-xsd-path`` and ``flycheck-xml-xmllint-xsd-path`` to | |||
| specify an XSD schema to validate XML documents against [GH-1272] | |||
| - Add ``flycheck-tslint-args`` to pass additional arguments to tslint [GH-1186] | |||
| - Add an error explainer to the ``rpm-rpmlint`` checker using | |||
| ``rpmlint -I`` [GH-1235] | |||
| - Add ``flycheck-emacs-lisp-check-declare`` to check function declaration in | |||
| the ``emacs-lisp`` checker [GH-1286] | |||
| - Add ``flycheck-shellcheck-follow-sources`` to check included files when | |||
| using the ``sh-shellcheck`` checker [GH-1256] | |||
| - Improvements: | |||
| - Use option ``flycheck-go-build-tags`` for ``go-test``, | |||
| ``go-vet`` and ``go-errcheck`` as well. | |||
| - Add a revert function to ``flycheck-verify-setup``, so hitting | |||
| ``g`` reloads the buffer. | |||
| - Make sure the erlang compiler is only run on compilable files. | |||
| - ``flycheck-tslint`` does not crash any more on deprecation notices [GH-1174] | |||
| - ``rust-cargo`` now checks integration tests, examples and benchmarks | |||
| [GH-1206] | |||
| - ``rust-cargo`` does not use ``flycheck-rust-library-path`` anymore, as | |||
| dependencies are taken care of by Cargo [GH-1206] | |||
| - ``c/c++-gcc`` checker now works from GCC 4.4 and up [GH-1226] | |||
| 30 (Oct 12, 2016) | |||
| ================= | |||
| - **Breaking changes** | |||
| - Flycheck now requires flake8 3.0 or newer | |||
| - Remove ``--config`` option in ``lua-luacheck`` in favour of ``luacheck``'s | |||
| own ``.luacheckrc`` detection. Therefore ``flycheck-luacheckrc`` is | |||
| no longer used [GH-1057] | |||
| - ``:modes`` is now mandatory for syntax checker definitions [GH-1071] | |||
| - Remove jade checker [GH-951] [GH-1084] | |||
| - Remove ``javascript-eslintrc`` and instead rely on eslint's own configuration file | |||
| search [GH-1085] | |||
| - ``C-c ! e`` explains errors now [GH-1122] | |||
| - New syntax checkers: | |||
| - Elixir with ``dogma`` [GH-969] | |||
| - sass and scss with ``sass-lint`` [GH-1070] | |||
| - Pug [GH-951] [GH-1084] | |||
| - New features: | |||
| - Add ``flycheck-cargo-rustc-args`` to pass multiple arguments to cargo rustc | |||
| subcommand [GH-1079] | |||
| - Add ``:error-explainer`` to ``flycheck-define-checker`` and | |||
| ``flycheck-explain-error-at-point`` to display explanations of errors | |||
| [GH-1122] | |||
| - Add an error explainer to the ``rust`` and ``rust-cargo`` checkers using | |||
| ``rustc --explain`` [GH-1122] | |||
| - Add ``:enabled`` property to ``flycheck-define-checker`` [GH-1089] | |||
| - Improvements: | |||
| - Do not use ``javascript-eslint`` if eslint cannot find a valid configuration | |||
| [GH-1085] | |||
| - Automatically disable syntax checkers which are not installed instead of | |||
| checking executable before each syntax check [GH-1116] | |||
| - Add patterns for syntax errors to ``scheme-chicken`` [GH-1123] | |||
| 29 (Aug 28, 2016) | |||
| ================= | |||
| - **Breaking changes** | |||
| - Change ``flycheck-eslint-rulesdir`` (string) to | |||
| ``flycheck-eslint-rules-directories`` (list of strings) [GH-1016] | |||
| - Require rust 1.7 or newer for ``rust`` and ``rust-cargo`` [GH-1036] | |||
| - New syntax checkers: | |||
| - Slim with ``slim-lint`` [GH-1013] | |||
| - CHICKEN Scheme with ``csc`` [GH-987] | |||
| - New features: | |||
| - Add ``:working-directory`` option to ``flycheck-define-command-checker`` | |||
| [GH-973] [GH-1012] | |||
| - ``flycheck-go-build-install-deps`` turns on dependency installation for ``go test`` | |||
| as well as ``go build`` [GH-1003] | |||
| - Improvements: | |||
| - Add default directory for ``haskell-stack-ghc`` and ``haskell-ghc`` checkers | |||
| [GH-1007] | |||
| - ``rust`` and ``rust-cargo`` checkers now support the new error format of | |||
| rust 1.12 [GH-1016] | |||
| - ``flycheck-verify-checker`` and ``flycheck-verify-setup`` now include | |||
| information about configuration files of syntax checkers [GH-1021] [GH-1038] | |||
| 28 (Jun 05, 2016) | |||
| ================= | |||
| - **Breaking changes**: | |||
| - Rename ``luacheck`` to ``lua-luacheck`` to comply with our naming | |||
| conventions | |||
| - Remove ``flycheck-cppcheck-language-standard`` in favour of | |||
| ``flycheck-cppcheck-standards`` which is a list of standards [GH-960] | |||
| - New features: | |||
| - Add option to set binary name for ``rust-cargo`` [GH-958] | |||
| - Add ``flycheck-cppcheck-standards`` to pass multiple code standards to | |||
| cppcheck [GH-960] | |||
| - Add ``flycheck-cppcheck-suppressions`` to suppress warnings for cppcheck | |||
| [GH-960] | |||
| - Improvements: | |||
| - Check Racket syntax in Geiser Mode [GH-979] | |||
| - Bug fixes | |||
| - Do not signal errors when tslint reports no output [GH-981] | |||
| - Do not generate invalid temporary filenames on Windows [GH-983] | |||
| 27 (May 08, 2016) | |||
| ================= | |||
| - **Breaking changes** | |||
| - Require PHP Code Sniffer 2.6 or newer for ``php-phpcs`` [GH-921] | |||
| - New syntax checkers: | |||
| - Go with ``go-unconvert`` [GH-905] | |||
| - Markdown with ``mdl`` [GH-839] [GH-916] | |||
| - TypeScript with ``tslint`` [GH-947] [GH-949] | |||
| - Improvements: | |||
| - Pass checkdoc settings from Emacs to `emacs-lisp-checkdoc` [GH-741] [GH-937] | |||
| - Bug fixes: | |||
| - Fix parsing of syntax errors in triple-quoted strings for | |||
| ``python-pycompile`` [GH-948] | |||
| - Correctly handle rules based on the current file name in ``php-phpcs`` | |||
| [GH-921] | |||
| 26 (Apr 27, 2016) | |||
| ================= | |||
| Flycheck now has a `Code of Conduct`_ which defines the acceptable behaviour and | |||
| the moderation guidelines for the Flycheck community. [GH-819] | |||
| Flycheck also provides a `Gitter channel`_ now for questions and discussions | |||
| about development. [GH-820] | |||
| The native Texinfo manual is again replaced with a Sphinx_ based documentation. | |||
| We hope that this change makes the manual easier to edit and to maintain and | |||
| more welcoming for new contributors. The downside is that we can not longer | |||
| include a Info manual in Flycheck’s MELPA packages. | |||
| From this release onward Flycheck will use a single continuously increasing | |||
| version number. Breaking changes may occur at any point. | |||
| .. _Code of Conduct: http://www.flycheck.org/en/latest/community/conduct.html | |||
| .. _Gitter channel: https://gitter.im/flycheck/flycheck | |||
| .. _Sphinx: http://sphinx-doc.org | |||
| - **Breaking changes**: | |||
| - Remove ``flycheck-copy-messages-as-kill``, obsolete since Flycheck | |||
| 0.22 | |||
| - Remove ``flycheck-perlcritic-verbosity``, obsolete since Flycheck | |||
| 0.22 | |||
| - Replace ``flycheck-completion-system`` with | |||
| ``flycheck-completing-read-function`` [GH-870] | |||
| - JSON syntax checkers now require ``json-mode`` and do not check in | |||
| Javascript Mode anymore | |||
| - Prefer eslint over jshint for Javascript | |||
| - Obsolete ``flycheck-info`` in favour of the new ``flycheck-manual`` command | |||
| - New syntax checkers: | |||
| - Processing [GH-793] [GH-812] | |||
| - Racket [GH-799] [GH-873] | |||
| - New features: | |||
| - Add ``flycheck-puppet-lint-rc`` to customise the location of the | |||
| puppetlint configuration file [GH-846] | |||
| - Add ``flycheck-puppet-lint-disabled-checks`` to disable specific | |||
| checks of puppetlint [GH-824] | |||
| - New library ``flycheck-buttercup`` to support writing Buttercup_ specs for | |||
| Flycheck | |||
| - Add ``flycheck-perlcriticrc`` to set a configuration file for | |||
| Perl::Critic [GH-851] | |||
| - Add ``flycheck-jshint-extract-javascript`` to extract Javascript | |||
| from HTML [GH-825] | |||
| - Add ``flycheck-cppcheck-language-standard`` to set the language | |||
| standard for cppcheck [GH-862] | |||
| - Add ``flycheck-mode-line-prefix`` to customise the prefix of | |||
| Flycheck’s mode line lighter [GH-879] [GH-880] | |||
| - Add ``flycheck-go-vet-shadow`` to check for shadowed variables | |||
| with ``go vet`` [GH-765] [GH-897] | |||
| - Add ``flycheck-ghc-stack-use-nix`` to enable Nix support for Stack GHC | |||
| [GH-913] | |||
| - Improvements: | |||
| - Map error IDs from flake8-pep257 to Flycheck error levels | |||
| - Explicitly display errors at point with ``C-c ! h`` [GH-834] | |||
| - Merge message and checker columns in the error list to remove redundant | |||
| ellipsis [GH-828] | |||
| - Indicate disabled checkers in verification buffers [GH-749] | |||
| - Do not enable Flycheck Mode in ``fundamental-mode`` buffers [GH-883] | |||
| - Write ``go test`` output to a temporary files [GH-887] | |||
| - Check whether ``lintr`` is actually installed [GH-911] | |||
| - Bug fixes: | |||
| - Fix folding of C/C++ errors from included files [GH-783] | |||
| - Fix verification of SCSS-Lint checkstyle reporter | |||
| - Don’t fall back to ``rust`` if ``rust-cargo`` should be used [GH-817] | |||
| - Don’t change current buffer when closing the error message buffer [GH-648] | |||
| - Never display error message buffer in current window [GH-822] | |||
| - Work around a caching issue in Rubocop [GH-844] | |||
| - Fix checkdoc failure with some Emacs Lisp syntax [GH-833] [GH-845] [GH-898] | |||
| - Correctly parse Haskell module name with exports right after the module name | |||
| [GH-848] | |||
| - Don’t hang when sending buffers to node.js processes on Windows | |||
| [GH-794][GH-850] | |||
| - Parse suggestions from ``hlint`` [GH-874] | |||
| - Go errcheck handles multiple ``$GOPATH`` entries correctly now | |||
| [GH-580][GH-906] | |||
| - Properly handle Go build failing in a directory with multiple packages | |||
| [GH-676] [GH-904] | |||
| - Make cppcheck recognise C++ header files [GH-909] | |||
| - Don’t run phpcs on empty buffers [GH-907] | |||
| .. _Buttercup: https://github.com/jorgenschaefer/emacs-buttercup | |||
| @ -0,0 +1,674 @@ | |||
| GNU GENERAL PUBLIC LICENSE | |||
| Version 3, 29 June 2007 | |||
| Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |||
| Everyone is permitted to copy and distribute verbatim copies | |||
| of this license document, but changing it is not allowed. | |||
| Preamble | |||
| The GNU General Public License is a free, copyleft license for | |||
| software and other kinds of works. | |||
| The licenses for most software and other practical works are designed | |||
| to take away your freedom to share and change the works. By contrast, | |||
| the GNU General Public License is intended to guarantee your freedom to | |||
| share and change all versions of a program--to make sure it remains free | |||
| software for all its users. We, the Free Software Foundation, use the | |||
| GNU General Public License for most of our software; it applies also to | |||
| any other work released this way by its authors. You can apply it to | |||
| your programs, too. | |||
| When we speak of free software, we are referring to freedom, not | |||
| price. Our General Public Licenses are designed to make sure that you | |||
| have the freedom to distribute copies of free software (and charge for | |||
| them if you wish), that you receive source code or can get it if you | |||
| want it, that you can change the software or use pieces of it in new | |||
| free programs, and that you know you can do these things. | |||
| To protect your rights, we need to prevent others from denying you | |||
| these rights or asking you to surrender the rights. Therefore, you have | |||
| certain responsibilities if you distribute copies of the software, or if | |||
| you modify it: responsibilities to respect the freedom of others. | |||
| For example, if you distribute copies of such a program, whether | |||
| gratis or for a fee, you must pass on to the recipients the same | |||
| freedoms that you received. You must make sure that they, too, receive | |||
| or can get the source code. And you must show them these terms so they | |||
| know their rights. | |||
| Developers that use the GNU GPL protect your rights with two steps: | |||
| (1) assert copyright on the software, and (2) offer you this License | |||
| giving you legal permission to copy, distribute and/or modify it. | |||
| For the developers' and authors' protection, the GPL clearly explains | |||
| that there is no warranty for this free software. For both users' and | |||
| authors' sake, the GPL requires that modified versions be marked as | |||
| changed, so that their problems will not be attributed erroneously to | |||
| authors of previous versions. | |||
| Some devices are designed to deny users access to install or run | |||
| modified versions of the software inside them, although the manufacturer | |||
| can do so. This is fundamentally incompatible with the aim of | |||
| protecting users' freedom to change the software. The systematic | |||
| pattern of such abuse occurs in the area of products for individuals to | |||
| use, which is precisely where it is most unacceptable. Therefore, we | |||
| have designed this version of the GPL to prohibit the practice for those | |||
| products. If such problems arise substantially in other domains, we | |||
| stand ready to extend this provision to those domains in future versions | |||
| of the GPL, as needed to protect the freedom of users. | |||
| Finally, every program is threatened constantly by software patents. | |||
| States should not allow patents to restrict development and use of | |||
| software on general-purpose computers, but in those that do, we wish to | |||
| avoid the special danger that patents applied to a free program could | |||
| make it effectively proprietary. To prevent this, the GPL assures that | |||
| patents cannot be used to render the program non-free. | |||
| The precise terms and conditions for copying, distribution and | |||
| modification follow. | |||
| TERMS AND CONDITIONS | |||
| 0. Definitions. | |||
| "This License" refers to version 3 of the GNU General Public License. | |||
| "Copyright" also means copyright-like laws that apply to other kinds of | |||
| works, such as semiconductor masks. | |||
| "The Program" refers to any copyrightable work licensed under this | |||
| License. Each licensee is addressed as "you". "Licensees" and | |||
| "recipients" may be individuals or organizations. | |||
| To "modify" a work means to copy from or adapt all or part of the work | |||
| in a fashion requiring copyright permission, other than the making of an | |||
| exact copy. The resulting work is called a "modified version" of the | |||
| earlier work or a work "based on" the earlier work. | |||
| A "covered work" means either the unmodified Program or a work based | |||
| on the Program. | |||
| To "propagate" a work means to do anything with it that, without | |||
| permission, would make you directly or secondarily liable for | |||
| infringement under applicable copyright law, except executing it on a | |||
| computer or modifying a private copy. Propagation includes copying, | |||
| distribution (with or without modification), making available to the | |||
| public, and in some countries other activities as well. | |||
| To "convey" a work means any kind of propagation that enables other | |||
| parties to make or receive copies. Mere interaction with a user through | |||
| a computer network, with no transfer of a copy, is not conveying. | |||
| An interactive user interface displays "Appropriate Legal Notices" | |||
| to the extent that it includes a convenient and prominently visible | |||
| feature that (1) displays an appropriate copyright notice, and (2) | |||
| tells the user that there is no warranty for the work (except to the | |||
| extent that warranties are provided), that licensees may convey the | |||
| work under this License, and how to view a copy of this License. If | |||
| the interface presents a list of user commands or options, such as a | |||
| menu, a prominent item in the list meets this criterion. | |||
| 1. Source Code. | |||
| The "source code" for a work means the preferred form of the work | |||
| for making modifications to it. "Object code" means any non-source | |||
| form of a work. | |||
| A "Standard Interface" means an interface that either is an official | |||
| standard defined by a recognized standards body, or, in the case of | |||
| interfaces specified for a particular programming language, one that | |||
| is widely used among developers working in that language. | |||
| The "System Libraries" of an executable work include anything, other | |||
| than the work as a whole, that (a) is included in the normal form of | |||
| packaging a Major Component, but which is not part of that Major | |||
| Component, and (b) serves only to enable use of the work with that | |||
| Major Component, or to implement a Standard Interface for which an | |||
| implementation is available to the public in source code form. A | |||
| "Major Component", in this context, means a major essential component | |||
| (kernel, window system, and so on) of the specific operating system | |||
| (if any) on which the executable work runs, or a compiler used to | |||
| produce the work, or an object code interpreter used to run it. | |||
| The "Corresponding Source" for a work in object code form means all | |||
| the source code needed to generate, install, and (for an executable | |||
| work) run the object code and to modify the work, including scripts to | |||
| control those activities. However, it does not include the work's | |||
| System Libraries, or general-purpose tools or generally available free | |||
| programs which are used unmodified in performing those activities but | |||
| which are not part of the work. For example, Corresponding Source | |||
| includes interface definition files associated with source files for | |||
| the work, and the source code for shared libraries and dynamically | |||
| linked subprograms that the work is specifically designed to require, | |||
| such as by intimate data communication or control flow between those | |||
| subprograms and other parts of the work. | |||
| The Corresponding Source need not include anything that users | |||
| can regenerate automatically from other parts of the Corresponding | |||
| Source. | |||
| The Corresponding Source for a work in source code form is that | |||
| same work. | |||
| 2. Basic Permissions. | |||
| All rights granted under this License are granted for the term of | |||
| copyright on the Program, and are irrevocable provided the stated | |||
| conditions are met. This License explicitly affirms your unlimited | |||
| permission to run the unmodified Program. The output from running a | |||
| covered work is covered by this License only if the output, given its | |||
| content, constitutes a covered work. This License acknowledges your | |||
| rights of fair use or other equivalent, as provided by copyright law. | |||
| You may make, run and propagate covered works that you do not | |||
| convey, without conditions so long as your license otherwise remains | |||
| in force. You may convey covered works to others for the sole purpose | |||
| of having them make modifications exclusively for you, or provide you | |||
| with facilities for running those works, provided that you comply with | |||
| the terms of this License in conveying all material for which you do | |||
| not control copyright. Those thus making or running the covered works | |||
| for you must do so exclusively on your behalf, under your direction | |||
| and control, on terms that prohibit them from making any copies of | |||
| your copyrighted material outside their relationship with you. | |||
| Conveying under any other circumstances is permitted solely under | |||
| the conditions stated below. Sublicensing is not allowed; section 10 | |||
| makes it unnecessary. | |||
| 3. Protecting Users' Legal Rights From Anti-Circumvention Law. | |||
| No covered work shall be deemed part of an effective technological | |||
| measure under any applicable law fulfilling obligations under article | |||
| 11 of the WIPO copyright treaty adopted on 20 December 1996, or | |||
| similar laws prohibiting or restricting circumvention of such | |||
| measures. | |||
| When you convey a covered work, you waive any legal power to forbid | |||
| circumvention of technological measures to the extent such circumvention | |||
| is effected by exercising rights under this License with respect to | |||
| the covered work, and you disclaim any intention to limit operation or | |||
| modification of the work as a means of enforcing, against the work's | |||
| users, your or third parties' legal rights to forbid circumvention of | |||
| technological measures. | |||
| 4. Conveying Verbatim Copies. | |||
| You may convey verbatim copies of the Program's source code as you | |||
| receive it, in any medium, provided that you conspicuously and | |||
| appropriately publish on each copy an appropriate copyright notice; | |||
| keep intact all notices stating that this License and any | |||
| non-permissive terms added in accord with section 7 apply to the code; | |||
| keep intact all notices of the absence of any warranty; and give all | |||
| recipients a copy of this License along with the Program. | |||
| You may charge any price or no price for each copy that you convey, | |||
| and you may offer support or warranty protection for a fee. | |||
| 5. Conveying Modified Source Versions. | |||
| You may convey a work based on the Program, or the modifications to | |||
| produce it from the Program, in the form of source code under the | |||
| terms of section 4, provided that you also meet all of these conditions: | |||
| a) The work must carry prominent notices stating that you modified | |||
| it, and giving a relevant date. | |||
| b) The work must carry prominent notices stating that it is | |||
| released under this License and any conditions added under section | |||
| 7. This requirement modifies the requirement in section 4 to | |||
| "keep intact all notices". | |||
| c) You must license the entire work, as a whole, under this | |||
| License to anyone who comes into possession of a copy. This | |||
| License will therefore apply, along with any applicable section 7 | |||
| additional terms, to the whole of the work, and all its parts, | |||
| regardless of how they are packaged. This License gives no | |||
| permission to license the work in any other way, but it does not | |||
| invalidate such permission if you have separately received it. | |||
| d) If the work has interactive user interfaces, each must display | |||
| Appropriate Legal Notices; however, if the Program has interactive | |||
| interfaces that do not display Appropriate Legal Notices, your | |||
| work need not make them do so. | |||
| A compilation of a covered work with other separate and independent | |||
| works, which are not by their nature extensions of the covered work, | |||
| and which are not combined with it such as to form a larger program, | |||
| in or on a volume of a storage or distribution medium, is called an | |||
| "aggregate" if the compilation and its resulting copyright are not | |||
| used to limit the access or legal rights of the compilation's users | |||
| beyond what the individual works permit. Inclusion of a covered work | |||
| in an aggregate does not cause this License to apply to the other | |||
| parts of the aggregate. | |||
| 6. Conveying Non-Source Forms. | |||
| You may convey a covered work in object code form under the terms | |||
| of sections 4 and 5, provided that you also convey the | |||
| machine-readable Corresponding Source under the terms of this License, | |||
| in one of these ways: | |||
| a) Convey the object code in, or embodied in, a physical product | |||
| (including a physical distribution medium), accompanied by the | |||
| Corresponding Source fixed on a durable physical medium | |||
| customarily used for software interchange. | |||
| b) Convey the object code in, or embodied in, a physical product | |||
| (including a physical distribution medium), accompanied by a | |||
| written offer, valid for at least three years and valid for as | |||
| long as you offer spare parts or customer support for that product | |||
| model, to give anyone who possesses the object code either (1) a | |||
| copy of the Corresponding Source for all the software in the | |||
| product that is covered by this License, on a durable physical | |||
| medium customarily used for software interchange, for a price no | |||
| more than your reasonable cost of physically performing this | |||
| conveying of source, or (2) access to copy the | |||
| Corresponding Source from a network server at no charge. | |||
| c) Convey individual copies of the object code with a copy of the | |||
| written offer to provide the Corresponding Source. This | |||
| alternative is allowed only occasionally and noncommercially, and | |||
| only if you received the object code with such an offer, in accord | |||
| with subsection 6b. | |||
| d) Convey the object code by offering access from a designated | |||
| place (gratis or for a charge), and offer equivalent access to the | |||
| Corresponding Source in the same way through the same place at no | |||
| further charge. You need not require recipients to copy the | |||
| Corresponding Source along with the object code. If the place to | |||
| copy the object code is a network server, the Corresponding Source | |||
| may be on a different server (operated by you or a third party) | |||
| that supports equivalent copying facilities, provided you maintain | |||
| clear directions next to the object code saying where to find the | |||
| Corresponding Source. Regardless of what server hosts the | |||
| Corresponding Source, you remain obligated to ensure that it is | |||
| available for as long as needed to satisfy these requirements. | |||
| e) Convey the object code using peer-to-peer transmission, provided | |||
| you inform other peers where the object code and Corresponding | |||
| Source of the work are being offered to the general public at no | |||
| charge under subsection 6d. | |||
| A separable portion of the object code, whose source code is excluded | |||
| from the Corresponding Source as a System Library, need not be | |||
| included in conveying the object code work. | |||
| A "User Product" is either (1) a "consumer product", which means any | |||
| tangible personal property which is normally used for personal, family, | |||
| or household purposes, or (2) anything designed or sold for incorporation | |||
| into a dwelling. In determining whether a product is a consumer product, | |||
| doubtful cases shall be resolved in favor of coverage. For a particular | |||
| product received by a particular user, "normally used" refers to a | |||
| typical or common use of that class of product, regardless of the status | |||
| of the particular user or of the way in which the particular user | |||
| actually uses, or expects or is expected to use, the product. A product | |||
| is a consumer product regardless of whether the product has substantial | |||
| commercial, industrial or non-consumer uses, unless such uses represent | |||
| the only significant mode of use of the product. | |||
| "Installation Information" for a User Product means any methods, | |||
| procedures, authorization keys, or other information required to install | |||
| and execute modified versions of a covered work in that User Product from | |||
| a modified version of its Corresponding Source. The information must | |||
| suffice to ensure that the continued functioning of the modified object | |||
| code is in no case prevented or interfered with solely because | |||
| modification has been made. | |||
| If you convey an object code work under this section in, or with, or | |||
| specifically for use in, a User Product, and the conveying occurs as | |||
| part of a transaction in which the right of possession and use of the | |||
| User Product is transferred to the recipient in perpetuity or for a | |||
| fixed term (regardless of how the transaction is characterized), the | |||
| Corresponding Source conveyed under this section must be accompanied | |||
| by the Installation Information. But this requirement does not apply | |||
| if neither you nor any third party retains the ability to install | |||
| modified object code on the User Product (for example, the work has | |||
| been installed in ROM). | |||
| The requirement to provide Installation Information does not include a | |||
| requirement to continue to provide support service, warranty, or updates | |||
| for a work that has been modified or installed by the recipient, or for | |||
| the User Product in which it has been modified or installed. Access to a | |||
| network may be denied when the modification itself materially and | |||
| adversely affects the operation of the network or violates the rules and | |||
| protocols for communication across the network. | |||
| Corresponding Source conveyed, and Installation Information provided, | |||
| in accord with this section must be in a format that is publicly | |||
| documented (and with an implementation available to the public in | |||
| source code form), and must require no special password or key for | |||
| unpacking, reading or copying. | |||
| 7. Additional Terms. | |||
| "Additional permissions" are terms that supplement the terms of this | |||
| License by making exceptions from one or more of its conditions. | |||
| Additional permissions that are applicable to the entire Program shall | |||
| be treated as though they were included in this License, to the extent | |||
| that they are valid under applicable law. If additional permissions | |||
| apply only to part of the Program, that part may be used separately | |||
| under those permissions, but the entire Program remains governed by | |||
| this License without regard to the additional permissions. | |||
| When you convey a copy of a covered work, you may at your option | |||
| remove any additional permissions from that copy, or from any part of | |||
| it. (Additional permissions may be written to require their own | |||
| removal in certain cases when you modify the work.) You may place | |||
| additional permissions on material, added by you to a covered work, | |||
| for which you have or can give appropriate copyright permission. | |||
| Notwithstanding any other provision of this License, for material you | |||
| add to a covered work, you may (if authorized by the copyright holders of | |||
| that material) supplement the terms of this License with terms: | |||
| a) Disclaiming warranty or limiting liability differently from the | |||
| terms of sections 15 and 16 of this License; or | |||
| b) Requiring preservation of specified reasonable legal notices or | |||
| author attributions in that material or in the Appropriate Legal | |||
| Notices displayed by works containing it; or | |||
| c) Prohibiting misrepresentation of the origin of that material, or | |||
| requiring that modified versions of such material be marked in | |||
| reasonable ways as different from the original version; or | |||
| d) Limiting the use for publicity purposes of names of licensors or | |||
| authors of the material; or | |||
| e) Declining to grant rights under trademark law for use of some | |||
| trade names, trademarks, or service marks; or | |||
| f) Requiring indemnification of licensors and authors of that | |||
| material by anyone who conveys the material (or modified versions of | |||
| it) with contractual assumptions of liability to the recipient, for | |||
| any liability that these contractual assumptions directly impose on | |||
| those licensors and authors. | |||
| All other non-permissive additional terms are considered "further | |||
| restrictions" within the meaning of section 10. If the Program as you | |||
| received it, or any part of it, contains a notice stating that it is | |||
| governed by this License along with a term that is a further | |||
| restriction, you may remove that term. If a license document contains | |||
| a further restriction but permits relicensing or conveying under this | |||
| License, you may add to a covered work material governed by the terms | |||
| of that license document, provided that the further restriction does | |||
| not survive such relicensing or conveying. | |||
| If you add terms to a covered work in accord with this section, you | |||
| must place, in the relevant source files, a statement of the | |||
| additional terms that apply to those files, or a notice indicating | |||
| where to find the applicable terms. | |||
| Additional terms, permissive or non-permissive, may be stated in the | |||
| form of a separately written license, or stated as exceptions; | |||
| the above requirements apply either way. | |||
| 8. Termination. | |||
| You may not propagate or modify a covered work except as expressly | |||
| provided under this License. Any attempt otherwise to propagate or | |||
| modify it is void, and will automatically terminate your rights under | |||
| this License (including any patent licenses granted under the third | |||
| paragraph of section 11). | |||
| However, if you cease all violation of this License, then your | |||
| license from a particular copyright holder is reinstated (a) | |||
| provisionally, unless and until the copyright holder explicitly and | |||
| finally terminates your license, and (b) permanently, if the copyright | |||
| holder fails to notify you of the violation by some reasonable means | |||
| prior to 60 days after the cessation. | |||
| Moreover, your license from a particular copyright holder is | |||
| reinstated permanently if the copyright holder notifies you of the | |||
| violation by some reasonable means, this is the first time you have | |||
| received notice of violation of this License (for any work) from that | |||
| copyright holder, and you cure the violation prior to 30 days after | |||
| your receipt of the notice. | |||
| Termination of your rights under this section does not terminate the | |||
| licenses of parties who have received copies or rights from you under | |||
| this License. If your rights have been terminated and not permanently | |||
| reinstated, you do not qualify to receive new licenses for the same | |||
| material under section 10. | |||
| 9. Acceptance Not Required for Having Copies. | |||
| You are not required to accept this License in order to receive or | |||
| run a copy of the Program. Ancillary propagation of a covered work | |||
| occurring solely as a consequence of using peer-to-peer transmission | |||
| to receive a copy likewise does not require acceptance. However, | |||
| nothing other than this License grants you permission to propagate or | |||
| modify any covered work. These actions infringe copyright if you do | |||
| not accept this License. Therefore, by modifying or propagating a | |||
| covered work, you indicate your acceptance of this License to do so. | |||
| 10. Automatic Licensing of Downstream Recipients. | |||
| Each time you convey a covered work, the recipient automatically | |||
| receives a license from the original licensors, to run, modify and | |||
| propagate that work, subject to this License. You are not responsible | |||
| for enforcing compliance by third parties with this License. | |||
| An "entity transaction" is a transaction transferring control of an | |||
| organization, or substantially all assets of one, or subdividing an | |||
| organization, or merging organizations. If propagation of a covered | |||
| work results from an entity transaction, each party to that | |||
| transaction who receives a copy of the work also receives whatever | |||
| licenses to the work the party's predecessor in interest had or could | |||
| give under the previous paragraph, plus a right to possession of the | |||
| Corresponding Source of the work from the predecessor in interest, if | |||
| the predecessor has it or can get it with reasonable efforts. | |||
| You may not impose any further restrictions on the exercise of the | |||
| rights granted or affirmed under this License. For example, you may | |||
| not impose a license fee, royalty, or other charge for exercise of | |||
| rights granted under this License, and you may not initiate litigation | |||
| (including a cross-claim or counterclaim in a lawsuit) alleging that | |||
| any patent claim is infringed by making, using, selling, offering for | |||
| sale, or importing the Program or any portion of it. | |||
| 11. Patents. | |||
| A "contributor" is a copyright holder who authorizes use under this | |||
| License of the Program or a work on which the Program is based. The | |||
| work thus licensed is called the contributor's "contributor version". | |||
| A contributor's "essential patent claims" are all patent claims | |||
| owned or controlled by the contributor, whether already acquired or | |||
| hereafter acquired, that would be infringed by some manner, permitted | |||
| by this License, of making, using, or selling its contributor version, | |||
| but do not include claims that would be infringed only as a | |||
| consequence of further modification of the contributor version. For | |||
| purposes of this definition, "control" includes the right to grant | |||
| patent sublicenses in a manner consistent with the requirements of | |||
| this License. | |||
| Each contributor grants you a non-exclusive, worldwide, royalty-free | |||
| patent license under the contributor's essential patent claims, to | |||
| make, use, sell, offer for sale, import and otherwise run, modify and | |||
| propagate the contents of its contributor version. | |||
| In the following three paragraphs, a "patent license" is any express | |||
| agreement or commitment, however denominated, not to enforce a patent | |||
| (such as an express permission to practice a patent or covenant not to | |||
| sue for patent infringement). To "grant" such a patent license to a | |||
| party means to make such an agreement or commitment not to enforce a | |||
| patent against the party. | |||
| If you convey a covered work, knowingly relying on a patent license, | |||
| and the Corresponding Source of the work is not available for anyone | |||
| to copy, free of charge and under the terms of this License, through a | |||
| publicly available network server or other readily accessible means, | |||
| then you must either (1) cause the Corresponding Source to be so | |||
| available, or (2) arrange to deprive yourself of the benefit of the | |||
| patent license for this particular work, or (3) arrange, in a manner | |||
| consistent with the requirements of this License, to extend the patent | |||
| license to downstream recipients. "Knowingly relying" means you have | |||
| actual knowledge that, but for the patent license, your conveying the | |||
| covered work in a country, or your recipient's use of the covered work | |||
| in a country, would infringe one or more identifiable patents in that | |||
| country that you have reason to believe are valid. | |||
| If, pursuant to or in connection with a single transaction or | |||
| arrangement, you convey, or propagate by procuring conveyance of, a | |||
| covered work, and grant a patent license to some of the parties | |||
| receiving the covered work authorizing them to use, propagate, modify | |||
| or convey a specific copy of the covered work, then the patent license | |||
| you grant is automatically extended to all recipients of the covered | |||
| work and works based on it. | |||
| A patent license is "discriminatory" if it does not include within | |||
| the scope of its coverage, prohibits the exercise of, or is | |||
| conditioned on the non-exercise of one or more of the rights that are | |||
| specifically granted under this License. You may not convey a covered | |||
| work if you are a party to an arrangement with a third party that is | |||
| in the business of distributing software, under which you make payment | |||
| to the third party based on the extent of your activity of conveying | |||
| the work, and under which the third party grants, to any of the | |||
| parties who would receive the covered work from you, a discriminatory | |||
| patent license (a) in connection with copies of the covered work | |||
| conveyed by you (or copies made from those copies), or (b) primarily | |||
| for and in connection with specific products or compilations that | |||
| contain the covered work, unless you entered into that arrangement, | |||
| or that patent license was granted, prior to 28 March 2007. | |||
| Nothing in this License shall be construed as excluding or limiting | |||
| any implied license or other defenses to infringement that may | |||
| otherwise be available to you under applicable patent law. | |||
| 12. No Surrender of Others' Freedom. | |||
| If conditions are imposed on you (whether by court order, agreement or | |||
| otherwise) that contradict the conditions of this License, they do not | |||
| excuse you from the conditions of this License. If you cannot convey a | |||
| covered work so as to satisfy simultaneously your obligations under this | |||
| License and any other pertinent obligations, then as a consequence you may | |||
| not convey it at all. For example, if you agree to terms that obligate you | |||
| to collect a royalty for further conveying from those to whom you convey | |||
| the Program, the only way you could satisfy both those terms and this | |||
| License would be to refrain entirely from conveying the Program. | |||
| 13. Use with the GNU Affero General Public License. | |||
| Notwithstanding any other provision of this License, you have | |||
| permission to link or combine any covered work with a work licensed | |||
| under version 3 of the GNU Affero General Public License into a single | |||
| combined work, and to convey the resulting work. The terms of this | |||
| License will continue to apply to the part which is the covered work, | |||
| but the special requirements of the GNU Affero General Public License, | |||
| section 13, concerning interaction through a network will apply to the | |||
| combination as such. | |||
| 14. Revised Versions of this License. | |||
| The Free Software Foundation may publish revised and/or new versions of | |||
| the GNU General Public License from time to time. Such new versions will | |||
| be similar in spirit to the present version, but may differ in detail to | |||
| address new problems or concerns. | |||
| Each version is given a distinguishing version number. If the | |||
| Program specifies that a certain numbered version of the GNU General | |||
| Public License "or any later version" applies to it, you have the | |||
| option of following the terms and conditions either of that numbered | |||
| version or of any later version published by the Free Software | |||
| Foundation. If the Program does not specify a version number of the | |||
| GNU General Public License, you may choose any version ever published | |||
| by the Free Software Foundation. | |||
| If the Program specifies that a proxy can decide which future | |||
| versions of the GNU General Public License can be used, that proxy's | |||
| public statement of acceptance of a version permanently authorizes you | |||
| to choose that version for the Program. | |||
| Later license versions may give you additional or different | |||
| permissions. However, no additional obligations are imposed on any | |||
| author or copyright holder as a result of your choosing to follow a | |||
| later version. | |||
| 15. Disclaimer of Warranty. | |||
| THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | |||
| APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | |||
| HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | |||
| OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | |||
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |||
| PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | |||
| IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | |||
| ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |||
| 16. Limitation of Liability. | |||
| IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | |||
| THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | |||
| GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | |||
| USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | |||
| DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | |||
| PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | |||
| EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | |||
| SUCH DAMAGES. | |||
| 17. Interpretation of Sections 15 and 16. | |||
| If the disclaimer of warranty and limitation of liability provided | |||
| above cannot be given local legal effect according to their terms, | |||
| reviewing courts shall apply local law that most closely approximates | |||
| an absolute waiver of all civil liability in connection with the | |||
| Program, unless a warranty or assumption of liability accompanies a | |||
| copy of the Program in return for a fee. | |||
| END OF TERMS AND CONDITIONS | |||
| How to Apply These Terms to Your New Programs | |||
| If you develop a new program, and you want it to be of the greatest | |||
| possible use to the public, the best way to achieve this is to make it | |||
| free software which everyone can redistribute and change under these terms. | |||
| To do so, attach the following notices to the program. It is safest | |||
| to attach them to the start of each source file to most effectively | |||
| state the exclusion of warranty; and each file should have at least | |||
| the "copyright" line and a pointer to where the full notice is found. | |||
| <one line to give the program's name and a brief idea of what it does.> | |||
| Copyright (C) <year> <name of author> | |||
| This program is free software: you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation, either version 3 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| Also add information on how to contact you by electronic and paper mail. | |||
| If the program does terminal interaction, make it output a short | |||
| notice like this when it starts in an interactive mode: | |||
| <program> Copyright (C) <year> <name of author> | |||
| This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
| This is free software, and you are welcome to redistribute it | |||
| under certain conditions; type `show c' for details. | |||
| The hypothetical commands `show w' and `show c' should show the appropriate | |||
| parts of the General Public License. Of course, your program's commands | |||
| might be different; for a GUI interface, you would use an "about box". | |||
| You should also get your employer (if you work as a programmer) or school, | |||
| if any, to sign a "copyright disclaimer" for the program, if necessary. | |||
| For more information on this, and how to apply and follow the GNU GPL, see | |||
| <http://www.gnu.org/licenses/>. | |||
| The GNU General Public License does not permit incorporating your program | |||
| into proprietary programs. If your program is a subroutine library, you | |||
| may consider it more useful to permit linking proprietary applications with | |||
| the library. If this is what you want to do, use the GNU Lesser General | |||
| Public License instead of this License. But first, please read | |||
| <http://www.gnu.org/philosophy/why-not-lgpl.html>. | |||
| @ -0,0 +1,59 @@ | |||
| (source gnu) | |||
| (source melpa) | |||
| (package-file "flycheck.el") | |||
| (files "flycheck.el" "flycheck-ert.el" "flycheck-buttercup.el") | |||
| (development | |||
| (depends-on "f") ; For some maintenance tools | |||
| (depends-on "buttercup") ; BDD test framework for Emacs | |||
| (depends-on "shut-up") ; Silence Emacs | |||
| ;; Various modes for use in the unit tests | |||
| (depends-on "adoc-mode") | |||
| (depends-on "bazel-mode") | |||
| (depends-on "coffee-mode") | |||
| (depends-on "cperl-mode") | |||
| (depends-on "cwl-mode") | |||
| (depends-on "d-mode") | |||
| (depends-on "dockerfile-mode") | |||
| (depends-on "elixir-mode") | |||
| (depends-on "erlang") | |||
| (depends-on "ess") | |||
| (depends-on "geiser") | |||
| (depends-on "go-mode") | |||
| (depends-on "groovy-mode") | |||
| (depends-on "haml-mode") | |||
| (depends-on "handlebars-mode") | |||
| (depends-on "haskell-mode") | |||
| (depends-on "js2-mode") | |||
| (depends-on "js3-mode") | |||
| (depends-on "rjsx-mode") | |||
| (depends-on "json-mode") | |||
| (depends-on "julia-mode") | |||
| (depends-on "less-css-mode") | |||
| (depends-on "lua-mode") | |||
| (depends-on "markdown-mode") | |||
| (depends-on "mmm-mode") | |||
| (depends-on "nix-mode") | |||
| (depends-on "php-mode") | |||
| (depends-on "processing-mode") | |||
| (depends-on "protobuf-mode") | |||
| (depends-on "pug-mode") | |||
| (depends-on "puppet-mode") | |||
| ;; (depends-on "racket-mode") ;; https://github.com/greghendershott/racket-mode/issues/461 | |||
| (depends-on "rhtml-mode") | |||
| (depends-on "rpm-spec-mode") | |||
| (depends-on "rust-mode") | |||
| (depends-on "sass-mode") | |||
| (depends-on "scala-mode") | |||
| (depends-on "scss-mode") | |||
| (depends-on "slim-mode") | |||
| (depends-on "systemd") | |||
| (depends-on "terraform-mode") | |||
| (depends-on "tuareg") | |||
| (depends-on "typescript-mode") | |||
| (depends-on "web-mode") | |||
| (depends-on "yaml-mode") | |||
| ) | |||
| @ -0,0 +1,59 @@ | |||
| (source gnu) | |||
| (source melpa) | |||
| (package-file "flycheck.el") | |||
| (files "flycheck.el" "flycheck-ert.el" "flycheck-buttercup.el") | |||
| (development | |||
| (depends-on "f") ; For some maintenance tools | |||
| (depends-on "buttercup") ; BDD test framework for Emacs | |||
| (depends-on "shut-up") ; Silence Emacs | |||
| ;; Various modes for use in the unit tests | |||
| (depends-on "adoc-mode") | |||
| ;; (depends-on "bazel-mode") ; requires Emacs 26+ | |||
| (depends-on "coffee-mode") | |||
| (depends-on "cperl-mode") | |||
| (depends-on "cwl-mode") | |||
| ;; (depends-on "d-mode") ; requires Emacs 25.1+ | |||
| (depends-on "dockerfile-mode") | |||
| (depends-on "erlang") | |||
| ;; Latest ess requires `project' from Emacs 25+. | |||
| ;; (depends-on "ess") | |||
| (depends-on "geiser") | |||
| (depends-on "go-mode") | |||
| (depends-on "groovy-mode") | |||
| (depends-on "haml-mode") | |||
| (depends-on "handlebars-mode") | |||
| ;; (depends-on "haskell-mode") ; requires Emacs 25.1+ | |||
| (depends-on "js2-mode") | |||
| (depends-on "js3-mode") | |||
| (depends-on "rjsx-mode") | |||
| (depends-on "json-mode") | |||
| (depends-on "julia-mode") | |||
| (depends-on "less-css-mode") | |||
| (depends-on "lua-mode") | |||
| ;; (depends-on "markdown-mode") ; 25+ | |||
| (depends-on "mmm-mode") | |||
| ;; (depends-on "nix-mode") ; 25+ | |||
| (depends-on "php-mode") | |||
| (depends-on "processing-mode") | |||
| (depends-on "protobuf-mode") | |||
| (depends-on "pug-mode") | |||
| (depends-on "puppet-mode") | |||
| ;; (depends-on "racket-mode") ; requires Emacs 25.1+ | |||
| (depends-on "rhtml-mode") | |||
| (depends-on "rpm-spec-mode") | |||
| ;; (depends-on "rust-mode") ; 25+ | |||
| (depends-on "sass-mode") | |||
| (depends-on "scala-mode") | |||
| (depends-on "scss-mode") | |||
| (depends-on "slim-mode") | |||
| (depends-on "systemd") | |||
| (depends-on "terraform-mode") | |||
| (depends-on "tuareg") | |||
| (depends-on "typescript-mode") | |||
| (depends-on "web-mode") | |||
| (depends-on "yaml-mode") | |||
| ) | |||
| @ -0,0 +1,58 @@ | |||
| (source gnu) | |||
| (source melpa) | |||
| (package-file "flycheck.el") | |||
| (files "flycheck.el" "flycheck-ert.el" "flycheck-buttercup.el") | |||
| (development | |||
| (depends-on "f") ; For some maintenance tools | |||
| (depends-on "buttercup") ; BDD test framework for Emacs | |||
| (depends-on "shut-up") ; Silence Emacs | |||
| ;; Various modes for use in the unit tests | |||
| (depends-on "adoc-mode") | |||
| ;; (depends-on "bazel-mode") ; requires Emacs 26+ | |||
| (depends-on "coffee-mode") | |||
| (depends-on "cperl-mode") | |||
| (depends-on "cwl-mode") | |||
| (depends-on "d-mode") | |||
| (depends-on "dockerfile-mode") | |||
| (depends-on "erlang") | |||
| (depends-on "ess") | |||
| (depends-on "geiser") | |||
| (depends-on "go-mode") | |||
| (depends-on "groovy-mode") | |||
| (depends-on "haml-mode") | |||
| (depends-on "handlebars-mode") | |||
| (depends-on "haskell-mode") | |||
| (depends-on "js2-mode") | |||
| (depends-on "js3-mode") | |||
| (depends-on "rjsx-mode") | |||
| (depends-on "json-mode") | |||
| (depends-on "julia-mode") | |||
| (depends-on "less-css-mode") | |||
| (depends-on "lua-mode") | |||
| (depends-on "markdown-mode") | |||
| (depends-on "mmm-mode") | |||
| (depends-on "nix-mode") | |||
| (depends-on "php-mode") | |||
| (depends-on "processing-mode") | |||
| (depends-on "protobuf-mode") | |||
| (depends-on "pug-mode") | |||
| (depends-on "puppet-mode") | |||
| ;; (depends-on "racket-mode") ;; https://github.com/greghendershott/racket-mode/issues/461 | |||
| (depends-on "rhtml-mode") | |||
| (depends-on "rpm-spec-mode") | |||
| (depends-on "rust-mode") | |||
| (depends-on "sass-mode") | |||
| (depends-on "scala-mode") | |||
| (depends-on "scss-mode") | |||
| (depends-on "slim-mode") | |||
| (depends-on "systemd") | |||
| (depends-on "terraform-mode") | |||
| (depends-on "tuareg") | |||
| (depends-on "typescript-mode") | |||
| (depends-on "web-mode") | |||
| (depends-on "yaml-mode") | |||
| ) | |||
| @ -0,0 +1,2 @@ | |||
| Clément Pit-Claudel <hidden@example.com> (@cpitclaudel) | |||
| fmdkdd <hidden@example.com> (@fmdkdd) | |||
| @ -0,0 +1,164 @@ | |||
| # Copyright (c) 2018 Flycheck contributors | |||
| # Copyright (c) 2012-2016 Sebastian Wiesner and Flycheck contributors | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| # Programs | |||
| CASK = cask | |||
| EMACS = emacs | |||
| GIT = git | |||
| INKSCAPE = inkscape | |||
| CONVERT = convert | |||
| OPTIPNG = optipng | |||
| # Program options | |||
| EMACSOPTS = | |||
| PATTERN = .* | |||
| LANGUAGE = | |||
| ifdef LANGUAGE | |||
| SELECTOR = (language $(LANGUAGE)) | |||
| endif | |||
| # Internal variables | |||
| EMACSBATCH = $(EMACS) -Q --batch -L . $(EMACSOPTS) | |||
| RUNEMACS = | |||
| # Program availability | |||
| ifdef CASK | |||
| RUNEMACS = $(CASK) exec $(EMACSBATCH) | |||
| HAVE_CASK := $(shell sh -c "command -v $(CASK)") | |||
| ifndef HAVE_CASK | |||
| $(warning "$(CASK) is not available. Please run make help") | |||
| endif | |||
| else | |||
| RUNEMACS = $(EMACSBATCH) | |||
| endif | |||
| HAVE_INKSCAPE := $(shell sh -c "command -v $(INKSCAPE)") | |||
| HAVE_CONVERT := $(shell sh -c "command -v $(CONVERT)") | |||
| HAVE_OPTIPNG := $(shell sh -c "command -v $(OPTIPNG)") | |||
| RUNTEST = $(RUNEMACS) --load test/flycheck-test --load test/run.el \ | |||
| -f flycheck-run-tests-main | |||
| # Export Emacs to goals, mainly for CASK | |||
| CASK_EMACS = $(EMACS) | |||
| export EMACS | |||
| export CASK_EMACS | |||
| # Run make help by default | |||
| .DEFAULT_GOAL = help | |||
| # File lists | |||
| SRCS = flycheck.el flycheck-ert.el | |||
| OBJS = $(SRCS:.el=.elc) | |||
| IMGS = doc/_static/logo.png | |||
| TEST_SRCS = flycheck.el flycheck-ert.el test/flycheck-test.el | |||
| # File rules | |||
| flycheck-ert.elc: flycheck.elc | |||
| flycheck-buttercup.elc: flycheck.elc | |||
| $(OBJS): %.elc: %.el | |||
| $(RUNEMACS) -l maint/flycheck-compile.el -f flycheck/batch-byte-compile $< | |||
| doc/_static/logo.png: flycheck.svg | |||
| ifndef HAVE_CONVERT | |||
| $(error "$(CONVERT) not available. Please run make help.") | |||
| endif | |||
| ifndef HAVE_INKSCAPE | |||
| $(error "$(INKSCAPE) not available. Please run make help.") | |||
| endif | |||
| ifndef HAVE_OPTIPNG | |||
| $(error "$(OPTIPNG) not available. Please run make help.") | |||
| endif | |||
| $(CONVERT) $< -trim -background white -bordercolor white \ | |||
| -border 5 $@ | |||
| $(OPTIPNG) $@ | |||
| # Public targets | |||
| .PHONY: init | |||
| init: | |||
| $(CASK) --verbose install # --verbose is workaround for Emacs 25.3 | |||
| $(CASK) update | |||
| .PHONY: clean | |||
| clean: | |||
| rm -rf $(OBJS) | |||
| $(MAKE) -C doc clean | |||
| .PHONY: purge | |||
| purge: | |||
| $(GIT) clean -xfd | |||
| .PHONY: format | |||
| format: | |||
| $(RUNEMACS) -l maint/flycheck-format.el -f flycheck/batch-format | |||
| .PHONY: check-format | |||
| check-format: | |||
| $(RUNEMACS) -l maint/flycheck-format.el -f flycheck/batch-check-format | |||
| .PHONY: checkdoc | |||
| checkdoc: | |||
| $(RUNEMACS) -l maint/flycheck-checkdoc.el -f flycheck/batch-checkdoc | |||
| .PHONY: check | |||
| check: check-format checkdoc | |||
| .PHONY: compile | |||
| compile: $(OBJS) | |||
| .PHONY: specs | |||
| specs: compile | |||
| $(CASK) exec buttercup -L . --pattern '$(PATTERN)' test/specs | |||
| .PHONY: unit | |||
| unit: compile | |||
| $(RUNTEST) '(and (not (tag external-tool)) $(SELECTOR))' | |||
| .PHONY: integ | |||
| integ: compile | |||
| $(RUNTEST) '(and (tag external-tool) $(SELECTOR))' | |||
| .PHONY: images | |||
| images: $(IMGS) | |||
| .PHONY: help | |||
| help: | |||
| @echo 'Run `make init` first to install and update all local dependencies.' | |||
| @echo '' | |||
| @echo 'Available targets:' | |||
| @echo ' init: Initialise the project. RUN FIRST!' | |||
| @echo ' check: Check all Emacs Lisp sources (needs Emacs 25)' | |||
| @echo ' compile: Byte-compile Emacs Lisp sources' | |||
| @echo ' format: Format all Emacs Lisp sources' | |||
| @echo ' specs: Run all buttercup specs for Flycheck' | |||
| @echo ' unit: Run all ERT unit tests for Flycheck (legacy)' | |||
| @echo ' integ: Run all integration tests for Flycheck' | |||
| @echo ' images: Generate PNG images from SVG sources' | |||
| @echo ' clean: Clean compiled files' | |||
| @echo ' purge: Clean everything' | |||
| @echo '' | |||
| @echo 'Available make variables:' | |||
| @echo ' PATTERN: A regular expression matching spec names to run with `specs`' | |||
| @echo ' SELECTOR: An ERT selector expression for `unit` and `integ`' | |||
| @echo ' LANGUAGE: The name of a language for `integ`. Overrides `SELECTOR`' | |||
| @echo ' EMACSOPTS: Additional options to pass to `emacs`' | |||
| @echo ' EMACS: The path or name of the Emacs to use for tests and compilation' | |||
| @echo '' | |||
| @echo 'Available programs:' | |||
| @echo ' $(CASK): $(if $(HAVE_CASK),yes,no)' | |||
| @echo '' | |||
| @echo 'You need $(CASK) to develop Flycheck.' | |||
| @echo 'See http://cask.readthedocs.io/ for more information.' | |||
| @ -0,0 +1,52 @@ | |||
| # [![Flycheck][logo]](https://www.flycheck.org) # | |||
| [][COPYING] | |||
| [](https://gitter.im/flycheck/flycheck) | |||
| [](https://stable.melpa.org/#/flycheck) | |||
| [](https://travis-ci.org/flycheck/flycheck) | |||
| <https://www.flycheck.org> | |||
| Modern on-the-fly syntax checking extension for GNU Emacs. [Try it][]! | |||
|  | |||
| For a more gentle introduction read the [Installation][] instructions and go | |||
| through [Quickstart][] guide. | |||
| Please ask questions about Flycheck on [Stack Exchange][sx] or in our | |||
| [Gitter chat][gitter], and report bugs to our [issue tracker][]. | |||
| We welcome all kinds of contributions, whether you write patches, open pull | |||
| requests, write documentation, help others with Flycheck issues, or just tell | |||
| other people about your experiences with Flycheck. Please take a look at our | |||
| [Contributor’s Guide][contrib] for help and guidance about contributing to | |||
| Flycheck. | |||
| We strive to create a safe, friendly and welcoming environment in the Flycheck | |||
| community and have a [Code of Conduct][coc] that defines acceptable and welcome | |||
| behaviour as well as sanctions for violations. All contributors and all | |||
| participants are expected to follow it, on Github, Gitter, Emacs.SX or any other | |||
| place that’s part of Flycheck’s broader community. | |||
| Flycheck is free software: you can redistribute it and/or modify it under the | |||
| terms of the [GNU General Public License][copying] as published by the Free | |||
| Software Foundation, either version 3 of the License, or (at your option) any | |||
| later version. | |||
| Flycheck is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |||
| PARTICULAR PURPOSE. See the [GNU General Public License][copying] for more | |||
| details. | |||
| [COPYING]: https://github.com/flycheck/flycheck/blob/master/COPYING | |||
| [manual]: https://www.flycheck.org/en/latest/index.html#the-user-guide | |||
| [logo]: https://raw.githubusercontent.com/flycheck/flycheck/master/doc/_static/logo.png | |||
| [try it]: https://www.flycheck.org/en/latest/#try-out | |||
| [Installation]: https://www.flycheck.org/en/latest/user/installation.html | |||
| [Quickstart]: https://www.flycheck.org/en/latest/user/quickstart.html | |||
| [sx]: https://emacs.stackexchange.com/questions/tagged/flycheck | |||
| [gitter]: https://gitter.im/flycheck/flycheck | |||
| [Issue Tracker]: https://github.com/flycheck/flycheck/issues | |||
| [contrib]: https://www.flycheck.org/en/latest/contributor/contributing.html | |||
| [coc]: https://www.flycheck.org/en/latest/community/conduct.html | |||
| @ -0,0 +1,5 @@ | |||
| # Sphinx build artifacts | |||
| /_build/ | |||
| # Python bytecode of the in-tree Sphinx extensions | |||
| __pycache__/ | |||
| @ -0,0 +1,428 @@ | |||
| Attribution-ShareAlike 4.0 International | |||
| ======================================================================= | |||
| Creative Commons Corporation ("Creative Commons") is not a law firm and | |||
| does not provide legal services or legal advice. Distribution of | |||
| Creative Commons public licenses does not create a lawyer-client or | |||
| other relationship. Creative Commons makes its licenses and related | |||
| information available on an "as-is" basis. Creative Commons gives no | |||
| warranties regarding its licenses, any material licensed under their | |||
| terms and conditions, or any related information. Creative Commons | |||
| disclaims all liability for damages resulting from their use to the | |||
| fullest extent possible. | |||
| Using Creative Commons Public Licenses | |||
| Creative Commons public licenses provide a standard set of terms and | |||
| conditions that creators and other rights holders may use to share | |||
| original works of authorship and other material subject to copyright | |||
| and certain other rights specified in the public license below. The | |||
| following considerations are for informational purposes only, are not | |||
| exhaustive, and do not form part of our licenses. | |||
| Considerations for licensors: Our public licenses are | |||
| intended for use by those authorized to give the public | |||
| permission to use material in ways otherwise restricted by | |||
| copyright and certain other rights. Our licenses are | |||
| irrevocable. Licensors should read and understand the terms | |||
| and conditions of the license they choose before applying it. | |||
| Licensors should also secure all rights necessary before | |||
| applying our licenses so that the public can reuse the | |||
| material as expected. Licensors should clearly mark any | |||
| material not subject to the license. This includes other CC- | |||
| licensed material, or material used under an exception or | |||
| limitation to copyright. More considerations for licensors: | |||
| wiki.creativecommons.org/Considerations_for_licensors | |||
| Considerations for the public: By using one of our public | |||
| licenses, a licensor grants the public permission to use the | |||
| licensed material under specified terms and conditions. If | |||
| the licensor's permission is not necessary for any reason--for | |||
| example, because of any applicable exception or limitation to | |||
| copyright--then that use is not regulated by the license. Our | |||
| licenses grant only permissions under copyright and certain | |||
| other rights that a licensor has authority to grant. Use of | |||
| the licensed material may still be restricted for other | |||
| reasons, including because others have copyright or other | |||
| rights in the material. A licensor may make special requests, | |||
| such as asking that all changes be marked or described. | |||
| Although not required by our licenses, you are encouraged to | |||
| respect those requests where reasonable. More_considerations | |||
| for the public: | |||
| wiki.creativecommons.org/Considerations_for_licensees | |||
| ======================================================================= | |||
| Creative Commons Attribution-ShareAlike 4.0 International Public | |||
| License | |||
| By exercising the Licensed Rights (defined below), You accept and agree | |||
| to be bound by the terms and conditions of this Creative Commons | |||
| Attribution-ShareAlike 4.0 International Public License ("Public | |||
| License"). To the extent this Public License may be interpreted as a | |||
| contract, You are granted the Licensed Rights in consideration of Your | |||
| acceptance of these terms and conditions, and the Licensor grants You | |||
| such rights in consideration of benefits the Licensor receives from | |||
| making the Licensed Material available under these terms and | |||
| conditions. | |||
| Section 1 -- Definitions. | |||
| a. Adapted Material means material subject to Copyright and Similar | |||
| Rights that is derived from or based upon the Licensed Material | |||
| and in which the Licensed Material is translated, altered, | |||
| arranged, transformed, or otherwise modified in a manner requiring | |||
| permission under the Copyright and Similar Rights held by the | |||
| Licensor. For purposes of this Public License, where the Licensed | |||
| Material is a musical work, performance, or sound recording, | |||
| Adapted Material is always produced where the Licensed Material is | |||
| synched in timed relation with a moving image. | |||
| b. Adapter's License means the license You apply to Your Copyright | |||
| and Similar Rights in Your contributions to Adapted Material in | |||
| accordance with the terms and conditions of this Public License. | |||
| c. BY-SA Compatible License means a license listed at | |||
| creativecommons.org/compatiblelicenses, approved by Creative | |||
| Commons as essentially the equivalent of this Public License. | |||
| d. Copyright and Similar Rights means copyright and/or similar rights | |||
| closely related to copyright including, without limitation, | |||
| performance, broadcast, sound recording, and Sui Generis Database | |||
| Rights, without regard to how the rights are labeled or | |||
| categorized. For purposes of this Public License, the rights | |||
| specified in Section 2(b)(1)-(2) are not Copyright and Similar | |||
| Rights. | |||
| e. Effective Technological Measures means those measures that, in the | |||
| absence of proper authority, may not be circumvented under laws | |||
| fulfilling obligations under Article 11 of the WIPO Copyright | |||
| Treaty adopted on December 20, 1996, and/or similar international | |||
| agreements. | |||
| f. Exceptions and Limitations means fair use, fair dealing, and/or | |||
| any other exception or limitation to Copyright and Similar Rights | |||
| that applies to Your use of the Licensed Material. | |||
| g. License Elements means the license attributes listed in the name | |||
| of a Creative Commons Public License. The License Elements of this | |||
| Public License are Attribution and ShareAlike. | |||
| h. Licensed Material means the artistic or literary work, database, | |||
| or other material to which the Licensor applied this Public | |||
| License. | |||
| i. Licensed Rights means the rights granted to You subject to the | |||
| terms and conditions of this Public License, which are limited to | |||
| all Copyright and Similar Rights that apply to Your use of the | |||
| Licensed Material and that the Licensor has authority to license. | |||
| j. Licensor means the individual(s) or entity(ies) granting rights | |||
| under this Public License. | |||
| k. Share means to provide material to the public by any means or | |||
| process that requires permission under the Licensed Rights, such | |||
| as reproduction, public display, public performance, distribution, | |||
| dissemination, communication, or importation, and to make material | |||
| available to the public including in ways that members of the | |||
| public may access the material from a place and at a time | |||
| individually chosen by them. | |||
| l. Sui Generis Database Rights means rights other than copyright | |||
| resulting from Directive 96/9/EC of the European Parliament and of | |||
| the Council of 11 March 1996 on the legal protection of databases, | |||
| as amended and/or succeeded, as well as other essentially | |||
| equivalent rights anywhere in the world. | |||
| m. You means the individual or entity exercising the Licensed Rights | |||
| under this Public License. Your has a corresponding meaning. | |||
| Section 2 -- Scope. | |||
| a. License grant. | |||
| 1. Subject to the terms and conditions of this Public License, | |||
| the Licensor hereby grants You a worldwide, royalty-free, | |||
| non-sublicensable, non-exclusive, irrevocable license to | |||
| exercise the Licensed Rights in the Licensed Material to: | |||
| a. reproduce and Share the Licensed Material, in whole or | |||
| in part; and | |||
| b. produce, reproduce, and Share Adapted Material. | |||
| 2. Exceptions and Limitations. For the avoidance of doubt, where | |||
| Exceptions and Limitations apply to Your use, this Public | |||
| License does not apply, and You do not need to comply with | |||
| its terms and conditions. | |||
| 3. Term. The term of this Public License is specified in Section | |||
| 6(a). | |||
| 4. Media and formats; technical modifications allowed. The | |||
| Licensor authorizes You to exercise the Licensed Rights in | |||
| all media and formats whether now known or hereafter created, | |||
| and to make technical modifications necessary to do so. The | |||
| Licensor waives and/or agrees not to assert any right or | |||
| authority to forbid You from making technical modifications | |||
| necessary to exercise the Licensed Rights, including | |||
| technical modifications necessary to circumvent Effective | |||
| Technological Measures. For purposes of this Public License, | |||
| simply making modifications authorized by this Section 2(a) | |||
| (4) never produces Adapted Material. | |||
| 5. Downstream recipients. | |||
| a. Offer from the Licensor -- Licensed Material. Every | |||
| recipient of the Licensed Material automatically | |||
| receives an offer from the Licensor to exercise the | |||
| Licensed Rights under the terms and conditions of this | |||
| Public License. | |||
| b. Additional offer from the Licensor -- Adapted Material. | |||
| Every recipient of Adapted Material from You | |||
| automatically receives an offer from the Licensor to | |||
| exercise the Licensed Rights in the Adapted Material | |||
| under the conditions of the Adapter's License You apply. | |||
| c. No downstream restrictions. You may not offer or impose | |||
| any additional or different terms or conditions on, or | |||
| apply any Effective Technological Measures to, the | |||
| Licensed Material if doing so restricts exercise of the | |||
| Licensed Rights by any recipient of the Licensed | |||
| Material. | |||
| 6. No endorsement. Nothing in this Public License constitutes or | |||
| may be construed as permission to assert or imply that You | |||
| are, or that Your use of the Licensed Material is, connected | |||
| with, or sponsored, endorsed, or granted official status by, | |||
| the Licensor or others designated to receive attribution as | |||
| provided in Section 3(a)(1)(A)(i). | |||
| b. Other rights. | |||
| 1. Moral rights, such as the right of integrity, are not | |||
| licensed under this Public License, nor are publicity, | |||
| privacy, and/or other similar personality rights; however, to | |||
| the extent possible, the Licensor waives and/or agrees not to | |||
| assert any such rights held by the Licensor to the limited | |||
| extent necessary to allow You to exercise the Licensed | |||
| Rights, but not otherwise. | |||
| 2. Patent and trademark rights are not licensed under this | |||
| Public License. | |||
| 3. To the extent possible, the Licensor waives any right to | |||
| collect royalties from You for the exercise of the Licensed | |||
| Rights, whether directly or through a collecting society | |||
| under any voluntary or waivable statutory or compulsory | |||
| licensing scheme. In all other cases the Licensor expressly | |||
| reserves any right to collect such royalties. | |||
| Section 3 -- License Conditions. | |||
| Your exercise of the Licensed Rights is expressly made subject to the | |||
| following conditions. | |||
| a. Attribution. | |||
| 1. If You Share the Licensed Material (including in modified | |||
| form), You must: | |||
| a. retain the following if it is supplied by the Licensor | |||
| with the Licensed Material: | |||
| i. identification of the creator(s) of the Licensed | |||
| Material and any others designated to receive | |||
| attribution, in any reasonable manner requested by | |||
| the Licensor (including by pseudonym if | |||
| designated); | |||
| ii. a copyright notice; | |||
| iii. a notice that refers to this Public License; | |||
| iv. a notice that refers to the disclaimer of | |||
| warranties; | |||
| v. a URI or hyperlink to the Licensed Material to the | |||
| extent reasonably practicable; | |||
| b. indicate if You modified the Licensed Material and | |||
| retain an indication of any previous modifications; and | |||
| c. indicate the Licensed Material is licensed under this | |||
| Public License, and include the text of, or the URI or | |||
| hyperlink to, this Public License. | |||
| 2. You may satisfy the conditions in Section 3(a)(1) in any | |||
| reasonable manner based on the medium, means, and context in | |||
| which You Share the Licensed Material. For example, it may be | |||
| reasonable to satisfy the conditions by providing a URI or | |||
| hyperlink to a resource that includes the required | |||
| information. | |||
| 3. If requested by the Licensor, You must remove any of the | |||
| information required by Section 3(a)(1)(A) to the extent | |||
| reasonably practicable. | |||
| b. ShareAlike. | |||
| In addition to the conditions in Section 3(a), if You Share | |||
| Adapted Material You produce, the following conditions also apply. | |||
| 1. The Adapter's License You apply must be a Creative Commons | |||
| license with the same License Elements, this version or | |||
| later, or a BY-SA Compatible License. | |||
| 2. You must include the text of, or the URI or hyperlink to, the | |||
| Adapter's License You apply. You may satisfy this condition | |||
| in any reasonable manner based on the medium, means, and | |||
| context in which You Share Adapted Material. | |||
| 3. You may not offer or impose any additional or different terms | |||
| or conditions on, or apply any Effective Technological | |||
| Measures to, Adapted Material that restrict exercise of the | |||
| rights granted under the Adapter's License You apply. | |||
| Section 4 -- Sui Generis Database Rights. | |||
| Where the Licensed Rights include Sui Generis Database Rights that | |||
| apply to Your use of the Licensed Material: | |||
| a. for the avoidance of doubt, Section 2(a)(1) grants You the right | |||
| to extract, reuse, reproduce, and Share all or a substantial | |||
| portion of the contents of the database; | |||
| b. if You include all or a substantial portion of the database | |||
| contents in a database in which You have Sui Generis Database | |||
| Rights, then the database in which You have Sui Generis Database | |||
| Rights (but not its individual contents) is Adapted Material, | |||
| including for purposes of Section 3(b); and | |||
| c. You must comply with the conditions in Section 3(a) if You Share | |||
| all or a substantial portion of the contents of the database. | |||
| For the avoidance of doubt, this Section 4 supplements and does not | |||
| replace Your obligations under this Public License where the Licensed | |||
| Rights include other Copyright and Similar Rights. | |||
| Section 5 -- Disclaimer of Warranties and Limitation of Liability. | |||
| a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE | |||
| EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS | |||
| AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF | |||
| ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, | |||
| IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, | |||
| WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR | |||
| PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, | |||
| ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT | |||
| KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT | |||
| ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. | |||
| b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE | |||
| TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, | |||
| NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, | |||
| INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, | |||
| COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR | |||
| USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN | |||
| ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR | |||
| DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR | |||
| IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. | |||
| c. The disclaimer of warranties and limitation of liability provided | |||
| above shall be interpreted in a manner that, to the extent | |||
| possible, most closely approximates an absolute disclaimer and | |||
| waiver of all liability. | |||
| Section 6 -- Term and Termination. | |||
| a. This Public License applies for the term of the Copyright and | |||
| Similar Rights licensed here. However, if You fail to comply with | |||
| this Public License, then Your rights under this Public License | |||
| terminate automatically. | |||
| b. Where Your right to use the Licensed Material has terminated under | |||
| Section 6(a), it reinstates: | |||
| 1. automatically as of the date the violation is cured, provided | |||
| it is cured within 30 days of Your discovery of the | |||
| violation; or | |||
| 2. upon express reinstatement by the Licensor. | |||
| For the avoidance of doubt, this Section 6(b) does not affect any | |||
| right the Licensor may have to seek remedies for Your violations | |||
| of this Public License. | |||
| c. For the avoidance of doubt, the Licensor may also offer the | |||
| Licensed Material under separate terms or conditions or stop | |||
| distributing the Licensed Material at any time; however, doing so | |||
| will not terminate this Public License. | |||
| d. Sections 1, 5, 6, 7, and 8 survive termination of this Public | |||
| License. | |||
| Section 7 -- Other Terms and Conditions. | |||
| a. The Licensor shall not be bound by any additional or different | |||
| terms or conditions communicated by You unless expressly agreed. | |||
| b. Any arrangements, understandings, or agreements regarding the | |||
| Licensed Material not stated herein are separate from and | |||
| independent of the terms and conditions of this Public License. | |||
| Section 8 -- Interpretation. | |||
| a. For the avoidance of doubt, this Public License does not, and | |||
| shall not be interpreted to, reduce, limit, restrict, or impose | |||
| conditions on any use of the Licensed Material that could lawfully | |||
| be made without permission under this Public License. | |||
| b. To the extent possible, if any provision of this Public License is | |||
| deemed unenforceable, it shall be automatically reformed to the | |||
| minimum extent necessary to make it enforceable. If the provision | |||
| cannot be reformed, it shall be severed from this Public License | |||
| without affecting the enforceability of the remaining terms and | |||
| conditions. | |||
| c. No term or condition of this Public License will be waived and no | |||
| failure to comply consented to unless expressly agreed to by the | |||
| Licensor. | |||
| d. Nothing in this Public License constitutes or may be interpreted | |||
| as a limitation upon, or waiver of, any privileges and immunities | |||
| that apply to the Licensor or You, including from the legal | |||
| processes of any jurisdiction or authority. | |||
| ======================================================================= | |||
| Creative Commons is not a party to its public | |||
| licenses. Notwithstanding, Creative Commons may elect to apply one of | |||
| its public licenses to material it publishes and in those instances | |||
| will be considered the “Licensor.” The text of the Creative Commons | |||
| public licenses is dedicated to the public domain under the CC0 Public | |||
| Domain Dedication. Except for the limited purpose of indicating that | |||
| material is shared under a Creative Commons public license or as | |||
| otherwise permitted by the Creative Commons policies published at | |||
| creativecommons.org/policies, Creative Commons does not authorize the | |||
| use of the trademark "Creative Commons" or any other trademark or logo | |||
| of Creative Commons without its prior written consent including, | |||
| without limitation, in connection with any unauthorized modifications | |||
| to any of its public licenses or any other arrangements, | |||
| understandings, or agreements concerning use of licensed material. For | |||
| the avoidance of doubt, this paragraph does not form part of the | |||
| public licenses. | |||
| Creative Commons may be contacted at creativecommons.org. | |||
| @ -0,0 +1,112 @@ | |||
| # Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| # This file is not part of GNU Emacs. | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| PIP = pip3 | |||
| SPHINXOPTS = -j4 | |||
| SPHINXBUILD = sphinx-build | |||
| SPHINXAUTOBUILD = sphinx-autobuild | |||
| OPTIPNG = optipng | |||
| BUILDDIR = _build | |||
| # Whether to build offline HTML that loads no external resources, for use in 3rd | |||
| # party packages, see https://github.com/flycheck/flycheck/issues/999 | |||
| OFFLINE = | |||
| ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(SPHINXOPTS) . | |||
| ifdef OFFLINE | |||
| ALLSPHINXOPTS += -Dflycheck_offline_html=1 | |||
| endif | |||
| IMAGES = images/*.png | |||
| .DEFAULT_GOAL := help | |||
| HAVE_SPHINXBUILD := $(shell sh -c "command -v $(SPHINXBUILD)") | |||
| ifndef HAVE_SPHINXBUILD | |||
| $(warning "$(SPHINXBUILD) is not available. Please run make help.") | |||
| endif | |||
| HAVE_SPHINXAUTOBUILD := $(shell sh -c "command -v $(SPHINXAUTOBUILD)") | |||
| HAVE_PIP := $(shell sh -c "command -v $(PIP)") | |||
| .PHONY: help | |||
| help: | |||
| @echo 'Available targets:' | |||
| @echo ' html: Build HTML documentation to $(BUILDDIR)/html' | |||
| @echo ' html-auto: Like html, but automatically rebuild on changes' | |||
| @echo ' linkcheck: Check all links and references' | |||
| @echo ' clean: Remove generated documentation' | |||
| @echo ' optimise-images: Optimise all images in the documentation' | |||
| @echo '' | |||
| @echo 'To build the documentation you need $(SPHINXBUILD).' | |||
| @echo 'For *-auto targets you also need $(SPHINXAUTOBUILD).' | |||
| @echo '' | |||
| @echo 'Available make variables:' | |||
| @echo ' OFFLINE: If set build HTML that loads no external resources' | |||
| @echo '' | |||
| @echo 'Available programs:' | |||
| @echo ' $(SPHINXBUILD): $(if $(HAVE_SPHINXBUILD),yes,no)' | |||
| @echo ' $(SPHINXAUTOBUILD): $(if $(HAVE_SPHINXAUTOBUILD),yes,no)' | |||
| @echo '' | |||
| @echo 'You need Python 3.4 or newer to install Sphinx for Flycheck.' | |||
| @echo '' | |||
| @echo 'Run make init to install all missing tools. It is recommended' | |||
| @echo 'that you use virtualenv (https://virtualenv.pypa.io/en/latest/)' | |||
| @echo 'to avoid a global installation of Python packages. make init' | |||
| @echo 'will warn you if you do not.' | |||
| .PHONY: init | |||
| init: | |||
| ifndef HAVE_PIP | |||
| $(error "$(PIP) not available. Please run make help.") | |||
| endif | |||
| ifndef VIRTUAL_ENV | |||
| $(warning "No virtualenv active. Installing Sphinx globally is not recommended.") | |||
| ifndef FORCE | |||
| $(error "Aborted. Run make FORCE=1 init to override or make help.") | |||
| endif | |||
| endif | |||
| pip install -r requirements.txt | |||
| .PHONY: clean | |||
| clean: | |||
| rm -rf $(BUILDDIR)/* | |||
| # HTML and related formats | |||
| .PHONY: html | |||
| html: | |||
| $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | |||
| @echo | |||
| @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." | |||
| .PHONY: html-auto | |||
| html-auto: SPHINXOPTS = -B | |||
| html-auto: | |||
| ifndef HAVE_SPHINXAUTOBUILD | |||
| $(error "sphinx-autobuild not available. Run make help.") | |||
| endif | |||
| $(SPHINXAUTOBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | |||
| # House-keeping targets | |||
| .PHONY: linkcheck | |||
| linkcheck: | |||
| $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck | |||
| @echo | |||
| @echo "Link check complete; look for any errors in the above output " \ | |||
| "or in $(BUILDDIR)/linkcheck/output.txt." | |||
| .PHONY: optimise-images | |||
| optimise-images: | |||
| $(OPTIPNG) $(filter %.png,$(IMAGES)) | |||
| @ -0,0 +1,43 @@ | |||
| {% if theme_logo %} | |||
| <p class="logo"> | |||
| <a href="{{ pathto(master_doc) }}"> | |||
| <img class="logo" src="{{ pathto('_static/' ~ theme_logo, 1) }}" alt="Logo"/> | |||
| {% if theme_logo_name|lower == 'true' %} | |||
| <h1 class="logo logo-name">{{ project }}</h1> | |||
| {% endif %} | |||
| </a> | |||
| </p> | |||
| {% else %} | |||
| <h1 class="logo"><a href="{{ pathto(master_doc) }}">{{ project }}</a></h1> | |||
| {% endif %} | |||
| {% if theme_description %} | |||
| <p class="blurb">{{ theme_description }}</p> | |||
| {% endif %} | |||
| {% macro badge(badge, href) -%} | |||
| <p><a href="{{href}}"><img src="https://img.shields.io/{{badge}}"/></a></p> | |||
| {%- endmacro %} | |||
| {% if theme_github_user and theme_github_repo and not flycheck_offline_html %} | |||
| {% if theme_github_button|lower == 'true' %} | |||
| <p> | |||
| <iframe src="https://ghbtns.com/github-btn.html?user={{ theme_github_user }}&repo={{ theme_github_repo }}&type={{ theme_github_type }}&count={{ theme_github_count }}&v=2" | |||
| allowtransparency="true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe> | |||
| </p> | |||
| {% endif %} | |||
| {% endif %} | |||
| {% if not flycheck_offline_html %} | |||
| <p> | |||
| <a href="https://gitter.im/flycheck/flycheck"> | |||
| <img src="https://img.shields.io/gitter/room/flycheck/flycheck.svg?maxAge=2592000" /> | |||
| </a> | |||
| </p> | |||
| <p> | |||
| <a href="https://stable.melpa.org/#/flycheck"><img alt="MELPA Stable" src="https://stable.melpa.org/packages/flycheck-badge.svg"/></a> | |||
| </p> | |||
| <p> | |||
| <a href="https://melpa.org/#/flycheck"><img alt="MELPA" src="https://melpa.org/packages/flycheck-badge.svg"/></a> | |||
| </p> | |||
| {% endif %} | |||
| @ -0,0 +1,20 @@ | |||
| {% extends "!layout.html" %} | |||
| {% block extrahead %} | |||
| <script type="text/javascript"> | |||
| /* Prevent injected analytics from running with a no-op, but | |||
| let other scripts be injected (we need that for the readthedocs | |||
| widget at the bottom-right of the screen) */ | |||
| (function(){ | |||
| var props = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src'); | |||
| var _set = props.set; | |||
| Object.defineProperty(HTMLScriptElement.prototype, 'src', { | |||
| configurable: false, /* Prevent further redefinition of this property */ | |||
| set: function(url) { | |||
| if (url.indexOf('google-analytics.com') > -1) return; | |||
| else _set.apply(this, arguments); | |||
| } | |||
| }); | |||
| }()) | |||
| </script> | |||
| {% endblock %} | |||
| @ -0,0 +1,6 @@ | |||
| <h4>Tables</h4> | |||
| <ul> | |||
| <li><a href="{{pathto('languages')}}">Supported languages</a></li> | |||
| <li><a href="{{pathto('changes')}}">List of changes</a></li> | |||
| <li><a href="{{pathto('genindex')}}">Index</a></li> | |||
| </ul> | |||
| @ -0,0 +1,5 @@ | |||
| ========= | |||
| Changes | |||
| ========= | |||
| .. include:: ../CHANGES.rst | |||
| @ -0,0 +1,96 @@ | |||
| .. _flycheck-conduct: | |||
| ========================== | |||
| Flycheck Code of Conduct | |||
| ========================== | |||
| Our Code of Conduct defines the social norms and policies within Flycheck’s | |||
| community. Whenever you interact with Flycheck or Flycheck developers, whether | |||
| in our official channels or privately, you’re expected to follow this Code of | |||
| Conduct. | |||
| Conduct | |||
| ======= | |||
| **Contact**: :ref:`Any moderator <flycheck-moderators>` | |||
| * We are committed to providing a friendly, safe and welcoming environment for | |||
| all, regardless of level of experience, gender, gender identity and | |||
| expression, sexual orientation, disability, personal appearance, body size, | |||
| race, ethnicity, age, religion, nationality, or similar personal | |||
| characteristic. | |||
| * Please avoid using overtly sexual nicknames or other nicknames that might | |||
| detract from a friendly, safe and welcoming environment for all. | |||
| * Please be kind and courteous. There's no need to be mean or rude. | |||
| * Please do not curse or use bad words. Foul language will not help us to build | |||
| a great product. | |||
| * Respect that people have differences of opinion and that every design or | |||
| implementation choice carries a trade-off and numerous costs. There is seldom | |||
| a right answer. | |||
| * Please keep unstructured critique to a minimum. If you have solid ideas you | |||
| want to experiment with, make a fork and see how it works. | |||
| * We will exclude you from interaction if you insult, demean or harass | |||
| anyone. That is not welcome behaviour. We interpret the term "harassment" as | |||
| including the definition in the `Citizen Code of Conduct`_; if you have any | |||
| lack of clarity about what might be included in that concept, please read | |||
| their definition. In particular, we don't tolerate behavior that excludes | |||
| people in socially marginalized groups. | |||
| * Private harassment is also unacceptable. No matter who you are, if you feel | |||
| you have been or are being harassed or made uncomfortable by a community | |||
| member, please contact a :ref:`moderator <flycheck-moderators>` | |||
| immediately. Whether you're a regular contributor or a newcomer, we care about | |||
| making this community a safe place for you and we've got your back. | |||
| * Likewise any spamming, trolling, flaming, baiting or other attention-stealing | |||
| behaviour is not welcome. | |||
| .. _Citizen Code of Conduct: http://citizencodeofconduct.org/ | |||
| Moderation | |||
| ========== | |||
| These are the policies for upholding our community's standards of conduct in our | |||
| communication channels, most notably in Flycheck’s Github organisation and in | |||
| Flycheck’s Gitter channels. | |||
| 1. Remarks that violate the Flycheck code of conduct, including hateful, | |||
| hurtful, oppressive, or exclusionary remarks, are not allowed. | |||
| 2. Remarks that moderators find inappropriate, whether listed in the code of | |||
| conduct or not, are also not allowed. | |||
| 3. Moderators will first respond to such remarks with a warning. | |||
| 4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of | |||
| the communication channel to cool off. | |||
| 5. If the user comes back and continues to make trouble, they will be banned, | |||
| i.e., indefinitely excluded. | |||
| 6. Moderators may choose at their discretion to un-ban the user if it was a | |||
| first offense and they offer the offended party a genuine apology. | |||
| 7. If a moderator bans someone and you think it was unjustified, please take it | |||
| up with that moderator, or with a different moderator, **in | |||
| private**. Complaints about bans in-channel are not allowed. | |||
| 8. Moderators are held to a higher standard than other community members. If a | |||
| moderator creates an inappropriate situation, they should expect less leeway | |||
| than others. | |||
| In the Flycheck community we strive to go the extra step to look out for each | |||
| other. Don't just aim to be technically unimpeachable, try to be your best | |||
| self. In particular, avoid flirting with offensive or sensitive issues, | |||
| particularly if they're off-topic; this all too often leads to unnecessary | |||
| fights, hurt feelings, and damaged trust; worse, it can drive people away from | |||
| the community entirely. | |||
| And if someone takes issue with something you said or did, resist the urge to be | |||
| defensive. Just stop doing what it was they complained about and apologize. Even | |||
| if you feel you were misinterpreted or unfairly accused, chances are good there | |||
| was something you could have communicated better — remember that it's your | |||
| responsibility to make your fellow Flycheck people comfortable. Everyone wants | |||
| to get along and we are all here first and foremost because we want to talk | |||
| about cool technology. You will find that people will be eager to assume good | |||
| intent and forgive as long as you earn their trust. | |||
| --- | |||
| Adapted from the `Rust Code of Conduct`_. | |||
| | Copyright (c) 2015 Sebastian Wiesner and Flycheck contributors | |||
| | Copyright (c) 2014 The Rust Project Developers | |||
| .. _Rust Code of Conduct: https://www.rust-lang.org/conduct.html | |||
| @ -0,0 +1,166 @@ | |||
| .. _flycheck-extensions: | |||
| ======================== | |||
| Recommended extensions | |||
| ======================== | |||
| The Emacs community has produced a number of extensions to Flycheck. This page | |||
| lists all that we know of and can safely recommend to our users. | |||
| *Official* extensions are (co-)maintained by the :ref:`Flycheck maintainers | |||
| <flycheck-maintainers>` who will take care to update official extensions in case | |||
| of breaking changes in Flycheck and work to provide extra API for extensions if | |||
| needed. If you'd like to make your extension an *official* one and move it into | |||
| the `Flycheck Github organisation`_ please contact a :ref:`maintainer | |||
| <flycheck-maintainers>`. | |||
| If you do know extensions not in this list, or would like to see your own | |||
| extension here, please feel free to `add it`_. | |||
| We would like to thank all people who created and contributed to Flycheck | |||
| extensions for their awesome work. Without your help and support Flycheck would | |||
| not be what it is today. | |||
| .. _add it: https://github.com/flycheck/flycheck/edit/master/doc/community/extensions.rst | |||
| .. _Flycheck Github organisation: https://github.com/flycheck | |||
| User interface | |||
| ============== | |||
| These extensions change Flycheck’s user interface: | |||
| * :flyc:`flycheck-color-mode-line` (*official*) colors the mode line according | |||
| to the Flycheck status. | |||
| * :flyc:`flycheck-pos-tip` (*official*) shows Flycheck error messages in a | |||
| graphical popup. | |||
| * :gh:`liblit/flycheck-status-emoji` adds cute emoji (e.g. 😱 for errors) to | |||
| Flycheck’s mode line status. | |||
| * :gh:`Wilfred/flycheck-title` shows Flycheck error messages in the frame title. | |||
| * :flyc:`flycheck-inline` shows Flycheck error messages in the buffer, directly | |||
| below their origin. | |||
| Language support | |||
| ================ | |||
| These extensions add support for new languages, or improve support for built-in | |||
| languages. They are grouped by the corresponding language so you can jump | |||
| directly to the languages that interest you: | |||
| .. contents:: Languages | |||
| :local: | |||
| Cadence | |||
| ------- | |||
| * :gh:`cmarqu/flycheck-hdl-irun` adds a syntax checker for hardware description | |||
| languages supported by `Cadence IES/irun`_. | |||
| .. _Cadence IES/irun: https://www.cadence.com/content/cadence-www/global/en_US/home/tools/system-design-and-verification/simulation-and-testbench-verification/incisive-enterprise-simulator.html | |||
| Clojure | |||
| ------- | |||
| * :gh:`clojure-emacs/squiggly-clojure` adds syntax checking for Clojure. | |||
| C/C++/Objective C | |||
| ----------------- | |||
| * :gh:`Wilfred/flycheck-pkg-config` configures Flycheck to use settings from | |||
| `pkg-config`_ when checking C/C++. | |||
| * :gh:`Sarcasm/flycheck-irony` adds a Flycheck syntax checker for C, C++ and | |||
| Objective C using :gh:`Irony Mode <Sarcasm/irony-mode>`. | |||
| .. _pkg-config: https://www.freedesktop.org/wiki/Software/pkg-config/ | |||
| D | |||
| - | |||
| * :flyc:`flycheck-d-unittest` (*official*) adds a Flycheck checker to run unit | |||
| tests for D programs on the fly. | |||
| Elixir | |||
| ------ | |||
| * :gh:`tomekowal/flycheck-mix` adds an Elixir syntax checker using the ``mix`` | |||
| build tool. | |||
| Emacs Lisp | |||
| ---------- | |||
| * :flyc:`flycheck-cask` (*official*) makes Flycheck use Cask packages for Emacs | |||
| Lisp syntax checking in Cask_ projects. | |||
| * :gh:`purcell/flycheck-package` checks Emacs Lisp packages for common problems | |||
| with package metadata. | |||
| .. _Cask: https://github.com/cask/cask | |||
| Julia | |||
| ----- | |||
| * :gh:`gdkrmr/flycheck-julia` makes linting for Julia_ available via Lint.jl_. | |||
| .. _Julia: https://julialang.org | |||
| .. _Lint.jl: https://lintjl.readthedocs.io/en/stable/ | |||
| Haskell | |||
| ------- | |||
| * :flyc:`flycheck-haskell` (*official*) configures Flycheck from the Cabal | |||
| settings and sandbox in Haskell projects. | |||
| Ledger | |||
| ------ | |||
| * :gh:`purcell/flycheck-ledger` adds a syntax checker for the Ledger_ accounting | |||
| tool. | |||
| .. _Ledger: https://ledger-cli.org/ | |||
| Mercury | |||
| ------- | |||
| * :flyc:`flycheck-mercury` (*official*) adds a syntax checker for the Mercury_ | |||
| language. | |||
| .. _Mercury: http://mercurylang.org/ | |||
| OCaml | |||
| ----- | |||
| * :flyc:`flycheck-ocaml` (*official*) adds a syntax checker for OCaml using the | |||
| :gh:`Merlin <ocaml/merlin>` backend. | |||
| PHP | |||
| --- | |||
| * :gh:`emacs-php/phpstan.el` adds a PHP static analyzer using PHPStan_. | |||
| * :gh:`emacs-php/psalm.el` adds a PHP static analyzer using Psalm_. | |||
| .. _PHPStan: https://phpstan.org/ | |||
| .. _Psalm: https://psalm.dev/ | |||
| Python | |||
| ------ | |||
| * :gh:`Wilfred/flycheck-pyflakes` adds a Python syntax checker using Pyflakes_. | |||
| * :gh:`msherry/flycheck-pycheckers` adds a checker for Python that can run multiple syntax checkers simultaneously (Pyflakes_, PEP8, Mypy_ 2/3, etc.). | |||
| * :gh:`chocoelho/flycheck-prospector` adds Prospector_ checker for Python syntax. | |||
| .. _Pyflakes: https://github.com/PyCQA/pyflakes | |||
| .. _Prospector: https://github.com/PyCQA/prospector | |||
| .. _Mypy: http://mypy-lang.org/ | |||
| Rust | |||
| ---- | |||
| * :flyc:`flycheck-rust` (*official*) configures Flycheck according to the Cargo | |||
| settings and layouts of the current Rust project. | |||
| Shell scripts | |||
| ------------- | |||
| * :gh:`Gnouc/flycheck-checkbashisms` adds a shell script syntax checker using | |||
| ``checkbashisms`` which is part of `Debian devscripts`_ and checks for common | |||
| Bash constructs in POSIX shell scripts. | |||
| .. _Debian devscripts: https://salsa.debian.org/debian/devscripts | |||
| @ -0,0 +1,17 @@ | |||
| .. _flycheck-get-help: | |||
| ========== | |||
| Get help | |||
| ========== | |||
| Please ask questions about Flycheck on `Stack Exchange`_ or in our `Gitter | |||
| chat`_. We try to answer all questions as fast and as precise as possible. | |||
| To report bugs and problems please please use our :flyc:`issue tracker | |||
| <flycheck/issues>`. Please note that we have a special policy for | |||
| :ref:`Windows-only issues <flycheck-windows-issues>`. | |||
| Please follow our :ref:`Code of Conduct <flycheck-conduct>` in all these places. | |||
| .. _Stack Exchange: https://emacs.stackexchange.com/questions/tagged/flycheck | |||
| .. _Gitter chat: https://gitter.im/flycheck/flycheck | |||
| @ -0,0 +1,293 @@ | |||
| ======== | |||
| People | |||
| ======== | |||
| .. _flycheck-teams: | |||
| Teams | |||
| ===== | |||
| .. _flycheck-maintainers: | |||
| Maintainers | |||
| ----------- | |||
| * **Clément Pit-Claudel** (:gh:`cpitclaudel`, owner) | |||
| * **fmdkdd** (:gh:`fmdkdd`, owner) | |||
| We maintain Flycheck and all official extensions within the `Flycheck | |||
| organisation`_, and set the direction and scope of Flycheck. We review and | |||
| accept pull requests and feature proposals and fix bugs in Flycheck. | |||
| Emphasized users are also owners of the `Flycheck Organisation`_, and thus have | |||
| administrative privileges for all repositories in Flycheck. Notably only owners | |||
| can currently make Flycheck releases, and their GPG keys sign release tags for | |||
| Flycheck. | |||
| Mention with ``@flycheck/maintainers``. | |||
| .. _Flycheck Organisation: https://github.com/flycheck | |||
| .. _flycheck-moderators: | |||
| Moderators | |||
| ---------- | |||
| Our moderators help uphold our :doc:`conduct`. Currently, we do not have a | |||
| dedicated moderation team; all our :ref:`flycheck-maintainers` also serve as | |||
| moderators in our Github organisation and in our official communication | |||
| channels. | |||
| Mention with ``@flycheck/moderators``. | |||
| .. note:: | |||
| If you’d like to help out with moderation, please contact a maintainer. | |||
| .. _flycheck-language-teams: | |||
| Language teams | |||
| -------------- | |||
| These teams provide support for particular languages in Flycheck. | |||
| Elixir | |||
| ~~~~~~ | |||
| * Aaron Jensen (:gh:`aaronjensen`) | |||
| * Kári Tristan Helgason (:gh:`kthelgason`) | |||
| Mention with ``@flycheck/elixir``. | |||
| Go | |||
| ~~ | |||
| * Dominik Honnef (:gh:`dominikh`) | |||
| Mention with ``@flycheck/go``. | |||
| Haskell | |||
| ~~~~~~~ | |||
| * Sergey Vinokurov (:gh:`sergv`) | |||
| * Steve Purcell (:gh:`purcell`) | |||
| Mention with ``@flycheck/haskell``. | |||
| Javascript | |||
| ~~~~~~~~~~ | |||
| * Saša Jovanić (:gh:`Simplify`) | |||
| Mention with ``@flycheck/javascript``. | |||
| Lua | |||
| ~~~ | |||
| * Gordon Gao (:gh:`ghprince`) | |||
| Mention with ``@flycheck/lua``. | |||
| Mercury | |||
| ~~~~~~~ | |||
| * Matthias Güdemann (:gh:`mgudemann`) | |||
| Mention with ``@flycheck/mercury``. | |||
| PHP | |||
| ~~~ | |||
| * USAMI Kenta (:gh:`zonuexe`) | |||
| Mention with ``@flycheck/php``. | |||
| Puppet | |||
| ~~~~~~ | |||
| * Romanos Skiadas (:gh:`rski`) | |||
| Mention with ``@flycheck/puppet``. | |||
| Ruby | |||
| ~~~~ | |||
| * Saša Jovanić (:gh:`Simplify`) | |||
| Mention with ``@flycheck/javascript``. | |||
| Rust | |||
| ~~~~ | |||
| * :gh:`fmdkdd` | |||
| * Michael Pankov (:gh:`mkpankov`) | |||
| Mention with ``@flycheck/rust``. | |||
| TypeScript | |||
| ~~~~~~~~~~ | |||
| * Saša Jovanić (:gh:`Simplify`) | |||
| Mention with ``@flycheck/typescript``. | |||
| Packagers | |||
| ========= | |||
| We would like to thank all people who package Flycheck on behalf of | |||
| distributions and support our development efforts with their feedback, their | |||
| patches and their testing: | |||
| * Sean Whitton (:gh:`spwhitton`) and the `Debian Emacs addon team`_ (Debian | |||
| packages) | |||
| .. _Debian Emacs addon team: https://pkg-emacsen.alioth.debian.org/ | |||
| Acknowledgements | |||
| ================ | |||
| We would also like to thank the following people and projects: | |||
| * Sebastian Wiesner (:gh:`lunaryorn`) for creating Flycheck in the first place, | |||
| for taking the time and dedication to maintain it for over 4 years, while | |||
| maintaining high standards of code quality and nurturing a healthy, active | |||
| community around it, giving Flycheck the best chances to thrive after his | |||
| departure. | |||
| * Bozhidar Batsov (:gh:`bbatsov`) for his valuable feedback and his constant | |||
| support and endorsement of Flycheck from the very beginning. Notably he added | |||
| Flycheck to his popular :gh:`Prelude <bbatsov/prelude>` project at a very | |||
| early stage and thus brought Flycheck to many new users. | |||
| * Magnar Sveen (:gh:`magnars`) for his :gh:`dash.el <magnars/dash.el>` and | |||
| :gh:`s.el <magnars/s.el>` libraries, which support considerable parts of | |||
| Flycheck internals, and greatly helped to overcome Sebastian’s initial | |||
| aversion to Emacs Lisp. | |||
| * Martin Grenfell (:gh:`scrooloose`) for the Vim syntax checking extension | |||
| :gh:`Syntastic <vim-syntastic/syntastic>` which saved Sebastian’s life back | |||
| when he was using Vim, and served as inspiration for Flycheck and many of its | |||
| syntax checkers. | |||
| * Matthias Güdemann (:gh:`mgudemann`), for his invaluable work on | |||
| Flycheck’s logo. | |||
| * Pavel Kobyakov for his work on GNU Flymake, which is a great work on | |||
| its own, despite its flaws and weaknesses. | |||
| * Simon Carter (:gh:`bbbscarter`), for his patient in-depth testing of automatic | |||
| syntax checking, and his very constructive feedback. | |||
| * Steve Purcell (:gh:`purcell`) for his valuable feedback, the fruitful | |||
| discussions and his important ideas about the shape and design of Flycheck, | |||
| and his indispensable and dedicated work on MELPA, which drives the continuous | |||
| distribution of Flycheck to its users. | |||
| Contributors | |||
| ============ | |||
| The following people—listed in alphabetical order—contributed substantial code | |||
| to Flycheck: | |||
| * Aaron Jensen (:gh:`aaronjensen`) | |||
| * Alain Kalker (:gh:`ackalker`) | |||
| * Alex Reed (:gh:`acr4`) | |||
| * Atila Neves (:gh:`atilaneves`) | |||
| * Ben Sless (:gh:`bsless`) | |||
| * Bozhidar Batsov (:gh:`bbatsov`) | |||
| * Clément Pit-Claudel (:gh:`cpitclaudel`, maintainer, owner) | |||
| * Colin Marquardt (:gh:`cmarqu`) | |||
| * Cristian Capdevila (:gh:`capdevc`) | |||
| * Damon Haley (:gh:`dhaley`) | |||
| * David Caldwell (:gh:`caldwell`) | |||
| * David Holm (:gh:`dholm`) | |||
| * DEADB17 (:gh:`DEADB17`) | |||
| * Deokhwan Kim (:gh:`dkim`) | |||
| * Derek Chen-Becker (:gh:`dchenbecker`) | |||
| * Derek Harland (:gh:`donkopotamus`) | |||
| * Dominik Honnef (:gh:`dominikh`) | |||
| * Doug MacEachern (:gh:`dougm`) | |||
| * Drew Wells (:gh:`drewwells`) | |||
| * Erik Hetzner (:gh:`egh`) | |||
| * Fanael Linithien (:gh:`Fanael`) | |||
| * :gh:`fmdkdd` (maintainer, owner) | |||
| * Fred Morcos (:gh:`fredmorcos`) | |||
| * Gereon Frey (:gh:`gfrey`) | |||
| * Gordon Gao (:gh:`ghprince`) | |||
| * Guido Kraemer (:gh:`gdkrmr`) | |||
| * Gulshan Singh (:gh:`gsingh93`) | |||
| * Iain Beeston (:gh:`iainbeeston`) | |||
| * Ibrahim Awwal (:gh:`ibrahima`) | |||
| * Jackson Ray Hamilton (:gh:`jacksonrayhamilton`) | |||
| * Jim Hester (:gh:`jimhester`) | |||
| * Jimmy Yuen Ho Wong (:gh:`wyuenho`) | |||
| * Joe DeVivo (:gh:`joedevivo`) | |||
| * John Shahid (:gh:`jvshahid`) | |||
| * Juergen Hoetzel (:gh:`juergenhoetzel`) | |||
| * Kári Tristan Helgason (:gh:`kthelgason`) | |||
| * Krzysztof Witkowski (:gh:`kwitek`) | |||
| * Lee Adams (:gh:`leeaustinadams`) | |||
| * Loïc Damien (:gh:`dzamlo`) | |||
| * Lorenzo Villani (:gh:`lvillani`) | |||
| * Łukasz Jędrzejewski (:gh:`jedrz`) | |||
| * Magnar Sveen (:gh:`magnars`) | |||
| * Malyshev Artem (:gh:`proofit404`) | |||
| * Manuel Uberti (:gh:`manuel-uberti`) | |||
| * Marc Sherry (:gh:`msherry`) | |||
| * Marcin Antczak (:gh:`marcinant`) | |||
| * Marcus Majewski (:gh:`hekto`) | |||
| * Marian Schubert (:gh:`maio`) | |||
| * Mario Rodas (:gh:`marsam`) | |||
| * Mark Laws (:gh:`drvink`) | |||
| * Mark Hellewell (:gh:`markhellewell`) | |||
| * Mark Karpov (:gh:`mrkkrp`) | |||
| * Martin Polden (:gh:`mpolden`) | |||
| * mats cronqvist (:gh:`massemanet`) | |||
| * Matthew Curry (:gh:`strawhatguy`) | |||
| * Matthias Dahl (:gh:`BinaryKhaos`) | |||
| * Michael Pankov (:gh:`mkpankov`) | |||
| * Michael Alan Dorman (:gh:`mdorman`) | |||
| * Miles Yucht (:gh:`mgyucht`) | |||
| * Miro Bezjak (:gh:`mbezjak`) | |||
| * Mitch Tishmack (:gh:`mitchty`) | |||
| * Moritz Bunkus (:gh:`mbunkus`) | |||
| * Omair Majid (:gh:`omajid`) | |||
| * :gh:`papaeye` | |||
| * Per Nordlöw (:gh:`nordlow`) | |||
| * Peter Eisentraut (:gh:`petere`) | |||
| * Peter Hoeg (:gh:`peterhoeg`) | |||
| * Peter Oliver (:gh:`mavit`) | |||
| * Peter Vasil (:gh:`ptrv`) | |||
| * Philipp Stephani (:gh:`phst`) | |||
| * Robert Dallas Gray (:gh:`rdallasgray`) | |||
| * Robert O'Connor (:gh:`robbyoconnor`) | |||
| * Robert Zaremba (:gh:`robert-zaremba`) | |||
| * Romano Skiadas (:gh:`rski`) | |||
| * Saša Jovanić (:gh:`Simplify`) | |||
| * Sean Gillespie (:gh:`swgillespie`) | |||
| * Sean Salmon (:gh:`phatcabbage`) | |||
| * Sean Whitton (:gh:`spwhitton`) | |||
| * Sebastian Beyer (:gh:`sebastianbeyer`) | |||
| * Sebastian Wiesner (:gh:`lunaryorn`, founder, former maintainer, former owner) | |||
| * Sebastian Schlueppel (:gh:`s3bs`) | |||
| * Sergey Vinokurov (:gh:`sergv`) | |||
| * Stephen Lewis (:gh:`stephenjlewis`) | |||
| * Steve Purcell (:gh:`purcell`) | |||
| * Sven Keidel (:gh:`svenkeidel`) | |||
| * Sylvain Benner (:gh:`syl20bnr`) | |||
| * Sylvain Rousseau (:gh:`thisirs`) | |||
| * Syohei Yoshida (:gh:`syohex`) | |||
| * Ted Zlatanov (:gh:`tzz`) | |||
| * Tom Jakubowski (:gh:`tomjakubowski`) | |||
| * Tom Willemse (:gh:`ryuslash`) | |||
| * Tomoya Tanjo (:gh:`tom-tan`) | |||
| * Troy Hinckley (:gh:`CeleritasCelery`) | |||
| * Usami Kenta (:gh:`zonuexe`) | |||
| * Victor Deryagin (:gh:`vderyagin`) | |||
| * Ville Skyttä (:gh:`scop`) | |||
| * Vlatko Basic (:gh:`vlatkoB`) | |||
| * Wieland Hoffmann (:gh:`mineo`) | |||
| * Wilfred Hughes (:gh:`Wilfred`) | |||
| * William Cummings (:gh:`wcummings`) | |||
| * William Xu (:gh:`xwl`) | |||
| * Yannick Roehlly (:gh:`yannick1974`) | |||
| * Yasuyuki Oka (:gh:`yasuyk`) | |||
| * Zhuo Yuan (:gh:`yzprofile`) | |||
| For a complete list of all code contributors see the `Contributor Graph`_ or | |||
| ``git shortlog --summary``. | |||
| .. _Contributor Graph: https://github.com/flycheck/flycheck/graphs/contributors | |||
| @ -0,0 +1,302 @@ | |||
| # Copyright (C) 2017, 2018 Flycheck contributors | |||
| # Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| # This file is not part of GNU Emacs. | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| import re | |||
| import sys | |||
| import os | |||
| from pathlib import Path | |||
| from docutils import nodes | |||
| from docutils.statemachine import ViewList | |||
| from docutils.transforms import Transform | |||
| from docutils.parsers.rst import Directive, directives | |||
| from sphinx import addnodes | |||
| from sphinx.util.nodes import set_source_info, process_index_entry | |||
| from sphinx.util import logging | |||
| logger = logging.getLogger(__name__) | |||
| sys.path.append(str(Path(__file__).parent)) | |||
| ON_RTD = os.environ.get('READTHEDOCS', None) == 'True' | |||
| needs_sphinx = '1.3' | |||
| extensions = [ | |||
| 'sphinx.ext.intersphinx', | |||
| 'sphinx.ext.extlinks', | |||
| 'sphinx.ext.todo', | |||
| # Domain for Emacs Lisp | |||
| 'elisp', | |||
| # Cross-references to info nodes | |||
| 'info' | |||
| ] | |||
| # Project metadata | |||
| project = 'Flycheck' | |||
| copyright = ' 2014-2017, Sebastian Wiesner and Flycheck contributors' | |||
| author = 'Sebastian Wiesner' | |||
| def read_version(): | |||
| """Extract version number from ``flycheck.el`` and return it as string.""" | |||
| version_pattern = re.compile(r'^;;\s*Version:\s+(\d.+)$', re.MULTILINE) | |||
| flycheck = Path(__file__).resolve().parent.parent.joinpath('flycheck.el') | |||
| with flycheck.open(encoding='utf-8') as source: | |||
| match = version_pattern.search(source.read()) | |||
| if match: | |||
| return match.group(1) | |||
| else: | |||
| raise ValueError('Failed to parse Flycheck version from ' | |||
| 'Version: of flycheck.el') | |||
| def read_minimum_emacs_version(): | |||
| """Extract minimum Emacs version from ``flycheck.el``.""" | |||
| version_pattern = re.compile( | |||
| r'^;; Package-Requires:.*\(emacs\s*"([^"]+)"\).*$', re.MULTILINE) | |||
| flycheck = Path(__file__).resolve().parent.parent.joinpath('flycheck.el') | |||
| with flycheck.open(encoding='utf-8') as source: | |||
| match = version_pattern.search(source.read()) | |||
| if match: | |||
| return match.group(1) | |||
| else: | |||
| raise ValueError('Vailed to parse minimum Emacs version from ' | |||
| 'Package-Requires of flycheck.el!') | |||
| release = read_version() | |||
| version = '.'.join(release.split('.')[:2]) | |||
| # Source settings | |||
| source_suffix = '.rst' | |||
| master_doc = 'index' | |||
| rst_prolog = """\ | |||
| .. role:: elisp(code) | |||
| :language: elisp | |||
| .. |min-emacs| replace:: {emacs_version}+ | |||
| """.format(emacs_version=read_minimum_emacs_version()) | |||
| # Build settings | |||
| exclude_patterns = ['_build'] | |||
| default_role = 'any' | |||
| primary_domain = 'el' | |||
| templates_path = ['_templates'] | |||
| # The name of the Pygments (syntax highlighting) style to use. | |||
| pygments_style = 'sphinx' | |||
| # Warn about all undefined references, but exclude references to built-in | |||
| # symbols which we don't document here. | |||
| # TODO: Resolve built-in symbols to the Emacs Lisp references? | |||
| nitpicky = True | |||
| nitpick_ignore = [ | |||
| ('any', 'default-directory'), | |||
| ('any', 'package-initialize'), | |||
| ('any', 'package-archives'), | |||
| ('any', 'user-init-file'), | |||
| ('any', 'user-emacs-directory'), | |||
| ('any', 'check-declare-file'), | |||
| ('any', 'declare-function'), | |||
| ('any', 'exec-path'), | |||
| ('any', 'sh-shell'), | |||
| ('any', 'rx'), | |||
| ] | |||
| # HTML settings | |||
| html_theme = 'alabaster' | |||
| html_theme_options = { | |||
| 'logo': 'logo.png', | |||
| 'logo_name': False, | |||
| 'description': 'Syntax checking for GNU Emacs', | |||
| 'github_user': 'flycheck', | |||
| 'github_repo': 'flycheck', | |||
| 'github_type': 'star', | |||
| 'github_banner': True, | |||
| 'travis_button': False, | |||
| } | |||
| html_sidebars = { | |||
| '**': [ | |||
| 'about.html', | |||
| 'tables.html', | |||
| 'navigation.html', | |||
| 'relations.html', | |||
| 'searchbox.html', | |||
| ] | |||
| } | |||
| html_static_path = ['_static'] | |||
| html_favicon = '_static/favicon.ico' | |||
| # Ignore localhost when checking links | |||
| linkcheck_ignore = [r'http://localhost:\d+/?'] | |||
| # Cross-reference remote Sphinx sites | |||
| intersphinx_mapping = { | |||
| 'python': ('https://docs.python.org/3.5', None) | |||
| } | |||
| extlinks = { | |||
| 'gh': ('https://github.com/%s', ''), | |||
| 'flyc': ('https://github.com/flycheck/%s', '') | |||
| } | |||
| # While still have work to do :) | |||
| # FIXME: Remove when the old Texinfo manual is completed ported | |||
| todo_include_todos = True | |||
| class SupportedLanguage(Directive): | |||
| required_arguments = 1 | |||
| final_argument_whitespace = True | |||
| has_content = True | |||
| option_spec = { | |||
| 'index_as': directives.unchanged | |||
| } | |||
| def run(self): | |||
| language = self.arguments[0] | |||
| indexed_languages = self.options.get('index_as') or language | |||
| index_specs = ['pair: {}; language'.format(lang) | |||
| for lang in indexed_languages.splitlines()] | |||
| name = nodes.fully_normalize_name(language) | |||
| target = 'language-{}'.format(name) | |||
| targetnode = nodes.target('', '', ids=[target]) | |||
| self.state.document.note_explicit_target(targetnode) | |||
| indexnode = addnodes.index() | |||
| indexnode['entries'] = [] | |||
| indexnode['inline'] = False | |||
| set_source_info(self, indexnode) | |||
| for spec in index_specs: | |||
| indexnode['entries'].extend(process_index_entry(spec, target)) | |||
| sectionnode = nodes.section() | |||
| sectionnode['names'].append(name) | |||
| title, messages = self.state.inline_text(language, self.lineno) | |||
| titlenode = nodes.title(language, '', *title) | |||
| sectionnode += titlenode | |||
| sectionnode += messages | |||
| self.state.document.note_implicit_target(sectionnode, sectionnode) | |||
| self.state.nested_parse(self.content, self.content_offset, sectionnode) | |||
| return [indexnode, targetnode, sectionnode] | |||
| class SyntaxCheckerConfigurationFile(Directive): | |||
| required_arguments = 1 | |||
| final_argument_whitespace = True | |||
| def run(self): | |||
| option = self.arguments[0] | |||
| wrapper = nodes.paragraph() | |||
| docname = self.state.document.settings.env.docname | |||
| template = ViewList("""\ | |||
| .. index:: single: Configuration file; {0} | |||
| .. el:defcustom:: {0} | |||
| Configuration file for this syntax checker. See | |||
| :ref:`flycheck-checker-config-files`. | |||
| """.format(option).splitlines(), docname) | |||
| self.state.nested_parse(template, self.content_offset, wrapper) | |||
| return wrapper.children.copy() | |||
| class IssueReferences(Transform): | |||
| ISSUE_PATTERN = re.compile(r'\[GH-(\d+)\]') | |||
| ISSUE_URL_TEMPLATE = 'https://github.com/flycheck/flycheck/issues/{}' | |||
| default_priority = 999 | |||
| def apply(self): | |||
| docname = self.document.settings.env.docname | |||
| if docname != 'changes': | |||
| # Only transform issue references in changelo | |||
| return | |||
| for node in self.document.traverse(nodes.Text): | |||
| parent = node.parent | |||
| new_nodes = [] | |||
| last_issue_ref_end = 0 | |||
| text = str(node) | |||
| for match in self.ISSUE_PATTERN.finditer(text): | |||
| # Extract the text between the last issue reference and the | |||
| # current issue reference and put it into a new text node | |||
| head = text[last_issue_ref_end:match.start()] | |||
| if head: | |||
| new_nodes.append(nodes.Text(head)) | |||
| # Adjust the position of the last issue reference in the | |||
| # text | |||
| last_issue_ref_end = match.end() | |||
| # Extract the issue text and the issue number | |||
| issuetext = match.group(0) | |||
| issue_id = match.group(1) | |||
| # Turn the issue into a proper reference | |||
| refnode = nodes.reference() | |||
| refnode['refuri'] = self.ISSUE_URL_TEMPLATE.format(issue_id) | |||
| refnode.append(nodes.inline( | |||
| issuetext, issuetext, classes=['xref', 'issue'])) | |||
| new_nodes.append(refnode) | |||
| # No issue references were found, move on to the next node | |||
| if not new_nodes: | |||
| continue | |||
| # Extract the remaining text after the last issue reference | |||
| tail = text[last_issue_ref_end:] | |||
| if tail: | |||
| new_nodes.append(nodes.Text(tail)) | |||
| parent.replace(node, new_nodes) | |||
| def build_offline_html(app): | |||
| from sphinx.builders.html import StandaloneHTMLBuilder | |||
| build_standalone = isinstance(app.builder, StandaloneHTMLBuilder) | |||
| if app.config.flycheck_offline_html and build_standalone: | |||
| logger.info( | |||
| 'Building offline documentation without external resources!') | |||
| app.builder.theme_options['github_banner'] = 'false' | |||
| app.builder.theme_options['github_button'] = 'false' | |||
| def add_offline_to_context(app, _pagename, _templatename, context, _doctree): | |||
| # Expose offline setting in HTML context | |||
| context['flycheck_offline_html'] = app.config.flycheck_offline_html | |||
| def setup(app): | |||
| app.add_object_type('syntax-checker', 'checker', | |||
| 'pair: %s; Syntax checker') | |||
| app.add_directive('supported-language', SupportedLanguage) | |||
| app.add_directive('syntax-checker-config-file', | |||
| SyntaxCheckerConfigurationFile) | |||
| app.add_transform(IssueReferences) | |||
| # Build offline HTML that loads no external resources, for use in 3rd party | |||
| # packages, see https://github.com/flycheck/flycheck/issues/999 | |||
| app.add_config_value('flycheck_offline_html', False, 'html') | |||
| app.connect('builder-inited', build_offline_html) | |||
| app.connect('html-page-context', add_offline_to_context) | |||
| @ -0,0 +1,274 @@ | |||
| .. _flycheck-contributors-guide: | |||
| ===================== | |||
| Contributor’s Guide | |||
| ===================== | |||
| Thank you very much for your interest in contributing to Flycheck! We’d like to | |||
| warmly welcome you in the Flycheck community, and hope that you enjoy your time | |||
| with us! | |||
| There are many ways to contribute to Flycheck, and we appreciate all of them. We | |||
| hope that this document helps you to contribute. If you have questions, please | |||
| ask on our `issue tracker`_ or in our `Gitter chatroom`_. | |||
| For a gentle start please take a look at all the things we `need your help | |||
| with`_ and look for `beginner-friendly tasks`_. | |||
| Please note that all contributors are expected to follow our :ref:`Code of | |||
| Conduct <flycheck-conduct>`. | |||
| .. _issue tracker: https://github.com/flycheck/flycheck/issues | |||
| .. _Gitter chatroom: https://gitter.im/flycheck/flycheck | |||
| .. _need your help with: https://github.com/flycheck/flycheck/issues?q=is%3Aissue+is%3Aopen+label%3A%22needs+help%22 | |||
| .. _beginner-friendly tasks: https://github.com/flycheck/flycheck/labels/beginner%20friendly | |||
| .. _flycheck-bug-reports: | |||
| Bug reports | |||
| =========== | |||
| Bugs are a sad reality in software, but we strive to have as few as possible in | |||
| Flycheck. Please liberally report any bugs you find. If you are not sure whether | |||
| something is a bug or not, please report anyway. | |||
| If you have the chance and time please `search existing issues`_, as it’s | |||
| possible that someone else already reported your issue. Of course, this doesn’t | |||
| always work, and sometimes it’s very hard to know what to search for, so this is | |||
| absolutely optional. We definitely don’t mind duplicates, please report | |||
| liberally. | |||
| To open an issue simply fill out the `issue form`_. To help us fix the issue, | |||
| include as much information as possible. When in doubt, better include too much | |||
| than too little. Here’s a list of facts that are important: | |||
| * What you did, and what you expected to happen instead | |||
| * Whether and how you were able to `reproduce the issue in emacs -Q`_ | |||
| * Your Flycheck setup from ``M-x flycheck-verify-setup`` | |||
| .. _search existing issues: https://github.com/flycheck/flycheck/issues?q=is%3Aissue | |||
| .. _issue form: https://github.com/flycheck/flycheck/issues/new | |||
| .. _reproduce the issue in emacs -Q: https://emacs.stackexchange.com/questions/28429/how-do-i-troubleshoot-emacs-problems | |||
| .. _flycheck-windows-issues: | |||
| Windows-only issues | |||
| ------------------- | |||
| As Flycheck does not support Windows officially we generally do *not* attempt to | |||
| fix issues that only occur on Windows. We will move all Windows-only issues to | |||
| the `list of open Windows issues`_, and leave them to Windows users and | |||
| developers. | |||
| We welcome anyone who wants to fix open Windows issues, and we will merge pull | |||
| requests for improved Windows compatibility. If you know Windows and Emacs, | |||
| please take a look at the list of open Windows issues and try to fix any of | |||
| these. | |||
| .. _list of open Windows issues: https://github.com/flycheck/flycheck/labels/arch%3A%20windows%20only | |||
| Feature requests | |||
| ================ | |||
| To request a new feature please open a new issue through our `issue form`_. | |||
| A feature request needs to find a core developer or maintainer who adopts and | |||
| implements it. | |||
| The build system | |||
| ================ | |||
| Flycheck provides a :file:`Makefile` with some convenient targets to compile and | |||
| test Flycheck. The Makefile requires Cask_, the Emacs Lisp dependency manager. | |||
| Run ``make help`` to see a list of all available targets. Some common ones are: | |||
| - ``make init`` initialises the project by installing local Emacs Lisp | |||
| dependencies. | |||
| - ``make check`` checks all Emacs Lisp sources. This target requires Emacs 25. | |||
| - ``make compile`` compiles Flycheck and its libraries to byte code. | |||
| - ``make format`` formats all Emacs Lisp sources. | |||
| - ``make specs`` runs all Buttercup_ specs for Flycheck. Set :makevar:`PATTERN` | |||
| to run only specs matching a specific regular expression, e.g. ``make | |||
| PATTERN='^Mode Line' specs`` to run only tests for the mode line. | |||
| - ``make unit`` runs all ERT unit tests for Flycheck. We are phasing ERT out in | |||
| favour of Buttercup; no new ERT unit tests will be added and this target will | |||
| eventually be removed. | |||
| - ``make integ`` runs all integration tests for Flycheck syntax checkers. These | |||
| tests are dependent on the checker programs and their versions; expect | |||
| failures when running this target with bleeding-edge checkers. Set | |||
| :makevar:`SELECTOR` to run only tests matching a specific ERT selector, | |||
| e.g. ``make SELECTOR='(language haskell)' integ`` to run only integration | |||
| tests for Haskell. ``make LANGUAGE=haskell integ`` is a shortcut for this. | |||
| If you want to replicate the integration tests that are run on the CI, | |||
| continue reading. | |||
| .. _Cask: http://cask.readthedocs.io/ | |||
| .. _Buttercup: https://github.com/jorgenschaefer/emacs-buttercup | |||
| Running all the integration tests | |||
| ================================= | |||
| To run all the integration tests, you need to have all the syntax checkers | |||
| installed. As that can be tedious work, and since your locally installed tools | |||
| can have different versions than the tools used on the CI, we have created a | |||
| Docker image with most of the supported checkers. To use the Docker image | |||
| locally and replicate the integration tests that are run on the CI, first you | |||
| need to build the image:: | |||
| cd flycheck | |||
| docker pull flycheck/emacs-cask:26.2 | |||
| docker pull flycheck/all-tools:latest | |||
| docker build --build-arg EMACS_VERSION=26.2 --tag tools-and-emacs:26.2 -f .travis/tools-and-emacs . | |||
| Replace ``26.2`` by the Emacs version you want to test. See the available | |||
| versions on `docker hub`_. | |||
| Once the image is built, you can use it to run the integration tests:: | |||
| docker run --rm -it -v `pwd`:/flycheck --workdir /flycheck tools-and-emacs:26.2 /bin/bash -c "make integ" | |||
| Note that the ``all-tools`` image is rebuilt each month, so the versions of the | |||
| its syntax checkers will change accordingly. You can check the version of each | |||
| installed tool by running the ``check-tools`` script in the image:: | |||
| docker run --rm -it -v `pwd`:/flycheck --workdir /flycheck tools-and-emacs:26.2 check-tools | |||
| .. _docker hub: https://hub.docker.com/r/flycheck/emacs-cask/tags | |||
| Pull requests | |||
| ============= | |||
| Pull Requests are the primary mechanism to submit your own changes to | |||
| Flycheck. Github provides great documentation about `Pull Requests`_. | |||
| .. _Pull Requests: https://help.github.com/articles/using-pull-requests/ | |||
| Please make your pull requests against the ``master`` branch. | |||
| Use ``make check specs unit`` to test your pull request locally. When making | |||
| changes to syntax checkers of a specific language, it’s also a good idea to run | |||
| :samp:`make LANGUAGE={language} integ` and check whether the tests for the | |||
| particular language still work. A successful ``make integ`` is by no means | |||
| mandatory for pull requests, though, the continuous integration will test your | |||
| changes, too. | |||
| .. important:: | |||
| To contribute to Flycheck you must sign our CLA_ (Contributor License | |||
| Agreement). The CLA Assistant bot will automatically ask you to do this when | |||
| you open a pull request, and will let you sign the CLA through your Github | |||
| account. | |||
| We require this process mostly to make you aware of the licensing | |||
| implications of contributing to Flycheck and to obtain your explicit approval | |||
| of our licenses for your contribution. | |||
| .. _CLA: https://gist.github.com/lunaryorn/c9c0d656fe7e704da2f734779242ec99 | |||
| All pull requests go through a two-stage review process: | |||
| * :ref:`Maintainer <flycheck-maintainers>` review the general idea and direction | |||
| of the pull request and leave a ``LGTM`` comment if they believe that the | |||
| change is a good addition to Flycheck. We currently require at least one | |||
| approval from a maintainer. | |||
| * :ref:`All contributors <flycheck-language-teams>`—language teams in | |||
| particular—check the technical implementation of a pull request through `pull | |||
| request reviews`_, and either approve it or request changes. We currently | |||
| require at least one approval and no requested changes. | |||
| .. important:: | |||
| We have a comprehensive :ref:`flycheck-style-guide` that explains what | |||
| features we will accept, how our code should look likewise, what tests we | |||
| require, how commit messages should look like, and so on. | |||
| Take a look at it to see what we look for in a code review. | |||
| Additionally all pull requests go through automated tests on `Travis CI`_ which | |||
| check code style, run unit tests, etc | |||
| Feel free to mention individual contributors or entire teams | |||
| (e.g. ``@flycheck/maintainers`` or ``@flycheck/javascript``) to ask for help or | |||
| feedback or request a review. Please mention the maintainers | |||
| (``@flycheck/maintainers``) if you think that your pull request has been waiting | |||
| for review too long. You can expect a first response to any pull request in a | |||
| couple of days. | |||
| Once the pull request passed review and automated tests we will merge it. We | |||
| may also ask you whether you'd like to join Flycheck and help us, thus giving | |||
| you commit access to our repository and let you merge your own pull request. | |||
| .. _pull request reviews: https://help.github.com/articles/about-pull-request-reviews/ | |||
| .. _Travis CI: https://travis-ci.org/flycheck/flycheck/pull_requests | |||
| Writing documentation | |||
| ===================== | |||
| Documentation improvements are very welcome. Flycheck’s manual is written in | |||
| reStructuredText_ and built with Sphinx_. The source of the manual resides in | |||
| the ``doc/`` directory. | |||
| You need Python 3.4 or newer to install Sphinx_ for Flycheck’s documentation. | |||
| On macOS it is recommended that you use Homebrew_ to install the latest Python | |||
| version with ``brew install python3``. On Linux you should be able to obtain | |||
| Python 3.4 from the package manager of your distribution. | |||
| With Python 3 installed change into the ``doc/`` directory and run ``make init`` | |||
| to install Sphinx and related tools required for Flycheck’s documentation. We | |||
| recommend that you use virtualenv_ to avoid a global installation of Python | |||
| modules. ``make init`` will warn you if you do not. | |||
| When editing documentation run ``make html-auto`` to view the results of your | |||
| edits. This target runs a local webserver at http://localhost:8000 which serves | |||
| the HTML documentation and watches the documentation sources for changes to | |||
| rebuild automatically. When you have finished your edits it is a good idea to | |||
| run ``make linkcheck`` to verify all links in the documentation. Note that this | |||
| target can take a while especially when run on a clean build. | |||
| Run ``make help`` to see a list of all available Make targets for the | |||
| documentation. | |||
| Documentation pull requests work in the same way as other pull requests. To | |||
| find documentation issues sort by the `documentation`_ label. | |||
| .. _ReStructuredText: http://docutils.sourceforge.net/rst.html | |||
| .. _Sphinx: http://www.sphinx-doc.org | |||
| .. _Homebrew: https://brew.sh | |||
| .. _virtualenv: https://virtualenv.pypa.io/en/latest/ | |||
| .. _documentation: https://github.com/flycheck/flycheck/labels/documentation | |||
| Issue management | |||
| ================ | |||
| We use Github labels for basic issue management: | |||
| - **The red “bug” label denotes critical bugs in Flycheck that must be fixed | |||
| urgently.** | |||
| - Violet labels describe the area of Flycheck the issue belongs to. | |||
| - The green “beginner friendly” label denotes easy tasks for newcomers to the | |||
| project. | |||
| - Orange labels denote blockers. | |||
| - Grey labels indicate resolutions to issues. | |||
| Out of tree contributions | |||
| ========================= | |||
| There are many ways that you can contribute to Flycheck that go beyond | |||
| this repository. | |||
| Answer questions in our `Gitter channel`_ or on StackExchange_. | |||
| Participate in Flycheck discussions in other Emacs communities and help | |||
| users with troubles. | |||
| Write :ref:`extensions for Flycheck <flycheck-extensions>`. | |||
| .. _Gitter channel: https://gitter.im/flycheck/flycheck | |||
| .. _StackExchange: https://emacs.stackexchange.com/questions/tagged/flycheck | |||
| -------------- | |||
| This contributing guide is heavily inspired by `Rust’s excellent | |||
| contributing | |||
| information <https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md>`__. | |||
| @ -0,0 +1,306 @@ | |||
| .. _flycheck-maintainers-guide: | |||
| ==================== | |||
| Maintainer’s Guide | |||
| ==================== | |||
| Issue triage | |||
| ============ | |||
| Please label incoming tickets accordingly according to these rules: | |||
| - Add the “bug” label to things that you think **must be fixed urgently**. | |||
| Please don’t use this label for bugs that do not severely impede Flycheck’s | |||
| functionality. | |||
| - Add the “needs review” label to new bugs and pull requests that need to be | |||
| reviewed. | |||
| - Add the “beginner friendly” label to really easy things. If you add this | |||
| label please also add a comment that outlines a possible solution. | |||
| - Add “blocked” to bugs that need further comment or help from the reporter, and | |||
| to pull requests that need to be improved. | |||
| - Add “needs help” to anything that no contributor will work on, to mark the | |||
| issue as available for external contributors and inform users that we will not | |||
| work on the issue. | |||
| - Add “windows only” for bugs that appear to only affect Windows operating | |||
| systems. | |||
| **If you’d like to review a bug or pull request please assign the corresponding | |||
| ticket to you.** | |||
| In issues for specific languages that Flycheck support please mention the | |||
| corresponding :ref:`language team <flycheck-language-teams>` if one exists. | |||
| Git workflow | |||
| ============ | |||
| Our Git workflow is simple: | |||
| * The ``master`` branch is always shippable. | |||
| * Every feature and every non-trivial change goes through a pull request. | |||
| GitHub calls this the “GitHub Flow” and has a very nice `visual guide`_ for this | |||
| model. | |||
| .. _visual guide: https://guides.github.com/introduction/flow/ | |||
| .. _flycheck-branch-rules: | |||
| Branch rules | |||
| ------------ | |||
| Our workflow implies a couple of rules about which branches to push code to: | |||
| * Please commit new features, larger changes and refactorings and updates to | |||
| documentation to separate branches and open a pull request for review and | |||
| discussion. | |||
| * The ``master`` branch is protected. Only :ref:`owners <flycheck-maintainers>` | |||
| can push directly to it. Everyone else needs to open a pull request. Github | |||
| requires maintainer approval and passing Travis CI tests before a pull request | |||
| can be merged to master. | |||
| .. important:: | |||
| When creating a new branch please use a *descriptive name* to communicate the | |||
| purpose of the branch to other developers and maintainers. ``fix-bug-42`` is | |||
| not a great name, but ``42-fix-void-function-error-in-error-list`` is. | |||
| .. _pull request: https://help.github.com/articles/using-pull-requests/ | |||
| .. _flycheck-pull-requests-reviews: | |||
| Pull requests reviews | |||
| --------------------- | |||
| We review all pull requests, and require two different kinds of approval: | |||
| * At least one maintainer must approve the idea and direction with a ``LGTM`` | |||
| comment. | |||
| * At least one contributor (maintainer or otherwise) must approve the | |||
| implementation by leaving an approved `pull request review`_, and no | |||
| contributors must have requested changes. | |||
| .. _pull request review: https://help.github.com/articles/about-pull-request-reviews/ | |||
| As a maintainer | |||
| ~~~~~~~~~~~~~~~ | |||
| * Consider whether you personally think that the change is a good addition to | |||
| Flycheck. | |||
| * Weight the expected benefits and impact of the feature against the | |||
| expected complexity. | |||
| * Check whether the pull request complies with our :ref:`style guide | |||
| <flycheck-style-guide>`, but don't go too much into technical details. | |||
| * Don't review for technical details. It's the idea and direction that counts. | |||
| If you would like to see the pull request in Flycheck leave a ``LGTM`` comment. | |||
| As a contributor | |||
| ~~~~~~~~~~~~~~~~ | |||
| * Check the technical implementation. | |||
| * Consider the impact on syntax checking for a language. | |||
| * Check whether the tests pass. | |||
| * Check whether the PR complies with our :ref:`style guide | |||
| <flycheck-style-guide>`. | |||
| * Challenge the technical implementation of a pull request, and ask questions | |||
| about dubious code. | |||
| * Consider whether there might be a simpler approach or a better solution to the | |||
| problem that the PR solves. | |||
| If you find any issues please leave a `pull request review`_ that requests | |||
| for changes. Please try to leave an inline comment wherever possible and try to | |||
| suggest a better solution, to make it easy for the PR author to discover and fix | |||
| the issues. | |||
| If you didn't find any issues leave a `pull request review`_ that approves the | |||
| changes. | |||
| In doubt request changes first and let the PR author explain their intention and | |||
| implementation. You can still approve the review afterwards if you are | |||
| satisfied. | |||
| Merge guidelines | |||
| ~~~~~~~~~~~~~~~~ | |||
| Any contributor may merge approved pull requests. Our protection rules for the | |||
| ``master`` branch ensure that only approved pull requests can be merged, but you | |||
| still have to check a few things before merging: | |||
| * Are commits squashed? Before merging please take an extra look at the commits | |||
| to make sure that the commits were properly squashed and have good commit | |||
| messages. If needed, ask the contributor to improve the commit messages and | |||
| squash the commits first, by requesting changes with a pull request review. | |||
| * Does the PR pass the integration tests? Not all checkers have integration | |||
| tests, and not all tests are run on CI, so contributors should make sure to | |||
| run them on their side. | |||
| * Should the PR warrant a line in the changelog? User-facing changes should be | |||
| documented in ``CHANGES.rst``. | |||
| For new features: | |||
| * Does the PR include tests? A new syntax checker should have at least one | |||
| accompanying integration test. | |||
| * Does the PR include documentation? New syntax checkers or options should be | |||
| documented in :ref:`flycheck-languages`. | |||
| If all the points above have been addressed, then go ahead and click that green | |||
| button :) | |||
| .. note:: | |||
| We require proper merges for pull requests, to preserve the fact that a | |||
| change came from a pull request in the git history and to retain any commit | |||
| signatures that may exist. As such you can't squash-merge or rebase-merge | |||
| through GitHub's UI. | |||
| .. _flycheck-git-signatures: | |||
| Signatures for commits and tags | |||
| ------------------------------- | |||
| We sign all release tags as part of our :ref:`flycheck-release-process`. Thus | |||
| you need a GPG key pair for Git. Github provides a great guide which helps you | |||
| to `generate a key`_ and to `tell Git about your key`_. Please also `add your | |||
| key`_ to your Github account. | |||
| We also recommend that you sign all your commits with your key. Again, Github | |||
| provides a good guide to `sign commits`_. | |||
| .. seealso:: | |||
| `Signing Your Work`_ | |||
| For more information about signing commits and tags take a look at the | |||
| section in the Git manual. | |||
| .. _Signing Your Work: https://git-scm.com/book/uz/v2/Git-Tools-Signing-Your-Work | |||
| .. _generate a key: https://help.github.com/articles/generating-a-gpg-key/ | |||
| .. _tell Git about your key: https://help.github.com/articles/telling-git-about-your-gpg-key/ | |||
| .. _add your key: https://help.github.com/articles/adding-a-new-gpg-key-to-your-github-account/ | |||
| .. _sign commits: https://help.github.com/articles/signing-commits-using-gpg/ | |||
| Tooling and Services | |||
| ==================== | |||
| In addition to Github_ where we host code and do code reviews we use a bit of | |||
| extra tooling and some 3rd party services for Flycheck: | |||
| * ReadTheDocs_ hosts http://www.flycheck.org and automatically rebuilds it on | |||
| every change. It works mostly automatically and requires little | |||
| configuration. | |||
| * `Travis CI`_ runs our tests after every push and for every pull request. | |||
| It's configured through ``.travis.yml``. | |||
| * `CLA assistant`_ checks signatures to our CLA_ and allows contributors to sign | |||
| the CLA through their Github account. | |||
| All :ref:`maintainers <flycheck-maintainers>` have administrative access to | |||
| these services so in case of an issue just contact them. | |||
| .. _Github: https://github.com/flycheck | |||
| .. _ReadTheDocs: https://readthedocs.org/projects/flycheck/ | |||
| .. _Travis CI: https://travis-ci.org/flycheck/flycheck | |||
| .. _CLA assistant: https://cla-assistant.io | |||
| .. _CLA: https://gist.github.com/lunaryorn/c9c0d656fe7e704da2f734779242ec99 | |||
| .. _flycheck-maintenance-scripts: | |||
| Maintenance scripts | |||
| =================== | |||
| Administrative processes are tedious and time-consuming, so we try to automate | |||
| as much as possible. The :file:`maint/` directory contains many scripts for | |||
| this purpose. ``make -C maint/ help`` provides an overview over all | |||
| administrative tasks. | |||
| Most of these scripts require Python 3.5 and additional Python libraries. On OS | |||
| X it is recommended that you use Homebrew_ to install the latest Python version | |||
| with ``brew install python3``. On Linux you should be able to obtain Python 3.5 | |||
| from the package manager of your distribution. | |||
| To install all required libraries run ``make -C maint init``. We recommend that | |||
| you use virtualenv_ to avoid a global installation of Python modules. ``make | |||
| init`` will warn you if you do not. | |||
| .. _Homebrew: https://brew.sh | |||
| .. _virtualenv: https://virtualenv.pypa.io/en/latest/ | |||
| Versioning and releases | |||
| ======================= | |||
| We use a single continuously increasing version number for Flycheck. | |||
| .. important:: | |||
| Breaking changes may occur **at any point**. | |||
| Please feel free to make a release whenever you think it’s appropriate. | |||
| It’s generally a good idea to release when | |||
| - you fixed an important bug that affects many users, | |||
| - there are a couple of new syntax checkers available, | |||
| - there’s a major new feature in ``master``, | |||
| - etc. | |||
| In doubt just make a release. We aim to release early and frequently. If | |||
| anything breaks anything we can just publish another release afterwards. | |||
| .. _flycheck-release-process: | |||
| Release process | |||
| --------------- | |||
| First, check that | |||
| 1. you are on ``master``, | |||
| 2. your working directory is clean, i.e. has no uncommitted changes or untracked | |||
| files, | |||
| 3. all commits are pushed, | |||
| 4. and Travis CI passes for the latest commit on ``master``. | |||
| If all is good a new release is a simple as | |||
| .. code-block:: console | |||
| $ make -C maint release | |||
| This runs the release script in :file:`maint/release.py`. If any of the above | |||
| requirements isn't met the release script will signal an error and abort. | |||
| The release script bumps the version number, commits and tags a new release, and | |||
| pushes it to Github. | |||
| .. note:: | |||
| The tag is *signed*; you must configure Git for :ref:`signing commits and | |||
| tags <flycheck-git-signatures>` before you make a release the first time. | |||
| After pushing the new release to Github, the script bumps the version number | |||
| again, to the next snapshot, and commits the changes again. | |||
| Once the script is completed please | |||
| 1. Edit the `release information`_ on Github and add a short summary about the | |||
| release. Don’t forget to add a link to the complete changelog and upload the | |||
| package TAR file. | |||
| 2. Enable the new release on the ReadTheDocs `versions dashboard`_. | |||
| 3. Announce the new release in our Gitter_ channel, and wherever else you see | |||
| fit. | |||
| .. _release information: https://github.com/flycheck/flycheck/releases | |||
| .. _versions dashboard: https://readthedocs.org/dashboard/flycheck/versions/ | |||
| .. _Gitter: https://gitter.im/flycheck/flycheck | |||
| New maintainers | |||
| =============== | |||
| To propose a new maintainer open a pull request that adds the user to | |||
| ``MAINTAINERS`` and ``doc/community/people.rst``. The pull request is subject | |||
| to the :ref:`same rules <flycheck-pull-requests-reviews>` as all other pull | |||
| requests. Notably it goes through the same approval process. | |||
| Once merged please also | |||
| - add the new maintainer to the ``Maintainers`` team of the Github | |||
| organisation. This does not award additional privileges, it's just to support | |||
| ``@flycheck/maintainers`` mentions for the sake of convenience, | |||
| - invite the new maintainer to the internal `Maintainers channel`_ on Gitter, | |||
| .. _Maintainers channel: https://gitter.im/flycheck/maintainers | |||
| @ -0,0 +1,193 @@ | |||
| .. _flycheck-style-guide: | |||
| ============= | |||
| Style Guide | |||
| ============= | |||
| This document describes our code style. It tells you what to look for when | |||
| making changes to Flycheck, or when reviewing pull requests. | |||
| Features | |||
| ======== | |||
| Flycheck’s scope and focus is providing the infrastructure and foundations for | |||
| on-the-fly syntax checking. Flycheck provides the basics but deep integration | |||
| with particular programming languages is best left to :ref:`separate packages | |||
| <flycheck-extensions>`. | |||
| Whether a feature is within the scope of Flycheck is the :ref:`maintainer’s | |||
| <flycheck-maintainers>` judgement call. Generally we reserve the right to | |||
| reject any pull request for being out of scope. | |||
| * Avoid a *disproportionate amount of code* for a single syntax checker or | |||
| language. Look at the built-in checkers for judgement. A syntax checker that | |||
| requires a lot more code than any built-in checker is likely to be rejected. | |||
| * Avoid *deep integration* with a particular UI or completion framework. Emacs’ | |||
| standard is our standard: We will reject code that is tied to Helm or Counsel. | |||
| * Likewise do not deviate from Emacs’ default behaviour too much. Stick to | |||
| Emacs’ standard for key bindings, interactive functions, etc. | |||
| Backward compatibility | |||
| ====================== | |||
| Checkers and languages evolve over time, and their error format often change as | |||
| a consequence. It is not a goal of Flycheck to work with every version of every | |||
| checker ever supported. However, the latest Flycheck version *should always | |||
| work* with the contemporary version of a checker. | |||
| As a rule of thumb, if maintaining backward compatibility is trivial (i.e., does | |||
| not incur code maintenance costs), then we should do it. For example, a | |||
| slightly more complex parsing regexp is OK, but doing version detection to add a | |||
| flag would most likely be too much. | |||
| Keep in mind that users may not have the choice of updating to the latest | |||
| version of a checker (e.g., ``gcc`` on Debian-based distributions). On the | |||
| other hand, npm or Python packages are usually trivial to update. Making an | |||
| extra effort to maintain backward compatibility for these hard-to-update | |||
| checkers is reasonable. | |||
| The integration tests that are run on our CI should always reflect the latest | |||
| supported version. | |||
| Style | |||
| ===== | |||
| .. important:: | |||
| ``make check compile`` must pass on Emacs 25 or newer. This command checks | |||
| for some formatting issues and compilation errors. | |||
| Run ``make format`` with Emacs 25 to automatically reformat the Emacs Lisp | |||
| source files. | |||
| * Generally try to fit into the style of the code you see. | |||
| * Indent with the default indentation rules. | |||
| * Follow the :infonode:`(elisp)Programming Tips` for Emacs Lisp. | |||
| * Whitespace: | |||
| * 80 characters per line. | |||
| * Avoid tabs and trailing spaces. | |||
| * Naming: | |||
| * Prefix all variables and functions with the name of the containing library, | |||
| i.e. ``flycheck-`` for everything that is in :file:`flycheck.el`. | |||
| * End boolean predicates with ``-p``, i.e. ``flycheck-valid-checker-p``. | |||
| * Avoid macros, and use them for syntax only. | |||
| * Adhere to the :infonode:`(elisp)Key Binding Conventions`. Particularly do not | |||
| define keys in Emacs’ reserved keymaps or in the :samp:`C-c {LETTER}` space | |||
| for user bindings. | |||
| Libraries | |||
| ========= | |||
| * Do **not** advise built-in or 3rd party functions and commands. | |||
| * Do **not** redefine built-in or 3rd party functions, unless for compatibility, | |||
| but then copy the newer definition verbatim. | |||
| * Do **not** use ``with-eval-after-load`` and similar functions. | |||
| * Dependencies: | |||
| * Use built-in Emacs libraries freely. | |||
| * Introduce external dependencies with care. Prefer built-in | |||
| libraries. ``dash.el`` is fine, though. | |||
| * Avoid dependencies on language-specific libraries. | |||
| * Avoid ``cl-lib``: | |||
| * Prefer ``seq`` over ``dash`` over ``cl-lib``. Use list functions from | |||
| ``cl-lib`` only as the very last resort. | |||
| * Prefer ``let-alist`` and ``pcase`` over ``cl-destructuring-bind``. | |||
| Tests | |||
| ===== | |||
| * Add comprehensive buttercup specs for new functions and commands to | |||
| :file:`test/specs/`. Check whether the specs fit into an existing spec file, | |||
| or add a new file instead. In doubt, use a new file. | |||
| * For new syntax checkers add at least one syntax checker integration test to | |||
| :file:`test/flycheck-test.el`. Make sure that the test passes with | |||
| :samp:`make LANGUAGE={language} integ`. | |||
| Documentation | |||
| ============= | |||
| * Add docstrings to all functions and variables. | |||
| * Follow the :infonode:`(elisp)Documentation Tips`. | |||
| * Take care to update our manual: | |||
| * Document new interactive commands and user options in the :ref:`user guide | |||
| <flycheck-user-guide>`. | |||
| * Document new syntax checkers and new options for existing syntax checkers in | |||
| the :ref:`list of languages <flycheck-languages>`. | |||
| * Document new or changed version requirements for syntax checkers in the | |||
| :ref:`list of languages <flycheck-languages>`. | |||
| * Document changes to our build system and tooling in the :ref:`contributor’s | |||
| guide <flycheck-contributors-guide>` or the :ref:`maintainer’s guide | |||
| <flycheck-maintainers-guide>`. | |||
| Commits | |||
| ======= | |||
| * Make each commit self-contained. | |||
| * Squash trivial fixes into previous commits so that no commit in and by itself | |||
| violates this style guide. | |||
| * Write commit messages that adhere to the style illustrated below. | |||
| * In doubt prefer long messages over short messages. Take the time to write a | |||
| good message that explains the intention of the change and illustrates | |||
| noteworthy aspects of the implementation. | |||
| * If the commit fixes a bug try to reproduce a brief description of the bug in | |||
| the message and make sure to mention the corresponding GitHub issue | |||
| (e.g. ``Fixes GH-42``). | |||
| Commit message style | |||
| -------------------- | |||
| This model commit message illustrates our style:: | |||
| Fix a foo bug | |||
| The first line is the summary, 50 characters or less. Write in the | |||
| imperative and in present tense: “Fix bug”, not “fixed bug” or “fixes | |||
| bug”. Explain the intend of the change not the actual contents which the | |||
| diff already provides | |||
| After the summary more paragraphs with detailed explanations may follow, | |||
| wrapped at 72 characters. Separate multiple paragraphs by blank lines. | |||
| You may use simple formatting like *emphasis* or _underline_, but keep | |||
| it to a minimum. Commit messages are not in Markdown :) | |||
| Commit messages may reference issues by number, like this: See GH-42. | |||
| Please use `GH-` to prefix issue numbers. You may also close issues | |||
| like this: Fixes GH-42 and closes GH-42. | |||
| `Git Commit`_ and Magit_ provide Emacs mode for Git commit messages, which helps | |||
| you to comply to these guidelines. | |||
| .. seealso:: | |||
| `A Note About Git Commit Messages`_ | |||
| Further information about good commit messages, including some motivation | |||
| for our rules for commit messages. | |||
| .. _Git Commit: https://github.com/magit/magit/ | |||
| .. _Magit: https://github.com/magit/magit/ | |||
| .. _A Note About Git Commit Messages: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html | |||
| @ -0,0 +1,399 @@ | |||
| .. _flycheck-developers-guide: | |||
| ================= | |||
| Developer's Guide | |||
| ================= | |||
| So you want to extend Flycheck, but have no idea where to start? This guide | |||
| will give you an overview of Flycheck internals, and take you through adding a | |||
| syntax checker to Flycheck. | |||
| An overview of Flycheck internals | |||
| ================================= | |||
| The goal of Flycheck is to display errors from external checker programs | |||
| directly in the buffer you are editing. Instead of you manually invoking | |||
| ``make`` or the compiler for your favorite language, Flycheck takes care of it | |||
| for you, collects the errors and displays them right there in the buffer. | |||
| How Flycheck works is rather straightforward. Whenever a syntax check is | |||
| started (see :ref:`flycheck-syntax-checks`), the following happens: | |||
| 1. First, Flycheck runs the external program as an asynchronous process using | |||
| ``start-process``. While this process runs, Flycheck simply accumulates its | |||
| output. | |||
| 2. When the process exits, Flycheck parses its output in order to collect the | |||
| errors. The raw output is turned into a list of `flycheck-error` objects | |||
| containing, among others, the filename, line, column, message and severity of | |||
| the error. | |||
| 3. Flycheck then filters the collected errors to keep only the relevant ones. | |||
| For instance, errors directed at other files than the one you are editing are | |||
| discarded. The exact sementics of which errors are relevant is defined in | |||
| ``flycheck-relevant-error-p``. | |||
| 4. Relevant errors are highlighted by Flycheck in the buffer, according to user | |||
| preference. By default, each error adds a mark in the fringe at the line it | |||
| occurs, and underlines the symbol at the position of the error using | |||
| *overlays*. | |||
| 5. Finally, Flycheck rebuilds the error list buffer. | |||
| Flycheck follows this process for all the :ref:`many different syntax checkers | |||
| <flycheck-languages>` that are provided by default. | |||
| .. note:: | |||
| Specifically, the above describes the process of *command checkers*, i.e., | |||
| checkers that run external programs. All the checkers defined in | |||
| ``flycheck-checkers`` are command checkers, but command checkers are actually | |||
| instances of *generic checkers*. Many external packages, such as | |||
| ``dafny-mode``, ``fstar-mode``, etc. use generic checkers, which allow you | |||
| more flexibility, including running Flycheck with persistent subprocess such | |||
| as language servers. See :flyc:`flycheck-ocaml` for an example | |||
| of how to use a generic checker. | |||
| .. seealso:: | |||
| :infonode:`(elisp)Asynchronous Processes` | |||
| How to run and control asynchronous processes from inside Emacs. | |||
| :infonode:`(elisp)Overlays` | |||
| How to add temporary annotations to a buffer. | |||
| .. _adding-a-checker: | |||
| Adding a syntax checker to Flycheck | |||
| =================================== | |||
| To add a syntax checker to Flycheck, you need to answer a few questions: | |||
| - How to invoke the checker? What is the name of its program, and what | |||
| arguments should Flycheck pass to it? | |||
| - How to parse the error messages from the checker output? | |||
| - What language (or languages) will the checker be used for? | |||
| For instance, if I were to manually run the Scala compiler ``scalac`` on the | |||
| following ``hello.scala`` file: | |||
| .. code-block:: scala | |||
| object { | |||
| println("Hello, world") | |||
| } | |||
| Here is the output I would get: | |||
| .. code-block:: console | |||
| $ scalac hello.scala | |||
| hello.scala:1: error: identifier expected but '{' found. | |||
| object { | |||
| ^ | |||
| one error found | |||
| The compiler reports one syntax error from the file ``hello.scala``, on line 3, | |||
| with severity ``error``, and the rest of the line contains the error message. | |||
| So, if we want to instruct Flycheck to run ``scalac`` on our Scala files, we | |||
| need to tell Flycheck to: | |||
| - Invoke ``scalac FILE-NAME`` | |||
| - Get errors from output lines of the form: ``file-name:line: error:message`` | |||
| Writing the checker | |||
| ------------------- | |||
| Once you have answered these questions, you merely have to translate the answers | |||
| to Emacs Lisp. Here is the full definition of the ``scala`` checker you can | |||
| find in ``flycheck.el``: | |||
| .. code-block:: elisp | |||
| (flycheck-define-checker scala | |||
| "A Scala syntax checker using the Scala compiler. | |||
| See URL `https://www.scala-lang.org/'." | |||
| :command ("scalac" "-Ystop-after:parser" source) | |||
| :error-patterns | |||
| ((error line-start (file-name) ":" line ": error: " (message) line-end)) | |||
| :modes scala-mode | |||
| :next-checkers ((warning . scala-scalastyle))) | |||
| The code is rather self-explanatory; but we'll go through it nonetheless. | |||
| First, we define a checker using `flycheck-define-checker`. Its first argument, | |||
| ``scala``, is the name of the checker, as a symbol. The name is used to refer | |||
| to the checker in the documentation, so it should usually be the name of the | |||
| language to check, or the name of the program used to do the checking, or a | |||
| combination of both. Here, ``scalac`` is the program, but the checker is named | |||
| ``scala``. There is another Scala checker using ``scalastyle``, with the name | |||
| ``scala-scalastyle``. See `flycheck-checkers` for the full list of checker | |||
| names defined in Flycheck. | |||
| After the name comes the docstring. This is a documentation string answering | |||
| three questions: 1) What language is this checker for? 2) What is the program | |||
| used? 3) Where can users get this program? Nothing more. In particular, this | |||
| string does *not* include user documentation, which should rather go in the | |||
| manual (see :ref:`flycheck-languages`). | |||
| The rest of the arguments are keyword arguments; their order does not matter, | |||
| but they are usually given in the fashion above. | |||
| - ``:command`` describes what command to run, and what arguments to pass. Here, | |||
| we tell Flycheck to run ``scalac -Ystop-after:parser`` on ``source``. In | |||
| Flycheck, we usually want to get error feedback as fast as possible, hence we | |||
| will pass any flag that will speed up the invocation of a compiler, even at | |||
| the cost of missing out on some errors. Here, we are telling ``scalac`` to | |||
| stop after the parsing phase to ensure we are getting syntax errors quickly. | |||
| The ``source`` argument is special: it instructs Flycheck to create a | |||
| temporary file containing the content of the current buffer, and to pass that | |||
| temporary file as argument to ``scalac``. That way, ``scalac`` can be run on | |||
| the content of the buffer, even when the buffer has not been saved. There are | |||
| other ways to pass the content of the buffer to the command, e.g., by piping | |||
| it through standard input. These special arguments are described in the | |||
| docstring of `flycheck-substitute-argument`. | |||
| - ``:error-patterns`` describes how to parse the output, using the `rx` regular | |||
| expression syntax. Here, we expect ``scalac`` to return error messages of the | |||
| form:: | |||
| file:line: error: message | |||
| This is a common output format for compilers. With the following | |||
| ``:error-patterns`` value: | |||
| .. code-block:: elisp | |||
| ((error line-start (file-name) ":" line ": error: " (message) line-end)) | |||
| we tell Flycheck to extract three parts from each line in the output that | |||
| matches the pattern: the ``file-name``, the ``line`` number, and the | |||
| ``message`` content. These three parts are then used by Flycheck to create a | |||
| `flycheck-error` with the ``error`` severity. | |||
| - ``:modes`` is the list of Emacs major modes in which this checker can run. | |||
| Here, we want the checker to run only in ``scala-mode`` buffers. | |||
| That's it! This definition alone contains everything Flycheck needs to run | |||
| ``scalac`` on a Scala buffer and parse its output in order to give error | |||
| feedback to the user. | |||
| .. note:: | |||
| ``rx.el`` is a built-in Emacs module for declarative regular expressions. | |||
| Look for the documentation of the `rx` function inside Emacs for its usage. | |||
| Flycheck extends `rx` with a few constructs like ``line``, ``file-name`` and | |||
| ``message``. You can find them the full list in the docstring for | |||
| `flycheck-rx-to-string`. | |||
| Registering the checker | |||
| ----------------------- | |||
| Usually, you'll want to register the checker so that it is eligible for | |||
| automatic selection. For that, you just need to add the checker symbol to | |||
| `flycheck-checkers`. The order of checkers does matter, as only one checker can | |||
| be enabled in a buffer at a time. Usually you want to put the most useful | |||
| checker as the first checker for that mode. For instance, here are the | |||
| JavaScript checkers provided by Flycheck: | |||
| .. code-block:: console | |||
| javascript-eslint | |||
| javascript-jshint | |||
| javascript-gjslint | |||
| javascript-jscs | |||
| javascript-standard | |||
| If a buffer is in ``js-mode``, Flycheck will try first to enable | |||
| ``javascript-eslint`` before any other JavaScript checker. | |||
| There are other factors governing checker selection in a buffer, namely whether | |||
| a checker is disabled by user configuration (see | |||
| :ref:`flycheck-disable-checkers`), and whether this checker *can* be enabled | |||
| (see the ``:enabled`` property in `flycheck-define-generic-checker`). | |||
| .. seealso:: | |||
| flycheck-get-checker-for-buffer | |||
| This is the function that looks through `flycheck-checkers` to find a | |||
| valid checker for the buffer. | |||
| Writing more complex checkers | |||
| ----------------------------- | |||
| Here are two examples of more complex checkers: | |||
| .. code-block:: elisp | |||
| (flycheck-define-checker protobuf-protoc | |||
| "A protobuf syntax checker using the protoc compiler. | |||
| See URL `https://developers.google.com/protocol-buffers/'." | |||
| :command ("protoc" "--error_format" "gcc" | |||
| (eval (concat "--java_out=" (flycheck-temp-dir-system))) | |||
| ;; Add the file directory of protobuf path to resolve import directives | |||
| (eval (concat "--proto_path=" (file-name-directory (buffer-file-name)))) | |||
| source-inplace) | |||
| :error-patterns | |||
| ((info line-start (file-name) ":" line ":" column | |||
| ": note: " (message) line-end) | |||
| (error line-start (file-name) ":" line ":" column | |||
| ": " (message) line-end) | |||
| (error line-start | |||
| (message "In file included from") " " (file-name) ":" line ":" | |||
| column ":" line-end)) | |||
| :modes protobuf-mode | |||
| :predicate (lambda () (buffer-file-name))) | |||
| .. code-block:: elisp | |||
| (flycheck-define-checker sh-shellcheck | |||
| "A shell script syntax and style checker using Shellcheck. | |||
| See URL `https://github.com/koalaman/shellcheck/'." | |||
| :command ("shellcheck" | |||
| "--format" "checkstyle" | |||
| "--shell" (eval (symbol-name sh-shell)) | |||
| (option-flag "--external-sources" | |||
| flycheck-shellcheck-follow-sources) | |||
| (option "--exclude" flycheck-shellcheck-excluded-warnings list | |||
| flycheck-option-comma-separated-list) | |||
| "-") | |||
| :standard-input t | |||
| :modes sh-mode | |||
| :error-parser flycheck-parse-checkstyle | |||
| :error-filter (lambda (errors) | |||
| (flycheck-remove-error-file-names "-" errors)) | |||
| :predicate (lambda () (memq sh-shell '(bash ksh88 sh))) | |||
| :verify | |||
| (lambda (_) | |||
| (let ((supported (memq sh-shell '(bash ksh88 sh)))) | |||
| (list (flycheck-verification-result-new | |||
| :label (format "Shell %s supported" sh-shell) | |||
| :message (if supported "yes" "no") | |||
| :face (if supports-shell 'success '(bold warning)))))) | |||
| :error-explainer | |||
| (lambda (err) | |||
| (let ((error-code (flycheck-error-id err)) | |||
| (url "https://github.com/koalaman/shellcheck/wiki/%S")) | |||
| (and error-code `(url . ,(format url error-code)))))) | |||
| The ``:command`` forms are longer, as the checkers pass more flags to ``protoc`` | |||
| and ``shellcheck``. Note the use of ``eval``, ``option``, and ``option-flag`` | |||
| for transforming Flycheck checker options into flags for the command. See the | |||
| docstring for `flycheck-substitute-argument` for more info, and look at other | |||
| checkers for examples. | |||
| The ``shellcheck`` checker does no use ``source`` nor ``source-inplace``: | |||
| instead, it passes the buffer contents on standard input, using | |||
| ``:standard-input t``. | |||
| The ``protoc`` checker has three patterns in ``:error-patterns``; the first one | |||
| will catch ``notes`` from the compiler and turn them into `flycheck-error` | |||
| objects with the ``info`` severity; the second is for errors from the file being | |||
| checked, and the third one is for errors from other files. In the | |||
| ``shellcheck`` checker, on the other hand, ``:error-parser`` replaces | |||
| ``:error-patterns``: ``shellcheck`` outputs results in the standard CheckStyle | |||
| XML format, so the definition above uses Flycheck's built-in CheckStyle parser, | |||
| and an ``:error-filter`` to replace ``-`` by the current buffer's filename. | |||
| Both checkers use a new ``:predicate`` property to determine when the checker | |||
| can be called. In addition to the ``:mode`` property which restricts the | |||
| ``protoc`` checker to buffers in ``protobuf-mode``, the ``:predicate`` property | |||
| ensures that ``protoc`` is called only when there is a file associated to the | |||
| buffer (this is necessary since we are passing the file associated to the buffer | |||
| ``protobuf`` using ``source-inplace`` in ``:command``; in contrast, the | |||
| ``shellcheck`` checker can run in all buffers, because it sends buffer contents | |||
| through a pipe). The second checker has a more complex ``:predicate`` to make | |||
| sure that the current shell dialect is supported, and a ``:verify`` function to | |||
| help users diagnose configuration issues ( ``:verify`` is helpful for giving | |||
| feedback to users; its output gets included when users invoke | |||
| `flycheck-verify-setup`) | |||
| Finally, the ``shellcheck`` checker includes an error explainer, which opens the | |||
| relevant page on the ShellCheck wiki when users run | |||
| `flycheck-explain-error-at-point`. | |||
| There are other useful properties, depending on your situation. Most important | |||
| is ``:enabled``, which is like ``:predicate`` but is run only once; it is used | |||
| to make sure a checker has everything it needs before being allowed to run in a | |||
| buffer (this is particularly useful when the checks are costly: running an | |||
| external program and parsing its output, checking for a plugin, etc.). | |||
| .. seealso:: | |||
| flycheck-define-generic-checker | |||
| For the full documentation of all the properties you can pass to | |||
| `flycheck-define-checker`. Look also in the docstring for | |||
| `flycheck-define-command-checker` for additional properties. | |||
| .. note:: | |||
| Don't be afraid to look into the ``flycheck.el`` code. The existing checkers | |||
| serve as useful examples you can draw from, and all core functions are | |||
| documented. | |||
| Sharing your checker | |||
| -------------------- | |||
| Once you have written your own syntax checker, why not `submit a pull request | |||
| <https://github.com/flycheck/flycheck/pulls>`__ to integrate it into Flycheck? | |||
| If it's useful to you, it may be useful for someone else! Please do check out | |||
| our :ref:`flycheck-contributors-guide` to learn how we deal with pull requests. | |||
| Issues with auto-quoting in `flycheck-define-checker` | |||
| ----------------------------------------------------- | |||
| You may have noticed that lists passed to the ``:command`` or | |||
| ``:error-patterns`` in the snippets above are not quoted. That is because | |||
| `flycheck-define-checker` is a macro which automatically quotes these arguments | |||
| (not unlike ``use-package`` and other configuration macros). | |||
| While this makes for less noisy syntax, it unfortunately prevents you from | |||
| defining a checker with compile-time arguments. For example, you may be tempted | |||
| to have a custom checker in your Emacs configuration written like this: | |||
| .. code-block:: elisp | |||
| (flycheck-define-checker my-foobar-checker | |||
| :command ("foobar" source) | |||
| :error-patterns ((error …)) | |||
| :modes `(foobar-mode ,my-other-foobar-mode)) | |||
| The idea is that you know statically one mode that you want to use the checker | |||
| in: ``foobar-mode``, but another mode can be given via the variable | |||
| ``my-other-foobar-mode`` before the checker is defined. This won't work, | |||
| because the ``:modes`` property is auto-quoted by `flycheck-define-checker`. | |||
| The issue arises not just with ``:modes``:, but with almost all the other | |||
| properties since they are also auto-quoted. | |||
| If you do find yourself in need to define such a checker, there is a solution | |||
| though. The `flycheck-define-checker` macro is just a convenience over | |||
| `flycheck-define-command-checker`, so you could define the checker above as | |||
| follows: | |||
| .. code-block:: elisp | |||
| (flycheck-def-executable-var my-foobar-checker "foobar") | |||
| (flycheck-define-command-checker 'my-foobar-checker | |||
| :command '("foobar" source) | |||
| :error-patterns '((error …)) | |||
| :modes `(foobar-mode ,my-other-foobar-mode)) | |||
| Using `flycheck-define-command-checker`, you now need to quote all the list | |||
| arguments, but now with the confidence that no auto-quoting will take place, | |||
| since `flycheck-define-command-checker` is just a function. Also note that you | |||
| need to explicitly define the executable variable for the checker. Using | |||
| `flycheck-define-command-checker` is the recommended way to define a checker | |||
| with compile-time arguments. | |||
| .. note:: | |||
| The `flycheck-define-checker` macro is an autoload, so using it inside a | |||
| `with-eval-after-load` form will load all of Flycheck. While this ensures | |||
| the macro is correctly expanded, it also defeats the purpose of using | |||
| `with-eval-after-load`. | |||
| For the background behind this state of affairs, see `issue 1398`_. | |||
| .. _issue 1398: https://github.com/flycheck/flycheck/issues/1398 | |||
| @ -0,0 +1,433 @@ | |||
| # Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| # This file is not part of GNU Emacs. | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| from collections import namedtuple | |||
| from sphinx import addnodes | |||
| from sphinx.util import ws_re | |||
| from sphinx.roles import XRefRole | |||
| from sphinx.domains import Domain, ObjType | |||
| from sphinx.util.nodes import make_refnode | |||
| from sphinx.directives import ObjectDescription | |||
| def make_target(cell, name): | |||
| """Create a target name from ``cell`` and ``name``. | |||
| ``cell`` is the name of a symbol cell, and ``name`` is a symbol name, both | |||
| as strings. | |||
| The target names are used as cross-reference targets for Sphinx. | |||
| """ | |||
| return '{cell}-{name}'.format(cell=cell, name=name) | |||
| def to_mode_name(symbol_name): | |||
| """Convert ``symbol_name`` to a mode name. | |||
| Split at ``-`` and titlecase each part. | |||
| """ | |||
| return ' '.join(p.title() for p in symbol_name.split('-')) | |||
| class Cell(namedtuple('Cell', 'objtype docname')): | |||
| """A cell in a symbol. | |||
| A cell holds the object type and the document name of the description for | |||
| the cell. | |||
| Cell objects are used within symbol entries in the domain data. | |||
| """ | |||
| pass | |||
| class KeySequence(namedtuple('KeySequence', 'keys')): | |||
| """A key sequence.""" | |||
| PREFIX_KEYS = {'C-u'} | |||
| PREFIX_KEYS.update('M-{}'.format(n) for n in range(10)) | |||
| @classmethod | |||
| def fromstring(cls, s): | |||
| return cls(s.split()) | |||
| @property | |||
| def command_name(self): | |||
| """The command name in this key sequence. | |||
| Return ``None`` for key sequences that are no command invocations with | |||
| ``M-x``. | |||
| """ | |||
| try: | |||
| return self.keys[self.keys.index('M-x') + 1] | |||
| except ValueError: | |||
| return None | |||
| @property | |||
| def has_prefix(self): | |||
| """Whether this key sequence has a prefix.""" | |||
| return self.keys[0] in self.PREFIX_KEYS | |||
| def __str__(self): | |||
| return ' '.join(self.keys) | |||
| class EmacsLispSymbol(ObjectDescription): | |||
| """An abstract base class for directives documenting symbols. | |||
| Provide target and index generation and registration of documented symbols | |||
| within the domain data. | |||
| Deriving classes must have a ``cell`` attribute which refers to the cell | |||
| the documentation goes in, and a ``label`` attribute which provides a | |||
| human-readable name for what is documented, used in the index entry. | |||
| """ | |||
| cell_for_objtype = { | |||
| 'defcustom': 'variable', | |||
| 'defconst': 'variable', | |||
| 'defvar': 'variable', | |||
| 'defface': 'face' | |||
| } | |||
| @property | |||
| def cell(self): | |||
| """The cell in which to store symbol metadata.""" | |||
| return self.cell_for_objtype[self.objtype] | |||
| @property | |||
| def label(self): | |||
| """The label for the documented object type.""" | |||
| return self.objtype | |||
| def handle_signature(self, signature, signode): | |||
| """Create nodes in ``signode`` for the ``signature``. | |||
| ``signode`` is a docutils node to which to add the nodes, and | |||
| ``signature`` is the symbol name. | |||
| Add the object type label before the symbol name and return | |||
| ``signature``. | |||
| """ | |||
| label = self.label + ' ' | |||
| signode += addnodes.desc_annotation(label, label) | |||
| signode += addnodes.desc_name(signature, signature) | |||
| return signature | |||
| def _add_index(self, name, target): | |||
| index_text = '{name}; {label}'.format( | |||
| name=name, label=self.label) | |||
| self.indexnode['entries'].append( | |||
| ('pair', index_text, target, '', None)) | |||
| def _add_target(self, name, sig, signode): | |||
| target = make_target(self.cell, name) | |||
| if target not in self.state.document.ids: | |||
| signode['names'].append(name) | |||
| signode['ids'].append(target) | |||
| signode['first'] = (not self.names) | |||
| self.state.document.note_explicit_target(signode) | |||
| obarray = self.env.domaindata['el']['obarray'] | |||
| symbol = obarray.setdefault(name, {}) | |||
| if self.cell in symbol: | |||
| self.state_machine.reporter.warning( | |||
| 'duplicate description of %s %s, ' % (self.objtype, name) | |||
| + 'other instance in ' | |||
| + self.env.doc2path(symbol[self.cell].docname), | |||
| line=self.lineno) | |||
| symbol[self.cell] = Cell(self.objtype, self.env.docname) | |||
| return target | |||
| def add_target_and_index(self, name, sig, signode): | |||
| target = self._add_target(name, sig, signode) | |||
| self._add_index(name, target) | |||
| class EmacsLispMinorMode(EmacsLispSymbol): | |||
| cell = 'function' | |||
| label = 'Minor Mode' | |||
| def handle_signature(self, signature, signode): | |||
| """Create nodes in ``signode`` for the ``signature``. | |||
| ``signode`` is a docutils node to which to add the nodes, and | |||
| ``signature`` is the symbol name. | |||
| Add the object type label before the symbol name and return | |||
| ``signature``. | |||
| """ | |||
| label = self.label + ' ' | |||
| signode += addnodes.desc_annotation(label, label) | |||
| signode += addnodes.desc_name(signature, to_mode_name(signature)) | |||
| return signature | |||
| def _add_index(self, name, target): | |||
| return super()._add_index(to_mode_name(name), target) | |||
| class EmacsLispFunction(EmacsLispSymbol): | |||
| """A directive to document Emacs Lisp functions.""" | |||
| cell_for_objtype = { | |||
| 'defun': 'function', | |||
| 'defmacro': 'function' | |||
| } | |||
| def handle_signature(self, signature, signode): | |||
| function_name, *args = ws_re.split(signature) | |||
| label = self.label + ' ' | |||
| signode += addnodes.desc_annotation(label, label) | |||
| signode += addnodes.desc_name(function_name, function_name) | |||
| for arg in args: | |||
| is_keyword = arg.startswith('&') | |||
| node = (addnodes.desc_annotation | |||
| if is_keyword | |||
| else addnodes.desc_addname) | |||
| signode += node(' ' + arg, ' ' + arg) | |||
| return function_name | |||
| class EmacsLispKey(ObjectDescription): | |||
| """A directive to document interactive commands via their bindings.""" | |||
| label = 'Interactive command' | |||
| def handle_signature(self, signature, signode): | |||
| """Create nodes to ``signode`` for ``signature``. | |||
| ``signode`` is a docutils node to which to add the nodes, and | |||
| ``signature`` is the symbol name. | |||
| """ | |||
| key_sequence = KeySequence.fromstring(signature) | |||
| signode += addnodes.desc_name(signature, str(key_sequence)) | |||
| return str(key_sequence) | |||
| def _add_command_target_and_index(self, name, sig, signode): | |||
| target_name = make_target('function', name) | |||
| if target_name not in self.state.document.ids: | |||
| signode['names'].append(name) | |||
| signode['ids'].append(target_name) | |||
| self.state.document.note_explicit_target(signode) | |||
| obarray = self.env.domaindata['el']['obarray'] | |||
| symbol = obarray.setdefault(name, {}) | |||
| if 'function' in symbol: | |||
| self.state_machine.reporter.warning( | |||
| 'duplicate description of %s %s, ' % (self.objtype, name) | |||
| + 'other instance in ' | |||
| + self.env.doc2path(symbol['function'].docname), | |||
| line=self.lineno) | |||
| symbol['function'] = Cell(self.objtype, self.env.docname) | |||
| index_text = '{name}; {label}'.format(name=name, label=self.label) | |||
| self.indexnode['entries'].append( | |||
| ('pair', index_text, target_name, '', None)) | |||
| def _add_binding_target_and_index(self, binding, sig, signode): | |||
| reftarget = make_target('key', binding) | |||
| if reftarget not in self.state.document.ids: | |||
| signode['names'].append(reftarget) | |||
| signode['ids'].append(reftarget) | |||
| signode['first'] = (not self.names) | |||
| self.state.document.note_explicit_target(signode) | |||
| keymap = self.env.domaindata['el']['keymap'] | |||
| if binding in keymap: | |||
| self.state_machine.reporter.warning( | |||
| 'duplicate description of binding %s, ' % binding | |||
| + 'other instance in ' | |||
| + self.env.doc2path(keymap[binding]), | |||
| line=self.lineno) | |||
| keymap[binding] = self.env.docname | |||
| index_text = '{name}; key binding'.format(name=binding) | |||
| self.indexnode['entries'].append( | |||
| ('pair', index_text, reftarget, '', None)) | |||
| def add_target_and_index(self, name, sig, signode): | |||
| # If unprefixed M-x command index as function and not as key binding | |||
| sequence = KeySequence.fromstring(name) | |||
| if sequence.command_name and not sequence.has_prefix: | |||
| self._add_command_target_and_index(sequence.command_name, | |||
| sig, signode) | |||
| else: | |||
| self._add_binding_target_and_index(name, sig, signode) | |||
| class XRefModeRole(XRefRole): | |||
| """A role to cross-reference a minor mode. | |||
| Like a normal cross-reference role but appends ``-mode`` to the reference | |||
| target and title-cases the symbol name like Emacs does when referring to | |||
| modes. | |||
| """ | |||
| fix_parens = False | |||
| lowercase = False | |||
| def process_link(self, env, refnode, has_explicit_title, title, target): | |||
| refnode['reftype'] = 'minor-mode' | |||
| target = target + '-mode' | |||
| return (title if has_explicit_title else to_mode_name(target), target) | |||
| class EmacsLispDomain(Domain): | |||
| """A domain to document Emacs Lisp code.""" | |||
| name = 'el' | |||
| label = 'Emacs Lisp' | |||
| object_types = { | |||
| # TODO: Set search prio for object types | |||
| # Types for user-facing options and commands | |||
| 'minor-mode': ObjType('minor-mode', 'function', 'mode', | |||
| cell='function'), | |||
| 'define-key': ObjType('key binding', cell='interactive'), | |||
| 'defcustom': ObjType('defcustom', 'defcustom', cell='variable'), | |||
| 'defface': ObjType('defface', 'defface', cell='face'), | |||
| # Object types for code | |||
| 'defun': ObjType('defun', 'defun', cell='function'), | |||
| 'defmacro': ObjType('defmacro', 'defmacro', cell='function'), | |||
| 'defvar': ObjType('defvar', 'defvar', cell='variable'), | |||
| 'defconst': ObjType('defconst', 'defconst', cell='variable') | |||
| } | |||
| directives = { | |||
| 'minor-mode': EmacsLispMinorMode, | |||
| 'define-key': EmacsLispKey, | |||
| 'defcustom': EmacsLispSymbol, | |||
| 'defvar': EmacsLispSymbol, | |||
| 'defconst': EmacsLispSymbol, | |||
| 'defface': EmacsLispSymbol, | |||
| 'defun': EmacsLispFunction, | |||
| 'defmacro': EmacsLispFunction | |||
| } | |||
| roles = { | |||
| 'mode': XRefModeRole(), | |||
| 'defvar': XRefRole(), | |||
| 'defconst': XRefRole(), | |||
| 'defcustom': XRefRole(), | |||
| 'defface': XRefRole(), | |||
| 'defun': XRefRole(), | |||
| 'defmacro': XRefRole() | |||
| } | |||
| data_version = 1 | |||
| initial_data = { | |||
| # Our domain data attempts to somewhat mirror the semantics of Emacs | |||
| # Lisp, so we have an obarray which holds symbols which in turn have | |||
| # function, variable, face, etc. cells, and a keymap which holds the | |||
| # documentation for key bindings. | |||
| 'obarray': {}, | |||
| 'keymap': {} | |||
| } | |||
| def clear_doc(self, docname): | |||
| """Clear all cells documented ``docname``.""" | |||
| for symbol in self.data['obarray'].values(): | |||
| for cell in list(symbol.keys()): | |||
| if docname == symbol[cell].docname: | |||
| del symbol[cell] | |||
| for binding in list(self.data['keymap']): | |||
| if self.data['keymap'][binding] == docname: | |||
| del self.data['keymap'][binding] | |||
| def resolve_xref(self, env, fromdocname, builder, | |||
| objtype, target, node, contnode): | |||
| """Resolve a cross reference to ``target``.""" | |||
| if objtype == 'key': | |||
| todocname = self.data['keymap'].get(target) | |||
| if not todocname: | |||
| return None | |||
| reftarget = make_target('key', target) | |||
| else: | |||
| cell = self.object_types[objtype].attrs['cell'] | |||
| symbol = self.data['obarray'].get(target, {}) | |||
| if cell not in symbol: | |||
| return None | |||
| reftarget = make_target(cell, target) | |||
| todocname = symbol[cell].docname | |||
| return make_refnode(builder, fromdocname, todocname, | |||
| reftarget, contnode, target) | |||
| def resolve_any_xref(self, env, fromdocname, builder, | |||
| target, node, contnode): | |||
| """Return all possible cross references for ``target``.""" | |||
| nodes = ((objtype, self.resolve_xref(env, fromdocname, builder, | |||
| objtype, target, node, contnode)) | |||
| for objtype in ['key', 'defun', 'defvar', 'defface']) | |||
| return [('el:{}'.format(objtype), node) for (objtype, node) in nodes | |||
| if node is not None] | |||
| def merge_warn_duplicate(self, objname, our_docname, their_docname): | |||
| self.env.warn( | |||
| their_docname, | |||
| "Duplicate declaration: '{}' also defined in '{}'.\n".format( | |||
| objname, their_docname)) | |||
| def merge_keymapdata(self, docnames, our_keymap, their_keymap): | |||
| for key, docname in their_keymap.items(): | |||
| if docname in docnames: | |||
| if key in our_keymap: | |||
| our_docname = our_keymap[key] | |||
| self.merge_warn_duplicate(key, our_docname, docname) | |||
| else: | |||
| our_keymap[key] = docname | |||
| def merge_obarraydata(self, docnames, our_obarray, their_obarray): | |||
| for objname, their_cells in their_obarray.items(): | |||
| our_cells = our_obarray.setdefault(objname, dict()) | |||
| for cellname, their_cell in their_cells.items(): | |||
| if their_cell.docname in docnames: | |||
| our_cell = our_cells.get(cellname) | |||
| if our_cell: | |||
| self.merge_warn_duplicate(objname, our_cell.docname, | |||
| their_cell.docname) | |||
| else: | |||
| our_cells[cellname] = their_cell | |||
| def merge_domaindata(self, docnames, otherdata): | |||
| self.merge_keymapdata(docnames, self.data['keymap'], | |||
| otherdata['keymap']) | |||
| self.merge_obarraydata(docnames, self.data['obarray'], | |||
| otherdata['obarray']) | |||
| def get_objects(self): | |||
| """Get all documented symbols for use in the search index.""" | |||
| for name, symbol in self.data['obarray'].items(): | |||
| for cellname, cell in symbol.items(): | |||
| yield (name, name, cell.objtype, cell.docname, | |||
| make_target(cellname, name), | |||
| self.object_types[cell.objtype].attrs['searchprio']) | |||
| def setup(app): | |||
| app.add_domain(EmacsLispDomain) | |||
| return {'version': '0.1', 'parallel_read_safe': True} | |||
| @ -0,0 +1,53 @@ | |||
| ========== | |||
| Glossary | |||
| ========== | |||
| The glossary explains most of the special terms we use in this documentation. | |||
| some of these are originally explained in the `Emacs manual`_ or the `Emacs Lisp | |||
| reference`_, but we reproduce them here for convenience. | |||
| .. _Emacs manual: https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html | |||
| .. _Emacs Lisp reference: https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html | |||
| .. glossary:: | |||
| init file | |||
| user init file | |||
| Your main Emacs configuration file. It’s typically located in your | |||
| :term:`user emacs directory` at :file:`$HOME/.emacs.d/init.el`. Emacs | |||
| also looks at :file:`$HOME/.emacs`, but this location is not recommended | |||
| anymore. To find out the actual path to your init file of your Emacs | |||
| session inspect the value of the variable `user-init-file` with :kbd:`C-h | |||
| v user-init-file`. You can visit it directly with :kbd:`M-: (find-file | |||
| user-init-file)`. | |||
| .. seealso:: | |||
| :infonode:`(emacs)Init File` | |||
| More information about the init file. | |||
| :infonode:`(elisp)Init File` | |||
| Programming interface for the init file. | |||
| user emacs directory | |||
| The directory for all Emacs related files of the current user, at | |||
| :file:`~/.emacs.d/`. Many Emacs packages create data files in this | |||
| directory, and it holds the recommended location for the :term:`init file` | |||
| at :file:`~/.emacs.d/init.el`. | |||
| registered syntax checker | |||
| A syntax checker in `flycheck-checkers`. Flycheck will only use these | |||
| syntax checkers when checking buffers automatically. | |||
| verification buffer | |||
| A buffer shown by `M-x flycheck-verify-setup`. This buffer contains | |||
| information about the Flycheck setup for the current buffer. | |||
| executable option | |||
| executable options | |||
| Options to override the executables of syntax checkers that run external | |||
| commands. They are named :samp:`flycheck-{checker}-executable`, | |||
| e.g. ``flycheck-c/c++-clang-executable`` for `c/c++-clang`. | |||
| Flycheck implicit defines these options for all syntax checkers defined | |||
| with `flycheck-define-checker`. | |||
| @ -0,0 +1,173 @@ | |||
| ========================================== | |||
| Flycheck — Syntax checking for GNU Emacs | |||
| ========================================== | |||
| **Flycheck** is a modern on-the-fly syntax checking extension for GNU Emacs, | |||
| intended as replacement for the older Flymake extension which is part of GNU | |||
| Emacs. For a detailed comparison to Flymake see :ref:`flycheck-versus-flymake`. | |||
| It uses various syntax checking and linting tools to :ref:`automatically check | |||
| the contents of buffers <flycheck-syntax-checks>` while you type, and reports | |||
| warnings and errors directly in the buffer, or in an optional :ref:`error list | |||
| <flycheck-error-list>`: | |||
| .. image:: images/flycheck-annotated.png | |||
| Out of the box Flycheck supports over :ref:`40 different programming languages | |||
| <flycheck-languages>` with more than 80 different syntax checking tools, and | |||
| comes with a :ref:`simple interface <flycheck-developers-guide>` to define new | |||
| syntax checkers. | |||
| Many :ref:`3rd party extensions <flycheck-extensions>` provide new syntax | |||
| checkers and other features like alternative error displays or mode line | |||
| indicators. | |||
| Try out | |||
| ======= | |||
| Flycheck needs GNU Emacs |min-emacs|, and works best on Unix systems. **Windows | |||
| users**, please be aware that Flycheck does not support Windows officially, | |||
| although it should mostly work fine on Windows. See :ref:`Windows support | |||
| <flycheck-windows-support>` and watch out for `known Windows issues`_! | |||
| To try Flycheck in your Emacs session install some :ref:`syntax checker tools | |||
| <flycheck-languages>` and type the following in your ``*scratch*`` buffer and | |||
| run ``M-x eval-buffer``: | |||
| .. code-block:: cl | |||
| (require 'package) | |||
| (add-to-list 'package-archives | |||
| '("MELPA Stable" . "http://stable.melpa.org/packages/") t) | |||
| (package-initialize) | |||
| (package-refresh-contents) | |||
| (package-install 'flycheck) | |||
| (global-flycheck-mode) | |||
| *On MacOS* also add the following to :ref:`fix your $PATH environment variable | |||
| <flycheck-macos-exec-path-from-shell>`: | |||
| .. code-block:: cl | |||
| (package-install 'exec-path-from-shell) | |||
| (exec-path-from-shell-initialize) | |||
| For a permanent installation of Flycheck follow the :ref:`Installation | |||
| <flycheck-installation>` instructions. For a gentle introduction into Flycheck | |||
| features go through :ref:`Quickstart <flycheck-quickstart>` guide. | |||
| .. important:: | |||
| If Flycheck fails to run properly or gives you any error messages please take | |||
| a look at the :ref:`troubleshooting section <flycheck-troubleshooting>` which | |||
| covers some common setup issues and helps you debug and fix problems with | |||
| Flycheck. | |||
| .. _`known windows issues`: https://github.com/flycheck/flycheck/labels/arch%3A%20windows%20only | |||
| .. _flycheck-user-guide: | |||
| The User Guide | |||
| ============== | |||
| The User Guide provides installation and usage help for Flycheck. It starts | |||
| with installation instructions and a quick start tutorial and then focuses on an | |||
| in-depth references of all parts of Flycheck. | |||
| .. toctree:: | |||
| user/installation | |||
| user/quickstart | |||
| user/troubleshooting | |||
| user/syntax-checks | |||
| user/syntax-checkers | |||
| user/error-reports | |||
| user/error-list | |||
| user/error-interaction | |||
| user/flycheck-versus-flymake | |||
| .. _flycheck-community-guide: | |||
| The Community Guide | |||
| =================== | |||
| The Community Guide provides information about Flycheck’s ecosystem and | |||
| community. | |||
| .. toctree:: | |||
| community/conduct | |||
| community/extensions | |||
| community/get-help | |||
| community/people | |||
| .. _flycheck-developer-guide: | |||
| The Developer Guide | |||
| =================== | |||
| The Developer Guide shows how extend Flycheck and how to write syntax checkers | |||
| for Flycheck. | |||
| .. toctree:: | |||
| developer/developing | |||
| .. _flycheck-contributor-guide: | |||
| The Contributor Guide | |||
| ===================== | |||
| The Contributor Guide explains how to contribute to Flycheck. | |||
| .. toctree:: | |||
| contributor/contributing | |||
| contributor/style-guide | |||
| contributor/maintaining | |||
| Indices and Tables | |||
| ================== | |||
| * :ref:`flycheck-languages` | |||
| * :doc:`glossary` | |||
| * :doc:`changes` | |||
| * :ref:`genindex` | |||
| * :ref:`search` | |||
| .. toctree:: | |||
| :hidden: | |||
| languages | |||
| glossary | |||
| changes | |||
| Licensing | |||
| ========= | |||
| Flycheck is free software; you can redistribute it and/or modify it under the | |||
| terms of the GNU General Public License as published by the Free Software | |||
| Foundation, either version 3 of the License, or (at your option) any later | |||
| version. | |||
| Flycheck is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |||
| PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| See :ref:`flycheck-gpl` for a copy of the GNU General Public License. | |||
| You may copy, distribute and/or modify the Flycheck documentation under the | |||
| terms of the Creative Commons Attribution-ShareAlike 4.0 International Public | |||
| License. See :ref:`flycheck-cc-by-sa` for a copy of the license. | |||
| Permission is granted to copy, distribute and/or modify the Flycheck logo under | |||
| the terms of the Creative Commons Attribution-ShareAlike 4.0 International | |||
| Public License. See :ref:`flycheck-cc-by-sa` for a copy of the license. | |||
| .. toctree:: | |||
| :hidden: | |||
| :maxdepth: 2 | |||
| licenses | |||
| @ -0,0 +1,192 @@ | |||
| # Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| # This file is not part of GNU Emacs. | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| import re | |||
| from string import Template | |||
| import requests | |||
| from docutils import nodes | |||
| from sphinx.roles import XRefRole | |||
| from sphinx.util import ws_re, logging | |||
| logger = logging.getLogger(__name__) | |||
| # Regular expression object to parse the contents of an Info reference | |||
| # role. | |||
| INFO_RE = re.compile(r'\A\((?P<manual>[^)]+)\)(?P<node>.+)\Z') | |||
| class InfoNodeXRefRole(XRefRole): | |||
| """A role to reference a node in an Info manual.""" | |||
| innernodeclass = nodes.emphasis | |||
| def process_link(self, env, refnode, has_explicit_title, title, target): | |||
| """Process the link created by this role. | |||
| Swap node and manual name, to more closely match the look of references | |||
| in Texinfo. | |||
| """ | |||
| # Normalize whitespace in info node targets | |||
| target = ws_re.sub(' ', target) | |||
| refnode['has_explicit_title'] = has_explicit_title | |||
| if not has_explicit_title: | |||
| match = INFO_RE.match(target) | |||
| if match: | |||
| # Swap title and node to create a title like info does | |||
| title = '{0}({1})'.format(match.group('node'), | |||
| match.group('manual')) | |||
| return title, target | |||
| def node_encode(char): | |||
| if char.isalnum(): | |||
| return char | |||
| elif char == ' ': | |||
| return '-' | |||
| else: | |||
| return '_00{:02x}'.format(ord(char)) | |||
| def expand_node_name(node): | |||
| """Expand ``node`` for use in HTML. | |||
| ``node`` is the name of a node as string. | |||
| Return a pair ``(filename, anchor)``, where ``filename`` is the base-name | |||
| of the corresponding file, sans extension, and ``anchor`` the HTML anchor. | |||
| See | |||
| http://www.gnu.org/software/texinfo/manual/texinfo/html_node/HTML-Xref-Node-Name-Expansion.html. | |||
| """ | |||
| if node == 'Top': | |||
| return ('index', 'Top') | |||
| else: | |||
| normalized = ws_re.sub(' ', node.strip()) | |||
| encoded = ''.join(node_encode(c) for c in normalized) | |||
| prefix = 'g_t' if not node[0].isalpha() else '' | |||
| return (encoded, prefix + encoded) | |||
| class HTMLXRefDB(object): | |||
| """Cross-reference database for Info manuals.""" | |||
| #: URL of the htmlxref database of GNU Texinfo | |||
| XREF_URL = 'http://ftpmirror.gnu.org/texinfo/htmlxref.cnf' | |||
| #: Regular expression to parse entries from an xref DB | |||
| XREF_RE = re.compile(r""" | |||
| ^\s* | |||
| (?: | |||
| (?P<comment>[#].*) | | |||
| (?P<substname>\w+)\s*=\s*(?P<substurl>\S+) | | |||
| (?P<manname>\w+)\s*(?P<mantype>node|mono)\s*(?P<manurl>\S+) | |||
| ) | |||
| \s*$""", re.VERBOSE) | |||
| @classmethod | |||
| def parse(cls, htmlxref): | |||
| substitutions = {} | |||
| manuals = {} | |||
| for line in htmlxref.splitlines(): | |||
| match = cls.XREF_RE.match(line) | |||
| if match: | |||
| if match.group('substname'): | |||
| url = Template(match.group('substurl')).substitute( | |||
| substitutions) | |||
| substitutions[match.group('substname')] = url | |||
| elif (match.group('manname') | |||
| and match.group('mantype') == 'node'): | |||
| url = Template(match.group('manurl')).substitute( | |||
| substitutions) | |||
| manuals[match.group('manname')] = url | |||
| return cls(manuals) | |||
| def __init__(self, entries): | |||
| """Initialize the HTMLXrefDB object with the provided entries.""" | |||
| self.entries = entries | |||
| def resolve(self, manual, node): | |||
| manual_url = self.entries.get(manual) | |||
| if not manual_url: | |||
| return None | |||
| else: | |||
| filename, anchor = expand_node_name(node) | |||
| return manual_url + filename + '.html#' + anchor | |||
| def update_htmlxref(app): | |||
| if not isinstance(getattr(app.env, 'info_htmlxref', None), HTMLXRefDB): | |||
| logger.info('fetching Texinfo htmlxref database from {0}... '.format( | |||
| HTMLXRefDB.XREF_URL)) | |||
| try: | |||
| app.env.info_htmlxref = HTMLXRefDB.parse( | |||
| requests.get(HTMLXRefDB.XREF_URL).text) | |||
| except requests.exceptions.ConnectionError: | |||
| logger.warning('Failed to load xref DB. ' | |||
| 'Info references will not be resolved') | |||
| app.env.info_htmlxref = None | |||
| def resolve_info_references(app, _env, refnode, contnode): | |||
| """Resolve Info references. | |||
| Process all :class:`~sphinx.addnodes.pending_xref` nodes whose ``reftype`` | |||
| is ``infonode``. | |||
| Replace the pending reference with a :class:`~docutils.nodes.reference` | |||
| node, which references the corresponding web URL, as stored in the database | |||
| referred to by :data:`HTMLXREF_URL`. | |||
| """ | |||
| if refnode['reftype'] != 'infonode': | |||
| return None | |||
| target = ws_re.sub(' ', refnode['reftarget']) | |||
| match = INFO_RE.match(target) | |||
| if not match: | |||
| logger.warning('Invalid info target: {0}'.format(target), | |||
| location=(refnode.source, refnode.line)) | |||
| return contnode | |||
| manual = match.group('manual') | |||
| node = match.group('node') | |||
| xrefdb = app.env.info_htmlxref | |||
| if xrefdb: | |||
| uri = xrefdb.resolve(manual, node) | |||
| if not uri: | |||
| message = 'Cannot resolve info manual {0}'.format(manual) | |||
| logger.warning(message, location=(refnode.source, refnode.line)) | |||
| return contnode | |||
| else: | |||
| reference = nodes.reference('', '', internal=False, | |||
| refuri=uri, reftitle=target) | |||
| reference += contnode | |||
| return reference | |||
| else: | |||
| # Without an xref DB we're unable to resolve any info references | |||
| return None | |||
| def setup(app): | |||
| app.add_role('infonode', InfoNodeXRefRole()) | |||
| app.connect(str('builder-inited'), update_htmlxref) | |||
| app.connect(str('missing-reference'), resolve_info_references) | |||
| return {'version': '0.1', 'parallel_read_safe': True} | |||
| @ -0,0 +1,17 @@ | |||
| =================== | |||
| Flycheck licenses | |||
| =================== | |||
| .. _flycheck-gpl: | |||
| GNU General Public License 3 | |||
| ============================ | |||
| .. literalinclude:: ../COPYING | |||
| .. _flycheck-cc-by-sa: | |||
| Creative Commons Attribution-ShareAlike 4.0 International | |||
| ========================================================= | |||
| .. literalinclude:: COPYING.cc-by-sa | |||
| @ -0,0 +1,10 @@ | |||
| # Sphinx | |||
| Sphinx>=1.6 | |||
| # Automatically build documentation on changes | |||
| sphinx-autobuild | |||
| # Sphinx theme | |||
| alabaster>=0.7.8 | |||
| # Syntax highlighting | |||
| Pygments>=2.1 | |||
| # Network access | |||
| requests>=2.9 | |||
| @ -0,0 +1,199 @@ | |||
| ====================== | |||
| Interact with errors | |||
| ====================== | |||
| There are a couple of things that you can do with Flycheck errors in a buffer: | |||
| * You can navigate to errors, and go to the next or previous error. | |||
| * You can display errors to read their error messages. | |||
| * You can put error messages and IDs into the kill ring. | |||
| This section documents the corresponding commands and their customisation | |||
| options. | |||
| Navigate errors | |||
| =============== | |||
| By default Flycheck hooks into Emacs’ standard error navigation on :kbd:`M-g n` | |||
| (`next-error`) and :kbd:`M-g p` (`previous-error`). When :mode:`flycheck` is | |||
| enabled these commands will jump to the next and previous Flycheck error | |||
| respectively. See :infonode:`(emacs)Compilation Mode` for more information | |||
| about these commands. | |||
| This way you don’t need to learn special keybindings to navigate Flycheck | |||
| errors; navigation should just work out of the box. | |||
| .. note:: | |||
| Visible compilation buffers such as buffers from ``M-x compile``, ``M-x | |||
| grep``, etc. still take *precedence* over Flycheck’s errors. | |||
| The exact behaviour of these error navigation features is very context-dependent | |||
| and can be very confusing at times so you can disable this integration: | |||
| .. defcustom:: flycheck-standard-error-navigation | |||
| Whether to integrate Flycheck errors into Emacs’ standard error navigation. | |||
| Defaults to ``t``, set to ``nil`` to disable. | |||
| .. important:: | |||
| When changing the value you must disable :mode:`flycheck` and enable it | |||
| again for the change to take effect in any buffers where :mode:`flycheck` | |||
| is enabled. | |||
| Flycheck provides an independent set of navigation commands which will always | |||
| navigate Flycheck errors in the current buffer, regardless of visible | |||
| compilation buffers and `flycheck-standard-error-navigation`: | |||
| .. define-key:: C-c ! n | |||
| M-x flycheck-next-error | |||
| Jump to the next error. | |||
| With prefix argument jump forwards by as many errors as specified by the | |||
| prefix argument, e.g. :kbd:`M-3 C-c ! n` will move to the 3rd error from the | |||
| current point. With negative prefix argument move to previous errors | |||
| instead. Signal an error if there are no more Flycheck errors. | |||
| .. define-key:: C-c ! p | |||
| M-x flycheck-previous-error | |||
| Jump to the previous Flycheck error. | |||
| With prefix argument jump backwards by as many errors as specified by the | |||
| prefix argument, e.g. :kbd:`M-3 C-c ! p` will move to the 3rd error before | |||
| the current point. With negative prefix argument move to next errors | |||
| instead. Signal an error if there are no more Flycheck errors. | |||
| .. define-key:: M-x flycheck-first-error | |||
| Jump to the first Flycheck error. | |||
| With prefix argument, jump forwards to by as many errors as specified by the | |||
| prefix argument, e.g. :kbd:`M-3 M-x flycheck-first-error` moves to the 3rd | |||
| error from the beginning of the buffer. With negative prefix argument move | |||
| to the last error instead. | |||
| By default error navigation jumps to all errors but you can choose to skip over | |||
| errors with low levels: | |||
| .. defcustom:: flycheck-navigation-minimum-level | |||
| The minimum levels of errors to consider for navigation. | |||
| If set to an error level only navigate to errors whose level is as least as | |||
| severe as this one. If ``nil`` navigate to all errors. | |||
| Display errors | |||
| ============== | |||
| Whenever you move point to an error location Flycheck automatically displays all | |||
| Flycheck errors at point after a short delay which you can customise: | |||
| .. defcustom:: flycheck-display-errors-delay | |||
| The number of seconds to wait before displaying the error at point. Floating | |||
| point numbers can express fractions of seconds. | |||
| By default Flycheck shows the error messages in the minibuffer or in a separate | |||
| buffer if the minibuffer is too small to hold the whole error message but this | |||
| behaviour is entirely customisable: | |||
| .. defcustom:: flycheck-display-errors-function | |||
| A function to display errors. | |||
| The function is given the list of Flycheck errors to display as sole argument | |||
| and shall display these errors to the user in some way. | |||
| Flycheck provides two built-in functions for this option: | |||
| .. defun:: flycheck-display-error-messages errors | |||
| flycheck-display-error-messages-unless-error-list errors | |||
| Show error messages and IDs in the echo area or in a separate buffer if the | |||
| echo area is too small (using `display-message-or-buffer` which see). The | |||
| latter only displays errors when the :ref:`error list <flycheck-error-list>` | |||
| is not visible. To enable it add the following to your :term:`init file`: | |||
| .. code-block:: elisp | |||
| (setq flycheck-display-errors-function | |||
| #'flycheck-display-error-messages-unless-error-list) | |||
| .. seealso:: | |||
| :flyc:`flycheck-pos-tip` | |||
| A Flycheck extension to display errors in a GUI popup. | |||
| Additionally Flycheck shows errors in a GUI tooltip whenever you hover an error | |||
| location with the mouse pointer. By default the tooltip contains the messages | |||
| and IDs of all errors under the pointer, but the contents are customisable: | |||
| .. defcustom:: flycheck-help-echo-function | |||
| A function to create the contents of the tooltip. | |||
| The function is given a list of Flycheck errors to display as sole argument | |||
| and shall return a single string to use as the contents of the tooltip. | |||
| Errors from other files | |||
| ======================= | |||
| Some checkers may return errors from files other than the current buffer (e.g., | |||
| `gcc` may complain about errors in included files). These errors appear in the | |||
| error list, and are also added on the first line of the current buffer. You can | |||
| jump to the incriminating files with `flycheck-previous-error`. | |||
| By default, warnings and info messages from other files are ignored, but you can | |||
| customize the minimum level: | |||
| .. defcustom:: flycheck-relevant-error-other-file-minimum-level | |||
| The minimum level errors from other files to consider for inclusion in the | |||
| current buffer. | |||
| If set to an error level, only display errors from other files whose error | |||
| level is at least as severe as this one. If ``nil``, display all errors from | |||
| other files. | |||
| To never show any errors from other files, set | |||
| `flycheck-relevant-error-other-file-show` to ``nil``. | |||
| .. defcustom:: flycheck-relevant-error-other-file-show | |||
| Whether to show errors from other files. | |||
| Explain errors | |||
| ============== | |||
| Flycheck also has the ability to display explanations for errors, provided the | |||
| error checker is capable of producing these explanations. Currently, only the | |||
| `rust` and `rust-cargo` checkers produce explanations. | |||
| .. define-key:: C-c ! e | |||
| M-x flycheck-explain-error-at-point | |||
| Display an explanation for the first explainable error at point. | |||
| Kill errors | |||
| =========== | |||
| You can put errors into the kill ring with `C-c ! w`: | |||
| .. define-key:: C-c ! C-w | |||
| M-x flycheck-copy-errors-as-kill | |||
| Copy all messages of the errors at point into the kill ring. | |||
| .. define-key:: C-u C-c ! C-w | |||
| C-u M-x flycheck-copy-errors-as-kill | |||
| Like `C-c ! w` but with error IDs. | |||
| .. define-key:: M-0 C-c ! C-w | |||
| M-0 M-x flycheck-copy-errors-as-kill | |||
| Like `C-c ! w` but do not copy the error messages but only the error IDs. | |||
| @ -0,0 +1,98 @@ | |||
| .. _flycheck-error-list: | |||
| ================= | |||
| List all errors | |||
| ================= | |||
| You can see all errors in the current buffer in Flycheck’s error list: | |||
| .. image:: /images/flycheck-error-list.png | |||
| :align: center | |||
| The key `C-c ! l` pops up the error list: | |||
| .. define-key:: C-c ! l | |||
| M-x flycheck-list-errors | |||
| M-x list-flycheck-errors | |||
| Pop up a list of errors in the current buffer. | |||
| The error list automatically updates itself after every syntax check and follows | |||
| the current buffer: If you switch to different buffer or window it automatically | |||
| shows the errors of the now current buffer. The buffer whose errors are shown | |||
| in the error list is the *source buffer*. | |||
| Whenever the point is on an error in the *source buffer* the error list | |||
| highlights these errors—the green line in the screenshot above. | |||
| Within the error list the following key bindings are available: | |||
| ========== ==== | |||
| :kbd:`RET` Go to the current error in the source buffer | |||
| :kbd:`n` Jump to the next error | |||
| :kbd:`p` Jump to the previous error | |||
| :kbd:`e` Explain the error | |||
| :kbd:`f` Filter the error list by level | |||
| :kbd:`F` Remove the filter | |||
| :kbd:`S` Sort the error list by the column at point | |||
| :kbd:`g` Check the source buffer and update the error list | |||
| :kbd:`q` Quit the error list and hide its window | |||
| ========== ==== | |||
| Filter the list | |||
| =============== | |||
| By the default the error list shows all errors but sometimes you'd like to hide | |||
| warnings to focus only on real errors. The error list lets you hide all errors | |||
| below a certain level with :kbd:`f`. This key prompts for an error level and | |||
| will remove all errors of lower levels from the list. The filter is permanent | |||
| as long as the error list buffer stays alive or the filter is reset with | |||
| :kbd:`F`. | |||
| Sort the list | |||
| ============= | |||
| You can press :kbd:`S` or click on the column headings to sort the error list by | |||
| any of the following columns: | |||
| * Line | |||
| * Level | |||
| * ID | |||
| * Message and checker | |||
| Click twice or press :kbd:`S` repeatedly to flip the sort order from ascending | |||
| to descending or vice versa. | |||
| Tune error list display | |||
| ======================= | |||
| By default the error list buffer pops up like any other buffer. Flycheck does | |||
| not enforce special rules on how it's displayed and where it's located in the | |||
| frame so essentially the error list pops up at arbitrary places wherever Emacs | |||
| can find a window for it. | |||
| However you can tell Emacs to obey certain rules when displaying buffers by | |||
| customizing the built-in option `display-buffer-alist`. You can use this option | |||
| to make the error list display like similar lists in contemporary IDEs like | |||
| VisualStudio, Eclipse, etc. with the following code in your :term:`init file`: | |||
| .. code-block:: elisp | |||
| (add-to-list 'display-buffer-alist | |||
| `(,(rx bos "*Flycheck errors*" eos) | |||
| (display-buffer-reuse-window | |||
| display-buffer-in-side-window) | |||
| (side . bottom) | |||
| (reusable-frames . visible) | |||
| (window-height . 0.33))) | |||
| This display rule tells Emacs to always display the error list at the bottom | |||
| side of the frame, occupying a third of the entire height of the frame. | |||
| .. seealso:: | |||
| Shackle_ | |||
| An Emacs package which provides an alternative way to control buffer | |||
| display | |||
| .. _shackle: https://github.com/wasamasa/shackle | |||
| @ -0,0 +1,317 @@ | |||
| ======================= | |||
| See errors in buffers | |||
| ======================= | |||
| When a syntax check in the current buffer has finished Flycheck reports the | |||
| results of the check in the current buffer in two ways: | |||
| * Highlight errors, warnings, etc. directly in the buffer according to | |||
| `flycheck-highlighting-mode` and `flycheck-highlighting-style`. | |||
| * Indicate errors, warnings, etc. in the fringe according to | |||
| `flycheck-indication-mode`. | |||
| Additionally Flycheck indicates its current state and the number of errors and | |||
| warnings in the mode line. | |||
| The following screenshot illustrates how this looks like in the default Emacs | |||
| color theme. It shows an info, a warning and an error annotation, from top to | |||
| bottom. Please also note the fringe indicators on the left side and the | |||
| emphasized mode line indicator in the bottom right corner: | |||
| .. image:: /images/flycheck-error-reports.png | |||
| :alt: Flycheck showing info, warning and error annotations | |||
| :align: center | |||
| .. note:: | |||
| The colours of fringe icons and the whole appearance of the error highlights | |||
| depend on the active color theme. Although red, orange and green or blue | |||
| seem to be somewhat standard colours for Flycheck’s annotations across many | |||
| popular themes, please take a closer look at your color theme if you’re in | |||
| doubt about the meaning of a Flycheck highlight. | |||
| Error levels | |||
| ============ | |||
| All errors that syntax checkers report have a *level* which tells you the | |||
| severity of the error. Flycheck has three built-in levels: | |||
| ``error`` | |||
| Severe errors like syntax or type errors. | |||
| ``warning`` | |||
| Potential but not fatal mistakes which you should likely fix nonetheless. | |||
| ``info`` | |||
| Purely informational messages which inform about notable things in the | |||
| current buffer, or provide additional help to fix errors or warnings. | |||
| Each error level has a distinct highlighting and colour which helps you to | |||
| identify the severity of each error right in the buffer. | |||
| Error highlights | |||
| ================ | |||
| Flycheck highlights errors directly in the buffer according to | |||
| `flycheck-highlighting-mode` and `flycheck-highlighting-style`. | |||
| Most checkers report a single error position, not a range, so Flycheck typically | |||
| needs to guess how far to extend the highlighting: by default, it highlights the | |||
| whole symbol at the location reported by the checker, as in the screenshot | |||
| above, but you can change that range (or even disable highlighting completely) | |||
| using `flycheck-highlighting-mode`. | |||
| .. defcustom:: flycheck-highlighting-mode | |||
| How Flycheck chooses which buffer region to highlight: | |||
| ``nil`` | |||
| Do not highlight anything at all. | |||
| ``lines`` | |||
| Highlight the whole line and discard any information about the column. | |||
| ``columns`` | |||
| Highlight the column of the error if any, otherwise like ``lines``. | |||
| ``symbols`` | |||
| Highlight the entire symbol around the error column if any, otherwise like | |||
| ``columns``. This is this default. | |||
| ``sexps`` | |||
| Highlight the entire expression around the error column if any, otherwise | |||
| like ``columns``. | |||
| .. warning:: | |||
| In some major modes ``sexps`` is *very* slow, because discovering | |||
| expression boundaries is costly. | |||
| The built-in ``python-mode`` is known to suffer from this issue. | |||
| Be careful when enabling this mode. | |||
| Conversely, when a checker reports a range, Flycheck uses that. | |||
| The style of the highlighting is determined by the value of | |||
| `flycheck-highlighting-style`. By default, Flycheck highlights error text with | |||
| a face indicating the severity of the error (typically, this face applies a | |||
| coloured wavy underline). Instead of faces, however, Flycheck can also indicate | |||
| erroneous text by inserting delimiters around it (checkers sometimes report | |||
| errors that span a large region of the buffer, making underlines distracting, so | |||
| in fact Flycheck only applies a face if the error spans less than 5 lines; this | |||
| is achieved using the ``conditional`` style described below). | |||
| .. defcustom:: flycheck-highlighting-style | |||
| How Flycheck highlights error regions. | |||
| ``nil`` | |||
| Do not indicate error regions. | |||
| ``level-face`` | |||
| Apply a face to erroneous text. | |||
| ``(delimiters BEFORE AFTER)`` | |||
| Bracket the error text between ``BEFORE`` and ``AFTER``, which can be | |||
| strings, images, etc. Chars are handled specially: they are repeated | |||
| twice to form double brackets. | |||
| ``(conditional NLINES S1 S2)`` | |||
| Chose between styles ``S1`` and ``S2``: ``S1`` if the error covers up to | |||
| ``NLINES``, and ``S2`` otherwise. | |||
| To change the style of the underline or use different colours in the | |||
| ``level-face`` style, customize the following faces, which are used depending on | |||
| the error level: | |||
| .. defface:: flycheck-error | |||
| flycheck-warning | |||
| flycheck-info | |||
| The highlighting face for ``error``, ``warning`` and ``info`` levels | |||
| respectively. | |||
| Delimiters use the same faces as the fringe icons described below, in addition | |||
| to the `flycheck-error-delimiter` face; delimited text has the | |||
| `flycheck-delimited-error` face, which is empty by default. | |||
| .. defface:: flycheck-error-delimiter | |||
| The face applied to ``BEFORE`` and ``AFTER`` delimiters. | |||
| .. defface:: flycheck-delimited-error | |||
| The face applied to error text in ``delimiters`` style. | |||
| Fringe and margin icons | |||
| ======================= | |||
| In GUI frames, Flycheck also adds indicators to the fringe—the left or right | |||
| border of an Emacs window—to help you identify erroneous lines quickly. | |||
| These indicators consist of a rightward-pointing double arrow shape coloured in | |||
| the colour of the corresponding error level. By default the arrow is 8 pixels | |||
| wide, but a 16 pixels version is used if the fringe is `wide enough | |||
| <https://www.gnu.org/software/emacs/manual/html_node/emacs/Fringes.html>`_. | |||
| .. note:: | |||
| Flycheck extensions can define custom error levels with different fringe | |||
| indicators. Furthermore some Emacs distributions like Spacemacs redefine | |||
| Flycheck’s error levels to use different indicators. If you're using such a | |||
| distribution please take a look at its documentation if you're unsure about | |||
| the appearance of Flycheck's indicators. | |||
| You can customise the location of these indicators (left or right fringe) with | |||
| `flycheck-indication-mode`, which also lets you turn off these indicators | |||
| completely; additionally, you can move these indicators into the margins instead | |||
| of the fringes: | |||
| .. defcustom:: flycheck-indication-mode | |||
| How Flycheck indicates errors and warnings in the buffer fringes: | |||
| ``left-fringe`` or ``right-fringe`` | |||
| Use the left or right fringe respectively. Fringes can only contain | |||
| monochrome bitmaps, so Flycheck draws small pixel-art arrows. | |||
| ``left-margin`` or ``right-margin`` | |||
| Use the left or right margin respectively. Margins can support all of | |||
| Emacs' rendering facilities, so Flycheck uses the ``»`` character, which | |||
| scales with the font size. | |||
| ``nil`` | |||
| Do not indicate errors and warnings in the fringe or in the margin. | |||
| By default, Emacs displays fringes, but not margins. With ``left-margin`` and | |||
| ``right-margin`` indication modes, you will need to enable margins in your | |||
| ``.emacs``. For example: | |||
| .. code-block:: elisp | |||
| (setq-default left-fringe-width 1 right-fringe-width 8 | |||
| left-margin-width 1 right-margin-width 0) | |||
| If you intend to use margins only with Flycheck, consider using | |||
| ``flycheck-set-indication-mode`` in a hook instead; this function adjusts | |||
| margins and fringes for the current buffer. | |||
| .. code-block:: elisp | |||
| (setq-default flycheck-indication-mode 'left-margin) | |||
| (add-hook 'flycheck-mode-hook #'flycheck-set-indication-mode) | |||
| That function sets fringes and margins to reasonable (but opinionated) defaults, | |||
| according to ``flycheck-indication-mode``. To set your own margin and fringe | |||
| widths, use a hook and call ``flycheck-refresh-fringes-and-margins``, like this: | |||
| .. code-block:: elisp | |||
| ;; Show indicators in the left margin | |||
| (setq flycheck-indication-mode 'left-margin) | |||
| ;; Adjust margins and fringe widths… | |||
| (defun my/set-flycheck-margins () | |||
| (setq left-fringe-width 8 right-fringe-width 8 | |||
| left-margin-width 1 right-margin-width 0) | |||
| (flycheck-refresh-fringes-and-margins)) | |||
| ;; …every time Flycheck is activated in a new buffer | |||
| (add-hook 'flycheck-mode-hook #'my/set-flycheck-margins) | |||
| The following faces control the colours of fringe and margin indicators. | |||
| .. defface:: flycheck-fringe-error | |||
| flycheck-fringe-warning | |||
| flycheck-fringe-info | |||
| The icon faces for ``error``, ``warning`` and ``info`` levels respectively. | |||
| When an error spans multiple lines, Flycheck displays a hatch pattern in the | |||
| fringes or vertical dots in the margins to indicate the extent of the error. | |||
| To change the fringe bitmap or the symbol used in the margins, use the function | |||
| ``flycheck-redefine-standard-error-levels``. | |||
| Mode line | |||
| ========= | |||
| Like all minor modes Flycheck also has a mode line indicator. You can see it in | |||
| the bottom right corner of the above screenshot. By default the indicator shows | |||
| Flycheck’s current state via one of the following texts: | |||
| +-------------+----------------------------------------------------------------+ | |||
| |``FlyC*`` |Flycheck is checking the buffer currently. | | |||
| +-------------+----------------------------------------------------------------+ | |||
| |``FlyC`` |There are no errors or warnings in the current buffer. | | |||
| +-------------+----------------------------------------------------------------+ | |||
| |``FlyC:3/5`` |There are three errors and five warnings in the current buffer. | | |||
| +-------------+----------------------------------------------------------------+ | |||
| |``FlyC-`` |Flycheck did not find a syntax checker for the current buffer. | | |||
| | |Take a look at the :ref:`list of supported languages | | |||
| | |<flycheck-languages>` and type `C-c ! v` to see what checkers | | |||
| | |are available for the current buffer. | | |||
| +-------------+----------------------------------------------------------------+ | |||
| |``FlyC!`` |The last syntax check failed. Inspect the ``*Messages*`` buffer| | |||
| | |look for error messages, and consider :ref:`reporting a bug | | |||
| | |<flycheck-bug-reports>`. | | |||
| +-------------+----------------------------------------------------------------+ | |||
| |``FlyC?`` |The last syntax check had a dubious result. The definition of a| | |||
| | |syntax checker may have a bug. Inspect the ``*Messages*`` | | |||
| | |buffer and consider :ref:`reporting a bug | | |||
| | |<flycheck-bug-reports>`. | | |||
| +-------------+----------------------------------------------------------------+ | |||
| You can entirely customise the mode line indicator with `flycheck-mode-line`: | |||
| .. defcustom:: flycheck-mode-line | |||
| A “mode line construct” for Flycheck’s mode line indicator. | |||
| .. seealso:: | |||
| :infonode:`(elisp)Mode Line Data` | |||
| Documentation of mode line constructs. | |||
| flycheck-status-emoji_ | |||
| A Flycheck extension which puts emojis into Flycheck's mode line | |||
| indicator. | |||
| :flyc:`flycheck-color-mode-line` | |||
| A Flycheck extension which colours the entire mode line according to | |||
| Flycheck's status. | |||
| .. _flycheck-status-emoji: https://github.com/liblit/flycheck-status-emoji | |||
| Error thresholds | |||
| ================ | |||
| To avoid flooding a buffers with excessive highlighting, cluttering the | |||
| appearance and slowing down Emacs, Flycheck takes precautions against syntax | |||
| checkers that report a large number of errors exceeding | |||
| `flycheck-checker-error-threshold`: | |||
| .. defcustom:: flycheck-checker-error-threshold | |||
| The maximum number of errors a syntax checker is allowed to report. | |||
| If a syntax checker reports more errors the error information is | |||
| **discarded**. To not run into the same issue again on the next syntax check | |||
| the syntax checker is automatically added to `flycheck-disabled-checkers` in | |||
| this case to disable it for the next syntax check. | |||
| Clear results | |||
| ============= | |||
| You can explicitly remove all highlighting and indication and all error | |||
| information from a buffer: | |||
| .. define-key:: C-c ! C | |||
| M-x flycheck-clear | |||
| Clear all reported errors, all highlighting and all indication icons from the | |||
| current buffer. | |||
| .. define-key:: C-u C-c ! C | |||
| C-u M-x flycheck-clear | |||
| Like `C-c ! C` but also interrupt any syntax check currently running. Use | |||
| this command if you think that Flycheck is stuck. | |||
| @ -0,0 +1,290 @@ | |||
| .. _flycheck-versus-flymake: | |||
| ========================= | |||
| Flycheck versus Flymake | |||
| ========================= | |||
| This article compares Flycheck to the *built-in* Flymake mode. It does not | |||
| consider third-party extensions such as flymake-easy_, but references them at | |||
| appropriate places. | |||
| We aim for this comparison to be fair and comprehensive, but it may contain | |||
| stale information. Please report any inaccuracy you might find, and feel free | |||
| to `edit this page`_ and improve it. | |||
| .. note:: | |||
| This comparison was updated at the time of the Emacs 26.1 release, which | |||
| contains an overhaul of Flymake. If you are using Emacs 25.3 or below, you | |||
| can still access the comparison between Flycheck and the legacy Flymake | |||
| `here`_. | |||
| .. _flymake-easy: https://github.com/purcell/flymake-easy | |||
| .. _edit this page: https://github.com/flycheck/flycheck/edit/master/doc/user/flycheck-versus-flymake.rst | |||
| .. _here: /en/31/ | |||
| Overview | |||
| ======== | |||
| This table gives an overview of the differences and similarities between | |||
| Flycheck and Flymake. The rest of this page describes each point in more | |||
| detail. | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| | |Flycheck |Flymake | | |||
| +===========================+=======================+=======================+ | |||
| |Supports Emacs versions ||min-emacs| |26.1+ | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |Built-in |no |yes | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Supported languages`_ |100+ built-in, |10 built-in, | | |||
| | |200+ w/ 3rd-party |50+ w/ 3rd party | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Automatic syntax |built-in |manual | | |||
| |checking`_ | | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |Check triggers |save, newline, change, |save, newline, change | | |||
| | |buffer switch | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |Asynchronous checking |yes, always |yes, for some modes | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Automatic syntax checker |by major mode and |no | | |||
| |selection <Syntax checker |custom predicates | | | |||
| |selection_>`_ | | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Multiple syntax checkers |yes (configurable |yes (all at once) | | |||
| |per buffer`_ |chain) | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Definition of new |single declarative |arbitrary function | | |||
| |syntax checkers`_ |macro |[#]_ | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |Configuration debugging |built-in (C-c ! v) |none | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Error identifiers`_ |yes |no | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Error explanations`_ |yes |no | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Error parsing helpers |for regexp, JSON and |none | | |||
| |<Error parsing_>`_ |XML | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |Fringe icons for errors |yes |yes | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |Error highlighting |faces, brackets, mixed |faces only | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Error indicators |fringes (incl HiDPI), |fringes only | | |||
| |<margins>`_ |margins | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |`Error message display`_ |tooltip, echo area, |tooltip, echo area | | |||
| | |fully customizable | | | |||
| | |(e.g. tooltip, popup | | | |||
| | |w/ 3rd party packages) | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| |List of all errors |yes; filterable by |yes | | |||
| | |error level | | | |||
| +---------------------------+-----------------------+-----------------------+ | |||
| Detailed review | |||
| =============== | |||
| Relation to Emacs | |||
| ----------------- | |||
| **Flymake** has been part of GNU Emacs since GNU Emacs 22. As such, | |||
| contributions to Flymake are subject to the FSF policies on GNU projects. Most | |||
| notably, contributors are required to assign their copyright to the FSF. | |||
| **Flycheck** is not part of GNU Emacs. However, it is free software as well, | |||
| and publicly developed on the well-known code hosting platform :gh:`Github | |||
| <flycheck/flycheck>`. Contributing to Flycheck does not require a copyright | |||
| assignment, only an explicit agreement that your contributions will be licensed | |||
| under the GPL. | |||
| Automatic syntax checking | |||
| ------------------------- | |||
| **Flymake** is not enabled automatically for supported languages. It must be | |||
| enabled for each mode individually, or by, e.g., adding to a hook that enables | |||
| it for all ``prog-mode`` buffers. If no backends for the major mode are | |||
| available, Flymake will non-intrusively tell you in the modeline. | |||
| **Flycheck** provides a global mode `global-flycheck-mode` which enables syntax | |||
| checking in every supported language, where it is safe to do so (remote and | |||
| encrypted buffers are excluded by default). | |||
| Syntax checkers | |||
| --------------- | |||
| Supported languages | |||
| ~~~~~~~~~~~~~~~~~~~ | |||
| **Flymake** comes with support for Emacs Lisp, Ruby (``ruby`` for syntax check | |||
| and ``rubocop`` for lints), Python and Perl. In addition, backends written for | |||
| the legacy Flymake are compatible with the new implementation. | |||
| **Flycheck** provides support for `over 50 languages <flycheck-languages>` with | |||
| over 100 syntax checkers, most of them contributed by the community. | |||
| Definition of new syntax checkers | |||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
| **Flymake** backends are single functions which report diagnostics to a callback | |||
| function given as argument. | |||
| **Flycheck** provides a single function `flycheck-define-checker` to define a | |||
| new syntax checker. This function uses a declarative syntax which is easy to | |||
| understand even for users unfamiliar with Emacs Lisp. In fact, most syntax | |||
| checkers in Flycheck were contributed by the community. | |||
| For example, the Perl checker in Flycheck is defined as follows: | |||
| .. code-block:: elisp | |||
| (flycheck-define-checker perl | |||
| "A Perl syntax checker using the Perl interpreter. | |||
| See URL `http://www.perl.org'." | |||
| :command ("perl" "-w" "-c" source) | |||
| :error-patterns | |||
| ((error line-start (minimal-match (message)) | |||
| " at " (file-name) " line " line | |||
| (or "." (and ", " (zero-or-more not-newline))) line-end)) | |||
| :modes (perl-mode cperl-mode)) | |||
| The whole process is described in :ref:`adding-a-checker`. | |||
| Customization of syntax checkers | |||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
| **Flymake** does not provide built-in means to customize syntax checkers. | |||
| Instead, when defining a new syntax checker the user needs to declare | |||
| customization variables explicitly and check their value in the init function. | |||
| **Flycheck** provides built-in functions to add customization variables to | |||
| syntax checkers and splice the value of these variables into the argument list | |||
| of a syntax checking tool. Many syntax checkers in Flycheck provide | |||
| customization variables. For instance, you can customize the enabled warnings | |||
| for C with `flycheck-clang-warnings`. Flycheck also tries to automatically find | |||
| configuration files for syntax checkers. | |||
| Executables of syntax checkers | |||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
| **Flymake** does not provide built-in means to change the executable of a syntax | |||
| checker. | |||
| **Flycheck** defines a variable to set the path of a syntax checker tool for | |||
| each defined syntax checker and provides the interactive command | |||
| `flycheck-set-checker-executable` to change the executable used in a buffer. | |||
| The process used to locate checker configuration files can also be customized | |||
| using `flycheck-locate-config-file-functions`, allowing you to store your | |||
| personal checker configuration files in your ``.emacs.d`` folder. | |||
| Syntax checker selection | |||
| ------------------------ | |||
| **Flymake** runs all functions added to the `flymake-diagnostic-functions` hook. | |||
| **Flycheck** uses the major mode and checker-specific predicates to | |||
| automatically select a syntax checker. | |||
| Custom predicates | |||
| ~~~~~~~~~~~~~~~~~ | |||
| **Flymake** may allow for backends to implement custom logic to decide whether | |||
| to run the check or not. There are no easily-defined predicate functions. | |||
| **Flycheck** supports custom predicate functions. For instance, Emacs uses | |||
| a single major mode for various shell script types (e.g. Bash, Zsh, POSIX Shell, | |||
| etc.), so Flycheck additionally uses a custom predicate to look at the value of | |||
| the variable `sh-shell` in Sh Mode buffers to determine which shell to use for | |||
| syntax checking. | |||
| Manual selection | |||
| ~~~~~~~~~~~~~~~~ | |||
| **Flymake** users may manually select a specific backend by overriding the value | |||
| of the backends list. | |||
| **Flycheck** provides the local variable `flycheck-checker` to explicitly use a | |||
| specific syntax checker for a buffer and the command `flycheck-select-checker` | |||
| to set this variable interactively. | |||
| Multiple syntax checkers per buffer | |||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
| **Flymake** will use all the backends added to the | |||
| `flymake-diagnostic-functions` hook to check a buffer; all backends are started | |||
| at the same time, but errors are reported in the buffer as soon as a backend | |||
| returns them. Backends can also be written to first report errors for the | |||
| visible region of the buffer, and collect errors for hidden regions later. | |||
| **Flycheck** can also apply multiple syntax checkers per buffer, but checkers | |||
| run in sequence rather than concurrently. For instance, Flycheck will check PHP | |||
| files with PHP CLI first to find syntax errors, then with PHP MessDetector to | |||
| additionally find idiomatic and semantic errors, and eventually with PHP | |||
| CheckStyle to find stylistic errors. The user will see all errors reported by | |||
| all of these tools in the buffer. These checker-chains are configurable (see | |||
| :ref:`flycheck-checker-chains`), so it's possible to run an advanced style | |||
| checker only if a basic syntax checker returned no errors (this avoids | |||
| accumulating too many false positives and improves performance). | |||
| Errors | |||
| ------ | |||
| Error identifiers | |||
| ~~~~~~~~~~~~~~~~~ | |||
| **Flymake** does not include special treatment for error identifiers. | |||
| **Flycheck** supports identifiers for different kinds of errors, if a syntax | |||
| checker provides these. The identifiers appear in the error list and in error | |||
| display, and can be copied independently, for instance for use in an inline | |||
| suppression comment or to search the web for a particular kind of error. | |||
| Error explanations | |||
| ~~~~~~~~~~~~~~~~~~ | |||
| Some **Flycheck** checkers can use error identifiers to provide error | |||
| explanations in an help buffer (see `flycheck-explain-error-at-point`). | |||
| .. _margins: | |||
| Error indicators | |||
| ~~~~~~~~~~~~~~~~ | |||
| Both **Flymake** and **Flycheck** indicate errors in the buffer (using overlays) | |||
| and in the fringes. Flycheck includes fringe bitmaps for HiDPI screens, and | |||
| also supports displaying indicators in the margins instead of the fringes (this | |||
| behavior can be customized using `flycheck-indication-mode`, and | |||
| `flycheck-highlighting-mode`). | |||
| Error parsing | |||
| ~~~~~~~~~~~~~ | |||
| **Flymake** lets backend parse error messages from | |||
| tools. There are no built-in helpers for defining error patterns, or for | |||
| parsing JSON or XML formats. | |||
| **Flycheck** checkers can use regular expressions as well as custom parsing functions. | |||
| The preferred way to define a checker is to use the `rx` syntax, extended with | |||
| custom forms for readable error patterns. Flycheck includes some ready-to-use | |||
| parsing functions for common output formats, such as Checkstyle XML, or JSON | |||
| interleaved with plain text. | |||
| Error message display | |||
| ~~~~~~~~~~~~~~~~~~~~~ | |||
| **Flymake** shows error messages in a tool tip if the user hovers | |||
| the mouse over an error location, or in the echo area if the user navigates to | |||
| the error with `flymake-goto-next-error`. | |||
| **Flycheck** shows error message in tool tips as well, and also displays error | |||
| messages in the echo area if the point is at an error location. This feature is | |||
| fully customizable via `flycheck-display-errors-function`, and several | |||
| `extensions <flycheck-extensions>` already provide alternative way to display | |||
| errors. | |||
| .. rubric:: Footnotes | |||
| .. [#] `flymake-easy`_ provides a function to define a new syntax checker, which | |||
| sets all required variables at once. | |||
| @ -0,0 +1,146 @@ | |||
| .. _flycheck-installation: | |||
| ============== | |||
| Installation | |||
| ============== | |||
| This document gives you detailed instructions and information about installing | |||
| Flycheck. | |||
| Prerequisites | |||
| ============= | |||
| Flycheck needs GNU Emacs |min-emacs| and works best on Unix-like systems like | |||
| Linux or macOS. It does not support older releases of GNU Emacs or other | |||
| flavours of Emacs (e.g. XEmacs, Aquamacs, etc.). | |||
| .. _flycheck-windows-support: | |||
| Windows support | |||
| --------------- | |||
| **Flycheck does not explicitly support Windows**, but tries to maintain Windows | |||
| compatibility and should generally work fine on Windows, too. However, we can | |||
| neither answer questions about Windows nor fix bugs that only occur on Windows | |||
| without the help of active Windows users. Please watch out for `known Windows | |||
| issues`_. | |||
| .. _known Windows issues: https://github.com/flycheck/flycheck/labels/arch%3A%20windows%20only | |||
| Syntax checking tools | |||
| --------------------- | |||
| Flycheck does not check buffers itself but relies on *external* programs to | |||
| check buffers. These programs must be installed separately. Please take a look | |||
| at the :ref:`list of supported languages <flycheck-languages>` to find out what | |||
| tools are required for a particular language. | |||
| Many of these programs are available in the package repositories of Linux | |||
| distributions or in Homebrew_ for macOS. Others can be installed with standard | |||
| package managers such as Rubygems, NPM, Cabal, etc. | |||
| .. important:: | |||
| For a GUI Emacs on MacOS we recommend to install and configure | |||
| exec-path-from-shell_ to make Emacs use the proper ``$PATH`` and avoid a | |||
| :ref:`common setup issue on MacOS <flycheck-macos-exec-path-from-shell>`. | |||
| .. _Homebrew: https://brew.sh | |||
| .. _exec-path-from-shell: https://github.com/purcell/exec-path-from-shell | |||
| .. _flycheck-package-installation: | |||
| Package installation | |||
| ==================== | |||
| We recommend to install Flycheck with Emacs' built-in package manager. Flycheck | |||
| is available in the popular `MELPA`_ archive which serves up to date snapshots | |||
| of Flycheck's development state. We recommend to read through the | |||
| :doc:`changelog </changes>` before every upgrade to check for any breaking | |||
| changes that might affect you. | |||
| .. note:: | |||
| The sibling repository `MELPA Stable`_ provides packages for Flycheck | |||
| releases. If you prefer to follow the most recent changes use MELPA instead, | |||
| but be aware that, while we try to be careful about the stability of the | |||
| development snapshots, we may make breaking changes anytime without prior | |||
| announcement. | |||
| Unfortunately the MELPA repositories are not available in Emacs by default. You | |||
| must explicitly add them to `package-archives` with the following code in your | |||
| :term:`init file`: | |||
| .. code-block:: elisp | |||
| (require 'package) | |||
| (add-to-list 'package-archives | |||
| '("MELPA Stable" . "https://stable.melpa.org/packages/") t) | |||
| (package-initialize) | |||
| This adds MELPA Stable; for MELPA replace ``https://stable.melpa.org`` with | |||
| ``https://melpa.org`` and change the name accordingly. If you do not know where | |||
| your init file is inspect the value of `user-init-file` with :kbd:`C-h v | |||
| user-init-file`. | |||
| Once the repository is set up you can install Flycheck from Emacs' package menu | |||
| at :kbd:`M-x list-packages`, or directly with :kbd:`M-x package-install RET | |||
| flycheck`. | |||
| use-package | |||
| ----------- | |||
| You may want to take a look at `use-package`_ which provides simple syntax to | |||
| declare and configure packages in your init file. Specifically it allows to | |||
| automatically install missing packages from package archive when Emacs starts. | |||
| Add the following form to your init file to setup Flycheck with `use-package`_: | |||
| .. code-block:: elisp | |||
| (use-package flycheck | |||
| :ensure t | |||
| :init (global-flycheck-mode)) | |||
| Then press :kbd:`C-M-x` with point somewhere in this form to install and enable | |||
| Flycheck for the current Emacs session. | |||
| .. _flycheck-distribution-packages: | |||
| Distribution packages | |||
| --------------------- | |||
| Alternatively some distributions provide binary packages of Flycheck. We | |||
| officially support the following distributions: | |||
| * Debian 9 and newer: ``apt-get install elpa-flycheck flycheck-doc`` (the latter | |||
| for our manual). The `Debian Emacs addon team`_ provides these packages. | |||
| .. _Debian Emacs addon team: https://pkg-emacsen.alioth.debian.org/ | |||
| .. _flycheck-legacy-installation-methods: | |||
| Legacy installation methods | |||
| =========================== | |||
| Some users prefer to install Flycheck with legacy methods such as el-get, Git | |||
| submodules, etc that were common before Emacs included a package manager. There | |||
| are also many 3rd party packages provided by various package managers. We do | |||
| neither support nor endorse any of these: | |||
| .. warning:: | |||
| If you install Flycheck in any way other than :ref:`our official packages | |||
| <flycheck-package-installation>` you do so **at your own risk**. | |||
| Please beware of breakage, and understand that while we do not actively work | |||
| against alternative installation methods we will not make compromises to support | |||
| alternative installation methods. We will close issues reported for alternative | |||
| installation if we fail to reproduce them with a proper installation of | |||
| Flycheck. | |||
| .. _MELPA: https://melpa.org | |||
| .. _MELPA Stable: https://stable.melpa.org | |||
| .. _Getting Started: https://melpa.org/#/getting-started | |||
| .. _use-package: https://github.com/jwiegley/use-package | |||
| @ -0,0 +1,80 @@ | |||
| .. _flycheck-quickstart: | |||
| ============ | |||
| Quickstart | |||
| ============ | |||
| This page gives a quick introduction into Flycheck and an overview of its most | |||
| important features. Before you start here please make sure that Flycheck is | |||
| :ref:`installed <flycheck-installation>`. | |||
| Enable Flycheck | |||
| =============== | |||
| Now add the following code to your :term:`init file` to permanently enable | |||
| syntax checking with Flycheck: | |||
| .. code-block:: elisp | |||
| (add-hook 'after-init-hook #'global-flycheck-mode) | |||
| Install syntax checker programs | |||
| =============================== | |||
| Now you need to install syntax checking programs for the languages you'd like to | |||
| use Flycheck with. The :ref:`list of supported languages <flycheck-languages>` | |||
| tells you which languages Flycheck supports and what programs it uses. | |||
| For instance, you can install Pylint_ for Python and ESLint_ for Javascript: | |||
| .. code-block:: shell | |||
| $ pip install pylint | |||
| $ npm install eslint | |||
| .. _Pylint: https://pylint.org | |||
| .. _ESLint: https://eslint.org | |||
| Check syntax in a buffer | |||
| ======================== | |||
| Now you are ready to use Flycheck in a Python or Javascript buffer. Visit a | |||
| Python or Javascript file and check whether your Flycheck setup is complete with | |||
| `C-c ! v`. | |||
| If everything is green, Flycheck will now start to check the buffer on the fly | |||
| while you are editing. Whenever you make a mistake that eslint or Pylint can | |||
| catch, Flycheck will highlight the corresponding place in the buffer with an | |||
| error underline whose color reflects the severity of the issue. Additionally, | |||
| Flycheck will put a symbol into the fringe for affected lines and show the total | |||
| number of errors and warnings in the buffer in the mode line. | |||
| Navigate and list errors | |||
| ======================== | |||
| With `C-c ! n` and `C-c ! p` you can now jump back and forth between erroneous | |||
| places. If you keep on such a place for a little while Flycheck will show the | |||
| corresponding error message in the each area. Likewise, if you hover such a | |||
| place with the mouse cursor Flycheck will show the error message in a tooltip. | |||
| Press `C-c ! l` to pop up a list of all errors in the current buffer. This list | |||
| automatically updates itself when you fix errors or introduce new ones, and | |||
| follows the currently selected buffer. If the error list is selected you can | |||
| type :kbd:`n` and :kbd:`p` to move up and down between errors and jump to their | |||
| corresponding location in the buffer. | |||
| More features | |||
| ============= | |||
| All Flycheck commands are available in the Emacs Menu at :menuselection:`Tools | |||
| ---> Syntax checking`: | |||
| .. figure:: /images/flycheck-menu.png | |||
| The menu of Flycheck, showing all available Flycheck commands | |||
| The same menu also pops up when you click on the mode line lighter: | |||
| .. figure:: /images/flycheck-mode-line-menu.png | |||
| The mode line menu of Flycheck | |||
| @ -0,0 +1,330 @@ | |||
| ================= | |||
| Syntax checkers | |||
| ================= | |||
| Flycheck does not check buffers on its own. Instead it delegates this task to | |||
| external *syntax checkers* which are external programs or services that receive | |||
| the contents of the current buffer and return a list of errors in the buffer, | |||
| together with metadata that tells Flycheck how to run the program, how to pass | |||
| buffer contents to it, and how to extract errors. | |||
| .. seealso:: | |||
| :ref:`flycheck-languages` | |||
| A complete list of all syntax checkers included in Flycheck | |||
| Like everything else in Emacs syntax checkers have online documentation which | |||
| you can access with `C-c ! ?`: | |||
| .. define-key:: C-c ! ? | |||
| M-x flycheck-describe-checker | |||
| Prompt for the name of a syntax checker and pop up a Help buffer with its | |||
| documentation. | |||
| The documentation includes the name of the program or service used, a list of | |||
| major modes the checker supports and a list of all options for this syntax | |||
| checker. | |||
| .. _flycheck-automatic-selection: | |||
| Select syntax checkers automatically | |||
| ==================================== | |||
| Normally Flycheck automatically selects the best syntax checkers for the current | |||
| buffer from `flycheck-checkers` whenever it needs to check the buffer: | |||
| .. defcustom:: flycheck-checkers | |||
| A list of all syntax checkers available for syntax checking. | |||
| A syntax checker in this list is a :term:`registered syntax checker`. | |||
| Flycheck picks the first syntax checker from this list which exists and supports | |||
| the current major mode, and runs it over the current buffer. When the checker | |||
| has finished, Flycheck looks for the next syntax checker to run, and if there is | |||
| one, Flycheck runs the next syntax checker, and so on, until there is no more | |||
| syntax checker for the current buffer. This process repeats whenever Flycheck | |||
| needs to check the buffer according to `flycheck-check-syntax-automatically`. | |||
| .. important:: | |||
| Under some circumstances—for instance if the syntax checker is not installed— | |||
| Flycheck automatically :ref:`disables syntax checkers | |||
| <flycheck-disable-checkers>` in the current buffer and will thus not even | |||
| consider them in any future checks in the current buffer. | |||
| In the `verification buffer <C-c ! v>` these syntax checkers are marked as | |||
| “disabled” just as if you had disabled them manually with `C-c ! x`, and | |||
| likewise you can re-enable automatically disabled syntax checkers with `C-u | |||
| C-c ! x`. | |||
| For instance, the first syntax checker for Emacs Lisp is `emacs-lisp` which | |||
| checks Emacs Lisp with Emacs' own byte compiler. This syntax checker asks for | |||
| `emacs-lisp-checkdoc` to run next, which checks for stylistic issues in Emacs | |||
| Lisp docstrings. Thus Flycheck will first run the byte compiler and then | |||
| checkdoc in an Emacs Lisp buffer. | |||
| .. _flycheck-manual-selection: | |||
| Select syntax checkers manually | |||
| =============================== | |||
| Alternatively you can tell Flycheck explicitly which syntax checker to start | |||
| with in the current buffer: | |||
| .. define-key:: C-c ! s | |||
| M-x flycheck-select-checker | |||
| Prompt for a syntax checker and use this syntax checker as the first syntax | |||
| checker for the current buffer. | |||
| Flycheck may still run further syntax checkers from `flycheck-checkers` if | |||
| the selected syntax checker asks for it. | |||
| Flycheck will use the selected syntax checker as “entry point” for syntax checks | |||
| in the current buffer, just as if it had selected this syntax checker | |||
| automatically. It will automatically run further syntax checkers from | |||
| `flycheck-checkers` if the selected syntax checker asks for it. | |||
| Under the hood `C-c ! s` sets `flycheck-checker`: | |||
| .. defvar:: flycheck-checker | |||
| The name of a syntax checker to use for the current buffer. | |||
| If ``nil`` (the default) let Flycheck :ref:`automatically select | |||
| <flycheck-automatic-selection>` the best syntax checker from | |||
| `flycheck-checkers`. | |||
| If set to a syntax checker Flycheck will use this syntax checker as the first | |||
| one in the current buffer, and run subsequent syntax checkers just as if it | |||
| had selected this one automatically. | |||
| If the syntax checker in this variable does not work in the current buffer | |||
| signal an error. | |||
| This variable is buffer-local. | |||
| We recommend to set `flycheck-checker` via directory local variables to enforce | |||
| a specific syntax checker for a project. For instance, Flycheck usually prefers | |||
| `javascript-eslint` for Javascript buffers, but if your project uses | |||
| `javascript-jshint` instead you can tell Flycheck to use `javascript-jshint` for | |||
| all Javascript buffers of your project with the following command in the | |||
| top-level directory of your project: :kbd:`M-x add-dir-local-variable RET | |||
| js-mode RET flycheck-checker RET javascript-jshint`. A new buffer pops up that | |||
| shows the newly created entry in the directory variables. Save this buffer and | |||
| kill it. From now on Flycheck will check all Javascript files of this project | |||
| with JSHint. | |||
| .. seealso:: | |||
| :infonode:`(emacs)Locals` | |||
| General information about local variables. | |||
| :infonode:`(emacs)Directory Variables` | |||
| Information about directory variables. | |||
| To go back to automatic selection either set `flycheck-checker` to ``nil`` or | |||
| type `C-u C-c ! s`: | |||
| .. define-key:: C-u C-c ! s | |||
| C-u M-x flycheck-select-checker | |||
| Remove any selected syntax checker and let Flycheck again :ref:`select a | |||
| syntax checker automatically <flycheck-automatic-selection>`. | |||
| .. _flycheck-disable-checkers: | |||
| Disable syntax checkers | |||
| ======================= | |||
| Even if you :ref:`select a checker manually <flycheck-manual-selection>` | |||
| Flycheck may still use a syntax checker that you’d not like to use. To | |||
| completely opt out from a specific syntax checker disable it: | |||
| .. define-key:: C-c ! x | |||
| M-x flycheck-disable-checker | |||
| Prompt for a syntax checker to disable in the current buffer. | |||
| For instance if you do not care for documentation conventions of Emacs Lisp you | |||
| can opt out from `emacs-lisp-checkdoc` which checks your code against these | |||
| conventions with :kbd:`C-c ! x emacs-lisp-checkdoc`. After the next check all | |||
| checkdoc warnings will be gone from the buffer. | |||
| Internally this command changes the buffer-local `flycheck-disabled-checkers`: | |||
| .. defcustom:: flycheck-disabled-checkers | |||
| A list of disabled syntax checkers. Flycheck will *never* use disabled | |||
| syntax checkers to check a buffer. | |||
| This option is buffer-local. You can customise this variable with :kbd:`M-x | |||
| customize-variable RET flycheck-disabled-checkers` or set the default value | |||
| in your :term:`init file` to permanently disable specific syntax checkers. | |||
| For instance: | |||
| .. code-block:: elisp | |||
| (setq-default flycheck-disabled-checkers '(c/c++-clang)) | |||
| will permanently disable `c/c++-clang` in all buffers. | |||
| You can also disable syntax checkers per project with directory local variables. | |||
| For instance type :kbd:`M-x add-dir-local-variable RET emacs-lisp-mode RET | |||
| flycheck-disabled-checkers RET (emacs-lisp-checkdoc)` in your :term:`user emacs | |||
| directory` to disable `emacs-lisp-checkdoc` for all Emacs Lisp files in your | |||
| personal configuration. | |||
| .. seealso:: | |||
| :infonode:`(emacs)Locals` | |||
| General information about local variables. | |||
| :infonode:`(emacs)Directory Variables` | |||
| Information about directory variables. | |||
| To enable a disabled checker again, remove it from `flycheck-disabled-checkers` | |||
| or use `C-u C-c ! x`: | |||
| .. define-key:: C-u C-c ! x | |||
| C-u M-x flycheck-disable-checker | |||
| Prompt for a disabled syntax checker to enable again in the current buffer. | |||
| .. _flycheck-checker-options: | |||
| Configure syntax checkers | |||
| ========================= | |||
| Many syntax checkers provide command line flags to change their behaviour. | |||
| Flycheck wraps important flags as regular Emacs user options. | |||
| The :ref:`list of supported languages <flycheck-languages>` includes all options | |||
| for each syntax checker. You can change these options in the Customize | |||
| interface under :menuselection:`programming --> tools --> flycheck --> | |||
| flycheck-options`, however we recommend to use Directory Variables to configure | |||
| syntax checkers per project. | |||
| .. seealso:: | |||
| :infonode:`(emacs)Directory Variables` | |||
| Information about directory variables. | |||
| .. _flycheck-checker-config-files: | |||
| Configuration files | |||
| ------------------- | |||
| Some syntax checkers can additionally read configuration from files. Flycheck | |||
| can find configuration files of syntax checkers and use them when invoking the | |||
| syntax checker program: | |||
| .. defcustom:: flycheck-local-config-file-functions | |||
| Functions to call to find a configuration file for a syntax checker. Each | |||
| function gets the name of a configuration file and shall return the absolute | |||
| path to a file if one exists. The default value leads to the following | |||
| steps: | |||
| 1. If the name is an absolute path, use it. | |||
| 2. If the name exists in any ancestor directory, use the nearest one. | |||
| 3. If the name exists in ``$HOME``, use it. | |||
| This option is an abnormal hook, see :infonode:`(elisp)Hooks`. | |||
| Flycheck takes the names of configuration files from user options defined for | |||
| syntax checkers that support configuration files. Like above the :ref:`list of | |||
| languages <flycheck-languages>` also lists all supported configuration file | |||
| options. You can also change these in Customize, under | |||
| :menuselection:`programming --> tools --> flycheck --> flycheck-config-files`, | |||
| but again we recommend to use Directory Variables. | |||
| We also recommend to prefer configuration files over options as you can usually | |||
| commit the configuration files to your source control repository to share them | |||
| with other contributors so that all contributors can use the same configuration | |||
| for syntax checking and linting. | |||
| .. _flycheck-checker-executables: | |||
| Change syntax checker executables | |||
| ================================= | |||
| Flycheck normally tries to run syntax checker tools by their standard name from | |||
| `exec-path`. Sometimes, though, you need to use a different version of a tool, | |||
| or probably don't even have a tool available globally—this frequently occurs in | |||
| Javascript project where dependencies including linter tools are typically | |||
| installed into a local ``node_modules`` directory: | |||
| .. define-key:: M-x flycheck-set-checker-executable | |||
| Prompt for a syntax checker and an executable file and make Flycheck use the | |||
| executable file for the syntax checker in the current buffer. | |||
| Internally this command sets a variable named | |||
| :samp:`flycheck-{checker}-executable` where :samp:`{checker}` is the name of | |||
| the syntax checker entered on the prompt, e.g. `c/c++-clang`. | |||
| Flycheck defines these :term:`executable options` for every syntax checker | |||
| that runs an external command. You can change these variables with directory | |||
| variables or set them in custom Emacs Lisp code such as mode hooks. | |||
| .. seealso:: | |||
| :infonode:`(emacs)Directory Variables` | |||
| Information about directory variables. | |||
| .. _flycheck-checker-chains: | |||
| Configuring checker chains | |||
| ========================== | |||
| In any given buffer where Flycheck is enabled, only one checker may be run at a | |||
| time. However, any number of checkers can be run in sequence. In such a | |||
| sequence, after the first checker has finished running and its errors have been | |||
| reported, the next checker of the sequence runs and its errors are reported, | |||
| etc. until there are no more checkers in the sequence. This sequence is called | |||
| a *checker chain*. | |||
| Some checkers chains are already setup by default in Flycheck: e.g., | |||
| `emacs-lisp` will be followed by `emacs-lisp-checkdoc`, and `python-mypy` will | |||
| be followed by `python-flake8`. | |||
| When defining a checker, you can specify which checkers may run after it by | |||
| setting the ``:next-checkers`` property (see the docstring of | |||
| `flycheck-define-generic-checker`). | |||
| For a given checker, several next checkers may be specified. Flycheck will run | |||
| the first (in order of declaration) whose error level matches (see below) and | |||
| which can be used in the current buffer. | |||
| You can also customize the next checker property by calling | |||
| `flycheck-add-next-checker` in your Emacs configuration file. | |||
| .. defun:: flycheck-add-next-checker checker next &optional append | |||
| Set *next* to run after *checker*. Both arguments are syntax checker | |||
| symbols. | |||
| For example, the following will make `python-pylint` run after | |||
| `python-flake8`: | |||
| .. code-block:: elisp | |||
| (flycheck-add-next-checker 'python-flake8 'python-pylint) | |||
| *Next* may also be a cons cell ``(level . next-checker)``, where | |||
| *next-checker* is a symbol denoting the syntax checker to run after | |||
| *checker*, and *level* is an error level. The *next-checker* will then only | |||
| be run if there is no current error whose level is more severe than *level*. | |||
| If *level* is ``t``, then *next-checker* is run regardless of the current | |||
| errors. | |||
| For instance, if you wanted to run `python-pylint` only if `python-flake8` | |||
| produced no errors (only warnings and info diagnostics), then you would | |||
| rather use: | |||
| .. code-block:: elisp | |||
| (flycheck-add-next-checker 'python-flake8 '(warning . python-pylint)) | |||
| @ -0,0 +1,145 @@ | |||
| .. _flycheck-syntax-checks: | |||
| =============== | |||
| Check buffers | |||
| =============== | |||
| Flycheck provides two Emacs minor modes for automatic syntax checking: | |||
| :mode:`flycheck` to enable syntax checking in the current buffer, and | |||
| :mode:`global-flycheck` to enable syntax checking in all buffers whenever | |||
| possible. | |||
| .. minor-mode:: flycheck-mode | |||
| Enable :ref:`automatic syntax checking <flycheck-automatic-checks>` in the | |||
| current buffer. | |||
| .. minor-mode:: global-flycheck-mode | |||
| Enable :mode:`flycheck` in all buffers where syntax checking is possible. | |||
| .. note:: | |||
| This mode does not enable :mode:`flycheck` in remote files (via | |||
| TRAMP) and encrypted files. Checking remote files may be very slow | |||
| depending on the network connections, and checking encrypted files would | |||
| leak confidential data to temporary files and subprocesses. | |||
| You can manually enable :mode:`flycheck` in these buffers nonetheless, but | |||
| we do *not* recommend this for said reasons. | |||
| Add the following to your :term:`init file` to enable syntax checking | |||
| permanently: | |||
| .. code-block:: elisp | |||
| (add-hook 'after-init-hook #'global-flycheck-mode) | |||
| You can exclude specific major modes from syntax checking with | |||
| `flycheck-global-modes`: | |||
| .. defcustom:: flycheck-global-modes | |||
| Major modes for which :mode:`global-flycheck` turns on :mode:`flycheck`: | |||
| ``t`` (the default) | |||
| Turn :mode:`flycheck` on for all major modes. | |||
| :samp:`({foo-mode} …)` | |||
| Turn :mode:`flycheck` on for all major modes in this list, | |||
| i.e. whenever the value of ``major-mode`` is contained in this list. | |||
| :samp:`(not {foo-mode} …)` | |||
| Turn :mode:`flycheck` on for all major nodes *not* in this list, | |||
| i.e. whenever the value of ``major-mode`` is *not* contained in this | |||
| list. | |||
| .. note:: | |||
| :mode:`global-flycheck` never turns on :mode:`flycheck` in major modes | |||
| whose ``mode-class`` property is ``special``, regardless of the value | |||
| of this option. Syntax checking simply makes no sense in special | |||
| buffers which are typically intended for non-interactive display rather | |||
| than editing. | |||
| .. seealso:: | |||
| :infonode:`(elisp)Major Mode Conventions` | |||
| Information about major modes, and modes marked as special. | |||
| .. _flycheck-automatic-checks: | |||
| Check automatically | |||
| =================== | |||
| By default :mode:`flycheck` automatically checks a buffer whenever | |||
| * it is enabled, | |||
| * the buffer is saved, | |||
| * a new line is inserted, | |||
| * or a short time after the last change was made in a buffer. | |||
| You can customise this behaviour with `flycheck-check-syntax-automatically`: | |||
| .. defcustom:: flycheck-check-syntax-automatically | |||
| A list of events which trigger a syntax check in the current buffer: | |||
| ``save`` | |||
| Check the buffer immediately after it was saved. | |||
| ``new-line`` | |||
| Check the buffer immediately after a new line was inserted. | |||
| ``idle-change`` | |||
| Check the buffer a short time after the last change. The delay is | |||
| customisable with `flycheck-idle-change-delay`: | |||
| .. defcustom:: flycheck-idle-change-delay | |||
| Seconds to wait after the last change to the buffer before starting a | |||
| syntax check. | |||
| ``idle-buffer-switch`` | |||
| Check the buffer a short time after switching to it from another | |||
| buffer. The delay is customisable with | |||
| `flycheck-idle-buffer-switch-delay`: | |||
| .. defcustom:: flycheck-idle-buffer-switch-delay | |||
| Seconds to wait after switching to a buffer before starting a | |||
| syntax check. | |||
| If you switch to several buffers in rapid succession, the | |||
| behavior depends on | |||
| `flycheck-buffer-switch-check-intermediate-buffers`: | |||
| .. defcustom:: flycheck-buffer-switch-check-intermediate-buffers | |||
| If non-nil, then a buffer you switch to will have a syntax | |||
| check run even if you switch to another buffer before it | |||
| starts. If nil, then only the current buffer can have a | |||
| syntax check run. Note that syntax checks can still be run | |||
| in other buffers due to changes to their contents. | |||
| ``mode-enabled`` | |||
| Check the buffer immediately after :mode:`flycheck` was enabled. | |||
| For instance with the following setting :mode:`flycheck` will only check the | |||
| buffer when it was saved: | |||
| .. code-block:: elisp | |||
| (setq flycheck-check-syntax-automatically '(mode-enabled save)) | |||
| .. _flycheck-manual-checks: | |||
| Check manually | |||
| ============== | |||
| You can also start a syntax check explicitly with `C-c ! c`: | |||
| .. define-key:: C-c ! c | |||
| M-x flycheck-buffer | |||
| Check syntax in the current buffer. | |||
| @ -0,0 +1,129 @@ | |||
| .. _flycheck-troubleshooting: | |||
| ================= | |||
| Troubleshooting | |||
| ================= | |||
| If syntax checking does not work as expected there are a number of steps that | |||
| you can follow to isolate and maybe fix the problem. | |||
| .. _flycheck-common-issues: | |||
| Common issues | |||
| ============= | |||
| First check whether your issue is one of the common setup issues and problems. | |||
| .. _flycheck-macos-exec-path-from-shell: | |||
| Flycheck can’t find any programs in GUI Emacs on MacOS | |||
| ------------------------------------------------------ | |||
| Try to install and configure exec-path-from-shell_ to make a GUI Emacs inherit | |||
| the ``$PATH`` environment variable from your shell configuration. | |||
| The issue is that due to the special way MacOS starts GUI programs a GUI Emacs | |||
| does not inherit the environment variables from the shell configuration so Emacs | |||
| will lack some important entries in ``$PATH``, most notably ``/usr/local/bin/`` | |||
| where Homebrew, NPM and many other package managers put binaries in. | |||
| The `exec-path-from-shell`_ works around this issue by extracting environment | |||
| variables from a shell session and inject them into the environment of the | |||
| running Emacs instance. | |||
| .. _exec-path-from-shell: https://github.com/purcell/exec-path-from-shell | |||
| Flycheck warns about “non-zero exit code, but no errors” | |||
| -------------------------------------------------------- | |||
| Make sure that you have the latest version of the syntax checker installed, | |||
| particularly if the message started appearing after you updated Flycheck. | |||
| Newer releases of Flycheck may require newer versions of syntax checking tools. | |||
| For instance Flycheck might now pass a command line flag that older versions do | |||
| not understand, or attempt to parse an updated output format. In these cases | |||
| the syntax checker will show an error message about an unknown flag, or emit | |||
| output that Flycheck does not understand, which prompts Flycheck to warn that | |||
| even though the syntax checker appeared to not have successfully checked the | |||
| buffer content there are no errors to be found. | |||
| If you *are* using the latest version then this message most likely indicates a | |||
| flaw in the syntax checker definition. In this case please :ref:`report a bug | |||
| <flycheck-bug-reports>` to us so that we can fix the issue. Please don’t forget | |||
| to say that you are using the latest version! | |||
| Verify your setup | |||
| ================= | |||
| If your issue is none of the aforementioned :ref:`common issues | |||
| <flycheck-common-issues>` the first step is to let Flycheck check your setup: | |||
| .. define-key:: C-c ! v | |||
| M-x flycheck-verify-setup | |||
| Show a :term:`verification buffer` with information about your | |||
| :mode:`flycheck` setup for the current buffer. | |||
| The buffer contains all syntax checkers available for the current buffer and | |||
| tells you whether Flycheck would use each one and what reasons would prevent | |||
| Flycheck from using a checker. It also includes information about your | |||
| Flycheck and Emacs version and your operating system. | |||
| The following image shows a :term:`verification buffer`: | |||
| .. image:: /images/flycheck-verify-buffer.png | |||
| The buffer shows all syntax checkers for the current buffer. Note that you can | |||
| click on the syntax checker names to show the docstring for a syntax checker. | |||
| * *Green* items indicate *good* configuration. In the screenshot both | |||
| `python-flake8` and `python-pycompile` exist. | |||
| * *Orange* items indicate a *potential* misconfiguration. The screenshot shows | |||
| that no configuration file was found for `python-flake8` which is perfectly | |||
| fine if there’s no flake8 configuration file in the project, but not so good | |||
| if you’d like Flycheck to use a configuration file for flake8. The section | |||
| :ref:`flycheck-checker-config-files` has more information about configuration | |||
| files. | |||
| Likewise the buffer warns you that a ``demo`` syntax checker (which is not | |||
| part of Flycheck of course) isn’t registered in `flycheck-checkers`. If you’d | |||
| like Flycheck to automatically use this syntax checker you should fix this | |||
| issue by adding it to `flycheck-checkers` but otherwise it’s safe to ignore | |||
| this warning. | |||
| * *Red* items indicate *bad* configuration. `python-pylint` wasn’t found in the | |||
| screenshot, so you’ll not be able to use pylint in the current buffer. | |||
| Debug syntax checkers | |||
| ===================== | |||
| If a syntax checker fails although it successfully verified you need to take a | |||
| closer look. Flycheck provides you with a command that lets you run a single | |||
| syntax checker just the way Flycheck would run it: | |||
| .. define-key:: C-c ! C-c | |||
| M-x flycheck-compile | |||
| Prompt for a syntax checker and run in as a shell command, showing the whole | |||
| output in a separate buffer. | |||
| .. important:: | |||
| The current implementation this command suffers from a couple of issues, | |||
| so we’d like to have a replacement in GH-854_ and we could use your help! | |||
| If you’d like to help out with this task please join the discussion in | |||
| that issue. | |||
| .. _GH-854: https://github.com/flycheck/flycheck/issues/854 | |||
| The output of this command can provide you helpful clues about what’s going on. | |||
| It also helps to compare the output of the command in Emacs with what happens if | |||
| you run the same command in a terminal. | |||
| If all else fails… | |||
| ================== | |||
| …please do :ref:`ask for help <flycheck-get-help>`. We have many different | |||
| channels, from Twitter to a chat room to StackOverflow, whatever suits you best, | |||
| and we try to help you as fast and as well as possible. | |||
| @ -0,0 +1,157 @@ | |||
| ;;; flycheck-buttercup.el --- Flycheck: Extensions to Buttercup -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2017 Flycheck contributors | |||
| ;; Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com> | |||
| ;; fmdkdd <fmdkdd@gmail.com> | |||
| ;; Keywords: lisp, tools | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; Extensions to Buttercup to write BDD tests for Flycheck. | |||
| ;; | |||
| ;; Buttercup is a BDD testing framework for Emacs, see URL | |||
| ;; `https://github.com/jorgenschaefer/emacs-buttercup/'. Flycheck uses | |||
| ;; Buttercup extensively for new tests. | |||
| ;; | |||
| ;; This library provides extensions to Buttercup to write Specs for Flycheck. | |||
| ;; | |||
| ;; * Custom matchers | |||
| ;; | |||
| ;; (expect 'foo :to-be-local) - Is `foo' a local variable in the current buffer? | |||
| ;;; Code: | |||
| (require 'buttercup) | |||
| (require 'flycheck) | |||
| (require 'seq) | |||
| ;;; Buttercup helpers | |||
| (defun flycheck-buttercup-format-error-list (errors) | |||
| "Format ERRORS into a human-readable string." | |||
| (mapconcat (lambda (e) (flycheck-error-format e 'with-file-name)) | |||
| errors "\n")) | |||
| ;;; Data matchers | |||
| (buttercup-define-matcher :to-be-empty-string (s) | |||
| (let ((s (funcall s))) | |||
| (if (equal s "") | |||
| (cons t (format "Expected %S not be an empty string" s)) | |||
| (cons nil (format "Expected %S to be an empty string" s))))) | |||
| (buttercup-define-matcher :to-match-with-group (re s index match) | |||
| (let* ((re (funcall re)) | |||
| (s (funcall s)) | |||
| (index (funcall index)) | |||
| (match (funcall match)) | |||
| (matches? (string-match re s)) | |||
| (result (and matches? (match-string index s)))) | |||
| (if (and matches? (equal result match)) | |||
| (cons t (format "Expected %S not to match %S with %S in group %s" | |||
| re s match index)) | |||
| (cons nil (format "Expected %S to match %S with %S in group %s, %s" | |||
| re s match index | |||
| (if matches? | |||
| (format "but got %S" result) | |||
| "but did not match")))))) | |||
| ;;; Emacs feature matchers | |||
| (buttercup-define-matcher :to-be-live (buffer) | |||
| (let ((buffer (get-buffer (funcall buffer)))) | |||
| (if (buffer-live-p buffer) | |||
| (cons t (format "Expected %S not to be a live buffer, but it is" | |||
| buffer)) | |||
| (cons nil (format "Expected %S to be a live buffer, but it is not" | |||
| buffer))))) | |||
| (buttercup-define-matcher :to-be-visible (buffer) | |||
| (let ((buffer (get-buffer (funcall buffer)))) | |||
| (cond | |||
| ((and buffer (get-buffer-window buffer)) | |||
| (cons t (format "Expected %S not to be a visible buffer, but it is" | |||
| buffer))) | |||
| ((not (bufferp buffer)) | |||
| (cons nil | |||
| (format "Expected %S to be a visible buffer, but it is not a buffer" | |||
| buffer))) | |||
| (t (cons | |||
| nil | |||
| (format "Expected %S to be a visible buffer, but it is not visible" | |||
| buffer)))))) | |||
| (buttercup-define-matcher :to-be-local (symbol) | |||
| (let ((symbol (funcall symbol))) | |||
| (if (local-variable-p symbol) | |||
| (cons t (format "Expected %S not to be a local variable, but it is" | |||
| symbol)) | |||
| (cons nil (format "Expected %S to be a local variable, but it is not" | |||
| symbol))))) | |||
| (buttercup-define-matcher :to-contain-match (buffer re) | |||
| (let ((buffer (funcall buffer)) | |||
| (re (funcall re))) | |||
| (if (not (get-buffer buffer)) | |||
| (cons nil (format "Expected %S to contain a match of %s, \ | |||
| but is not a buffer" buffer re)) | |||
| (with-current-buffer buffer | |||
| (save-excursion | |||
| (goto-char (point-min)) | |||
| (if (re-search-forward re nil 'noerror) | |||
| (cons t (format "Expected %S to contain a match \ | |||
| for %s, but it did not" buffer re)) | |||
| (cons nil (format "Expected %S not to contain a match for \ | |||
| %s but it did not." buffer re)))))))) | |||
| ;;; Flycheck matchers | |||
| (buttercup-define-matcher :to-be-equal-flycheck-errors (a b) | |||
| (let* ((a (funcall a)) | |||
| (b (funcall b)) | |||
| (a-formatted (flycheck-buttercup-format-error-list a)) | |||
| (b-formatted (flycheck-buttercup-format-error-list b))) | |||
| (if (equal a b) | |||
| (cons t (format "Expected | |||
| %s | |||
| not to be equal to | |||
| %s" a-formatted b-formatted)) | |||
| (cons nil (format "Expected | |||
| %s | |||
| to be equal to | |||
| %s" a-formatted b-formatted))))) | |||
| (provide 'flycheck-buttercup) | |||
| ;; Disable byte compilation for this library, to prevent package.el choking on a | |||
| ;; missing `buttercup' library. See | |||
| ;; https://github.com/flycheck/flycheck/issues/860 | |||
| ;; Local Variables: | |||
| ;; no-byte-compile: t | |||
| ;; End: | |||
| ;;; flycheck-buttercup.el ends here | |||
| @ -0,0 +1,507 @@ | |||
| ;;; flycheck-ert.el --- Flycheck: ERT extensions -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2017-2018 Flycheck contributors | |||
| ;; Copyright (C) 2013-2016 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com> | |||
| ;; fmdkdd <fmdkdd@gmail.com> | |||
| ;; URL: https://github.com/flycheck/flycheck | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; Unit testing library for Flycheck, the modern on-the-fly syntax checking | |||
| ;; extension for GNU Emacs. | |||
| ;; Provide various utility functions and unit test helpers to test Flycheck and | |||
| ;; Flycheck extensions. | |||
| ;;; Code: | |||
| (require 'flycheck) | |||
| (require 'ert) | |||
| (require 'macroexp) ; For macro utilities | |||
| ;;; Compatibility | |||
| (eval-and-compile | |||
| ;; Provide `ert-skip' and friends for Emacs 24.3 | |||
| (defconst flycheck-ert-ert-can-skip (fboundp 'ert-skip) | |||
| "Whether ERT supports test skipping.") | |||
| (unless (fboundp 'define-error) | |||
| ;; from Emacs `subr.el' | |||
| (defun define-error (name message &optional parent) | |||
| "Define NAME as a new error signal. | |||
| MESSAGE is a string that will be output to the echo area if such an error | |||
| is signaled without being caught by a `condition-case'. | |||
| PARENT is either a signal or a list of signals from which it inherits. | |||
| Defaults to `error'." | |||
| (unless parent (setq parent 'error)) | |||
| (let ((conditions | |||
| (if (consp parent) | |||
| (apply #'append | |||
| (mapcar | |||
| (lambda (parent) | |||
| (cons parent | |||
| (or (get parent 'error-conditions) | |||
| (error "Unknown signal `%s'" parent)))) | |||
| parent)) | |||
| (cons parent (get parent 'error-conditions))))) | |||
| (put name 'error-conditions | |||
| (delete-dups (copy-sequence (cons name conditions)))) | |||
| (when message (put name 'error-message message))))) | |||
| (unless flycheck-ert-ert-can-skip | |||
| ;; Fake skipping | |||
| (define-error 'flycheck-ert-skipped "Test skipped") | |||
| (defun ert-skip (data) | |||
| (signal 'flycheck-ert-skipped data)) | |||
| (defmacro skip-unless (form) | |||
| `(unless (ignore-errors ,form) | |||
| (signal 'flycheck-ert-skipped ',form))) | |||
| (defun ert-test-skipped-p (result) | |||
| (and (ert-test-failed-p result) | |||
| (eq (car (ert-test-failed-condition result)) | |||
| 'flycheck-ert-skipped))))) | |||
| ;;; Internal variables | |||
| (defvar flycheck-ert--resource-directory nil | |||
| "The directory to get resources from in this test suite.") | |||
| ;;; Resource management macros | |||
| (defmacro flycheck-ert-with-temp-buffer (&rest body) | |||
| "Eval BODY within a temporary buffer. | |||
| Like `with-temp-buffer', but resets the modification state of the | |||
| temporary buffer to make sure that it is properly killed even if | |||
| it has a backing file and is modified." | |||
| (declare (indent 0) (debug t)) | |||
| `(with-temp-buffer | |||
| (unwind-protect | |||
| ,(macroexp-progn body) | |||
| ;; Reset modification state of the buffer, and unlink it from its backing | |||
| ;; file, if any, because Emacs refuses to kill modified buffers with | |||
| ;; backing files, even if they are temporary. | |||
| (set-buffer-modified-p nil) | |||
| (set-visited-file-name nil 'no-query)))) | |||
| (defmacro flycheck-ert-with-file-buffer (file-name &rest body) | |||
| "Create a buffer from FILE-NAME and eval BODY. | |||
| BODY is evaluated with `current-buffer' being a buffer with the | |||
| contents FILE-NAME." | |||
| (declare (indent 1) (debug t)) | |||
| `(let ((file-name ,file-name)) | |||
| (unless (file-exists-p file-name) | |||
| (error "%s does not exist" file-name)) | |||
| (flycheck-ert-with-temp-buffer | |||
| (insert-file-contents file-name 'visit) | |||
| (set-visited-file-name file-name 'no-query) | |||
| (cd (file-name-directory file-name)) | |||
| ;; Mark the buffer as not modified, because we just loaded the file up to | |||
| ;; now. | |||
| (set-buffer-modified-p nil) | |||
| ,@body))) | |||
| (defmacro flycheck-ert-with-help-buffer (&rest body) | |||
| "Execute BODY and kill the help buffer afterwards. | |||
| Use this macro to test functions that create a Help buffer." | |||
| (declare (indent 0)) | |||
| `(unwind-protect | |||
| ,(macroexp-progn body) | |||
| (when (buffer-live-p (get-buffer (help-buffer))) | |||
| (kill-buffer (help-buffer))))) | |||
| (defmacro flycheck-ert-with-global-mode (&rest body) | |||
| "Execute BODY with Global Flycheck Mode enabled. | |||
| After BODY, restore the old state of Global Flycheck Mode." | |||
| (declare (indent 0)) | |||
| `(let ((old-state global-flycheck-mode)) | |||
| (unwind-protect | |||
| (progn | |||
| (global-flycheck-mode 1) | |||
| ,@body) | |||
| (global-flycheck-mode (if old-state 1 -1))))) | |||
| (defmacro flycheck-ert-with-env (env &rest body) | |||
| "Add ENV to `process-environment' in BODY. | |||
| Execute BODY with a `process-environment' which contains all | |||
| variables from ENV added. | |||
| ENV is an alist, where each cons cell `(VAR . VALUE)' is a | |||
| environment variable VAR to be added to `process-environment' | |||
| with VALUE." | |||
| (declare (indent 1)) | |||
| `(let ((process-environment (copy-sequence process-environment))) | |||
| (pcase-dolist (`(,var . ,value) ,env) | |||
| (setenv var value)) | |||
| ,@body)) | |||
| ;;; Test resources | |||
| (defun flycheck-ert-resource-filename (resource-file) | |||
| "Determine the absolute file name of a RESOURCE-FILE. | |||
| Relative file names are expanded against | |||
| `flycheck-ert--resource-directory'." | |||
| (expand-file-name resource-file flycheck-ert--resource-directory)) | |||
| (defmacro flycheck-ert-with-resource-buffer (resource-file &rest body) | |||
| "Create a temp buffer from a RESOURCE-FILE and execute BODY. | |||
| The absolute file name of RESOURCE-FILE is determined with | |||
| `flycheck-ert-resource-filename'." | |||
| (declare (indent 1)) | |||
| `(flycheck-ert-with-file-buffer | |||
| (flycheck-ert-resource-filename ,resource-file) | |||
| ,@body)) | |||
| ;;; Test suite initialization | |||
| (defun flycheck-ert-initialize (resource-dir) | |||
| "Initialize a test suite with RESOURCE-DIR. | |||
| RESOURCE-DIR is the directory, `flycheck-ert-resource-filename' | |||
| should use to lookup resource files." | |||
| (when flycheck-ert--resource-directory | |||
| (error "Test suite already initialized")) | |||
| (let ((tests (ert-select-tests t t))) | |||
| ;; Select all tests | |||
| (unless tests | |||
| (error "No tests defined. \ | |||
| Call `flycheck-ert-initialize' after defining all tests!")) | |||
| (setq flycheck-ert--resource-directory resource-dir) | |||
| ;; Emacs 24.3 don't support skipped tests, so we add poor man's test | |||
| ;; skipping: We mark skipped tests as expected failures by adjusting the | |||
| ;; expected result of all test cases. Not particularly pretty, but works :) | |||
| (unless flycheck-ert-ert-can-skip | |||
| (dolist (test tests) | |||
| (let ((result (ert-test-expected-result-type test))) | |||
| (setf (ert-test-expected-result-type test) | |||
| `(or ,result (satisfies ert-test-skipped-p)))))))) | |||
| ;;; Test case definitions | |||
| (defmacro flycheck-ert-def-checker-test (checker language name | |||
| &rest keys-and-body) | |||
| "Define a test case for a syntax CHECKER for LANGUAGE. | |||
| CHECKER is a symbol or a list of symbols denoting syntax checkers | |||
| being tested by the test. The test case is skipped, if any of | |||
| these checkers cannot be used. LANGUAGE is a symbol or a list of | |||
| symbols denoting the programming languages supported by the | |||
| syntax checkers. This is currently only used for tagging the | |||
| test appropriately. | |||
| NAME is a symbol denoting the local name of the test. The test | |||
| itself is ultimately named | |||
| `flycheck-define-checker/CHECKER/NAME'. If CHECKER is a list, | |||
| the first checker in the list is used for naming the test. | |||
| Optionally, the keyword arguments `:tags' and `:expected-result' | |||
| may be given. They have the same meaning as in `ert-deftest.', | |||
| and are added to the tags and result expectations set up by this | |||
| macro. | |||
| The remaining forms KEYS-AND-BODY denote the body of the test | |||
| case, including assertions and setup code." | |||
| (declare (indent 3)) | |||
| (unless checker | |||
| (error "No syntax checkers specified")) | |||
| (unless language | |||
| (error "No languages specified")) | |||
| (let* ((checkers (if (symbolp checker) (list checker) checker)) | |||
| (checker (car checkers)) | |||
| (languages (if (symbolp language) (list language) language)) | |||
| (language-tags (mapcar (lambda (l) (intern (format "language-%s" l))) | |||
| languages)) | |||
| (checker-tags (mapcar (lambda (c) (intern (format "checker-%s" c))) | |||
| checkers)) | |||
| (local-name (or name 'default)) | |||
| (full-name (intern (format "flycheck-define-checker/%s/%s" | |||
| checker local-name))) | |||
| (keys-and-body (ert--parse-keys-and-body keys-and-body)) | |||
| (body (cadr keys-and-body)) | |||
| (keys (car keys-and-body)) | |||
| (default-tags '(syntax-checker external-tool))) | |||
| `(ert-deftest ,full-name () | |||
| :expected-result ,(or (plist-get keys :expected-result) :passed) | |||
| :tags (append ',(append default-tags language-tags checker-tags) | |||
| ,(plist-get keys :tags)) | |||
| ,@(mapcar (lambda (c) | |||
| `(skip-unless | |||
| ;; Ignore non-command checkers | |||
| (or (not (flycheck-checker-get ',c 'command)) | |||
| (executable-find (flycheck-checker-executable ',c))))) | |||
| checkers) | |||
| ,@body))) | |||
| ;;; Test case results | |||
| (defun flycheck-ert-syntax-check-timed-out-p (result) | |||
| "Whether RESULT denotes a timed-out test. | |||
| RESULT is an ERT test result object." | |||
| (and (ert-test-failed-p result) | |||
| (eq (car (ert-test-failed-condition result)) | |||
| 'flycheck-ert-syntax-check-timed-out))) | |||
| ;;; Syntax checking in tests | |||
| (defvar-local flycheck-ert-syntax-checker-finished nil | |||
| "Non-nil if the current checker has finished.") | |||
| (add-hook 'flycheck-after-syntax-check-hook | |||
| (lambda () (setq flycheck-ert-syntax-checker-finished t))) | |||
| (defconst flycheck-ert-checker-wait-time 10 | |||
| "Time to wait until a checker is finished in seconds. | |||
| After this time has elapsed, the checker is considered to have | |||
| failed, and the test aborted with failure.") | |||
| (define-error 'flycheck-ert-syntax-check-timed-out "Syntax check timed out.") | |||
| (defun flycheck-ert-wait-for-syntax-checker () | |||
| "Wait until the syntax check in the current buffer is finished." | |||
| (let ((starttime (float-time))) | |||
| (while (and (not flycheck-ert-syntax-checker-finished) | |||
| (< (- (float-time) starttime) flycheck-ert-checker-wait-time)) | |||
| (accept-process-output nil 0.02)) | |||
| (unless (< (- (float-time) starttime) flycheck-ert-checker-wait-time) | |||
| (flycheck-stop) | |||
| (signal 'flycheck-ert-syntax-check-timed-out nil))) | |||
| (setq flycheck-ert-syntax-checker-finished nil)) | |||
| (defun flycheck-ert-buffer-sync () | |||
| "Like `flycheck-buffer', but synchronously." | |||
| (setq flycheck-ert-syntax-checker-finished nil) | |||
| (should (not (flycheck-running-p))) | |||
| (flycheck-mode) ;; This will only start a deferred check, | |||
| (should (flycheck-get-checker-for-buffer)) | |||
| (flycheck-buffer) ;; …so we need an explicit manual check | |||
| ;; After starting the check, the checker should either be running now, or | |||
| ;; already be finished (if it was fast). | |||
| (should (or flycheck-current-syntax-check | |||
| flycheck-ert-syntax-checker-finished)) | |||
| ;; Also there should be no deferred check pending anymore | |||
| (should-not (flycheck-deferred-check-p)) | |||
| (flycheck-ert-wait-for-syntax-checker)) | |||
| (defun flycheck-ert-ensure-clear () | |||
| "Clear the current buffer. | |||
| Raise an assertion error if the buffer is not clear afterwards." | |||
| (flycheck-clear) | |||
| (should (not flycheck-current-errors)) | |||
| (should (not (-any? (lambda (ov) (overlay-get ov 'flycheck-overlay)) | |||
| (overlays-in (point-min) (point-max)))))) | |||
| ;;; Test assertions | |||
| (defun flycheck-error-without-group (err) | |||
| "Return a copy ERR with the `group' property set to nil." | |||
| (let ((copy (copy-flycheck-error err))) | |||
| (setf (flycheck-error-group copy) nil) | |||
| copy)) | |||
| (defun flycheck-ert-should-overlay (error) | |||
| "Test that ERROR has a proper overlay in the current buffer. | |||
| ERROR is a Flycheck error object." | |||
| (let* ((overlay (-first (lambda (ov) | |||
| (equal (flycheck-error-without-group | |||
| (overlay-get ov 'flycheck-error)) | |||
| (flycheck-error-without-group error))) | |||
| (flycheck-overlays-in 0 (+ 1 (buffer-size))))) | |||
| (region | |||
| ;; Overlays of errors from other files are on the first line | |||
| (if (flycheck-relevant-error-other-file-p error) | |||
| (cons (point-min) | |||
| (save-excursion (goto-char (point-min)) (point-at-eol))) | |||
| (flycheck-error-region-for-mode error 'symbols))) | |||
| (level (flycheck-error-level error)) | |||
| (category (flycheck-error-level-overlay-category level)) | |||
| (face (get category 'face)) | |||
| (fringe-bitmap (flycheck-error-level-fringe-bitmap level)) | |||
| (fringe-face (flycheck-error-level-fringe-face level)) | |||
| (fringe-icon (list 'left-fringe fringe-bitmap fringe-face))) | |||
| (should overlay) | |||
| (should (overlay-get overlay 'flycheck-overlay)) | |||
| (should (= (overlay-start overlay) (car region))) | |||
| (should (= (overlay-end overlay) (cdr region))) | |||
| (should (eq (overlay-get overlay 'face) face)) | |||
| (should (equal (get-char-property 0 'display | |||
| (overlay-get overlay 'before-string)) | |||
| fringe-icon)) | |||
| (should (eq (overlay-get overlay 'category) category)) | |||
| (should (equal (flycheck-error-without-group (overlay-get overlay | |||
| 'flycheck-error)) | |||
| (flycheck-error-without-group error))))) | |||
| (defun flycheck-ert-sort-errors (errors) | |||
| "Sort ERRORS by `flycheck-error-<'." | |||
| (seq-sort #'flycheck-error-< errors)) | |||
| (defun flycheck-ert-should-errors (&rest errors) | |||
| "Test that the current buffers has ERRORS. | |||
| ERRORS is a list of errors expected to be present in the current | |||
| buffer. Each error is given as a list of arguments to | |||
| `flycheck-error-new-at'. | |||
| If ERRORS are omitted, test that there are no errors at all in | |||
| the current buffer. | |||
| With ERRORS, test that each error in ERRORS is present in the | |||
| current buffer, and that the number of errors in the current | |||
| buffer is equal to the number of given ERRORS. In other words, | |||
| check that the buffer has all ERRORS, and no other errors." | |||
| (let ((expected (flycheck-ert-sort-errors | |||
| (mapcar (apply-partially #'apply #'flycheck-error-new-at) | |||
| errors))) | |||
| (current (flycheck-ert-sort-errors flycheck-current-errors))) | |||
| (should (equal (mapcar #'flycheck-error-without-group expected) | |||
| (mapcar #'flycheck-error-without-group current))) | |||
| ;; Check that related errors are the same | |||
| (cl-mapcar | |||
| (lambda (err1 err2) | |||
| (should (equal (flycheck-ert-sort-errors | |||
| (mapcar #'flycheck-error-without-group | |||
| (flycheck-related-errors err1 expected))) | |||
| (flycheck-ert-sort-errors | |||
| (mapcar #'flycheck-error-without-group | |||
| (flycheck-related-errors err2)))))) | |||
| expected current) | |||
| (mapc #'flycheck-ert-should-overlay expected)) | |||
| (should (= (length errors) | |||
| (length (flycheck-overlays-in (point-min) (point-max)))))) | |||
| (define-error 'flycheck-ert-suspicious-checker "Suspicious state from checker") | |||
| (defun flycheck-ert-should-syntax-check-in-buffer (&rest errors) | |||
| "Test a syntax check in BUFFER, expecting ERRORS. | |||
| This is like `flycheck-ert-should-syntax-check', but with a | |||
| buffer in the right mode instead of a file." | |||
| ;; Load safe file-local variables because some tests depend on them | |||
| (let ((enable-local-variables :safe) | |||
| ;; Disable all hooks at this place, to prevent 3rd party packages | |||
| ;; from interfering | |||
| (hack-local-variables-hook)) | |||
| (hack-local-variables)) | |||
| ;; Configure config file locating for unit tests | |||
| (let ((process-hook-called 0) | |||
| (suspicious nil)) | |||
| (add-hook 'flycheck-process-error-functions | |||
| (lambda (_err) | |||
| (setq process-hook-called (1+ process-hook-called)) | |||
| nil) | |||
| nil :local) | |||
| (add-hook 'flycheck-status-changed-functions | |||
| (lambda (status) | |||
| (when (eq status 'suspicious) | |||
| (setq suspicious t))) | |||
| nil :local) | |||
| (flycheck-ert-buffer-sync) | |||
| (when suspicious | |||
| (signal 'flycheck-ert-suspicious-checker nil)) | |||
| (apply #'flycheck-ert-should-errors errors) | |||
| (should (= process-hook-called (length errors)))) | |||
| (flycheck-ert-ensure-clear)) | |||
| (defun flycheck-ert-should-syntax-check (resource-file modes &rest errors) | |||
| "Test a syntax check in RESOURCE-FILE with MODES. | |||
| RESOURCE-FILE is the file to check. MODES is a single major mode | |||
| symbol or a list thereof, specifying the major modes to syntax | |||
| check with. If more than one major mode is specified, the test | |||
| is run for each mode separately, so if you give three major | |||
| modes, the entire test will run three times. ERRORS is the list | |||
| of expected errors, as in `flycheck-ert-should-errors'. If | |||
| omitted, the syntax check must not emit any errors. The errors | |||
| are cleared after each test. | |||
| The syntax checker is selected via standard syntax checker | |||
| selection. To test a specific checker, you need to set | |||
| `flycheck-checker' or `flycheck-disabled-checkers' accordingly | |||
| before using this predicate, depending on whether you want to use | |||
| manual or automatic checker selection. | |||
| During the syntax check, configuration files of syntax checkers | |||
| are also searched in the `config-files' sub-directory of the | |||
| resource directory." | |||
| (when (symbolp modes) | |||
| (setq modes (list modes))) | |||
| (dolist (mode modes) | |||
| (unless (fboundp mode) | |||
| (ert-skip (format "%S missing" mode))) | |||
| (flycheck-ert-with-resource-buffer resource-file | |||
| (funcall mode) | |||
| (apply #'flycheck-ert-should-syntax-check-in-buffer errors)))) | |||
| (defun flycheck-ert-at-nth-error (n) | |||
| "Determine whether point is at the N'th Flycheck error. | |||
| Return non-nil if the point is at the N'th Flycheck error in the | |||
| current buffer. Otherwise return nil." | |||
| (let* ((error (nth (1- n) flycheck-current-errors)) | |||
| (mode flycheck-highlighting-mode) | |||
| (region (flycheck-error-region-for-mode error mode))) | |||
| (and (member error (flycheck-overlay-errors-at (point))) | |||
| (= (point) (car region))))) | |||
| (defun flycheck-ert-explain--at-nth-error (n) | |||
| "Explain a failed at-nth-error predicate at N." | |||
| (let ((errors (flycheck-overlay-errors-at (point)))) | |||
| (if (null errors) | |||
| (format "Expected to be at error %s, but no error at point %s" | |||
| n (point)) | |||
| (let ((pos (cl-position (car errors) flycheck-current-errors))) | |||
| (format "Expected to be at point %s and error %s, \ | |||
| but point %s is at error %s" | |||
| (car (flycheck-error-region-for-mode | |||
| (nth (1- n) flycheck-current-errors) | |||
| flycheck-highlighting-mode)) | |||
| n (point) (1+ pos)))))) | |||
| (put 'flycheck-ert-at-nth-error 'ert-explainer | |||
| 'flycheck-ert-explain--at-nth-error) | |||
| (provide 'flycheck-ert) | |||
| ;;; flycheck-ert.el ends here | |||
| @ -0,0 +1,77 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
| <svg | |||
| xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
| xmlns:cc="http://creativecommons.org/ns#" | |||
| xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
| xmlns:svg="http://www.w3.org/2000/svg" | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| version="1.1" | |||
| width="256" | |||
| height="256" | |||
| id="svg3007"> | |||
| <title | |||
| id="title3028">Flycheck Logo</title> | |||
| <defs | |||
| id="defs3009" /> | |||
| <metadata | |||
| id="metadata3012"> | |||
| <rdf:RDF> | |||
| <cc:Work | |||
| rdf:about=""> | |||
| <dc:format>image/svg+xml</dc:format> | |||
| <dc:type | |||
| rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
| <dc:title>Flycheck Logo</dc:title> | |||
| <dc:creator> | |||
| <cc:Agent> | |||
| <dc:title>Sebastian Wiesner</dc:title> | |||
| </cc:Agent> | |||
| </dc:creator> | |||
| <dc:rights> | |||
| <cc:Agent> | |||
| <dc:title>Copyright (C) 2014 Sebastian Wiesner</dc:title> | |||
| </cc:Agent> | |||
| </dc:rights> | |||
| <cc:license | |||
| rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | |||
| </cc:Work> | |||
| <cc:License | |||
| rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"> | |||
| <cc:permits | |||
| rdf:resource="http://creativecommons.org/ns#Reproduction" /> | |||
| <cc:permits | |||
| rdf:resource="http://creativecommons.org/ns#Distribution" /> | |||
| <cc:requires | |||
| rdf:resource="http://creativecommons.org/ns#Notice" /> | |||
| <cc:requires | |||
| rdf:resource="http://creativecommons.org/ns#Attribution" /> | |||
| <cc:permits | |||
| rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | |||
| <cc:requires | |||
| rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | |||
| </cc:License> | |||
| </rdf:RDF> | |||
| </metadata> | |||
| <g | |||
| transform="translate(0,192)" | |||
| id="layer1"> | |||
| <path | |||
| d="m 45.347346,-13.742775 3.834571,-3.328834 4.511523,3.328834 4.173046,-3.29785 4.173048,3.29785 4.173047,-3.29785 4.173048,3.29785 3.834571,-3.328834 4.511524,3.328834 4.173046,-3.29785 4.173047,3.29785 4.173051,-3.29785 4.173048,3.29785 3.83456,-3.328834 4.511534,3.328834 4.17305,-3.29785 4.17303,3.29785 4.17306,-3.29785 4.17305,3.29785 3.83457,-3.328834 4.51154,3.328834 4.17304,-3.29785 4.17304,3.29785 4.17304,-3.29785 4.17306,3.29785 4.17304,-3.29785 4.17305,3.29785 4.17305,-3.29785 4.17304,3.29785 4.17304,-3.29785 4.17305,3.29785 3.83459,-3.328834 4.51151,3.328834 4.17305,-3.29785 4.17306,3.29785 4.17303,-3.29785 4.17304,3.29785 3.83457,-3.328834 4.51155,3.328834 4.17303,-3.29785 4.17304,3.29785 4.17306,-3.29785 4.17305,3.29785 3.83456,-3.328834 4.51154,3.328834 4.17304,-3.29785 4.17305,3.29785 4.17305,-3.29785 4.17304,3.29785 3.83456,-3.328834" | |||
| id="path3923" | |||
| style="fill:none;stroke:#ff0000;stroke-width:1.77537644;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> | |||
| <text | |||
| x="-11.331055" | |||
| y="-41.734375" | |||
| id="text3951" | |||
| xml:space="preserve" | |||
| style="font-size:40px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro Light"><tspan | |||
| x="-11.331055" | |||
| y="-41.734375" | |||
| id="tspan3953" | |||
| style="font-size:100px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Anonymous Pro;-inkscape-font-specification:Anonymous Pro Bold"><tspan | |||
| id="tspan3955" | |||
| style="font-size:100px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#ff0000;font-family:Anonymous Pro;-inkscape-font-specification:Anonymous Pro Bold">!</tspan>Flyc</tspan></text> | |||
| </g> | |||
| </svg> | |||
| @ -0,0 +1,59 @@ | |||
| # Copyright (c) 2012-2016 Sebastian Wiesner and Flycheck contributors | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| PYTHON = python3 | |||
| FLAKE8 = flake8 | |||
| PIP = pip3 | |||
| HAVE_PIP := $(shell sh -c "command -v $(PIP)") | |||
| .DEFAULT_GOAL := help | |||
| .PHONY: init | |||
| init: | |||
| ifndef HAVE_PIP | |||
| $(error "$(PIP) not available. Please run make help.") | |||
| endif | |||
| ifndef VIRTUAL_ENV | |||
| $(warning "No virtualenv active. Installing globally is not recommended.") | |||
| ifndef FORCE | |||
| $(error "Aborted. Run make FORCE=1 init to override or make help.") | |||
| endif | |||
| endif | |||
| pip install -r requirements.txt | |||
| .PHONY: help | |||
| help: | |||
| @echo 'Available targets:' | |||
| @echo ' init: Install dependencies of maintenance scripts' | |||
| @echo ' check: Check maintenance scripts' | |||
| @echo ' release: Make a Flycheck release' | |||
| @echo '' | |||
| @echo 'You need Python 3.5 for all maintenance scripts' | |||
| @echo '' | |||
| @echo 'Run make init to install required libraries. It is recommended' | |||
| @echo 'that you use virtualenv (https://virtualenv.pypa.io/en/latest/)' | |||
| @echo 'to avoid a global installation of Python packages. make init' | |||
| @echo 'will warn you if you do not.' | |||
| .PHONY: release | |||
| release: | |||
| @./release.py | |||
| .PHONY: lint | |||
| lint: | |||
| $(FLAKE8) .. | |||
| .PHONY: check | |||
| check: lint | |||
| @ -0,0 +1,88 @@ | |||
| ;;; flycheck-checkdoc.el --- Flycheck: Checkdoc runner -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; This file provides checkdoc linting for Flycheck. It's intended for | |||
| ;; non-interactive use, see "make checkdoc". | |||
| ;;; Code: | |||
| (unless (version<= "25" emacs-version) | |||
| (user-error "Emacs 25 required for checkdoc")) | |||
| (require 'subr-x) | |||
| (require 'seq) | |||
| (require 'f) | |||
| (require 'checkdoc) | |||
| (require 'flycheck-maint | |||
| (expand-file-name "flycheck-maint" | |||
| (file-name-directory (f-this-file)))) | |||
| (defconst flycheck/source-dir (locate-dominating-file load-file-name "Cask") | |||
| "The source directory of Flycheck.") | |||
| (defun flycheck/checkdoc-get-current-errors () | |||
| "Get the current checkdoc errors. | |||
| Return a list of all error messages from checkdoc, and erase the | |||
| error message buffer, so that the next checkdoc check starts | |||
| fresh without previous errors. | |||
| Each error is just a string with the complete human-readable | |||
| location and error message." | |||
| (with-current-buffer checkdoc-diagnostic-buffer | |||
| (unwind-protect | |||
| (progn | |||
| (goto-char (point-min)) | |||
| ;; Skip over the checkdoc header | |||
| (re-search-forward (rx line-start "***" (1+ not-newline) | |||
| ": checkdoc-current-buffer")) | |||
| (forward-line 1) | |||
| (let ((text (buffer-substring-no-properties (point) (point-max)))) | |||
| (and (not (string-empty-p text)) | |||
| (split-string text "\n")))) | |||
| (kill-buffer)))) | |||
| (defun flycheck/checkdoc-file (filename) | |||
| "Run checkdoc on FILENAME and return a list of errors. | |||
| Each error is just a string with the complete human-readable | |||
| location and error message." | |||
| (with-temp-buffer | |||
| ;; Visit the file to make sure that the filename is set, as some checkdoc | |||
| ;; lints only apply for buffers with filenames | |||
| (insert-file-contents filename 'visit) | |||
| (set-buffer-modified-p nil) | |||
| ;; Switch to Emacs Lisp mode to give checkdoc the proper syntax table, etc. | |||
| (delay-mode-hooks (emacs-lisp-mode)) | |||
| (setq delay-mode-hooks nil) | |||
| (let ((checkdoc-arguments-in-order-flag nil)) | |||
| (checkdoc-current-buffer 'take-notes)) | |||
| (flycheck/checkdoc-get-current-errors))) | |||
| (defun flycheck/batch-checkdoc () | |||
| "Run checkdoc on all source files and exit." | |||
| (let ((errors (seq-mapcat #'flycheck/checkdoc-file | |||
| (flycheck/all-source-files)))) | |||
| (seq-do (lambda (err) (message "%s" err)) errors) | |||
| (kill-emacs (if errors 1 0)))) | |||
| ;;; flycheck-checkdoc.el ends here | |||
| @ -0,0 +1,76 @@ | |||
| ;;; flycheck-compile.el --- Flycheck byte compiler -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; This file provides non-interactive byte compilation for Flycheck. | |||
| ;; | |||
| ;; It's essentially a wrapper around `batch-byte-compile' which sets some | |||
| ;; additional byte compiler options for Flycheck. | |||
| ;;; Code: | |||
| (require 'warnings) | |||
| (require 'bytecomp) | |||
| (unless noninteractive | |||
| (error "This file must not be used interactively")) | |||
| (defun flycheck/batch-byte-compile () | |||
| "Like `batch-byte-compile', but set additional flags. | |||
| Specifically set `byte-compile-error-on-warn' to t on Emacs 25." | |||
| ;; Unfortunately `byte-compile-error-on-warn' does not quite what the name | |||
| ;; suggest because for whatever mysterious reason there's also | |||
| ;; `byte-compile-log-warning' used throughout Emacs' code which bypasses | |||
| ;; `byte-compile-error-on-warn' and instead logs an Emacs warning with | |||
| ;; `display-warning'. These warnings don't trigger errors even if | |||
| ;; `byte-compile-error-on-warn' is non-nil, which is… well, at least a very | |||
| ;; _unusual_ design decision, which leads the whole purpose of | |||
| ;; `byte-compile-error-on-warn' ad absurdum. | |||
| ;; | |||
| ;; To work around this mess (I'm sorry) we check the size of | |||
| ;; `byte-compile-log-buffer' after each file to check if any warnings end up | |||
| ;; there and exit with a non-zero code if the buffer is not empty. | |||
| ;; | |||
| ;; Unfortunately this means that we can't use `batch-byte-compile' (which is | |||
| ;; the proper API) and instead have to call the undocumented internal function | |||
| ;; `batch-byte-compile-file'. Yay, so now proper byte compilation of Flycheck | |||
| ;; depends on Emacs' internals, and much evil is accomplished. Can't get any | |||
| ;; worse, can it? | |||
| (let ((byte-compile-error-on-warn (version<= "25" emacs-version))) | |||
| (while command-line-args-left | |||
| (let ((filename (pop command-line-args-left))) | |||
| (unless (batch-byte-compile-file filename) | |||
| ;; Exit if compilation failed | |||
| (kill-emacs 1)) | |||
| (when (and byte-compile-error-on-warn | |||
| (get-buffer byte-compile-log-buffer) | |||
| (> (buffer-size (get-buffer byte-compile-log-buffer)) 0)) | |||
| ;; If there's anything in the log buffer (from the idiocy that is | |||
| ;; `byte-compile-log-warning') exit as well to _ALL_ warnings, really | |||
| ;; ALL WARNINGS. Got it, Emacs? Why are making my life so hard? At | |||
| ;; least we don't have to print the contents explicitly because | |||
| ;; `display-warnings' writes to standard whatever stream in batch | |||
| ;; mode. | |||
| (kill-emacs 1))))) | |||
| (kill-emacs 0)) | |||
| ;;; flycheck-compile.el ends here | |||
| @ -0,0 +1,151 @@ | |||
| ;;; flycheck-format.el --- Flycheck: Source code formatter -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2016, 2018 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; This file provides source code formatting for Flycheck. It's mainly intended | |||
| ;; for non-interactive use, see "make format". | |||
| ;;; Code: | |||
| (unless (version<= "25" emacs-version) | |||
| (user-error "Emacs 25 required for formatting")) | |||
| (require 'seq) | |||
| (require 'rx) | |||
| (require 'f) | |||
| (require 'whitespace) | |||
| (require 'elisp-mode) | |||
| ;; Work around Emacs bug #39761 | |||
| (require 'cl-lib) | |||
| (require 'flycheck-maint | |||
| (expand-file-name "flycheck-maint" | |||
| (file-name-directory (f-this-file)))) | |||
| (defun flycheck/eval-and-format-buffer (filename) | |||
| "Format the current buffer for FILENAME. | |||
| THIS FUNCTION HAS GLOBAL AND LOCAL SIDE EFFECTS. | |||
| Evaluate the buffer to make all special indentation rules of | |||
| local definitions available before formatting. | |||
| Switch the buffer to Emacs Lisp mode." | |||
| (let (delayed-mode-hooks) | |||
| (delay-mode-hooks (emacs-lisp-mode))) | |||
| ;; Load the file to make indentation rules from local definitions available. | |||
| ;; We load files instead of evaluating them because some files in our code | |||
| ;; rely on `load-file-name' and similar stuff. Don't load files which are | |||
| ;; already loaded, though, to prevent a recursive load of this file. | |||
| (unless (flycheck/already-loaded-p filename) | |||
| (let ((load-prefer-newer t)) ; Silence "newer" messages | |||
| (load filename 'noerror 'nomessage 'nosuffix))) | |||
| (widen) | |||
| (let ((indent-tabs-mode nil) | |||
| (whitespace-style | |||
| '(empty ; Cleanup empty lines at end | |||
| indentation::space ; Replace tabs with spaces | |||
| space-before-tab::space ; Replace tabs with spaces | |||
| trailing ; Remove trailing spaces | |||
| ))) | |||
| (let ((inhibit-message t)) | |||
| ;; Silence "Indenting region..." progress reporter | |||
| (indent-region (point-min) (point-max))) | |||
| (whitespace-cleanup-region (point-min) (point-max)))) | |||
| (defun flycheck/check-long-lines (filename &optional length) | |||
| "Check FILENAME for lines longer than LENGTH. | |||
| Display a message for any line longer than LENGTH. If LENGTH is | |||
| nil, default to `fill-column'. Return t if FILENAME has no long | |||
| lines, otherwise return nil. | |||
| If FILENAME is a package file, return t regardless if there are | |||
| long lines or not." | |||
| (let ((long-lines 0) | |||
| (max-length (or length fill-column))) | |||
| (save-excursion | |||
| (goto-char (point-min)) | |||
| ;; If the file has a Commentary line, then it's a package and we start | |||
| ;; checking for long lines after the Commentary section. Lines before it | |||
| ;; may be too long but some are unsplittable. | |||
| (when (search-forward ";;; Commentary:" nil t) | |||
| (while (not (eobp)) | |||
| (end-of-line) | |||
| (when (> (current-column) max-length) | |||
| (message "%s:%d: line is over %d characters" | |||
| filename | |||
| (line-number-at-pos (point)) | |||
| max-length) | |||
| (setq long-lines (1+ long-lines))) | |||
| (forward-line 1)))) | |||
| (= long-lines 0))) | |||
| (defun flycheck/can-have-long-lines (filename) | |||
| "Whether FILENAME can have arbitrarily long lines. | |||
| Test files which contain error messages from checkers are allowed | |||
| to have long lines." | |||
| (string-match-p (rx (or "languages/test-" "flycheck-test.el")) filename)) | |||
| (defun flycheck/file-formatted-p (filename) | |||
| "Check whether FILENAME is properly formatted. | |||
| Return a non-nil value in this case, otherwise return nil." | |||
| (with-temp-buffer | |||
| (insert-file-contents filename) | |||
| (set-buffer-modified-p nil) | |||
| (flycheck/eval-and-format-buffer filename) | |||
| (and (not (buffer-modified-p)) | |||
| (or (flycheck/can-have-long-lines filename) | |||
| (flycheck/check-long-lines filename 80))))) | |||
| (defun flycheck/batch-check-format () | |||
| "Check formatting of all sources." | |||
| (let ((bad-files (seq-remove #'flycheck/file-formatted-p | |||
| (flycheck/all-source-files)))) | |||
| (if (null bad-files) | |||
| (kill-emacs 0) | |||
| (seq-do (lambda (filename) (message "%s: misformatted!" filename)) | |||
| bad-files) | |||
| (kill-emacs 1)))) | |||
| (defun flycheck/format-file (filename) | |||
| "Format FILENAME. | |||
| Return a non-nil value if the file was formatted, and nil | |||
| otherwise." | |||
| (with-temp-file filename | |||
| (insert-file-contents filename) | |||
| (set-buffer-modified-p nil) | |||
| (flycheck/eval-and-format-buffer filename) | |||
| (buffer-modified-p))) | |||
| (defun flycheck/batch-format () | |||
| "Format all Flycheck source files." | |||
| (let ((formatted-files (seq-filter #'flycheck/format-file | |||
| (flycheck/all-source-files)))) | |||
| (seq-do (lambda (filename) (message "Formatted %s" filename)) | |||
| formatted-files) | |||
| (kill-emacs 0))) | |||
| ;;; flycheck-format.el ends here | |||
| @ -0,0 +1,57 @@ | |||
| ;;; flycheck-maint.el --- Flycheck: Maintenance library -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; This file provides helper functions for maintenance tools. | |||
| ;;; Code: | |||
| (unless noninteractive | |||
| (error "This file must not be used interactively")) | |||
| (defconst flycheck/source-dir (locate-dominating-file load-file-name "Cask") | |||
| "The source directory of Flycheck.") | |||
| (defun flycheck/collect-el-files (directory &optional recursive) | |||
| "Collect all Emacs Lisp files in DIRECTORY. | |||
| If RECURSIVE is given and non-nil collect files recursively." | |||
| (let ((fn-re (rx ".el" eos))) | |||
| (if recursive | |||
| (directory-files-recursively directory fn-re) | |||
| (directory-files directory 'full fn-re)))) | |||
| (defun flycheck/all-source-files () | |||
| "Find all source files of Flycheck." | |||
| (append | |||
| (seq-mapcat (lambda (rel-name) | |||
| (flycheck/collect-el-files | |||
| (expand-file-name rel-name flycheck/source-dir))) | |||
| '("." "maint/" "doc/" "test/")) | |||
| (flycheck/collect-el-files | |||
| (expand-file-name "test/specs/" flycheck/source-dir) 'recursive))) | |||
| (defun flycheck/already-loaded-p (filename) | |||
| "Whether FILENAME is already loaded." | |||
| (not (null (assoc filename load-history)))) | |||
| (provide 'flycheck-maint) | |||
| ;;; flycheck-maint.el ends here | |||
| @ -0,0 +1,201 @@ | |||
| #!/usr/bin/env python3 | |||
| # Copyright (C) 2017 Flycheck contributors | |||
| # Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors | |||
| # This file is not part of GNU Emacs. | |||
| # This program is free software: you can redistribute it and/or modify it under | |||
| # the terms of the GNU General Public License as published by the Free Software | |||
| # Foundation, either version 3 of the License, or (at your option) any later | |||
| # version. | |||
| # This program is distributed in the hope that it will be useful, but WITHOUT | |||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |||
| # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |||
| # details. | |||
| # You should have received a copy of the GNU General Public License along with | |||
| # this program. If not, see <http://www.gnu.org/licenses/>. | |||
| import re | |||
| import sys | |||
| import subprocess | |||
| from datetime import date | |||
| from collections import namedtuple | |||
| from pathlib import Path | |||
| import requests | |||
| from git import Repo | |||
| SOURCE_DIR = Path(__file__).resolve().parent.parent | |||
| FLYCHECK_EL = SOURCE_DIR.joinpath('flycheck.el') | |||
| CHANGELOG = SOURCE_DIR.joinpath('CHANGES.rst') | |||
| TRAVIS_ENDPOINT = 'https://api.travis-ci.org/repos/flycheck/flycheck' | |||
| VERSION_HEADER_RE = re.compile( | |||
| r'^(?P<label>;;\s*Version:\s*)(?P<value>\S+)\s*$', | |||
| re.MULTILINE) | |||
| class CannotReleaseError(Exception): | |||
| pass | |||
| class Version(namedtuple('Version', 'version is_snapshot')): | |||
| RE = re.compile(r'^(?P<version>\d+)(?:(?P<snapshot>-cvs))?$') | |||
| @classmethod | |||
| def fromstring(cls, s): | |||
| match = cls.RE.match(s) | |||
| if not match: | |||
| raise ValueError('Not a version: {}'.format(s)) | |||
| return cls(version=int(match.group('version')), | |||
| is_snapshot=match.group('snapshot') is not None) | |||
| def __str__(self): | |||
| if self.is_snapshot: | |||
| return '{}-cvs'.format(self.version) | |||
| else: | |||
| return str(self.version) | |||
| @property | |||
| def is_released(self): | |||
| return not self.is_snapshot | |||
| def bump(self): | |||
| if self.is_snapshot: | |||
| # If snapshot, then bump to release version by dropping the | |||
| # snapshot indicator | |||
| return self._replace(is_snapshot=False) | |||
| else: | |||
| # If release bump to the next snapshot version | |||
| return self._replace(version=self.version + 1, is_snapshot=True) | |||
| class BuildState(namedtuple('BuildState', 'commit state')): | |||
| @classmethod | |||
| def get_from_travis_ci(cls): | |||
| response = requests.get( | |||
| TRAVIS_ENDPOINT + '/branches/master', | |||
| headers={'Accept': 'application/vnd.travis-ci.2+json'}).json() | |||
| return cls(commit=response['commit']['sha'], | |||
| state=response['branch']['state']) | |||
| def read_version_from_library_header(path): | |||
| contents = path.read_text() | |||
| match = VERSION_HEADER_RE.search(contents) | |||
| if match: | |||
| return Version.fromstring(match.group('value')) | |||
| else: | |||
| raise ValueError('Could not find version header in {}'.format(path)) | |||
| def set_version_in_library_header(path, version): | |||
| contents = path.read_text() | |||
| path.write_text(VERSION_HEADER_RE.sub( | |||
| r'\g<label>{}'.format(version), contents)) | |||
| def finalise_relase_in_changelog(path, version, date): | |||
| lines = path.read_text().splitlines() | |||
| if not lines[0].endswith(' (in development)'): | |||
| raise ValueError('Failed to find snapshot header in {}'.format(path)) | |||
| new_header = '{} ({})'.format(version, date.strftime('%b %d, %Y')) | |||
| header_underline = '=' * len(new_header) | |||
| path.write_text( | |||
| '\n'.join([new_header, header_underline] + lines[2:]) + '\n') | |||
| def add_snapshot_to_changelog(path, version): | |||
| header = '{} (in development)'.format(version) | |||
| contents = path.read_text() | |||
| underline = '=' * len(header) | |||
| path.write_text('{}\n{}\n\n{}'.format(header, underline, contents)) | |||
| def commit_and_push_release(repo, version): | |||
| repo.index.add(str(p) for p in [FLYCHECK_EL, CHANGELOG]) | |||
| repo.index.commit('Release version {}'.format(version)) | |||
| repo.create_tag(str(version), message='Flycheck {}'.format(version), | |||
| sign=True) | |||
| repo.remotes.origin.push('master', follow_tags=True) | |||
| def commit_and_push_snapshot(repo): | |||
| repo.index.add(str(p) for p in [FLYCHECK_EL, CHANGELOG]) | |||
| repo.index.commit('Bump version in master') | |||
| repo.remotes.origin.push('master') | |||
| def build_dist(): | |||
| subprocess.run(['cask', 'package'], cwd=str(SOURCE_DIR), check=True) | |||
| def ask_yes_or_no(prompt): | |||
| return input(prompt).lower() == 'y' | |||
| def ensure_can_make_release(repo): | |||
| if repo.head.ref != repo.refs.master: | |||
| raise CannotReleaseError( | |||
| 'Cannot make release from branch {}.' | |||
| ' Switch to master!'.format(repo.head.ref)) | |||
| if repo.is_dirty(untracked_files=True): | |||
| raise CannotReleaseError( | |||
| 'Cannot release from dirty working directory.' | |||
| ' Please commit or stash all changes!') | |||
| state = BuildState.get_from_travis_ci() | |||
| if state.commit != repo.head.ref.object.hexsha: | |||
| raise CannotReleaseError( | |||
| 'HEAD not tested on Travis CI.\n' | |||
| 'Please push your changes and wait for the build to complete.') | |||
| if state.state != 'passed': | |||
| raise CannotReleaseError( | |||
| 'Build not passed (state: {})\n' | |||
| 'Wait for the build to finish or fix the error!'.format( | |||
| state.state)) | |||
| def main(): | |||
| try: | |||
| repo = Repo(str(SOURCE_DIR)) | |||
| ensure_can_make_release(repo) | |||
| current_version = read_version_from_library_header(FLYCHECK_EL) | |||
| next_version = current_version.bump() | |||
| if not ask_yes_or_no('Releasing Flycheck {}, ' | |||
| 'are you sure? [yn] '.format(next_version)): | |||
| raise CannotReleaseError('Aborted') | |||
| set_version_in_library_header(FLYCHECK_EL, next_version) | |||
| finalise_relase_in_changelog(CHANGELOG, next_version, date.today()) | |||
| commit_and_push_release(repo, next_version) | |||
| build_dist() | |||
| # Now bump to next snapshot version | |||
| next_snapshot = next_version.bump() | |||
| set_version_in_library_header(FLYCHECK_EL, next_snapshot) | |||
| add_snapshot_to_changelog(CHANGELOG, next_snapshot) | |||
| commit_and_push_snapshot(repo) | |||
| print('Flycheck {} out now, new snapshot {}! Please'.format( | |||
| next_version, next_snapshot)) | |||
| print(""" | |||
| * add information about the release to https://github.com/flycheck/flycheck/releases/edit/{0} | |||
| * upload `dist/flycheck-{0}.tar, | |||
| * enable version {0} on https://readthedocs.org/dashboard/flycheck/versions/, and | |||
| * announce the release in the flycheck/flycheck Gitter channel. | |||
| """.format(next_version)) # noqa: E501 | |||
| except CannotReleaseError as error: | |||
| sys.exit(str(error)) | |||
| if __name__ == '__main__': | |||
| main() | |||
| @ -0,0 +1,14 @@ | |||
| # Network access | |||
| requests>=2.9 | |||
| # Git operations | |||
| GitPython>=2.0 | |||
| # Linting for our Python code | |||
| flake8>=3.0 | |||
| pep8>=1.7 | |||
| pep8-naming>=0.4 | |||
| flake8-quotes>=0.8 | |||
| flake8_docstrings>=1.0 | |||
| # Workaround for 'pydocstyle has no attribute tokenize_open' error | |||
| # see https://gitlab.com/pycqa/flake8-docstrings/issues/36 | |||
| pydocstyle<4 | |||
| @ -0,0 +1 @@ | |||
| /init-elpa | |||
| @ -0,0 +1,152 @@ | |||
| ;;; init.el --- Flycheck: Init file for testing -*- lexical-binding: t; -*- | |||
| ;; Copyright (C) 2017 Flycheck contributors | |||
| ;; Copyright (C) 2015-2016 Sebastian Wiesner and Flycheck contributors | |||
| ;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | |||
| ;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com> | |||
| ;; fmdkdd <fmdkdd@gmail.com> | |||
| ;; URL: https://www.flycheck.org | |||
| ;; This file is not part of GNU Emacs. | |||
| ;; This program is free software; you can redistribute it and/or modify | |||
| ;; it under the terms of the GNU General Public License as published by | |||
| ;; the Free Software Foundation, either version 3 of the License, or | |||
| ;; (at your option) any later version. | |||
| ;; This program is distributed in the hope that it will be useful, | |||
| ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| ;; GNU General Public License for more details. | |||
| ;; You should have received a copy of the GNU General Public License | |||
| ;; along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| ;;; Commentary: | |||
| ;; Use with `emacs -Q -l test/init.el -f flycheck/init' to start a clean session | |||
| ;; with only Flycheck present. | |||
| ;; | |||
| ;; Installs all dependencies of Flycheck to a temporary package directory, and | |||
| ;; loads Flycheck. | |||
| ;;; Code: | |||
| (require 'package) | |||
| (defconst flycheck/init-file (if load-in-progress | |||
| load-file-name | |||
| buffer-file-name) | |||
| "The path of this file.") | |||
| (defun flycheck/init () | |||
| "Initialize a minimal Flycheck session. | |||
| Install Flycheck and its dependencies into a separate package | |||
| directory (init-elpa in the current directory) and enable | |||
| Flycheck globally. | |||
| Set some global customization options to get rid of some of the | |||
| worst defaults of Emacs and create a half-way bearable Emacs | |||
| session. | |||
| Define a `demo' checker which can be used to demonstrate Flycheck | |||
| in this file." | |||
| (setq load-prefer-newer t) ; Don't load outdated bytecode | |||
| (setq package-user-dir (expand-file-name "init-elpa" (file-name-directory | |||
| flycheck/init-file)) | |||
| package-check-signature nil) | |||
| (add-to-list 'package-archives | |||
| '("MELPA" . "https://stable.melpa.org/packages/")) | |||
| (package-initialize) | |||
| (let* ((source-dir (locate-dominating-file flycheck/init-file "flycheck.el")) | |||
| (flycheck-el (expand-file-name "flycheck.el" source-dir))) | |||
| ;; Install Flycheck to bring its dependencies in | |||
| (unless (package-installed-p 'flycheck) | |||
| (package-refresh-contents) | |||
| (package-install-file flycheck-el)) | |||
| (load flycheck-el)) | |||
| (require 'flycheck) | |||
| (global-flycheck-mode) | |||
| ;; Some dummy code for warnings which we use to demonstrate Flycheck, see | |||
| ;; `demo' checker below. | |||
| (list 'an-info-here | |||
| 'a-warning-here | |||
| 'an-error-here) | |||
| ;; Some little convenience, to this Emacs session at least half way bearable | |||
| (require 'ido) | |||
| (ido-mode t) | |||
| (setq ido-enable-flex-matching t) | |||
| ;; Get rid of all the silly UI clutter of a default Emacs session and opt out | |||
| ;; of all the stupid startup and license messages | |||
| (tool-bar-mode -1) | |||
| (blink-cursor-mode -1) | |||
| (setq ring-bell-function #'ignore | |||
| inhibit-startup-screen t | |||
| initial-scratch-message "") | |||
| (fset 'yes-or-no-p #'y-or-n-p) | |||
| (fset 'display-startup-echo-area-message #'ignore) | |||
| ;; Improve OS X key behaviour | |||
| (when (eq system-type 'darwin) | |||
| (setq mac-option-modifier 'meta ; Option is simply the natural Meta | |||
| mac-command-modifier 'meta ; But command is a lot easier to hit | |||
| mac-right-command-modifier 'left | |||
| mac-right-option-modifier 'none ; Keep right option for accented input | |||
| mac-function-modifier 'hyper)) | |||
| (flycheck-define-generic-checker 'demo | |||
| "A demo syntax checker." | |||
| :start (lambda (checker callback) | |||
| (funcall callback 'finished | |||
| (save-excursion | |||
| (goto-char (point-min)) | |||
| (search-forward "an-info-here") | |||
| (list (flycheck-error-new-at | |||
| (line-number-at-pos) 10 'info | |||
| "An info here" :checker checker) | |||
| (flycheck-error-new-at | |||
| (+ 1 (line-number-at-pos)) 10 'warning | |||
| "A warning here" :checker checker) | |||
| (flycheck-error-new-at | |||
| (+ 2 (line-number-at-pos)) 10 'error | |||
| "A error here" :checker checker))))) | |||
| :modes 'emacs-lisp-mode)) | |||
| (defun flycheck-prepare-screenshot (&optional hide-cursor) | |||
| "Prepare this Emacs session for a screenshot. | |||
| If HIDE-CURSOR is non-nil or if a prefix arg is given hide the | |||
| cursor, otherwise keep it." | |||
| (interactive "P") | |||
| ;; Reduce UI and disable cursor | |||
| (menu-bar-mode -1) | |||
| (scroll-bar-mode -1) | |||
| (setq-default truncate-lines t) | |||
| (when hide-cursor | |||
| (setq-default cursor-type nil)) | |||
| (set-frame-font "Source Code Pro-13") | |||
| (set-frame-size (selected-frame) 750 560 'pixelwise) | |||
| ;; Tuck the error list to the bottom side window at a fixed height | |||
| (add-to-list 'display-buffer-alist | |||
| `(,(rx bos "*Flycheck errors*") | |||
| (display-buffer-reuse-window | |||
| display-buffer-in-side-window) | |||
| (side . bottom) | |||
| (reusable-frames . visible) | |||
| (window-height . 0.33)))) | |||
| ;; Local Variables: | |||
| ;; no-byte-compile: t | |||
| ;; End: | |||
| ;;; init.el ends here | |||
| @ -0,0 +1 @@ | |||
| A dummy file to test automatic syntax checking | |||
| @ -0,0 +1,13 @@ | |||
| #!/usr/bin/python | |||
| # -*- coding: utf-8; -*- | |||
| from __future__ import print_function | |||
| import sys | |||
| import re | |||
| filename = sys.argv[-1] | |||
| print('{0}:17:4:Error: t is not true!'.format(filename)) | |||
| print('{0}:19:11:Warning: This is a stupid message'.format(filename)) | |||
| sys.exit(1) | |||
| @ -0,0 +1,29 @@ | |||
| ;;; dummy-package-autoloads.el --- automatically extracted autoloads | |||
| ;; | |||
| ;;; Code: | |||
| ;;;### (autoloads nil "dummy-package" "dummy-package.el" (20978 39905 | |||
| ;;;;;; 0 0)) | |||
| ;;; Generated autoloads from dummy-package.el | |||
| (autoload 'dummy-package-foo "dummy-package" "\ | |||
| \(fn)" nil nil) | |||
| ;;;*** | |||
| ;;;### (autoloads nil nil ("dummy-package-pkg.el") (20978 39909 438930 | |||
| ;;;;;; 0)) | |||
| ;;;*** | |||
| (provide 'dummy-package-autoloads) | |||
| ;; Local Variables: | |||
| ;; version-control: never | |||
| ;; no-byte-compile: t | |||
| ;; no-update-autoloads: t | |||
| ;; coding: utf-8 | |||
| ;; End: | |||
| ;;; dummy-package-autoloads.el ends here | |||
| @ -0,0 +1 @@ | |||
| (define-package "dummy-package" "0.1" "Dummy package" 'nil) | |||
| @ -0,0 +1,5 @@ | |||
| ;;;###autoload | |||
| (defun dummy-package-foo () | |||
| (message "Hello world")) | |||
| (provide 'dummy-package) | |||
| @ -0,0 +1 @@ | |||
| A dummy file to test whether the global mode can be enabled or not | |||
| @ -0,0 +1,11 @@ | |||
| with Ada.Text_IO; | |||
| with Ada.Command_Line; | |||
| procedure Hello is | |||
| package IO renames Ada.Text_IO; | |||
| Name : String := Ada.Command_Line.Argument (1); | |||
| begin | |||
| pragma Foo; | |||
| IO.Put_Line("Hello, world!"); | |||
| IO.New_Line; | |||
| end Hello; | |||
| @ -0,0 +1,8 @@ | |||
| with Ada.Text_IO; | |||
| with Ada.Command_Line; | |||
| procedure SyntaxError is | |||
| package IO renames Ada.Text_IO; | |||
| begin | |||
| IO.Put_Line("Hello, world!") | |||
| end SyntaxErro; | |||
| @ -0,0 +1,15 @@ | |||
| [paragraph] | |||
| {empty} | |||
| `---`--- | |||
| 1 2 | |||
| 3 4 | |||
| 5 6 | |||
| -------- | |||
| [format="csv", width="%60%", cols="4"] | |||
| |====== | |||
| 1,2,3,4 | |||
| a,b,c,d | |||
| A,B,C,D | |||
| |====== | |||
| @ -0,0 +1,6 @@ | |||
| = Document | |||
| :doctype: article | |||
| === P1 | |||
| endif::[] | |||
| @ -0,0 +1,2 @@ | |||
| x=| | |||
| @ -0,0 +1,3 @@ | |||
| cc_binary!( | |||
| name = "hello-world", | |||
| ) | |||
| @ -0,0 +1,4 @@ | |||
| cc_binary( | |||
| name = "hello-world", | |||
| srcs = ["hello-world.cc"], | |||
| ) | |||
| @ -0,0 +1,8 @@ | |||
| template <typename T> | |||
| void foo(T& x) { x.bar(); } | |||
| struct A {}; | |||
| void bar() { A a; foo(a); } | |||
| #pragma nope | |||
| @ -0,0 +1,3 @@ | |||
| class test {}; | |||
| #include "warning.c" | |||
| @ -0,0 +1 @@ | |||
| #define FLYCHECK_LIBRARY | |||
| @ -0,0 +1,2 @@ | |||
| #include "local.h" | |||
| #include <library.h> | |||
| @ -0,0 +1 @@ | |||
| #define FLYCHECK_LOCAL | |||
| @ -0,0 +1,14 @@ | |||
| int f(int x) | |||
| { | |||
| int null = 0; | |||
| int unused; | |||
| // cppcheck-suppress unusedVariable | |||
| int unused2; | |||
| return x * 2 / null; | |||
| } | |||
| std::string foobar(const std::string foo) { | |||
| return foo + "bar"; | |||
| } | |||
| @ -0,0 +1,7 @@ | |||
| void f(int x) | |||
| { | |||
| int i = 0; | |||
| if (x) { | |||
| for ( ; i < 10; ++i) ; | |||
| } | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| #include <stdio.h> | |||
| int f(int x) | |||
| { | |||
| int unused; | |||
| unsigned int y = 10; | |||
| return x < y ? ++x : x; | |||
| #warning | |||
| } | |||
| @ -0,0 +1,10 @@ | |||
| body common control | |||
| { | |||
| bundlesequence => { run }; | |||
| } | |||
| bundle agent run | |||
| { | |||
| nosuchpromisetype: | |||
| "huh"; | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| body common control | |||
| { | |||
| host_licenses_paid => "2000"; | |||
| bundlesequence => { run }; | |||
| } | |||
| bundle agent run | |||
| { | |||
| } | |||
| @ -0,0 +1,14 @@ | |||
| # FC002: Avoid string interpolation where not required | |||
| package "mysql-server" do | |||
| version "#{node['mysql']['version']}" | |||
| action :install | |||
| end | |||
| # FC003: Check whether you are running with chef server before using server-specific features | |||
| nodes = search(:node, "hostname:[* TO *] AND chef_environment:#{node.chef_environment}") | |||
| # FC004: Use a service resource to start and stop services | |||
| execute "start-tomcat" do | |||
| command "/etc/init.d/tomcat6 start" | |||
| action :run | |||
| end | |||