-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement indentation_linter #1411
Conversation
Putting this out here looking for feedback. |
supersedes #497
6943fcd
to
c1e1fa1
Compare
So far, every mis-indented line causes a lint.
Causes four lints, one per line. |
So, there were a ton of indentation lints in lintr itself. lapply(1:10, function(x) {
x^2
})
structure(1:10 %>%
cumsum() %>%
mean(), class = "meh") Currently, the first code doesn't lint, because hanging indents are suppressed if there is a multi-line expression on the same line as the Any thoughts on how hanging indents should be defined and detected and what exception there should be? |
This one definitely seems susceptible to edge cases -- have you tried any .dev/compare_branches here to see what sort of patterns might be missed "in the wild"? (can only turn up false positives of course). also, at a glance there's a lot going on & several loops -- I'm curious the performance relative to other default linters. |
I've hand sifted all lints on lintr (which brought up quite a few edge cases that made it to the tests), but haven't run compare_branches yet. Will try to get compare_branches to run. Regarding performance, I'm not too worried because the XPath should produce relatively few hits on each expression and is written to avoid common nodes (such as expr), but will produce a benchmark when satisfied with the behavior. |
I ran on the top 20 CRAN packages, yielding quite a few lints. CLI has some odd formatted Hanging indents of styler::style_text("
if (a &&
b) {
boo
}
")
# and
styler::style_text("
if (a &&
b) {
boo
}
")
#> if (a &&
#> b) {
#> boo
#> } This one seems like it definitely shouldn't lint, but currently lints ll. 28-37: Ditto here, I think a hanging indent should trigger, although L232 should lint because the argument binds to The huge number of lints produced will require careful examination. |
Satisfied with cli now. R/scale-.R:801 #' @rdname ggplot2-ggproto
#' @format NULL
#' @usage NULL
#' @export
ScaleDiscrete <- ggproto("ScaleDiscrete", Scale,
drop = TRUE,
na.value = NA,
n.breaks.cache = NULL,
palette.cache = NULL,
is_discrete = function() TRUE,
train = function(self, x) {
if (length(x) == 0) {
return()
}
self$range$train(x, drop = self$drop, na.rm = !self$na.translate)
}
# ...
) |
Here's a current tally of lints:
Deduplicating consecutive lines:
Both stringi and ggplot2 feature function declarations of this form: fun <- function(a, b)
{
code
} Since that style is caught by |
# Conflicts: # tests/testthat/test-get_source_expressions.R
Agree it's tricky to always get right, but {styler} does have some logic that helps. Maybe the way to approach it is piecemeal -- if we can think of a good rule for detecting "false positives" in a certain case, add it, gradually improving. |
Agreed |
Agreed, seems like a more general issue, no need to fix here I'd say |
Agreed, the linter should be useful even for packages using tabs-not-spaces, and But as it's not part of the style guide, happy to defer on that to a future PR. |
Also agree. Are you using CRAN or dev {styler}? I know there's been a lot of improvements in dev. If dev, maybe worth an issue? IMO that should be edited to: if (
a &&
b
) {
} OTOH, I think {styler}'s current choice does stick to the letter of the guide (except maybe the trailing |
I like the idea of offering a few options. The 3 option names you gave sound good to me. Unless there's some universal reference to apply here, that's about as good as we'll be able to muster. Definitely a place for "See examples" in the docs & we use the examples you gave. |
…m with expression level
Okay, I've spotted a problem with the only remaining false-positive: test_that("multi-line
test describtion", {
})
hanging_call(looking,
basically,
identical = function() {
but_with_a_need_for_hanging_indent
}) Therefor, I think this is ready to merge now. Here is a tally of lints using default settings:
To get a gist of the consistency within "problematic" packages, I intersected the default lints with the customized parametrization to find only completely broken indentations.
@MichaelChirico are you okay with the propsal? Then I'll see to fixing our lints and get this merged. |
LGTM. I think you are the master of indentation now. You'll need a cross & garlic to read r-devel source code from now on 😄 |
BTW, QQ here to check my understanding, the difference between the testthat example: test_that("multi-line
test describtion", {
}) and the comparison example: hanging_call(looking,
basically,
identical = function() {
but_with_a_need_for_hanging_indent
}) is that hanging_call(looking,
basically, function() {
but_with_a_need_for_hanging_indent
}) |
Great work here @AshesITR !! thanks for the final push to get it over the line. Original issue = 6.5 years ago 🚀 🚀 🚀 |
supersedes #497
fixes #63