I would like to modify an input function, so that the expressions always call
`{`()
, and doing so, keep the comments at the right place.
Here is an example :
input_fun <- function(){
if(TRUE)
foo
else
# bar
bar
if(FALSE) {
this
# baz
baz
that
}
repeat
while(condition)
# qux
qux
}
cat(deparse(input_fun, control = "useSource"),sep ="\n")
#> function(){
#>
#> if(TRUE)
#> foo
#> else
#> # bar
#> bar
#>
#> if(FALSE) {
#> this
#> # baz
#> baz
#> that
#> }
#>
#> repeat
#> while(condition)
#> # qux
#> qux
#> }
The output would be the following output_fun
or similar, where similar means that
inserting or removing new lines before/after {
or }
is not important, and nor is
indentation.
I also don't mind losing comments that are not on their own line (though I slightly better to keep them).
output_fun <- function(){
if(TRUE){
foo
} else {
# bar
bar
}
if(FALSE) {
this
# baz
baz
that
}
repeat {
while(condition){
# qux
qux
}
}
}
cat(deparse(output_fun, control = "useSource"),sep ="\n")
#> function(){
#> if(TRUE){
#> foo
#> } else {
#> # bar
#> bar
#> }
#>
#> if(FALSE) {
#> this
#> # baz
#> baz
#> that
#> }
#>
#> repeat {
#> while(condition){
#> # qux
#> qux
#> }
#> }
#> }
Maybe something can be done by keeping a count of control flow constructs and opened brackets, or maybe we should go through the parse tree of the input function, edit to add the {
and find a way to plug back the comments from the original srcref at the right place, but I'm a bit stuck, any method will do.
edit :
We might be able to use this :
repair <- function(call){
if(!is.call(call)) {
return(call)
}
# if
if(call[[1]] == quote(`if`)) {
if(!is.call(call[[3]]) || call[[3]][[1]] != quote(`{`)){
call[[3]] <- as.call(list(quote(`{`), call[[3]]))
}
if(length(call) == 4 && (!is.call(call[[4]]) || call[[4]][[1]] != quote(`{`))){
call[[4]] <- as.call(list(quote(`{`), call[[4]]))
}
call[-1] <- lapply(as.list(call[-1]), repair)
return(call)
}
# for
if(call[[1]] == quote(`for`)) {
if(!is.call(call[[4]]) || call[[4]][[1]] != quote(`{`)){
call[[4]] <- as.call(list(quote(`{`), call[[4]]))
}
call[-1] <- lapply(as.list(call[-1]), repair)
return(call)
}
# repeat
if(call[[1]] == quote(`repeat`)) {
if(!is.call(call[[2]]) || call[[2]][[1]] != quote(`{`)){
call[[2]] <- as.call(list(quote(`{`), call[[2]]))
}
call[-1] <- lapply(as.list(call[-1]), repair)
return(call)
}
# while
if(call[[1]] == quote(`while`)) {
if(!is.call(call[[3]]) || call[[3]][[1]] != quote(`{`)){
call[[3]] <- as.call(list(quote(`{`), call[[3]]))
}
call[-1] <- lapply(as.list(call[-1]), repair)
return(call)
}
#
call[] <- lapply(call, repair)
call
}
output_fun0 <- input_fun
body(output_fun0) <- repair(body(input_fun))
output_fun0
#> function ()
#> {
#> if (TRUE) {
#> foo
#> }
#> else {
#> bar
#> }
#> if (FALSE) {
#> this
#> baz
#> that
#> }
#> repeat {
#> while (condition) {
#> qux
#> }
#> }
#> }