Skip to content

Commit 26413c6

Browse files
- Merge branch indent-eq-formals into master (#353)
2 parents d771f9d + b591a12 commit 26413c6

15 files changed

+190
-53
lines changed

R/indent.R

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ indent_braces <- function(pd, indent_by) {
1919
set_unindention_child(pd, token = "')'", unindent_by = indent_by)
2020
}
2121

22-
#' @describeIn update_indention Indents operators
22+
#' @describeIn update_indention Indents *all* tokens after `token` - including
23+
#' the last token.
2324
indent_op <- function(pd,
2425
indent_by,
2526
token = c(
@@ -35,13 +36,29 @@ indent_op <- function(pd,
3536
pd
3637
}
3738

39+
#' Revert the indention of function declaration header
40+
#'
41+
#' Necessary for consistent indention of the function declaration header.
42+
#' @param pd A parse table.
43+
#' @seealso set_unindention_child update_indention_ref_fun_dec
44+
unindent_fun_dec <- function(pd) {
45+
if (is_function_dec(pd)) {
46+
idx_closing_brace <- which(pd$token %in% "')'")
47+
fun_dec_head <- seq2(2L, idx_closing_brace)
48+
pd$indent[fun_dec_head] <- 0L
49+
}
50+
pd
51+
}
52+
3853
#' @describeIn update_indention Updates indention for token EQ_SUB. Only differs
39-
#' from indent_op in the sense that the last token on the table where EQ_SUB
54+
#' from [indent_op()] in the sense that not all subsequent tokens in the parse
55+
#' table are necessarily indented, as `EQ_SUB` and `EQ_FORMALS` can occur
56+
#' multiple times in a parse table.
4057
#' occurs is not indented (see[compute_indent_indices()])
4158
indent_eq_sub <- function(pd,
4259
indent_by,
43-
token = "EQ_SUB") {
44-
eq_sub <- which(pd$token == "EQ_SUB")
60+
token = c("EQ_SUB", "EQ_FORMALS")) {
61+
eq_sub <- which(pd$token %in% token)
4562
if (length(eq_sub) == 0) return(pd)
4663
has_line_break <- which(pd$lag_newlines > 0)
4764
indent_indices <- intersect(eq_sub + 1, has_line_break)
@@ -126,7 +143,9 @@ compute_indent_indices <- function(pd,
126143
token_closing = NULL) {
127144
npd <- nrow(pd)
128145
potential_triggers <- which(pd$token %in% token_opening)
129-
needs_indention <- needs_indention(pd, potential_triggers)
146+
needs_indention <- needs_indention(pd, potential_triggers,
147+
other_trigger_tokens = c("EQ_SUB", "EQ_FORMALS")
148+
)
130149
trigger <- potential_triggers[needs_indention][1]
131150
if (is.na(trigger)) return(numeric(0))
132151
start <- trigger + 1
@@ -144,28 +163,55 @@ compute_indent_indices <- function(pd,
144163
#'
145164
#' Checks for each potential trigger token in `pd` whether it actually should
146165
#' cause indention.
147-
#' @param potential_triggers A vector with indices of the potential trigger
166+
#' @param potential_triggers_pos A vector with indices of the potential trigger
148167
#' tokens in `pd`.
149168
#' @inheritParams needs_indention_one
150-
needs_indention <- function(pd, potential_triggers) {
151-
map_lgl(potential_triggers, needs_indention_one, pd = pd)
169+
needs_indention <- function(pd,
170+
potential_triggers_pos,
171+
other_trigger_tokens = NULL) {
172+
map_lgl(potential_triggers_pos, needs_indention_one,
173+
pd = pd, other_trigger_tokens = other_trigger_tokens
174+
)
152175
}
153176

154177

155178
#' Check whether indention is needed
156179
#'
157-
#' Indention is needed if and only if there is no multi-line token between the
158-
#' trigger and the first line break.
180+
#' Indention is needed if the two conditions apply:
181+
#'
182+
#' * there is no multi-line token between the trigger and the first line break.
183+
#' * there is no other token between the potential trigger and the first line
184+
#' break that is going to cause indention.
185+
#'
159186
#' @param pd A parse table.
160-
#' @param potential_trigger the index of the token in the parse table
187+
#' @param potential_trigger_pos the index of the token in the parse table
161188
#' for which it should be checked whether it should trigger indention.
162189
#' @return Returns `TRUE` if indention is needed, `FALSE` otherwise.
190+
#' @param other_trigger_tokens Other tokens that are going to cause indention
191+
#' if on the same line as the token corresponding to `potential_trigger`.
163192
#' @return `TRUE` if indention is needed, `FALSE` otherwise.
164193
#' @importFrom rlang seq2
165-
needs_indention_one <- function(pd, potential_trigger) {
194+
needs_indention_one <- function(pd,
195+
potential_trigger_pos,
196+
other_trigger_tokens) {
166197
before_first_break <- which(pd$lag_newlines > 0)[1] - 1
167198
if (is.na(before_first_break)) return(FALSE)
168-
!any(pd$multi_line[seq2(potential_trigger, before_first_break)])
199+
row_idx_between_trigger_and_line_break <- seq2(
200+
potential_trigger_pos, before_first_break
201+
)
202+
multi_line_token <- pd_is_multi_line(
203+
pd[row_idx_between_trigger_and_line_break, ]
204+
)
205+
remaining_row_idx_between_trigger_and_line_break <- setdiff(
206+
row_idx_between_trigger_and_line_break,
207+
potential_trigger_pos
208+
)
209+
210+
other_trigger_on_same_line <-
211+
pd$token[remaining_row_idx_between_trigger_and_line_break] %in%
212+
other_trigger_tokens
213+
214+
!any(multi_line_token) & !any(other_trigger_on_same_line)
169215
}
170216

171217

R/reindent.R

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ update_indention_ref_fun_call <- function(pd_nested) {
5858
#' @importFrom rlang seq2
5959
update_indention_ref_fun_dec <- function(pd_nested) {
6060
if (pd_nested$token[1] == "FUNCTION") {
61-
seq <- seq2(3, nrow(pd_nested) - 1)
61+
seq <- seq2(3, nrow(pd_nested) - 2)
6262
pd_nested$indention_ref_pos_id[seq] <- pd_nested$pos_id[2]
6363
}
6464
pd_nested
@@ -91,15 +91,12 @@ apply_ref_indention <- function(flattened_pd) {
9191
#' @param target_token The index of the token from which the indention level
9292
#' should be applied to other tokens.
9393
apply_ref_indention_one <- function(flattened_pd, target_token) {
94-
token_points_to_ref <-
95-
flattened_pd$indention_ref_pos_id == flattened_pd$pos_id[target_token]
96-
first_token_on_line <- flattened_pd$lag_newlines > 0L
97-
token_to_update <- which(token_points_to_ref & first_token_on_line)
9894

95+
token_to_update <- find_tokens_to_update(flattened_pd, target_token)
9996
# udate spaces
10097
copied_spaces <- flattened_pd$col2[target_token]
10198
old_spaces <- flattened_pd$lag_spaces[token_to_update[1]]
102-
shift <- copied_spaces - old_spaces
99+
shift <- copied_spaces
103100
flattened_pd$lag_spaces[token_to_update] <-
104101
flattened_pd$lag_spaces[token_to_update] + shift
105102

@@ -110,6 +107,32 @@ apply_ref_indention_one <- function(flattened_pd, target_token) {
110107
flattened_pd
111108
}
112109

110+
#' Find the tokens to update when applying a reference indention
111+
#'
112+
#' Given a target token and a flattened parse table, the token for which the
113+
#' spacing information needs to be updated are computed. Since indention is
114+
#' already embeded in the column `lag_spaces`, only tokens at the beginning of
115+
#' a line are of concern.
116+
#' @param flattened_pd A flattened parse table.
117+
#' @inheritParams apply_ref_indention_one
118+
#' @seealso apply_ref_indention_one()
119+
#' @examples
120+
#' style_text("function(a =
121+
#' b,
122+
#' dd
123+
#' ) {}", scope = "indention")
124+
#' style_text("function(a,
125+
#' b,
126+
#' dd
127+
#' ) {}", scope = "indention")
128+
find_tokens_to_update <- function(flattened_pd, target_token) {
129+
token_points_to_ref <-
130+
flattened_pd$indention_ref_pos_id == flattened_pd$pos_id[target_token]
131+
first_token_on_line <- flattened_pd$lag_newlines > 0L
132+
which(token_points_to_ref & first_token_on_line)
133+
}
134+
135+
113136
#' Set indention of tokens that match regex
114137
#'
115138
#' Force the level of indention of tokens whose text matches a regular

R/style_guides.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ tidyverse_style <- function(scope = "tokens",
6565
space_manipulators <- if (scope >= "spaces") {
6666
lst(
6767
indent_braces = partial(indent_braces, indent_by = indent_by),
68+
unindent_fun_dec,
6869
indent_op = partial(indent_op, indent_by = indent_by),
6970
indent_eq_sub = partial(indent_eq_sub, indent_by = indent_by),
7071
indent_without_paren = partial(indent_without_paren,

R/transform-files.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ parse_transform_serialize <- function(text, transformers) {
131131
#' hence line breaks must be modified first).
132132
#' * spacing rules (must be after line-breaks and updating newlines and
133133
#' multi-line).
134+
#' * indention.
134135
#' * token manipulation / replacement (is last since adding and removing tokens
135136
#' will invalidate columns token_after and token_before).
136137
#' * Update indention reference (must be after line breaks).

man/apply_transformers.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/find_tokens_to_update.Rd

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/needs_indention.Rd

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/needs_indention_one.Rd

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/unindent_fun_dec.Rd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/update_indention.Rd

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)