1# lintr
2[![Travis-CI Build Status](https://travis-ci.org/jimhester/lintr.svg?branch=master)](https://travis-ci.org/jimhester/lintr)
3[![codecov.io](https://codecov.io/github/jimhester/lintr/coverage.svg?branch=master)](https://codecov.io/github/jimhester/lintr?branch=master)
4[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/lintr)](https://cran.r-project.org/package=lintr) [![Join the chat at https://gitter.im/jimhester-lintr/Lobby](https://badges.gitter.im/jimhester-lintr/Lobby.svg)](https://gitter.im/jimhester-lintr/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
6## Static code analysis for R ##
7
8`lintr` is an R package offering [static code analysis for R](https://en.wikipedia.org/wiki/Static_program_analysis). It checks adherence to a given style, syntax errors and possible semantic issues, see the animation below. In this README find out
9
10* [what linters i.e. checks are supported](#available-linters);
11
12* [how to configure the project to e.g. tweak checks and ignore files](#project-configuration);
13
14* [how to setup `lintr` for on-the-fly checking in different editors](#editors-setup);
15
16* [how to use `lintr` in combination with continuous integration](#continuous-integration);
17
18![lintr](http://i.imgur.com/acV27NV.gif "lintr")
19
20### What to do with `lintr` output?
21
22If you need a bit automatic help for re-styling your code, have a look at [the `styler` package](https://github.com/r-lib/styler)
23
24## Available linters ##
25
26* `Syntax errors`: reported by [parse](https://www.rdocumentation.org/packages/base/versions/3.4.0/topics/parse).
27* `object_usage_linter`: check that closures have the proper usage using
28  [codetools::checkUsage()](https://www.rdocumentation.org/packages/codetools/versions/0.2-15/topics/checkUsage).  Note this runs
29  [base::eval()](https://www.rdocumentation.org/packages/base/versions/3.4.0/topics/eval) on the code, so do not use with untrusted code.
30* `absolute_path_linter`: check that no absolute paths are used (e.g. "/var", "C:\\System", "~/docs").
31* `nonportable_path_linter`: check that file.path() is used to construct safe and portable paths.
32* `pipe_continuation_linter`: Check that each step in a pipeline is on a new
33  line, or the entire pipe fits on one line.
34* `assignment_linter`: check that `<-` is always used for assignment
35* `camel_case_linter`: check that objects are not in camelCase.
36* `closed_curly_linter`: check that closed curly braces should always be on their
37  own line unless they are followed by an else.
38* `commas_linter`: check that all commas are followed by spaces, but do not
39  have spaces before them.
40* `commented_code_linter`: check that there is no commented code outside of roxygen comments.
41* `cyclocomp_linter`: check for overly complicated expressions.
42* `equals_na_linter`: check for x == NA
43* `extraction_operator_linter`: check that the `[[` operator is used when extracting a single
44  element from an object, not `[` (subsetting) nor `$` (interactive use).
45* `function_left_parentheses_linter`: check that all left parentheses in a
46  function call do not have spaces before them.
47* `implicit_integer_linter`: check that integers are explicitly typed using the form `1L` instead of `1`.
48* `infix_spaces_linter`: check that all infix operators have spaces around them.
49* `line_length_linter`: check the line length of both comments and code is less than
50  length.
51* `no_tab_linter`: check that only spaces are used, never tabs.
52* `object_length_linter`: check that function and variable names are not more than `length` characters.
53* `object_name_linter`: check that object names conform to a single naming
54  style, e.g. CamelCase, camelCase, snake_case, dotted.case, lowercase,
55  or UPPERCASE.
56* `open_curly_linter`: check that opening curly braces are never on their own
57  line and are always followed by a newline.
58* `paren_brace_linter`: check that there is a space between right parenthesis and an opening curly brace.
59* `semicolon_terminator_linter`: check that no semicolons terminate statements.
60* `seq_linter`: check for `1:length(...)`, `1:nrow(...)`, `1:ncol(...)`,
61  `1:NROW(...)`, and `1:NCOL(...)` expressions. These often cause bugs when the
62  right hand side is zero. It is safer to use `seq_len()` or `seq_along()`
63  instead.
64* `single_quotes_linter`: check that only single quotes are used to delimit
65  string constants.
66* `spaces_inside_linter`: check that parentheses and square brackets do not have
67  spaces directly inside them.
68* `spaces_left_parentheses_linter`: check that all left parentheses have a space before them
69  unless they are in a function call.
70* `todo_comment_linter`: check that the source contains no TODO comments (case-insensitive).
71* `trailing_blank_lines_linter`: check there are no trailing blank lines.
72* `trailing_whitespace_linter`: check there are no trailing whitespace characters.
73* `T_and_F_symbol_linter`: avoid the symbols `T` and `F` (for `TRUE` and `FALSE`).
74* `undesirable_function_linter`: report the use of undesirable functions, e.g. `options` or `sapply` and suggest an alternative.
75* `undesirable_operator_linter`: report the use of undesirable operators, e.g. `:::` or `<<-` and
76  suggest an alternative.
77* `unneeded_concatenation_linter`: check that the `c` function is not used without arguments nor
78  with a single constant.
79
80### References ###
81Most of the default linters are based on [Hadley Wickham's R Style Guide](http://r-pkgs.had.co.nz/style.html).
82
83## Project Configuration ##
84
85Lintr supports per-project configuration of the following fields.
86The config file (default file name: `.lintr`) is in [Debian Control Field Format](https://www.debian.org/doc/debian-policy/#document-ch-controlfields).
87
88- `linters` - see `?with_defaults` for example of specifying only a few non-default linters.
89- `exclusions` - a list of filenames to exclude from linting.  You can use a
90  named item to exclude only certain lines from a file.
91- `exclude` - a regex pattern for lines to exclude from linting.  Default is "# nolint"
92- `exclude_start` - a regex pattern to start exclusion range. Default is "# nolint start"
93- `exclude_end` - a regex pattern to end exclusion range. Default is "# nolint end"
94
95An example file that uses 120 character line lengths, excludes a couple of
96files and sets different default exclude regexs follows.
97```
98linters: with_defaults(line_length_linter(120))
99exclusions: list("inst/doc/creating_linters.R" = 1, "inst/example/bad.R", "tests/testthat/exclusions-test")
100exclude: "# Exclude Linting"
101exclude_start: "# Begin Exclude Linting"
102exclude_end: "# End Exclude Linting"
103```
104
105With the following command, you can create a configuration file for `lintr` that ignores all linters that show at least one error:
106
107```r
108# Create configuration file for lintr
109# Source this file in package root directory
110
111# List here files to exclude from lint checking, as a character vector
112excluded_files <- c(
113    list.files("data",      recursive = TRUE, full.names = TRUE),
114    list.files("docs",      recursive = TRUE, full.names = TRUE),
115    list.files("inst/doc",  recursive = TRUE, full.names = TRUE),
116    list.files("man",       recursive = TRUE, full.names = TRUE),
117    list.files("vignettes", recursive = TRUE, full.names = TRUE)
118)
119
120### Do not edit after this line ###
121
122library(magrittr)
123library(dplyr)
124
125# Make sure we start fresh
126if (file.exists(".lintr")) { file.remove(".lintr") }
127
128# List current lints
129lintr::lint_package() %>%
130    as.data.frame %>%
131    group_by(linter) %>%
132    tally(sort = TRUE) %$%
133    sprintf("linters: with_defaults(\n    %s\n    dummy_linter = NULL\n  )\n",
134            paste0(linter, " = NULL, # ", n, collapse = "\n    ")) %>%
135    cat(file = ".lintr")
136
137sprintf("exclusions: list(\n    %s\n  )\n",
138        paste0('"', excluded_files, '"', collapse = ",\n    ")) %>%
139    cat(file = ".lintr", append = TRUE)
140
141# Clean up workspace
142remove(excluded_files)
143```
144
145The resulting configuration will contain each currently failing linter and the corresponding number of hits as a comment. Proceed by successively enabling linters, starting with those with the least number of hits. Note that this requires `lintr` 0.3.0.9001 or later.
146
147If you are developing a package, you can add `^\.lintr$` to your `.Rbuildignore` file using `usethis::use_build_ignore(".lintr")`.
148
149## Continuous integration ##
150If you want to run `lintr` on [Travis-CI](https://travis-ci.org) in order to check that commits and pull requests don't deteriorate code style, you will need
151to have Travis install the package first.  This can be done by adding the
152following line to your `.travis.yml`
153
154```yaml
155r_github_packages:
156  - jimhester/lintr
157```
158
159We recommend running `lintr::lint_package()` as an [after_success step in your build process](#non-failing-lints)]
160
161[lintr-bot](https://github.com/lintr-bot) will then add comments
162to the commit or pull request with the lints found and they will also be
163printed on Travis-CI.  If you want to disable the commenting you can
164set the environment variable `LINTR_COMMENT_BOT=false`.
165
166### Non-failing Lints ###
167```yaml
168after_success:
169  - R CMD INSTALL $PKG_TARBALL
170  - Rscript -e 'lintr::lint_package()'
171```
172
173Live example of a package using this setup: [`hibpwned`](https://github.com/lockedata/HIBPwned/blob/master/.travis.yml), [lintr-bot commenting on a PR](https://github.com/lockedata/HIBPwned/pull/30).
174
175## Installation of development version ##
176To install the latest development version of lintr from GitHub
177
178```r
179devtools::install_github("jimhester/lintr")
180```
181
182
183## Editors setup ##
184
185### RStudio ###
186lintr lints are automatically displayed in the RStudio Markers pane, Rstudio versions (> v0.99.206).
187![RStudio Example](http://i.imgur.com/PIKnpbn.png "Rstudio Example")
188
189#### Installation ####
190Install lintr, type `install.packages("lintr")` in the Console.
191
192In order to show the "Markers" pane in RStudio:
193Menu "Tools" -> "Global Options...", a window with title "Options" will pop up. In that window: Click "Code" on the left; Click "Diagnostics" tab; check "Show diagnostics for R".
194
195To lint a source file `test.R` type in the Console `lintr::lint("test.R")` and look at the result in the "Markers" pane.
196
197This package also includes two addins for linting the current source and package.
198To bind the addin to a keyboard shortcut navigate to Tools > addins >
199Browse Addins > Keyboard Shortcuts. It's recommended to use Alt+Shift+L for
200linting the current source code and Ctrl+Shift+Alt+L to code the package.
201These are easy to remember as you are Alt+Shift+L(int) ;)
202
203### Emacs ###
204lintr has [built-in integration](http://www.flycheck.org/en/latest/languages.html#r) with [flycheck](https://github.com/flycheck/flycheck) versions greater than `0.23`.
205![Emacs Example](http://i.imgur.com/vquPht3.gif "Emacs Example")
206
207#### Installation ####
208lintr is fully integrated into flycheck when using [ESS](http://ess.r-project.org/).  See the
209installalation documentation for those packages for more information.
210
211#### Configuration ####
212You can also configure what linters are used. e.g. using a different line length cutoff.
213- `M-x customize-option` -> `flycheck-lintr-linters` -> `with_defaults(line_length_linter(120))`
214
215### Vim
216lintr can be integrated with
217[syntastic](https://github.com/scrooloose/syntastic) for on the fly linting.
218
219![Vim Example](http://i.imgur.com/fR6Os5M.gif "Vim Example")
220
221#### Installation ####
222Put the file [syntastic/lintr.vim](inst/syntastic/lintr.vim)
223in `syntastic/syntax_checkers/r`.  If you are using
224[pathogen](https://github.com/tpope/vim-pathogen) this directory is
225`~/.vim/bundles/syntastic/syntax_checkers/r`.
226
227You will also need to add the following lines to your `.vimrc`.
228```vim
229let g:syntastic_enable_r_lintr_checker = 1
230let g:syntastic_r_checkers = ['lintr']
231```
232#### Configuration ####
233You can also configure what linters are used. e.g. using a different line length cutoff.
234```vim
235let g:syntastic_r_lintr_linters = "with_defaults(line_length_linter(120))"
236```
237
238### Sublime Text 3 ###
239lintr can be integrated with
240[Sublime Linter](https://github.com/SublimeLinter/SublimeLinter3) for on the fly linting.
241
242![Sublime Example](http://i.imgur.com/3pua2yz.gif "Sublime Example")
243
244#### Installation ####
245Simply install `sublimeLinter-contrib-lintr` using [Package Control](https://packagecontrol.io/).
246
247For more information see [Sublime Linter Docs](http://sublimelinter.readthedocs.org/en/latest/installation.html#installing-via-pc)
248
249#### Configuration ####
250You can also configure what linters are used. e.g. disabling the assignment linter and using a different line length cutoff.
251In the SublimeLinter User Settings
252```
253{
254  "linters": {
255    "lintr": {
256      "linters": "with_defaults(assignment_linter = NULL, line_length_linter(120))"
257    }
258  }
259}
260```
261
262### Atom ###
263lintr can be integrated with
264[Linter](https://github.com/atom-community/linter) for on the fly linting.
265
266![Atom Example](http://i.imgur.com/E1Isi4T.png "Atom Example")
267
268#### Installation ####
269Simply install `linter-lintr` from within Atom or on the command line with:
270```bash
271apm install linter-lintr
272```
273
274For more information and bug reports see [Atom linter-lintr](https://github.com/AtomLinter/linter-lintr).
275