Open
Description
In this blog post, you explain how to go to prod with rpp::rpp_to_prod()
:
foo <- function(x ) { # !q foo <- Character()? function(x = ?Character()) {
out <- paste("foo:", x) # !q Character()? out <- paste("foo:", x)
out
}
I suggest to give the user the opportunity use {styler} with scope = I("spaces")
(if they want) to style this text and since the line count should not change, replace all lines that have a comment with # q!
with the styled code. Here is a quick implementation:
library(magrittr)
#' Style prod code
style_prod <- function(text) {
text <- ensure_last_empty(convert_newlines_to_linebreaks(text))
text_new <- c(
as.character(styler::style_text(text, scope = I("spaces"))),
""
)
if (length(text) != length(text_new)) {
# TODO EOF
rlang::warn("You hit a bug in {styler}, not formatting prod code. [more instrucitons]")
return(text)
}
pd <- getParseData(parse(text = text))
active_tokens <- grepl("^# !q", pd$text) & pd$token == 'COMMENT'
active_lines <- unique(c(pd$line1[active_tokens], pd$line2[active_tokens]))
text[active_lines] <- text_new[active_lines]
text
}
# From {styler}, ensure input has a traling newline so formatting with scope = 'spaces'
# has same line count
ensure_last_empty <- function(x) {
if (all(x == "")) {
return("")
}
x <- c(x, "", "")
x <- x[seq(1, length(x) - which(rev(x) != "")[1] + 1L)]
c(x, rep("", 1))
}
# from {styler}, turn text into a character vector where every element is one
# line, i.e. convert_newlines_to_linebreaks('x\n2') -> c('x', '2')
convert_newlines_to_linebreaks <- function(text) {
split <- strsplit(text, "\n", fixed = TRUE)
purrr::map(split, ~ if (identical(.x, character(0))) {
""
} else {
.x
}) %>%
unlist()
}
text <- 'foo <- function(x ) { # !q foo <- Character()? function(x = ?Character()) {
out <- paste("foo:", x) # !q Character()? out <- paste("foo:", x)
out
}
'
style_prod(text)
#> [1] "foo <- function(x) { # !q foo <- Character()? function(x = ?Character()) {"
#> [2] " out <- paste(\"foo:\", x) # !q Character()? out <- paste(\"foo:\", x)"
#> [3] " out"
#> [4] "}"
#> [5] ""
Created on 2021-10-19 by the reprex package (v2.0.1)
Only drawback is that {styler} is slow (but the cache helps in 2nd styling). You could also remove certain elements in the code, e.g. Character()?
from the parse data and then collapse it together similar to how styler does it.
getParseData(parse(text = "Character()? x <- 'hi'"))
Anyways, not sure how often rpp::rpp_to_prod()
is called, probably not often.
Metadata
Metadata
Assignees
Labels
No labels