Skip to content

Commit 9d62e3a

Browse files
Improve formatter documentation with minimal examples and better organization
Co-authored-by: felix-andreas <[email protected]>
1 parent a3cec0a commit 9d62e3a

20 files changed

+201
-175
lines changed

crates/roughly/tests/format/formatter.template.md

Lines changed: 59 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Roughly applies specific formatting rules to different R code constructs. The fo
4949
```r
5050
# assignment_operators : compare
5151
x<-1
52-
result<<-calculate()
52+
data<<-process()
5353
```
5454

5555
**Binary operators** get spaces around them, except for range (`:`) and power (`^`) operators:
@@ -58,7 +58,7 @@ result<<-calculate()
5858
# binary_operators : compare
5959
result=x+y*z
6060
power=base^exponent
61-
sequence=1:10
61+
data=1:10
6262
```
6363

6464
**Pipeline operators** maintain proper indentation when expressions span multiple lines:
@@ -67,7 +67,7 @@ sequence=1:10
6767
# pipeline_operators : compare
6868
data %>%
6969
filter(condition) %>%
70-
summarize(mean_value=mean(value))
70+
select(mean_value=mean(value))
7171
```
7272

7373
### Code Blocks and Braced Expressions
@@ -114,11 +114,11 @@ The formatter normalizes line spacing between expressions, allowing at most one
114114

115115
```r
116116
# line_spacing : compare
117-
calculate_mean <- function(data) {
118-
clean_data <- data[!is.na(data)]
117+
process <- function(data) {
118+
result <- filter(data)
119119

120120

121-
mean(clean_data)
121+
result
122122
}
123123
```
124124

@@ -128,15 +128,13 @@ Function calls receive consistent formatting with proper spacing around argument
128128

129129
```r
130130
# function_calls : compare
131-
calculate(data=dataset,method="mean",na.rm=TRUE)
132-
complex_call(argument1,
133-
argument2=value,
134-
argument3)
131+
process(data=dataset,method="mean",na.rm=TRUE)
132+
call(arg1,
133+
arg2=value,
134+
arg3)
135135
```
136136

137-
**Argument hugging**: When function arguments can fit on a single line and the last argument's value starts on the same line as the opening parenthesis, the formatter keeps a compact format. Otherwise, it expands to multiple lines with proper indentation.
138-
139-
**Nested function calls** are formatted with hugging when appropriate:
137+
**Nested function calls** are formatted with proper spacing:
140138

