diff --git a/R/trailing_whitespace_linter.R b/R/trailing_whitespace_linter.R index e55b7ee96..1f1d6d7d7 100644 --- a/R/trailing_whitespace_linter.R +++ b/R/trailing_whitespace_linter.R @@ -1,34 +1,44 @@ #' @describeIn linters check there are no trailing whitespace characters. #' @export -trailing_whitespace_linter <- function(source_file) { +trailing_whitespace_linter <- function(check_empty_lines = TRUE) { + # for backwards compatibility, check if this was called on the + # check_empty_lines option or directly on a source file + if (is.logical(check_empty_lines)) { + function(source_file) trailws_linter(source_file, check_empty_lines) + } else { # call with old default + source_file <- check_empty_lines + trailws_linter(source_file, TRUE) + } +} + +trailws_linter <- function(source_file, check_empty_lines) { res <- re_matches(source_file$lines, rex(capture(name = "space", some_of(" ", regex("\\t"))), or(newline, end)), global = TRUE, locations = TRUE) - lapply(seq_along(source_file$lines), function(itr) { + if (any(lapply(res, nrow) != 1L)) { + stop("invalid data: text after '\\n' found") + } - mapply( - FUN = function(start, end) { - if (is.na(start)) { - return() - } - line_number <- names(source_file$lines)[itr] - Lint( - filename = source_file$filename, - line_number = line_number, - column_number = start, - type = "style", - message = "Trailing whitespace is superfluous.", - line = source_file$lines[as.character(line_number)], - ranges = list(c(start, end)), - linter = "trailing_whitespace_linter" - ) - }, - start = res[[itr]]$space.start, - end = res[[itr]]$space.end, - SIMPLIFY = FALSE - ) - }) + lapply(seq_along(source_file$lines), function(idx) { + start <- res[[idx]]$space.start + end <- res[[idx]]$space.end + skip_empty_line <- !check_empty_lines && start == 1L + if (is.na(start) || skip_empty_line) { + return() + } + + Lint( + filename = source_file$filename, + line_number = names(source_file$lines)[[idx]], + column_number = start, + type = "style", + message = "Trailing whitespace is superfluous.", + line = source_file$lines[[idx]], + ranges = list(c(start, end)), + linter = "trailing_whitespace_linter" + ) + }) } diff --git a/R/zzz.R b/R/zzz.R index 8ee3b6ff4..8495ae6c6 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -4,6 +4,7 @@ #' @title linters #' @param source_file returned by \code{\link{get_source_expressions}} #' @param length the length cutoff to use for the given linter. +#' @param check_empty_lines if \code{trailing_whitespace_linter} should consider completely empty lines. NULL named_list <- function(...) { @@ -75,7 +76,7 @@ default_linters <- with_defaults(default = list(), multiple_dots_linter, object_length_linter(30), object_usage_linter, - trailing_whitespace_linter, + trailing_whitespace_linter(), trailing_blank_lines_linter, commented_code_linter, diff --git a/man/linters.Rd b/man/linters.Rd index d27dda10c..8bc321372 100644 --- a/man/linters.Rd +++ b/man/linters.Rd @@ -65,7 +65,7 @@ trailing_blank_lines_linter(source_file) trailing_semicolons_linter(source_file) -trailing_whitespace_linter(source_file) +trailing_whitespace_linter(check_empty_lines = TRUE) } \arguments{ \item{source_file}{returned by \code{\link{get_source_expressions}}} @@ -74,6 +74,8 @@ trailing_whitespace_linter(source_file) same line.} \item{length}{the length cutoff to use for the given linter.} + +\item{check_empty_lines}{if \code{trailing_whitespace_linter} should consider completely empty lines.} } \description{ Available linters diff --git a/tests/testthat/test-assignment_linter.R b/tests/testthat/test-assignment_linter.R index 145207f6c..643308d3a 100644 --- a/tests/testthat/test-assignment_linter.R +++ b/tests/testthat/test-assignment_linter.R @@ -1,5 +1,6 @@ context("assignment_linter") options(encoding = "UTF-8") +Sys.setenv(LANGUAGE = "en") # make sure no translated messages are matched test_that("returns the correct linting", { expect_lint("blah", NULL, assignment_linter) diff --git a/tests/testthat/test-error.R b/tests/testthat/test-error.R index d72a0b276..485c1c4cc 100644 --- a/tests/testthat/test-error.R +++ b/tests/testthat/test-error.R @@ -1,4 +1,5 @@ context("error") +Sys.setenv(LANGUAGE = "en") # make sure no translated messages are matched test_that("returns the correct linting", { expect_lint("\"\\R\"", rex("is an unrecognized escape in character string starting") diff --git a/tests/testthat/test-trailing_whitespace_linter.R b/tests/testthat/test-trailing_whitespace_linter.R index 8af793f54..82110eb86 100644 --- a/tests/testthat/test-trailing_whitespace_linter.R +++ b/tests/testthat/test-trailing_whitespace_linter.R @@ -2,16 +2,16 @@ context("trailing_whitespace_linter") test_that("returns the correct linting", { expect_lint("blah", NULL, - trailing_whitespace_linter) + trailing_whitespace_linter()) expect_lint("blah <- 1 ", c(message = rex("Trailing whitespace is superfluous."), column_number = 10), - trailing_whitespace_linter) + trailing_whitespace_linter()) expect_lint("blah <- 1 \n'hi'", rex("Trailing whitespace is superfluous."), - trailing_whitespace_linter) + trailing_whitespace_linter()) expect_lint("blah <- 1\n'hi'\na <- 2 ", list( @@ -20,5 +20,5 @@ test_that("returns the correct linting", { line_number = 3 ) ), - trailing_whitespace_linter) + trailing_whitespace_linter()) })