Skip to content

Commit

Permalink
improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzwalthert committed Apr 13, 2021
1 parent 622ceef commit 63c3749
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 142 deletions.
20 changes: 18 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
# styler 1.4.1.9000 (Development version)

* `#>` is recognized as an output marker and no space is added after `#` (#771).
* speeding up alignment detection (#774).

* code with left alignment after `=` in function calls is now recognized as
aligned and won't be reformatted (#774).
```
# newly detected
call(
x = 12345,
y2 = 17
)
# already detected previously
call(
x = 12345,
y2 = 17
)
```
Also see `vignette("detect-alignment")`:


# styler 1.4.1

* Fix interaction between cache and `base_indention`. This also fixes
Expand Down
209 changes: 69 additions & 140 deletions vignettes/detect-alignment.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ vignette: >
knitr::opts_chunk$set(eval = FALSE)
```

# Overview

Sometimes, you deliberately align code to make it more readable.

```{r}
call(
a = 3,
b = 3213232
a = 3,
bre = 3213232
)
```

Until styler 1.1.1.9002 (with `strict = TRUE`, e.g. as in
Expand All @@ -27,9 +28,8 @@ Until styler 1.1.1.9002 (with `strict = TRUE`, e.g. as in
```{r}
call(
a = 3,
b = 3213232
bre = 3213232
)
```

because no alignment detection was built in.^[With `strict = FALSE`, the spacing
Expand All @@ -42,6 +42,31 @@ vignette describes how aligned code is defined in styler and gives some examples
so users can format their aligned code to match the definition styler uses to
ensure their code is not unintentionally reformatted.

## Examples

These typical examples match *styler*'s definition of alignment. Note the
spacing around operators and commas.

```{r}
tibble::tribble(
~key_here, ~value_here,
"left", "right", # comments are allowed
"long string", "shrt" # columns can overlap ('~' above ',')
)
purrr::map(x, fun, # arguments on same line as opening brace are not considered
arg2 = 2,
ar = f(k, x)
)
purrr::map(x, fun, # arguments on same line as opening brace are not considered
arg2 = 2,
ar = f(k, x)
)
```

# Details

An important definition used in the remainder is the one of a **column**. All
arguments of a function call that have the same position but are placed on
different lines form a column. The below call shows a call with two columns and
Expand All @@ -52,173 +77,79 @@ unnamed:
```{r}
call(
# column 1 | column 2 |
abkj = f(2), 7,
abkj = f(2), 7,
more_ = "a", 2 # more
)
```

## Function calls

### Non-technical definition

Below, we try to explain in an intuitive way how your code should look like to
be recognized as aligned.

**If all arguments in the first column are named**: Make commas match position
vertically and right align everything between commas:
**If all arguments in the first column are named**:

Make commas match position vertically and align everything right before commas:

```{r}
# all arguments of first column named -> must right align
# aligned if the (imaginary) comma on the last line is in line with the commas
# from the two top lines.
# all arguments of first column named -> must right align values after `=`,
# one or more spaces around `=`, none before and at least one after the comma.
# aligned if the (imaginary) comma on the last line is in line with the commas
fell(
x = 1,
x = 1,
y = 23,
zz = NULL
)
# this works also with more than one column
fell(
x = 1, annoying = 3,
x = 1, annoying = 3,
y = 23, # nothing in column 2 for row 2
zz = NULL, finally = ""
zz = NULL, finally = "stuff"
)
```

**If not all arguments of the first column are named:**^[In the below example,
the first argument of the first column is named (`p = 2`). The second argument
of the first column is not (`31`).] Make **all except the first column's
commas** match position

- vertically

- right align everything between the commas

- except before the first comma on a line

- give priority to correctly indent (i.e. left align):

```{r}
# not all arguments of first column named, hence, only
# commas of all but the first column must agree.
gell(
p = 2, g = gg(x), n = 3 * 3, #
31, fds = -1, gz = f / 3,
)
```

By *align everything in between the commas*, we mean put zero space before a
comma and at least one after. Note that the arguments on the first line are
ignored when detecting alignment, which is best shown when code is formatted
such that no line breaks will be modified by _styler_. This applies if all names
on the first line are unnamed and all subsequent are named:
... or match position of `=` vertically and align everything after this operator
left

```{r}
map(x, f,
arg1 = 121,
arg2 = 1
)
```

**Examples**

These typical examples match _styler_'s definition of alignment.

```{r}
tibble::tribble(
~key_here, ~value_here,
"left", "right", # comments are allowed
"long string", "shrt" # columns can overlap ('~' above ',')
)
purrr::map(x, fun, # arguments on same line as opening brace are not considered
arg2 = 2,
ar = f(x)
)
```

### Technical definition

This section closely follows the implementation of the alignment detection and
is mostly aimed at developers for understanding _styler_ internals.

Function calls are aligned if **all** of the following conditions hold (for all
but the very first line (i.e. `call(` below):

* all rows in first column have the same number of lag spaces. This basically
means that the indention is identical for all columns (except for the closing
brace if it is on its own line). The below example has one column, because the
maximal number of commas on one line is one.

```{r}
# holds
call(
a = 3,
b = 32
# all arguments of first column named -> must left align values after `=`,
# at least one space before `=`, exactly one after, none before and at least one
# after the comma.
# aligned if the first values after `=` are aligned (and exactly one space after
# `=`)
fell(
x = 1,
y = 23,
zz = NULL
)
# doesn't hold
call(
a = 3,
b = 32
# this works also with more than one column
fell(
x = 1, annoying = 3,
y = 23, # nothing in column 2 for row 2
zz = NULL, finally = "stuff"
)
```

* spacing around comma (0 before, > 1 after, >= 0 after last column on line) and
spacing around `=` (at least one before and after).

```{r}
# holds
call(
a = 3, k = 3,
b = 32, 222
)
# doesn't hold
call(
a = 3 ,
b = 32
)
```

* All commas from all columns are aligned. This means that for every column, all
commas must be on the same positions as the commas from the other lines. If
not all arguments are named in the first column, this column is not
considered. The reason to exclude the first column is that, as in the example
below, it is possible that some arguments are named while others are not.
Then, it is not generally possible to keep the first rule (i.e. indention
identical across lines). Also ensuring that the comma does not have any spaces
before it and its alignment with other lines does not hold true. This is shown
below with the line `f(x, y),`. For this reason, the requirements exclude the
first column in such cases. The *holds* example shows that is is possible (but
not required) for named arguments to also have the commas separating the first
and second column aligned.
**If not all arguments of the first column are named:**^[In the below example,
the first argument of the first column is named (`p = 2`). The second argument
of the first column is not (`31`).] The same as above, but the first column is
ignored.

```{r}
# holds
call(
a = ff("pk"), k = 3, x = 2,
b = f(-g), 22 + 1, yy = 1,
c = 1,
f(x, y),
k
)
# doesn't hold
call(
a = 3,
b = 32, c = 2
# not all arguments of first column named, hence, all (except the first
# column's) commas must match position
gell(
p = 2, g = gg(x), n = 3 * 3, #
31, fds = -1, gz = f / 3,
)
```
Note that the above definition does not check alignment of `=`, so _styler_ will
treat the following as aligned:

```{r}
rge(
x = 99, x = 2,
fs = 1, y = 1,
# or all (except the first column's) `=` must match position
gell(
p = 2, g = gg(x), n = 3 * 3, #
31, fds = -1, gz = f / 3 + 1,
)
```

Expand All @@ -229,5 +160,3 @@ not supported yet.
## Assignment

not supported yet.


0 comments on commit 63c3749

Please sign in to comment.