# Formatting Options

rformat applies base R style conventions to R code. All transforms operate on the token stream from `parse()` + `getParseData()`, so they never change the meaning of your code – only its whitespace and style.

This vignette walks through each option with before/after examples.

## Default formatting

With no options, rformat normalizes spacing, converts `=` assignment to `<-`, and indents by nesting depth.

    > library(rformat)
    > cat(rformat("x=1+2"))
    x <- 1 + 2
    > cat(rformat("f=function(x,y){
    + if(x>0)
    + y=mean(x,na.rm=TRUE)
    + else y=NA
    + }"))
    f <- function(x, y) {
        if (x > 0)
        y <- mean(x, na.rm = TRUE)
        else y <- NA
    }

## `indent`

Indentation per nesting level. Default is 4 spaces. Pass an integer for spaces or a character string for a literal indent.

    > # 2 spaces per level
    > cat(rformat("f <- function(x) {\nif (x) {\ny\n}\n}", indent = 2L))
    f <- function(x) {
      if (x) {
        y
      }
    }
    > # Tab indent (shown as \t in output)
    > rformat("f <- function(x) {\nif (x) {\ny\n}\n}", indent = "\t")
    [1] "f <- function(x) {\n\tif (x) {\n\t\ty\n\t}\n}\n"

## `line_limit`

Maximum line width before wrapping kicks in (default 80). This affects function signature wrapping and long expression wrapping.

    > long_call <- "result <- some_function(alpha, bravo, charlie, delta)"
    > # Default 80: fits on one line
    > cat(rformat(long_call))
    result <- some_function(alpha, bravo, charlie, delta)
    > # Narrow limit: forces wrapping
    > cat(rformat(long_call, line_limit = 40))
    result <- some_function(alpha, bravo,
        charlie, delta)

## `wrap`

Controls continuation indent style for wrapped function signatures.

- `"paren"` (default): aligns continuation to the opening parenthesis
- `"fixed"`: uses an 8-space continuation indent

    > long_sig <- paste0(
    +     "my_function <- function(alpha, beta, gamma, ",
    +     "delta, epsilon, zeta, eta, theta, iota) ",
    +     "{\n    1\n}")
    > # Paren-aligned (default): continuation aligns to (
    > cat(rformat(long_sig, wrap = "paren"))
    my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
                            iota) {
        1
    }
    > # Fixed: continuation uses 8-space indent
    > cat(rformat(long_sig, wrap = "fixed"))
    my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
            iota) {
        1
    }

## `brace_style`

Controls opening brace placement for function definitions.

- `"kr"` (default): K&R style, opening brace on same line as `)`
- `"allman"`: opening brace on its own line

    > long_def <- paste0(
    +     "my_function <- function(alpha, beta, gamma, ",
    +     "delta, epsilon, zeta, eta, theta, iota) ",
    +     "{\n    y <- 1\n    y\n}")
    > # K&R (default): { on same line as )
    > cat(rformat(long_def, brace_style = "kr"))
    my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
                            iota) {
        y <- 1
        y
    }
    > # Allman: { on its own line
    > cat(rformat(long_def, brace_style = "allman"))
    my_function <- function(alpha, beta, gamma, delta, epsilon, zeta, eta, theta,
                            iota)
    {
        y <- 1
        y
    }

## `control_braces`

When TRUE, adds braces to bare (unbraced) control flow bodies. Default FALSE matches R Core source code, where 59% of control flow bodies are bare.

    > code <- "f <- function(x) {
    + if (x > 0) y <- log(x)
    + if (x < 0) stop('negative')
    + }"
    > # Default: bare bodies left alone
    > cat(rformat(code))
    f <- function(x) {
        if (x > 0) y <- log(x)
        if (x < 0) stop('negative')
    }
    > # Add braces
    > cat(rformat(code, control_braces = TRUE))
    f <- function(x) {
        if (x > 0) { y <- log(x) }
        if (x < 0) { stop('negative') }
    }

## `expand_if`

When TRUE, expands inline if-else expressions to multi-line form.

    > code <- "y <- if (x > 0) log(x) else NA"
    > # Default: inline if-else preserved
    > cat(rformat(code))
    y <- if (x > 0) log(x) else NA
    > # Expanded to multi-line
    > cat(rformat(code, expand_if = TRUE))
    if (x > 0) {
        y <- log(x)
    } else {
        y <- NA
    }

## `else_same_line`

In R, `else` on its own line is a parse error at top level (though it’s valid inside braces). When TRUE (default), this option repairs top-level `}\nelse` by joining them to `} else` before formatting. When FALSE, unparseable input is returned unchanged with a warning.

    > # Top-level } else on separate lines is a parse error.
    > # else_same_line (the default) repairs it:
    > code <- "if (x) {\n    1\n}\nelse {\n    2\n}"
    > cat(rformat(code))
    if (x) {
        1
    } else {
        2
    }

## `join_else`

When TRUE (default), moves `else` to the same line as the preceding `}`. Matches R Core source code where 70% use same-line else. When FALSE, `}\nelse` on separate lines is preserved.

This is an AST-level transform that works on already-valid code inside braces, unlike `else_same_line` which is a text-level parse repair.

    > code <- "f <- function(x) {
    + if (x > 0) {
    +     y <- log(x)
    + }
    + else {
    +     y <- NA
    + }
    + y
    + }"
    > # Default: else joins the } line
    > cat(rformat(code))
    f <- function(x) {
        if (x > 0) {
            y <- log(x)
        } else {
            y <- NA
        }
        y
    }
    > # Preserve } / else on separate lines
    > cat(rformat(code, join_else = FALSE))
    f <- function(x) {
        if (x > 0) {
            y <- log(x)
        }
        else {
            y <- NA
        }
        y
    }

## `function_space`

When TRUE, adds a space before `(` in function definitions: `function (x)` instead of `function(x)`. Default FALSE matches 96% of R Core source code.

    > code <- "f <- function(x, y) {\n    x + y\n}"
    > # Default: no space
    > cat(rformat(code))
    f <- function(x, y) {
        x + y
    }
    > # With space
    > cat(rformat(code, function_space = TRUE))
    f <- function (x, y) {
        x + y
    }

## Combining options

Options compose naturally. Here is a more opinionated style that adds braces, expands if-else, and uses Allman braces with 2-space indent:

    > code <- "f=function(x){
    + y=if(x>0) log(x) else NA
    + y
    + }"
    > cat(rformat(code,
    +     indent = 2L,
    +     brace_style = "allman",
    +     control_braces = TRUE,
    +     expand_if = TRUE))
    f <- function(x) {
      if (x > 0) {
        y <- log(x)
      } else {
        y <- NA
      }
      y
    }

## Formatting files and directories

`rformat_file()` formats a file in place (or to a new path). `rformat_dir()` formats all `.R` files in a directory. Both accept the same options as `rformat()`.

    > # Format a file (dry run)
    > f <- tempfile(fileext = ".R")
    > writeLines("x=1+2", f)
    > rformat_file(f, dry_run = TRUE)
    > # Format all R files in a directory (dry run)
    > d <- file.path(tempdir(), "rformat_demo")
    > dir.create(d, showWarnings = FALSE)
    > writeLines("y = 3", file.path(d, "example.R"))
    > rformat_dir(d, dry_run = TRUE)
    Would format: /tmp/RtmpqnaPGt/rformat_demo/example.R

    > unlink(d, recursive = TRUE)
    > unlink(f)