flint
is a small R package to find and replace lints in R code.
- Lints detection with
lint()
- Automatic replacement of lints with
fix()
- Compatibility with (some)
{lintr}
rules - Fast
- Low-dependency
flint
is powered by
astgrepr
, which is
itself built on the Rust crate
ast-grep
.
install.packages('flint', repos = c('https://etiennebacher.r-universe.dev'))
Optional setup:
setup_flint()
: creates the folderflint
and populates it with built-in rules as well as a cache file. You can modify those rules or add new ones if you want more control.
You can use flint
as-is, without any setup. However, running
setup_flint()
enables the use of caching, meaning that the subsequent
runs will be faster. It is also gives you a place where you can store
custom rules for your project/package.
The everyday usage consists of two functions:
lint()
looks for lints in R files;fix()
looks for lints in R files and automatically applies their replacement (if any).
One can also experiment with flint::lint_text()
and
flint::fix_text()
:
flint::lint_text("
any(is.na(x))
any(duplicated(y))
")
#> Original code: any(is.na(x))
#> Suggestion: anyNA(x) is better than any(is.na(x)).
#> Rule ID: any_na-1
#>
#> Original code: any(duplicated(y))
#> Suggestion: anyDuplicated(x, ...) > 0 is better than any(duplicated(x), ...).
#> Rule ID: any_duplicated-1
flint::fix_text("
any(is.na(x))
any(duplicated(y))
")
#> Old code:
#> any(is.na(x))
#> any(duplicated(y))
#>
#> New code:
#> anyNA(x)
#> anyDuplicated(y) > 0
The most used tool for lints detection in R is lintr
. However,
lintr
’s performance is not optimal when it is applied on medium to
large packages. Also, lintr
cannot perform automatic replacement of
lints.
styler
is a package to clean code by fixing indentation and other
things, but doesn’t perform code replacement based on lints.
flint
is extremely performant. This is a small benchmark on 3.5k lines
of code with only three linters:
file <- system.file("bench/test.R", package = "flint")
bench::mark(
lintr = lintr::lint(
file, linters = list(lintr::any_duplicated_linter(), lintr::any_is_na_linter(),
lintr::matrix_apply_linter())
),
flint = flint::lint(
file, linters = list(flint::any_duplicated_linter(), flint::any_is_na_linter(),
flint::matrix_apply_linter()),
verbose = FALSE
),
check = FALSE
)
#> Warning: Some expressions had a GC in every iteration; so filtering is
#> disabled.
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 lintr 2.77s 2.77s 0.361 315.4MB 9.03
#> 2 flint 150.51ms 155.09ms 6.26 1.45MB 3.13
Did you find some bugs or some errors in the documentation? Do you want
flint
to support more rules?
Take a look at the contributing guide for instructions on bug report and pull requests.
The website theme was heavily inspired by Matthew Kay’s ggblend
package: https://mjskay.github.io/ggblend/.