141139
```r
142140
# nested_function_calls : compare
@@ -149,9 +147,9 @@ Function definitions follow consistent formatting rules for parameters and body
149147

150148
```r
151149
# function_definitions : compare
152-
calc<-function(x,y=1){x+y}
153-
stats<-function(data,method="mean"){
154-
result(data,method)
150+
process<-function(x,y=1){x+y}
151+
filter<-function(data,method="simple"){
152+
select(data,method)
155153
}
156154
```
157155

@@ -172,17 +170,15 @@ lapply(data,\(x)x+1)
172170

173171
```r
174172
# conditional_statements : compare
175-
if(condition){action} else{alternative}
173+
if(condition){process()} else{filter()}
176174

177175
if(
178-
long_condition ||
176+
condition ||
179177
other_condition){
180-
action()
178+
process()
181179
}
182180
```
183181

184-
**Condition hugging**: When conditions fit on a single line without comments, the formatter keeps them compact. For multiline conditions, proper indentation is applied.
185-
186182
**Block enforcement**: If an if-statement has a multiline condition, the formatter ensures the body is wrapped in braces even if it's a single expression.
187183

188184
### Loops and Control Flow
@@ -191,38 +187,36 @@ if(
191187

192188
```r
193189
# for_loops : compare
194-
for(item in collection) process(item)
190+
for(item in data) process(item)
195191
```
196192

197193
**While loops** follow similar block enforcement rules:
198194

199195
```r
200196
# while_loops : compare
201-
while(condition) action()
197+
while(condition) process()
202198
```
203199

204200
**Repeat loops** also enforce braced blocks:
205201

206202
```r
207203
# repeat_loops : compare
208-
repeat action()
204+
repeat process()
209205
```
210206

211207
**Loop condition formatting**: Complex conditions that span multiple lines receive proper indentation within the parentheses.
212208

213209
### Parenthesized Expressions
214210

215-
Parenthesized expressions maintain their layout with smart formatting for readability:
211+
Parenthesized expressions receive proper spacing for operators:
216212

217213
```r
218214
# parenthesized_expressions : compare
219-
(x+y*z)
220-
(long_expression+
221-
other_part)
215+
(
216+
expression +
217+
other_part)
222218
```
223219

224-
**Parenthesis hugging**: If the content fits on one line, parentheses hug the content. For multiline content, proper indentation is applied.
225-
226220
### String Literals
227221

228222
String literals receive intelligent quote normalization. The formatter prefers double quotes (`"`) unless the string contains unescaped double quotes:
@@ -239,17 +233,17 @@ quoted_content <- 'Say "hello"'
239233

240234
```r
241235
# subsetting : compare
242-
data[row_index,column_index]
243-
environment[["variable_name"]]
244-
object$member_variable
236+
data[row,col]
237+
data[["name"]]
238+
object$value
245239
```
246240

247241
**Namespace operators** (`::` and `:::`):
248242

249243
```r
250244
# namespace_operators : compare
251-
package::public_function
252-
package:::private_function
245+
pkg::process
246+
pkg:::filter
253247
```
254248

255249
### Unary Operators
@@ -259,36 +253,37 @@ Unary operators receive appropriate spacing based on their type and context:
259253
```r
260254
# unary_operators : compare
261255
result = ! condition
262-
number = - 42
263-
formula = ~ response + predictor
256+
value = - 42
257+
formula = ~ x + y
264258
```
265259

266260
**Special spacing rule**: The `~` (formula) operator gets a space when followed by complex expressions, but not when followed by simple identifiers.
267261

268262
## Format Suppression
269263

270-
You can disable formatting for specific code sections using the `# fmt: skip` comment directive:
264+
You can disable formatting for specific code sections using the `# fmt: skip` comment directive. This is useful when you want to preserve specific formatting for readability, such as aligned data structures.
271265

272266
```r
273267
# format_suppression : format
274268
# fmt: skip
275-
matrix(
276-
c(
277-
1, 2,
278-
3, 4
279-
),
280-
nrow=2
269+
c(
270+
1, 2,
271+
3, 4
281272
) # This code won't be reformatted
282273

283-
matrix(c(1, 2,
284-
3, 4), nrow=2) # fmt: skip
285-
# The line above won't be reformatted
274+
# fmt: skip
275+
c(1, 2,
276+
3, 4) # The line above won't be reformatted
286277
```
287278

279+
Without the `fmt: skip` directive, the `c(...)` expression would be formatted according to standard rules.
280+
288281
The `fmt: skip` directive can be placed:
289282
- Before a line to skip formatting that entire expression
290283
- At the end of a line to skip formatting just that line
291284

285+
You can also skip formatting for an entire file by placing `# fmt: skip-file` at the top of the file. This directive must be placed at the very beginning of the file to take effect.
286+
292287
## Advanced Formatting Features
293288

294289
The formatter intelligently handles various R idioms and special patterns:
@@ -341,7 +336,6 @@ PersonClass <- R6Class(
341336
- **Switch statements**: Fallthrough cases (`case = ,`) are handled correctly
342337
- **Multi-line strings**: String literal structure is preserved
343338
- **Formula objects**: Proper spacing around `~` operator based on complexity
344-
- **S4 slot access**: `@` operator formatting maintained
345339

346340
## Auto-Bracing
347341

@@ -351,7 +345,7 @@ The formatter automatically adds braces to control flow structures when they imp
351345

352346
```r
353347
# auto_bracing_function_defintions : compare
354-
f <- function(x)
348+
process <- function(x)
355349
x + 1
356350
```
357351

@@ -360,7 +354,7 @@ f <- function(x)
360354
```r
361355
# auto_bracing_conditional_statements : compare
362356
if (condition)
363-
single_statement
357+
process()
364358
```
365359

366360
**Loops**: All loop bodies are automatically braced for consistency:
@@ -373,7 +367,7 @@ for (i in 1:n)
373367

374368
## Hugging Behavior
375369

376-
"Hugging" refers to how nested function calls are formatted - keeping them compact by allowing the inner calls to start on the same line as the outer call's opening parenthesis. This is part of roughly's non-invasive approach: both hugged and expanded formats are allowed.
370+
"Hugging" refers to how nested expressions are formatted in multiline contexts - keeping them compact by allowing inner expressions to start on the same line as the outer expression's opening delimiter. This is part of roughly's non-invasive approach: both hugged and expanded formats are allowed, but hugging only applies to multiline expressions.
377371

378372
**Nested function calls** can be formatted in a hugged style:
379373

@@ -392,6 +386,20 @@ result <- outer(
392386
)
393387
```
394388

389+
**Parenthesized expressions** can also use hugging:
390+
391+
```r
392+
# hugging_parenthesized : format
393+
(expression +
394+
other_part)
395+
396+
# Also allowed
397+
(
398+
expression +
399+
other_part
400+
)
401+
```
402+
395403
**Non-invasive multi-line formatting**: When expressions are already multi-line, roughly only adds necessary spacing but preserves the overall structure. However, if all arguments don't fit on their separate lines, they will be properly separated:
396404

397405
```r

crates/roughly/tests/snapshots/test_format__documentation_examples__assignment_operators.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
55
x <- 1
6-
result <<- calculate()
6+
data <<- process()

crates/roughly/tests/snapshots/test_format__documentation_examples__auto_bracing_conditional_statements.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
55
if (condition) {
6-
single_statement
6+
process()
77
}

crates/roughly/tests/snapshots/test_format__documentation_examples__auto_bracing_function_defintions.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
5-
f <- function(x) {
5+
process <- function(x) {
66
x + 1
77
}

crates/roughly/tests/snapshots/test_format__documentation_examples__binary_operators.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ expression: code
44
---
55
result = x + y * z
66
power = base^exponent
7-
sequence = 1:10
7+
data = 1:10

crates/roughly/tests/snapshots/test_format__documentation_examples__conditional_statements.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
5-
if (condition) { action } else { alternative }
5+
if (condition) { process() } else { filter() }
66

77
if (
8-
long_condition ||
8+
condition ||
99
other_condition
1010
) {
11-
action()
11+
process()
1212
}

crates/roughly/tests/snapshots/test_format__documentation_examples__for_loops.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
5-
for (item in collection) {
5+
for (item in data) {
66
process(item)
77
}

crates/roughly/tests/snapshots/test_format__documentation_examples__format_suppression.snap

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,11 @@ source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
55
# fmt: skip
6-
matrix(
7-
c(
8-
1, 2,
9-
3, 4
10-
),
11-
nrow=2
6+
c(
7+
1, 2,
8+
3, 4
129
) # This code won't be reformatted
1310

14-
matrix(c(1, 2,
15-
3, 4), nrow=2) # fmt: skip
16-
# The line above won't be reformatted
11+
# fmt: skip
12+
c(1, 2,
13+
3, 4) # The line above won't be reformatted

crates/roughly/tests/snapshots/test_format__documentation_examples__function_calls.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
5-
calculate(data = dataset, method = "mean", na.rm = TRUE)
6-
complex_call(
7-
argument1,
8-
argument2 = value,
9-
argument3
5+
process(data = dataset, method = "mean", na.rm = TRUE)
6+
call(
7+
arg1,
8+
arg2 = value,
9+
arg3
1010
)

crates/roughly/tests/snapshots/test_format__documentation_examples__function_definitions.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
source: crates/roughly/tests/test_format.rs
33
expression: code
44
---
5-
calc <- function(x, y = 1) { x + y }
6-
stats <- function(data, method = "mean") {
7-
result(data, method)
5+
process <- function(x, y = 1) { x + y }
6+
filter <- function(data, method = "simple") {
7+
select(data, method)
88
}

0 commit comments

Comments
 (0)