\input texinfo   @c -*-texinfo-*-
@c %**start of header
@setfilename flycheck.info
@settitle Flycheck
@documentencoding UTF-8
@c %**end of header

@include macros.texi

@c Index setup

@syncodeindex vr fn
@syncodeindex tp fn

@copying
Modern on-the-fly syntax checking for GNU Emacs 24.

Copyright @copyright{} 2014-2016 Sebastian Wiesner

@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled ``GNU
Free Documentation License''.

A copy of the license is also available from the Free Software
Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.

Alternatively, you may copy, distribute and/or modify this documentation
under the terms of the Creative Commons Attribution-ShareAlike 4.0
International Public License. A copy of the license can be obtained at
@url{https://creativecommons.org/licenses/by-sa/4.0/legalcode}.
@end quotation
@end copying

@dircategory Emacs
@direntry
* Flycheck: (flycheck). Modern on-the-fly syntax checking
@end direntry

@titlepage
@title Flycheck
@subtitle Modern on-the-fly syntax checking for GNU Emacs
@author Sebastian Wiesner @email{swiesner@@lunaryorn.com}
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@ifnottex
@node Top
@top Flycheck

@insertcopying
@end ifnottex

Flycheck is a modern GNU Emacs package that provides on-the-fly syntax
checking for buffers.  It is intended as replacement for the older
Flymake package which is built into Emacs.

@xref{Introduction}, for more information about Flycheck.  For
installations instructions and a quick tutorial, @pxref{Installation}
and @ref{Quickstart} respectively.  @xref{Usage}, for a detailed user
guide.

@ifnotinfo
@noindent
@strong{With Flycheck installed you can read this manual inside Emacs
with @key{M-x flycheck-info}}.  This opens Emacs' built-in Info reader.
@xref{Getting Started,,,info}, to see how to use this reader.
@end ifnotinfo

@menu
* Introduction::                An introduction to Flycheck
* Installation::                How to install Flycheck
* Quickstart::                  A quick Flycheck tutorial
* Usage::                       How to use Flycheck
* Syntax checker definitions::  How to add new syntax checkers to Flycheck
* Flycheck hooks::              How to hook into Flycheck
* Flycheck API::                API documentation
* Supported languages::         A list of supported languages
* Getting Help::                How to obtain help about Flycheck
* GNU Free Documentation License::  How to copy this manual
* Main Index::                  Index of Flycheck concepts
* Key Index::                   Index of all keybindings
* Function and Variable Index::  Index of commands, options and types
@end menu

@node Introduction
@chapter Introduction

Flycheck provides modern on-the-fly syntax checking extension for GNU
Emacs 24, intended as replacement for the older Flymake extension which
is part of GNU Emacs.

Flycheck runs various linting tools and services to automatically check
the contents of buffers while you are typing, and reports warnings and
errors directly in the buffer, in the mode line and in an optional error
list.  You can navigate errors and warnings in the current buffer, show
the corresponding messages, and copy errors to the kill ring.

@cindex features

@itemize @bullet
@item
Over 40 languages with more than 70 checkers.  @xref{Supported languages}.
@item
Fully automatic, fail-safe, on-the-fly syntax checking in buffers
@item
In-buffer error highlighting, with fringe indicators
@item
Error navigation
@item
Auto-updating error list
@item
Many customisation options
@item
A comprehensive manual
@item
A simple API to add support for new languages and tools
@item
A “doesn't get in your way guarantee”
@end itemize

@node Quickstart
@chapter Quickstart
@section Install and enable Flycheck

To get started with Flycheck, enable it by adding the following to your
init file:

@lisp
(add-hook 'after-init-hook #'global-flycheck-mode)
@end lisp

If you don't know where your init file is take a look at the value of
the variable @code{user-init-file} with @kbd{C-h v user-init-file}.

@section Install syntax checker tools

Next you need to install syntax checking tools for the major modes you
are using.  For instance, for Python you may want to install
@uref{http://pylint.org, Pylint}:

@example
$ pip install pylint
@end example

For Ruby, you might want to use @ghref{bbatsov/rubocop, Rubocop} and
@ghref{YorickPeterse/ruby-lint, ruby-lint}:

@example
$ gem install rubocop ruby-lint
@end example

@xref{Supported languages}, for a complete list of all languages that
Flycheck supports.

@section Check syntax in a buffer

Now switch to a Python or Ruby Mode buffer and run @kbd{M-x
flycheck-verify-setup} to check whether Flycheck is correctly setup.

If everything is fine Flycheck will now check syntax using these tools,
when you visit a buffer in any of these languages.  Syntax checking
happens @emph{automatically} when you save the buffer or make any
changes.  Flycheck highlights errors and warnings in the buffer,
indicates them in the fringe, and reports their numbers in the mode
line.

You can also manually check a buffer with @kbd{C-c ! c}
(@code{flycheck-buffer}).

@section Navigate and list errors

Use @kbd{C-c ! n} (@code{flycheck-next-error}) and @kbd{C-c ! p}
(@code{flycheck-previous-error}) to navigate between error locations.
If you keep the point at an error location, Flycheck will show the error
message in the echo area after a short delay.  You can also hover error
locations with the mouse and see the error message in a tooltip.

To get an overview of all errors and warnings in the current buffer,
type @kbd{C-c ! l} (@code{flycheck-list-errors}) to pop up a list of all
errors in your current buffer.  The error list updates automatically
when you fix errors or introduce new ones, or when you switch to another
buffer.

@section More features

All Flycheck commands are available in the Emacs menu at @samp{Syntax
checking} in the @samp{Tools} menu.

@ifnotinfo
@image{images/flycheck-menu}
@end ifnotinfo

The same menu is also available by clicking on the mode line lighter of
Flycheck.

@ifnotinfo
@image{images/flycheck-mode-line-menu}
@end ifnotinfo

@node Usage
@chapter Usage

This chapter explains the usage of Flycheck in-depth.

@vindex flycheck-keymap-prefix

@strong{Note:} All commands in this chapter are documented with their
default key prefix @kbd{C-c !}.  You can customise this prefix with
@code{flycheck-keymap-prefix}, but remember your custom prefix while
reading this chapter.

@menu
* Checking buffers::            How buffers are checked
* Syntax checkers::             Tools used to check a buffer
* Reporting results::           How results of checks are reported
* Navigating errors::           How to navigate to Flycheck errors
* Displaying errors::           How to display error messages
* Killing errors::              How to put error messages into the kill ring
* Listing errors::              How to show a list of all errors
* Mode line display::           How to interpret Flycheck's mode line
* Configuring checkers::        How to configure syntax checkers
@end menu

@node Checking buffers
@section Checking buffers

@cindex flycheck mode
@vindex flycheck-mode
@vindex global-flycheck-mode
@vindex flycheck-global-modes

The minor mode @code{flycheck-mode} enables syntax checking in a single
buffer.  @code{global-flycheck-mode} automatically enables
@code{flycheck-mode} all buffers whenever possible.  You can exclude
specific major modes from @code{global-flycheck-mode} with
@code{flycheck-global-modes}.

@strong{Note:} @code{global-flycheck-mode} does not enable
@code{flycheck-mode} for remote or encrypted files.  The former is flaky
and might be very slow, and the latter would leak confidential data to
temporary directories.  You may still check syntax in these buffers by
manually enabling @code{flycheck-mode} with @kbd{M-x flycheck-mode}.
However, this is @emph{not} recommended for said reasons.

Add the following code to your init file to enable syntax checking
permanently:

@lisp
(add-hook 'after-init-hook #'global-flycheck-mode)
@end lisp

When @code{flycheck-mode} is enabled, Flycheck automatically checks a
buffer whenever

@itemize @bullet
@item
the buffer is saved,
@item
new lines are inserted,
@item
or a short time after you stopped to make changes to the buffer.
@end itemize

You can customise this behaviour by changing
@code{flycheck-check-syntax-automatically}:

@defopt flycheck-check-syntax-automatically
A list of events that trigger a new syntax check in the current buffer:

@table @code
@item save
Check the buffer immediately after it was saved.
@item idle-change
@vindex flycheck-idle-change-delay
Check the buffer a short time after the last change to the buffer.  The
delay is customisable with @code{flycheck-idle-change-delay}.
@item new-line
Check the buffer immediately after a new line was inserted.
@item mode-enabled
Check the buffer immediately after Flycheck Mode was enabled.
@end table

For instance, with the following code in your init file Flycheck will
only check the buffer when it is saved, but never while you are making
changes to the buffer:

@example
(setq flycheck-check-syntax-automatically '(mode-enabled save))
@end example
@end defopt

In addition to automatic syntax checking you can always check the
current buffer manually:

@table @asis
@flyccmd{C-c ! c, flycheck-buffer}
Check syntax in the current buffer.
@end table

@noindent @strong{Note:} If syntax checking does not work, please check your
setup:

@table @asis
@flyccmd{C-c ! v, flycheck-verify-setup}
Popup a buffer with information about the Flycheck setup for the current
buffer.

Lists the syntax checkers available for the current buffer, together
with potential problems in their setup.
@end table

@vindex flycheck-temp-prefix

During syntax checks Flycheck creates temporary files to feed to
contents of the current buffer to external programs.  You can change the
prefix used for the names of these temporary files with
@code{flycheck-temp-prefix}.

@node Syntax checkers
@section Syntax checkers

@cindex syntax checker
@cindex syntax checker selection, automatic
@cindex automatic syntax checker selection

Flycheck does not check buffers by itself, but relies on external
@emph{syntax checkers}.  When checking a buffer Flycheck automatically
selects the best syntax checker from @code{flycheck-checkers}:

@defopt flycheck-checkers
A list of all syntax checkers available for syntax checking.

A syntax checker in this list is a @emph{registered} syntax checker.
@end defopt

@cindex chaining of syntax checkers

Flycheck may apply further syntax checkers to the current buffer, if the
selected syntax checker @emph{chains} to other syntax checkers.  For
instance, the @flyc{emacs-lisp} syntax checker, which checks Emacs Lisp
with Emacs' byte compiler, @emph{chains} to the
@flyc{emacs-lisp-checkdoc} syntax checker, which checks Emacs Lisp for
violations of documentation conventions, @ref{Documentation
Tips,,,elisp}.  In Emacs Lisp buffers, Flycheck will first use
@flyc{emacs-lisp}, and then @flyc{emacs-lisp-checkdoc}.

Flycheck ignores chained checkers which are not contained in
@code{flycheck-checkers}.

Like everything else in GNU Emacs, syntax checkers have online
documentation as well.  If you are interested what major modes a
particular syntax checker in @code{flycheck-checkers} supports, or what
tool it uses, type @key{C-c ! ?}:

@table @asis
@flyccmd{C-c ! ?, flycheck-describe-checker}
Prompt for a syntax checker and show its documentation.

The documentation includes the name of the program or service used by
the syntax checker, a list of major modes in which the checker will be
used, and a list of its options.
@end table

@cindex syntax checker selection, manual
@cindex manual syntax checker selection

Instead of letting Flycheck select a syntax checker automatically you
can also explicitly tell Flycheck which checker to use for the current
buffer, by manually selecting a specific syntax checker:

@table @asis
@flyccmd{C-c ! s, flycheck-select-checker}
Prompt for a syntax checker and select this syntax checker for the
current buffer.

@flyccmdp{C-u, C-c ! s, flycheck-select-checker} Remove any manual
syntax checker selection for the current buffer, and let Flycheck
automatically select a syntax checker from @code{flycheck-checkers}
again.
@end table

You can also select a syntax checker via the variable
@code{flycheck-checker}.  In fact, @code{flycheck-select-checker}
just sets this variable accordingly:

@defvar flycheck-checker
A syntax checker to use for the current buffer.

If nil (the default), Flycheck will automatically select the best
checker from @code{flycheck-checkers}.

If set to a syntax checker, Flycheck will use this syntax checker for
the current buffer, and never automatically select any other.  Flycheck
still runs chained checkers, though.

If the syntax checker selected by this variable does not work in the
current buffer, Flycheck signals an error.

You can set this variable locally.  For instance, if your Python project
mandates @uref{http://flake8.readthedocs.org/en/2.2.3/,Flake8} as a
syntax checker, you can tell Flycheck to only use the corresponding
checker @flyc{python-flake8} in Python files of your project by setting
@code{flycheck-checker} as a directory-local variable in the top-level
directory of your project with @kbd{M-x add-dir-local-variable RET
python-mode RET flycheck-checker RET python-flake8}.  @xref{Directory
Variables, , ,emacs}, for more information about directory variables.
@end defvar

Occasionally you may want to disable specific syntax checkers
completely, so that they can never be used at all, neither via automatic
nor via manual selection:

@table @asis
@flyccmd{C-c ! x, flycheck-disable-checker}
Prompt for a syntax checker to disable in the current buffer.

@flyccmdp{C-u, C-c ! x, flycheck-disable-checker}
Prompt for a syntax checker to re-enable in the current buffer.
@end table

This is particularly useful if you want to disable syntax checkers that
are chained after others.  For instance, if you do not care for
documentation conventions of Emacs Lisp you may not need for the
@flyc{emacs-lisp-checkdoc} checker, so you can disable it for the
current buffer with @key{M-x flycheck-disable-checker RET
emacs-lisp-checkdoc}.

@code{flycheck-disable-checker} actually sets the buffer-local value of
the @code{flycheck-disabled-checkers} option:

@defopt flycheck-disabled-checkers
A list of disabled syntax checkers.  Flycheck will @emph{never} use
disabled syntax checkers to check a buffer.

You can customise this variable with @key{M-x customize-variable RET
flycheck-disabled-checkers} or set its default value in your init file
to permanently disable specific checkers.  For instance, to permanently
disable Clang for all C/C++ buffers:

@lisp
(setq-default flycheck-disabled-checkers '(c/c++-clang))
@end lisp

You can also disable checkers via local variables.  For instance, to
disable @flyc{emacs-lisp-checkdoc} for your entire project, add it to
@code{flycheck-disabled-checkers} in the @file{.dir-locals.el} file of
your project:

@lisp
((emacs-lisp-mode (flycheck-disabled-checkers emacs-lisp-checkdoc)))
@end lisp

@xref{Directory Variables,,,emacs}, for more information about directory
variables.
@end defopt

@node Reporting results
@section Reporting results of syntax checking

When a syntax check in the current buffer has finished, Flycheck reports
the results of the syntax checkers used by the check in the current
buffer:

@itemize @bullet
@item
It highlights errors and warnings reported by a syntax checking in the
buffer according to @code{flycheck-highlighting-mode},
@item
and indicates these locations in the fringe according to
@code{flycheck-indication-mode}.
@end itemize

@defopt flycheck-highlighting-mode
How Flycheck highlights errors and warnings in the buffer:

@table @code
@item lines
Highlight the whole line, ignoring any column information.
@item columns
Highlight the column of the error, if the error has a column, otherwise
behave as @code{lines}.
@item symbols
Highlight the symbol at the error column, if any, otherwise behave like
@code{columns}.  This is default
@item sexps
Highlight the expression at the error column, if any, otherwise behave
like @code{columns}.  @strong{Warning:} @code{sexps} can be @emph{very}
slow in some major modes, notably the built-in @code{python-mode}.
@item nil
Do not highlight errors at all.
@end table

@vindex flycheck-error
@vindex flycheck-warning
@vindex flycheck-info

Flycheck uses the @code{flycheck-error}, @code{flycheck-warning} and
@code{flycheck-info} faces to highlight errors, warnings and info
messages respectively.
@end defopt

@defopt flycheck-indication-mode
How Flycheck indicates errors and warnings:

@table @code
@item left-fringe
@itemx right-fringe
Indicate errors in the left or right fringe respectively.
@xref{Fringes, , ,emacs}, for more information about fringes.

Flycheck uses the @code{flycheck-fringe-error},
@code{flycheck-fringe-warning}, and @code{flycheck-fringe-info} faces
for the indicators for the corresponding error levels.
@item nil
Do not indicate errors and warnings.
@end table
@end defopt

@vindex flycheck-checker-error-threshold

To avoid flooding a buffer with excessive reports, Flycheck discards any
reports and @emph{disables} the corresponding syntax checker
subsequently, if the total number of reported errors of any level
exceeds the value of @code{flycheck-checker-error-threshold}.

@findex flycheck-clear

You can explicitly clear with the @code{flycheck-clear} command.

@node Navigating errors
@section Navigating errors

@vindex flycheck-standard-error-navigation

By default, Flycheck integrates into standard error navigation commands
of Emacs: @kbd{M-g n} (@code{next-error}) and @kbd{M-g p}
(@code{previous-error}) will navigate between Flycheck warnings and
errors in the current buffer.  @xref{Compilation Mode,,,emacs}, for more
information about these commands.  You can disable this integration by
setting @code{flycheck-standard-error-navigation} to nil, and
re-enabling @code{flycheck-mode} afterwards.

@strong{Note:} With standard error navigation @emph{visible} compilation
buffers (e.g. from M-x compile, M-x grep, M-x occur, etc.)  take
precedence over Flycheck errors.

Flycheck provides an independent set of navigation commands which will
always navigate Flycheck errors in the current buffer, regardless of
visible compilation buffers and
@code{flycheck-standard-error-navigation}:

@table @asis
@flyccmd{C-c ! n, 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.

@flyccmd{C-c ! p, 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.

@findex flycheck-first-error
@item @kbd{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.
@end table

By default, these commands consider all errors in the current buffer.
With @code{flycheck-navigation-minimum-level} you can restrict them to
errors above certain levels:

@defopt 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.
@end defopt

@node Displaying errors
@section Displaying errors

When the point moves to an error location Flycheck automatically
displays the error at point after a short delay:

@defopt flycheck-display-errors-delay
The number of seconds to wait before displaying the error at point.
Floating point numbers can express fractions of seconds.
@end defopt

You can also display errors at point explicitly with @kbd{C-c ! h}:

@table @asis
@flyccmd{C-c ! h, flycheck-display-error-at-point}
Show the error(s) at point.
@end table

By default Flycheck shows the error message and the error ID in the echo
area, but you can customise how Flycheck displays errors with
@code{flycheck-display-errors-function}:

@defopt flycheck-display-errors-function
A function to display errors.  The function is called with a list of
Flycheck error objects to display.  @xref{Errors}, for more information
about these objects.
@end defopt

@cindex error display function
@cindex functions for error display
Flycheck provides some built-in display functions:

@defun flycheck-display-error-messages
Show error messages and IDs in the echo area.
@end defun

@defun flycheck-display-error-messages-unless-error-list
Like @code{flycheck-display-error-messages}, but does not show anything
if the error list is visible.  @xref{Listing errors}, for more
information about the error list.
@end defun

Alternatively the @ghref{flycheck/flycheck-pos-tip, flycheck-pos-tip}
extension provides an display function which shows error messages in a
graphical popup.

@cindex error tooltip
@findex display-local-help
@kindex C-h .
In addition to this display mechanism, Flycheck adds a tooltip to each
error which appears when you hover the error location with the mouse
pointer.  You can force Emacs to show the contents of the tooltip in the
echo area with @kbd{C-h .} (@code{display-local-help}).

The contents of this tooltip are created with
@code{flycheck-help-echo-function}:

@defopt flycheck-help-echo-function
A function to compute the contents of the error tooltips.

By default Flycheck adds the error message and the error ID of all
errors at point to the tooltip contents.
@end defopt

@node Killing errors
@section Killing errors

You can also put error messages into the kill ring:

@table @asis
@flyccmd{C-c ! C-w, flycheck-copy-errors-as-kill}
Copy all Flycheck error messages at point into the kill ring.

Each error message is killed @emph{separately}, so @kbd{C-y}
(@code{yank}) only yanks a single error message.  You can use @kbd{M-y}
(@code{yank-pop}) to cycle between the killed messages after yanking the
first one.

@flyccmdp{C-u, C-c ! C-w, flycheck-copy-errors-as-kill}
Copy all Flycheck error messages at point, including their IDs.

@flyccmdp{M-0, C-c ! C-w, flycheck-copy-errors-as-kill}
Copy the IDs of the errors at point.
@end table

@node Listing errors
@section Listing errors

To get an overview of all errors in the current buffer you can popup an
error list:

@table @asis
@findex list-flycheck-errors
@flyccmd{C-c ! l,flycheck-list-errors}
@itemx @kbd{M-x list-flycheck-errors}
List all errors in the current buffer.

@vindex flycheck-error-list-after-refresh-hook

The error list automatically refreshes itself after a syntax check.  It
also follows the current buffer and window, and automatically updates to
show the errors of the new buffer if you switch to another buffer or
window.  After each refresh the hook
@code{flycheck-error-list-after-refresh-hook}.
@end table

In the error list window the following keybindings are available:

@table @kbd
@item n
Move to the next error.
@item p
Move to the previous error.
@item f
Filter the list, showing only errors whose level is above a threshold of
your choice.
@item F
Remove all filters.
@item q
Hide the error list window.
@item RET
Jump to the location of the error at point.
@item g
Refresh the error list, by triggering a new syntax check in the
associated buffer.
@item S
Sort the error list by the column at point.  Press repeatedly to inverse
the sorting order.

For instance, you can sort errors by their level by moving the point
onto the text of the @samp{Level} column, and then pressing @kbd{S}.
You can achieve the same effect by clicking on the column header.
@end table

By default, the error list shows all errors in the current buffer.  In
addition to filtering manually, you can restrict it to errors
above certain levels with @code{flycheck-error-list-minimum-level}:

@defopt flycheck-error-list-minimum-level
The minimum level of errors to display in the error list.

If set to an error level, only displays errors whose error level
is at least as severe as this one in the error list.  If nil,
display all errors.
@end defopt

@vindex flycheck-error-list-highlight

When you move the point in the current buffer while the error list is
visible, all errors on the current line are highlighted in the error
list with the @code{flycheck-error-list-highlight} face.

@node Mode line display
@section Mode line display

Flycheck always indicates its current state in the mode line, with one
of the following strings:

@table @samp
@item FlyC
There are no errors in the current buffer.
@item FlyC*
Flycheck currently checks the current buffer.
@item FlyC:3/5
There are three errors and five warnings in the current buffer.
@item FlyC-
Flycheck did not find any syntax checker for the current buffer.  Try
@kbd{C-c ! v} (@code{flycheck-verify-setup}) to find out why.
@item FlyC!
The syntax check failed.  Inspect the @samp{*Messages*} buffer for more
information about the failure.
@item FlyC?
The syntax check had a dubious result.  The definition of the syntax
checker may be flawed.  Inspect the @samp{*Messages*} buffer for
details.
@end table

This indicator should @strong{never} appear for built-in syntax
checkers.  If it does, please consider reporting an issue to the
Flycheck developers.  @xref{Issues}, for more information.

The 3rd party extension
@ghref{flycheck/flycheck-color-mode-line,flycheck-color-mode-line}
automatically changes the background colour of the mode line according
to the results of the last syntax check.

@node Configuring checkers
@section Configuring syntax checkers

Flycheck provides a rich interface to configure syntax checkers.  There
are three different kinds of options for syntax checkers:

@itemize @bullet
@item
@emph{Syntax checker options} which directly change specific settings of
syntax checkers,
@item
@emph{syntax checker configuration files} which point syntax checkers to
configuration files which can comprehensively configure a syntax
checker, and
@item
@emph{syntax checker executables} which change the executables that
Flycheck runs for syntax checkers.
@end itemize

@subsection Syntax checker options

@anchor{Syntax checker options}
@cindex syntax checker options
@cindex options of syntax checkers

Man syntax checkers can be configured via individual options.  For
instance, the @code{flycheck-flake8-maximum-line-length} tells the
@flyc{python-flake8} syntax checker about the maximum number of
characters allowed on a line.  Use the command
@code{flycheck-describe-checker} to see what options a syntax checker
provides.  Type @kbd{M-x customize-group RET flycheck-options} to get a
list of all available options.

Options are mainly intended to be set per file or per project via file
or directory variables.  @xref{File Variables,,,emacs}, and
@ref{Directory Variables,,,emacs} respectively, for more information.

For instance, if you the following file variables section at the end of
a Python file, the @flyc{python-flake8} syntax checker will warn about
lines longer than 100 characters, rather than the default limit of 80
characters:

@example
# Local Variables:
# flycheck-flake8-maximum-line-length: 100
# End:
@end example

@subsection Syntax checker configuration files

@anchor{Syntax checker configuration files}
@cindex syntax checker configuration files
@cindex configuration files of syntax checkers

Some syntax checkers also read configuration files.  These syntax
checkers have an associated @emph{configuration file variable} which
specifies the path to the configuration file.  All configuration file
variables are customisable via @kbd{M-x customize-group RET
flycheck-config-files}.

If the value of a configuration file variable is nil, Flycheck will not
use any configuration file for the corresponding syntax checker.  If it
is a string, however, Flycheck tries to locate an appropriate
configuration file, with the following procedure:

@enumerate
@item
If the value contains a directory separator, expand the path against the
@code{default-directory} of the current buffer.
@item
If the buffer has a file name, search the buffer's directory and any
ancestor directories up to the root directory for the configuration
file.
@item
Eventually try to find the configuration file in the user's home
directory.
@end enumerate

If any of these steps returns an existing file, this file is given to
the syntax checker.  For instance, assume you edit the file
@file{foo/bar/hello.py} in the following project layout:

@example
.
├── .pylintrc
├── README.rst
├── foo
│   ├── __init__.py
│   └── bar
│       ├── __init__.py
│       └── hello.py
└── setup.py
@end example

When using the @flyc{python-pylint} syntax checker, Flycheck would find
the file @file{.pylintrc} and pass it to @command{pylint}.  This file
could then contain project-wide style settings for your Python code.

You can change the default procedure for locating configuration files by
adding or replacing functions in
@code{flycheck-locate-config-file-functions}:

@defopt flycheck-locate-config-file-functions
Functions to locate configuration files.

Each function accepts two arguments @var{value} and @var{checker}.
@var{value} is the value of the configuration file variable, and
@var{checker} is the syntax checker to locate a configuration file for.
The function shall either return a string with the absolute path to an
existing configuration file, or nil if it could not locate the file.

Flycheck calls the functions in order of appearance, until the first
function returns nil.  If all functions return nil, no configuration
file is given to the syntax checker.
@end defopt

@strong{Note:} The formats of configuration files are specific to each
syntax checker.  Please consult the documentation of the corresponding
checker tool for information about the configuration file format
understood by the tool.

Like syntax checker options (@pxref{Syntax checker options}) you can
set these variables with file or directory variables.  @xref{File
Variables,,,emacs}, and @ref{Directory Variables,,,emacs} respectively,
for more information.

@subsection Syntax checker executables

@anchor{Syntax checker executables}
@cindex syntax checker executables
@cindex executables of syntax checkers

Occasionally, you need to point Flycheck to a different executable when
running a syntax checker.  For instance, you might want to use
@command{gcc-4.9} to check your C code, or use @command{pylint} from a
specific virtualenv.

For these situations, each syntax checker has a buffer-local,
customizable variable named @code{flycheck-@var{checker}-executable},
where @var{checker} is the name of the syntax checker.  The value of
this variable is either nil, or a string.  In the former case, Flycheck
uses the default executable from the syntax checker definition when
executing the syntax checker.  In the latter case, it uses the value of
the variable as executable.

You can either set these variables directly in your init file, or change
them interactively:

@table @asis
@flyccmd{C-c ! e, flycheck-set-checker-executable}
Set the executable of a syntax checker in the current buffer.

Prompt for a syntax checker and an executable file, and set the
executable variable of the syntax checker.
@flyccmdp{C-u,C-c ! e, flycheck-set-checker-executable}
Reset the executable of a syntax checker in the current buffer.

Prompt for a syntax checker and reset its executable to the default.
@end table

@node Syntax checker definitions
@chapter Syntax checker definitions

This chapter explains how to add new syntax checkers and how to extend
built-in syntax checkers, by example.  @xref{Flycheck API}, for a
detailed reference on the involved types, functions and macros.

If you define a new syntax checker or have an extension to a built-in
syntax checker, please report it to Flycheck (@pxref{Issues}), so that
we can consider it for inclusion to make it available to all other users
of Flycheck.

@menu
* Defining syntax checkers::    How to define new syntax checkers
* Finding error patterns::      How to find error patterns for a checker
* Trying new checkers::         How to try a new syntax checker
* Registering new checkers::    How to register for automatic selection
* Parsing structured output::   How to parse structured output like XML
* Passing configuration to checkers::  How to make syntax checkers configurable
* Controlling use of checkers:: How to control when checkers are used
* Applying multiple checkers::  How to use more than one checker per buffer
@end menu

@node Defining syntax checkers
@section Defining syntax checkers

Flycheck provides the macro @code{flycheck-define-checker} to define a
new syntax checker.  The following example defines a simple syntax
checker for the popular @uref{http://batsov.com/rubocop/, Rubocop} tool for
Ruby:

@lisp
(flycheck-define-checker ruby-rubocop
  "A Ruby syntax and style checker using the RuboCop tool.

See URL `http://batsov.com/rubocop/'."
  :command ("rubocop" "--display-cop-names" "--format" "emacs"
            (config-file "--config" flycheck-rubocoprc)
            (option-flag "--lint" flycheck-rubocop-lint-only)
            "--stdin" source-original)
  :standard-input t
  :error-patterns
  ((info line-start (file-name) ":" line ":" column ": C: "
         (optional (id (one-or-more (not (any ":")))) ": ") (message) line-end)
   (warning line-start (file-name) ":" line ":" column ": W: "
            (optional (id (one-or-more (not (any ":")))) ": ") (message)
            line-end)
   (error line-start (file-name) ":" line ":" column ": " (or "E" "F") ": "
          (optional (id (one-or-more (not (any ":")))) ": ") (message)
          line-end))
  :modes (enh-ruby-mode ruby-mode)
  :next-checkers ((warning . ruby-rubylint)))
@end lisp

The first argument to @code{flycheck-define-checker} is the @emph{name}
of a syntax checker, by which we can refer to this particular syntax
checker.

Next comes the @emph{docstring}, which should provide a bit of
information about the syntax checker.  It's a good idea to provide a
link to the homepage of the syntax checker tool here.  You can view this
docstring in Emacs with @code{flycheck-describe-checker} at
@kbd{C-c ! ?}, e.g. @kbd{C-c ! ? ruby-rubocop}.

Eventually we specify the @emph{properties} of the new syntax checker.
These properties tell Flycheck when to use your new syntax checker, how
to run it, and how to parse its output:

@itemize @bullet
@item
The @code{:command} specifies the command Flycheck should run to check
the buffer.  It's a simple list containing the executable and its
arguments.

In the example above we pass a couple of arguments to @command{rubocop}
to configure its output format.  Next come two options:  The special
@code{config-file} cell takes the name of a configuration file from the
given variable, searches it and passes the path—if found—to the syntax
checker.  The @code{option-flag} cell passes the given argument to the
syntax checker if the given variable is non-nil.

At last we specify @code{--stdin} to make Rubocop read source code
from standard input.  The special @code{source-original} symbol gives
the name of the file being checked to Rubocop; Rubocop uses this name in
its error output.

For a complete list of all special symbols refer to the function
@code{flycheck-substitute-argument}.

@item
@code{:standard-input t} makes Flycheck send the contents of the buffer
via standard input.  This is the preferred way to pass buffer contents
to syntax checkers.

For syntax checkers that can't read from standard input Flycheck
provides the special @code{source} and @code{source-inplace} argument
symbols for the @code{:command} property.  These argument symbols create
temporary files in the system temp directory or beneath the original
file respectively and give pass them to the syntax checker upon
invocation.

@item
The @code{:error-patterns} tell Flycheck how to parse the output of the
command in order to obtain error locations.  Each pattern has a
@emph{level}, followed by @code{rx} forms which specify a regular
expression to find an error in the output of the command.

Flycheck understands three error levels by default: @code{error} is for
critical errors that absolutely require the user's attention
(e.g. syntax errors), @code{warning} is for issues that can be ignored,
but should not (e.g. unused variables), and @code{info} is for other
messages that provide information about the buffer, but do not
immediately require action from the user.
@code{flycheck-define-error-level} lets you define custom error levels.

Flycheck provides special @code{rx} forms to extract the relevant
information from each error:

@itemize @bullet
@item
The @code{(file-name)} and @code{(message)} forms match a sequence of
any character save new line as file name and message of the error.  Both
optionally accept further @code{rx} forms, to specify an alternative
regular expression to match the file name or the message, for instance
to parse multi-line error messages.
@item
The @code{line} and @code{column} forms match a sequence of one or more
digits as line and column respectively of the error.
@end itemize

See the docstring of the function @code{rx}, for a list of all standard
@code{rx} forms, and the docstring of the function
@code{flycheck-rx-to-string} for a list of all special Flycheck forms.

@item
The @code{:modes} property denotes the major modes in which Flycheck may
use this syntax checker.  @command{rubocop} checks Ruby code, so the
@code{:modes} of our example specify @code{ruby-mode} and
@code{enh-ruby-mode}.

@end itemize

@node Finding error patterns
@section Finding the right error patterns

Finding the right error patterns is the hardest part of a syntax checker
definition.  For a first version, you just run the tool on a file, look
at its output and write a regular expression to match it.  @kbd{M-x
shell} comes handy here.

However, as you start to debug and refine your patterns, this quickly
becomes cumbersome.  Flycheck provides an easier way to test a syntax
checker: Evaluate the syntax checker definition with @kbd{C-M-x} and run
@code{flycheck-compile}.

@table @asis
@flyccmd{C-c ! C-c, flycheck-compile}
Run a syntax checker on the current buffer in a fresh Compilation Mode
buffer.  Prompt for a syntax checker to run.
@end table

This command runs the command like a normal syntax check would do, but
instead of highlighting errors within the buffer it shows a new buffer
in Compilation Mode, which contains the entire output of the command and
highlights everything that matches a pattern.  You can then refine the
error pattern, and iterate through this process until the error pattern
is complete.

@indentedblock
The @code{re-builder} tool can help you to quickly develop patterns for
the current output.  It lets you interactively develop a regular
expression while continously matching the current expression against the
buffer contents.  Start @code{re-builder} with @kbd{M-x re-builder}, and
switch to the @code{rx} syntax with @kbd{C-c TAB}.  Then type your
@code{rx} expression into the small window at the bottom, and observe
how the matching parts of the buffer are highlighted.

Note that @code{re-builder} does @emph{not} support the special Flycheck
@code{rx} forms available in @code{:error-patterns}.  As such, you
cannot directly type a Flycheck expression into @code{re-builder}.
@end indentedblock

Sometimes however an output format doesn't lend itself to error
patterns.  In this case, you need to write a more sophisticated parser
yourself.  @xref{Parsing structured output}, for more information.

@node Trying new checkers
@section Trying a new syntax checker

After evaluating a syntax checker definition you can try whether it
works for normal syntax checks by selecting it manually with @kbd{C-c !
s} or @kbd{M-x flycheck-select-checker}.  If anything breaks, you can
unselect the syntax checker again with @kbd{C-u C-c ! s} and fix the
error without further affecting Flycheck.

Once you have confirmed that your new syntax checker works flawlessly,
you can make it available for automatic syntax checking by registering
it.

@node Registering new checkers
@section Registering new syntax checkers

To register a new syntax checker for automatic syntax checking, just add
it to @code{flycheck-checkers}:

@lisp
(add-to-list 'flycheck-checkers 'python-pylint)
@end lisp

Flycheck will try all syntax checkers in this variable when checking a
buffer automatically, and check the buffer with the first syntax checker
in this list whose @code{:modes} contains the current major mode.

@indentedblock
Do @emph{not} use @code{flycheck-checker} and
@code{flycheck-select-checker} to enable your own syntax checker in
Flycheck extensions.  They are reserved for @emph{user customization}.

Specifically, please do @emph{not} provide a hook function which selects
the syntax checker explicitly by assigning to @code{flycheck-checker} or
by calling @code{flycheck-select-checker}.  In other words, this is
@strong{bad}:

@lisp
(defun enable-my-new-syntax-checker ()
  (setq flycheck-checker 'my-new-syntax-checker)
  (flycheck-buffer))

(add-hook 'my-major-mode-hook #'enable-my-new-syntax-checker)
@end lisp

This circumvents the entire automatic selection of Flycheck, and
prevents the user from effectively customizing Flycheck.

Instead, just register your syntax checker in @code{flycheck-checkers}
and let Flycheck automatically pick the best syntax checker.  In other
words, this is @strong{good}:

@lisp
(add-to-list 'flycheck-checkers 'my-new-syntax-checker)
@end lisp
@end indentedblock

@node Parsing structured output
@section Parsing structured output

If your syntax checker tool offers some structured output format as
alternative to human-readable free text, you can use an
@code{:error-parser} function instead of writing an error pattern.  For
instance, @uref{http://www.jshint.com/, JSHint} offers the widely spread
Checkstyle XML output format which Flycheck supports out of the box:

@lisp
(flycheck-define-checker javascript-jshint
  "A JavaScript syntax and style checker using jshint.

See URL `http://www.jshint.com'."
  :command ("jshint" "--checkstyle-reporter" source)
  :error-parser flycheck-parse-checkstyle
  :modes (js-mode js2-mode js3-mode))
@end lisp

As you can see, there are no patterns in this definition.  Instead
Flycheck calls the function @code{flycheck-parse-checkstyle} to parse
the output.  This function parses the XML to extract the errors.  It's
built-in into Flycheck, so if your tool supports Checkstyle XML, error
parsing comes @emph{for free} in Flycheck.  @xref{Error parsers},
for more information about error parsers.

@node Passing configuration to checkers
@section Passing options and configuration files to syntax checkers

Many linting tools provide a rich set of options to configure their
analysis.  Flycheck makes it easy to define proper Emacs options and map
them to options of commands.

For instance, the @ghref{bbatsov/rubocop, Rubocop} tool checks Ruby for
semantic and stylistic issues.  Since style is mainly a matter of taste,
it has a special linting mode in which all stylistic checks are disabled
(error patterns omitted for readability):

@lisp
(flycheck-define-checker ruby-rubocop
  "A Ruby syntax and style checker using the RuboCop tool.

See URL `http://batsov.com/rubocop/'."
  :command ("rubocop" "--format" "emacs"
            (option-flag "--lint" flycheck-rubocop-lint-only)
            source)
  :error-patterns ...
  :modes (ruby-mode))
@end lisp

Note the special @code{option-flag} argument, which splices the value of
the boolean Emacs option @code{flycheck-rubocop-lint-only} into the
command: If the variable is non-nil, Flycheck adds the @option{--lint}
option to the final command line, otherwise Flycheck omits the entire
argument.

Flycheck also supports other special @code{option-} arguments for plain
values or lists of values.  @xref{Argument Substitution}, for a list of
all special arguments.

Flycheck also provides a convenience macro
@code{flycheck-def-option-var} to declare these options:

@lisp
(flycheck-def-option-var flycheck-rubocop-lint-only nil ruby-rubocop
  "Whether to only report code issues in Rubocop.

When non-nil, only report code issues in Rubocop, via `--lint'.
Otherwise report style issues as well."
  :safe #'booleanp
  :type 'boolean)
@end lisp

Essentially, this macro is just a wrapper around the built-in
@code{defcustom}, which additionally keeps track of the syntax checker
the option belongs to, and adds the option to the appropriate custom
group.  You can pass arbitrary custom keywords to this macro as we did
in this example: @code{:type} marks this option as boolean flag, and
@code{:safe} allows the use as file-local variable, if the value is
boolean.  @xref{Syntax checker options}, for more information about
syntax checker configuration, and @ref{Checker configuration}, for the
corresponding API reference.

By a similar mechanism you can also pass paths to configuration files to
a syntax checker tool.  The aforementioned
@uref{http://www.pylint.org/,Pylint} reads a configuration file for
instance:

@lisp
(flycheck-define-checker python-pylint
  "A Python syntax and style checker using Pylint.

This syntax checker requires Pylint 1.0 or newer.

See URL `http://www.pylint.org/'."
  ;; -r n disables the scoring report
  :command ("pylint" "-r" "n"
            "--msg-template" "@{path@}:@{line@}:@{column@}:@{C@}:@{msg@} (@{msg_id@})"
            (config-file "--rcfile" flycheck-pylintrc)
            source)
  :error-patterns ...
  :modes python-mode)
@end lisp

The special @code{config-file} argument passes a configuration file from
@code{flycheck-pylintrc} to @command{pylint}, if the value of the
variable is non-nil.

Flycheck provides a sophisticated logic to find an appropriate
configuration file.  @xref{Syntax checker configuration files}, for more
information about syntax checker configuration, and @ref{Checker
configuration}, for the corresponding API reference.

@node Controlling use of checkers
@section Controlling the use of a syntax checker

If you need more control about when a syntax checker is used for syntax
checking, you can supply a custom @code{:predicate} function.  Consider
the following syntax checker for Zsh scripts in Sh Mode:

@lisp
(flycheck-define-checker sh-zsh
  "A Zsh syntax checker using the Zsh shell.

See URL `http://www.zsh.org/'."
  :command ("zsh" "-n" "-d" "-f" source)
  :error-patterns
  ((error line-start (file-name) ":" line ": " (message) line-end))
  :modes sh-mode
  :predicate (lambda () (eq sh-shell 'zsh)))
@end lisp

Sh Mode also supports Bash and other shells besides Zsh, so we
additionally provide a @code{:predicate} that checks whether the current
buffer has the right shell.

You can even omit @code{:modes} and only use a predicate to determine
whether a syntax checker is applicable for the current buffer.

@node Applying multiple checkers
@section Applying multiple syntax checkers

Frequently, we would like to use multiple syntax checkers in a buffer.
For instance, we might want to check the syntax of a script with
@code{sh-zsh} from the previous section, and then use
@ghref{koalaman/shellcheck/, Shellcheck} to check for questionable code
such as unquoted variable expansions, if there are no syntax errors.
Flycheck supports this scenario by @emph{chaining} syntax checkers.

Suppose we defined a syntax checker for Shellcheck called
@sc{sh-shellcheck} as follows:

@lisp
(flycheck-define-checker sh-shellcheck
  "A shell script syntax and style checker using Shellcheck.

See URL `https://github.com/koalaman/shellcheck/'."
  :command ("shellcheck" "-f" "checkstyle"
            "-s" (eval (symbol-name sh-shell))
            source)
  :modes sh-mode
  :error-parser flycheck-parse-checkstyle)
@end lisp

Note how we use the special @code{eval} argument to put the result of an
arbitrary Emacs Lisp expression into the command line of
@command{shellcheck}, in order to tell Shellcheck what shell the script
is written for.

We can now arrange for this syntax checker to be used after
@code{sh-zsh} with @code{flycheck-add-next-checker}:

@lisp
(flycheck-add-next-checker 'sh-zsh '(warning . sh-shellcheck))
@end lisp

The first item of the cons cell in the second argument is the
@emph{maximum error level} in the buffer, for which @code{sh-shellcheck}
is still applicable.  With @code{warning} Flycheck will run
@code{sh-shellcheck} after @code{sh-zsh} if there are @code{warning} or
@code{info} level errors from @code{sh-zsh}, but not if there are any
errors with level @code{error}, such as syntax errors.

Flycheck will only use a chained syntax checker if it is registered in
@code{flycheck-checkers}, so we need to register our new syntax checker
(@pxref{Registering new checkers}):

@lisp
(add-to-list 'flycheck-checkers 'sh-shellcheck 'append)
@end lisp

Note that unlike before we @emph{append} the new syntax checker at the
end of @code{flycheck-checkers}.  This ensures that Flycheck does not
try @code{sh-shellcheck} @emph{before} @code{sh-zsh}.  Flycheck tries
all syntax checkers in this list in @emph{order of appearance}, so if
you add your new chained syntax checker at the beginning, it will likely
be used right away, before any prior syntax checkers.

You also can specify chained syntax checkers directly in
@code{flycheck-define-checker} with the @code{:next-checkers} property.
Instead of calling @code{flycheck-add-next-checker}, we could also have
added this property to the definition of @code{sh-zsh}:

@lisp
(flycheck-define-checker sh-zsh
  "A Zsh syntax checker using the Zsh shell.

See URL `http://www.zsh.org/'."
  :command ("zsh" "-n" "-d" "-f" source)
  :error-patterns ...
  :modes sh-mode
  :predicate (lambda () (eq sh-shell 'zsh))
  :next-checkers ((warning . sh-shellcheck)))
@end lisp

If you control the definition of both syntax checkers, this style is
@emph{preferable} to @code{flycheck-add-next-checker}.  Use the latter
only if you cannot change the definition of the prior syntax checker.

@node Flycheck hooks
@chapter Flycheck hooks

This chapter gives you a brief overview over Flycheck's rich hook
interface, which you can use for your own extensions.

@section Status changes

@code{flycheck-before-syntax-check-hook} and
@code{flycheck-after-syntax-check-hook} run before and after syntax
checks, and let you update your Emacs instance according to Flycheck's
state.  For instance, @ghref{flycheck/flycheck-color-mode-line,
flycheck-color-mode-line} uses these hooks to colour your mode-line
according to the result of the last syntax check.  Additionally,
@code{flycheck-status-changed-functions} runs on every single status
change of Flycheck, and provides a fine-grained reporting about what
Flycheck is currently doing.

@section Executables and commands

Flycheck uses the function given by the option
@code{flycheck-executable-find} to search for executables, and passes
all syntax checker commands through
@code{flycheck-command-wrapper-function} before running them.  These
features let you adapt Flycheck to search executables and run commands
in sandboxed environments such as @code{bundle exec} or
@code{nix-shell}.

@section Error processing

The functions in @code{flycheck-process-error-functions} are used to
process new errors reported by a Flycheck syntax checker.  Add to this
hook to get informed about each error reported in a Flycheck buffer.  In
fact, Flycheck uses this hook itself: The standard value
@code{flycheck-add-overlay} is responsible for adding error highlighting
to the buffer.  As a consequence, you can @emph{entirely opt out} from
highlighting with a custom hook.

@section Error display

The function @code{flycheck-display-errors-function} is called to
display an error at point.  The @ghref{flycheck/flycheck-pos-tip,
flycheck-pos-tip} extension uses this hook to show errors in a GUI popup
like conventional IDEs do.

@node Flycheck API
@chapter Flycheck API

TODO: The API documentation still needs to be written.

@menu
* Command syntax checkers::     Syntax checkers with external commands
* Errors::                      Error representation in Flycheck
@end menu

@node Command syntax checkers
@section Command syntax checkers

@menu
* Argument Substitution::       Argument substitution in syntax checker commands
* Checker configuration::       Configuration for command checkers
* Error parsers::               Parsing structured output formats
@end menu

@node Argument Substitution
@subsection Argument substitution

@node Checker configuration
@subsection Configuration options and files

@node Error parsers
@subsection Error parsers

@node Errors
@section Errors

@node Getting Help
@appendix Getting Help

@section Asking questions

Please ask questions about Flycheck on
@uref{https://emacs.stackexchange.com/questions/tagged/flycheck,Stack
Exchange} or in our @uref{https://gitter.im/flycheck/flycheck,Gitter
channel}.  We try to answer all questions as fast and as precise as
possible.

@section Reporting issues
@anchor{Issues}

To report problems or bugs, please use our
@ghref{flycheck/flycheck/issues,issue tracker}.  Our
@ghref{flycheck/flycheck/blob/master/CONTRIBUTING.md, Contribution
Guidelines} help you to create good bug reports; please take a look.

We welcome patches and pull requests that fix bugs or provide new
features.  Please read our Contribution Guidelines for help and
guidelines before submitting pull requests.  When making larger changes
to Flycheck or implementing new features we recommend that you first
open a separate issue or ask in our Gitter channel to discuss
you intended changes.

@section Conduct

Please follow our @flycref{conduct.html,Code of Conduct} in all our
communication channels.

@node GNU Free Documentation License
@appendix GNU Free Documentation License

@include fdl-1.3.texi

@node Main Index
@unnumbered Main Index

@printindex cp

@node Key Index
@unnumbered Key Index

@printindex ky

@node Function and Variable Index
@unnumbered Function and variable index

@printindex fn

@bye

@c Local Variables:
@c mode: texinfo
@c TeX-master: t
@c End:

@c flycheck.texi ends here
