---
title: "Get started"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Get started}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, echo = FALSE}
knitr::opts_chunk$set(echo = TRUE, comment = "")
knitr::knit_engines$set(list(
  styler = function(options) {
    options$comment <- ""
    knitr::engine_output(
      options,
      c("# Before", options$code),
      c("# After", styler::style_text(options$code))
    )
  }
))

options(styler.colored_print.vertical = FALSE)
styler::cache_deactivate()
```

# Entry-points

styler provides the following API to format code:

-   `style_file()` styles `.qmd`, `.R`, `.Rmd`, `.Rmarkdown`, `.Rnw`, and `.Rprofile` files.

-   `style_dir()` styles all these files in a directory.

-   `style_pkg()` styles the source files of an R package.

-   RStudio Addins for styling the active file, styling the current package and styling the highlighted selection, see `help("styler_addins")`.

Beyond that, styler can be used through other tools documented in the `vignette("third-party-integrations")`. Let's get started.
```{r}
library(styler)
```



### Passing arguments to the style guide

styler separates the abstract definition of a style guide from the application of it. That's why you must supply a style guide via `transformers` when styling (in case you don't want to rely on the defaults):

```{r}
style_text("a + b", transformers = tidyverse_style(scope = "indention"))
```

The styler API was designed so that you can pass arguments to the style guide via the styling function (e.g. `style_file()`) to allow more concise syntax:

```{r, results = 'hide'}
# equivalent
style_text("a + b", transformers = tidyverse_style(scope = "indention"))
style_text("a + b", scope = "indention")
```

The magic is possible thanks to `...`. See `style_text()` for details.

# Invasiveness

### `scope`: What to style?

This argument of `tidyverse_style()` determines the invasiveness of styling. The following levels for `scope` are available (in increasing order):

-   "none": Performs no transformation at all.

-   "spaces": Manipulates spacing between token on the same line.

-   "indention": Manipulates the indention, i.e. number of spaces at the beginning of each line.

-   "line_breaks": Manipulates line breaks between tokens.

-   "tokens": manipulates tokens.

There are two ways to specify the scope of styling.

-   As a string: In this case all less invasive scope levels are implied, e.g. `"line_breaks"` includes `"indention"`, `"spaces"`. This is brief and what most users need. This is supported in `styler >= 1.0.0`.

-   As vector of class `AsIs`: Each level has to be listed explicitly by wrapping one ore more levels of the scope in `I()`. This offers more granular control at the expense of more verbosity. This is supported in `styler > 1.3.2`.

```{r}
# tokens and everything less invasive
style_text("a=2", scope = "tokens")

# just tokens and indention
style_text("a=2", scope = I(c("tokens", "indention")))
```

As you can see from the output, the assignment operator `=` is replaced with `<-` in both cases, but spacing remained unchanged in the second example.

### How `strict` do you want styler to be?

Another option that is helpful to determine the level of 'invasiveness' is `strict` (defaulting to `TRUE`). Some rules won't be applied so strictly with `strict = FALSE`, assuming you deliberately formatted things the way they are. Please see in `vignette("strict")`. For `styler >= 1.2` alignment in function calls is detected and preserved so you don't need `strict = FALSE`, e.g.

```{r}
style_text(
  "tibble::tibble(
     small  = 2 ,
     medium = 4,#comment without space
     large  = 6
   )"
)
```

The details are in `vignette("detect-alignment")`.

# Ignoring certain lines

You can tell styler to ignore some lines if you want to keep current formatting. You can mark whole blocks or inline expressions with `styler: on` and `styler: off`:

```{r}
styler::style_text(
  "
  #> blocks
  blibala= 3
  # styler: off
  I_have(good+reasons, to = turn_off,
    styler
  )
  # styler: on
  1+1

  #> inline
  ignore( this) # styler: off
  f( ) # not ignored anymore
"
)
```

You can also use custom markers as described in `help("stylerignore", package = "styler")`. As described above and in `vignette("detect-alignment")`, some alignment is recognized and hence, *stylerignore* should not be necessary in that context.

# Caching

styler is rather slow, so leveraging a cache for styled code brings big speedups in many situations. Starting with version `1.3.0`, you can benefit from it. For people using styler interactively (e.g. in RStudio), typing `styler::cache_info()` and then confirming the creation of a permanent cache is sufficient. Please refer to `help("caching")` for more information. The cache is by default dependent on the version of styler which means if you upgrade, the cache will be re-built. Also, the cache takes literally 0 disk space because only the hash of styled code is stored.

# Dry mode

As of version `1.3.2`, styler has a dry mode which avoids writing output to the file(s) you want to format. The following options are available:

-   *off* (default): Write back to the file if applying styling changes the input.

-   *on*: Applies styling and returns the results without writing changes (if any) back to the file(s).

-   *fail*: returns an error if the result of styling is not identical to the input.

In any case, you can use the (invisible) return value of `style_file()` and friends to learn how files were changed (or would have changed):

```{r, comment = "#>"}
out <- withr::with_tempfile(
  "code.R",
  {
    writeLines("1+1", "code.R")
    style_file("code.R", dry = "on")
  }
)
out
```

# More configuration options

### Roxygen code example styling

This is enabled by default, you can turn it off with `include_roxygen_examples = FALSE`.

### Custom math token spacing

`styler` can identify and handle unary operators and other math tokens:

```{styler}
1++1-1-1/2
```

This is tidyverse style. However, styler offers very granular control for math token spacing. Assuming you like spacing around `+` and `-`, but not around `/` and `*` and `^`, do the following:

```{r}
style_text(
  "1++1/2*2^2",
  math_token_spacing = specify_math_token_spacing(zero = c("'/'", "'*'", "'^'"))
)
```

### Custom indention

If you, say, don't want comments starting with `###` to be indented and indention to be 4 instead of two spaces, you can formulate an unindention rule and set `indent_by` to 4:

```{r}
style_text(
  c(
    "a <- function() {",
    "### not to be indented",
    "# indent normally",
    "33",
    "}"
  ),
  reindention = specify_reindention(regex_pattern = "###", indention = 0),
  indent_by = 4
)
```

### Custom style guides

These were some (not all) configurations exposed in `style_file()` and friends as well as `tidyverse_style()`. If the above did not give you the flexibility you hoped for, your can create your own style guide and customize styler even further:

-   either by removing rules from the tidyverse style guide as described in `vignette("remove_rules")`.
-   or by creating your own style guide from scratch as described in `vignette("customizing_styler")`.
