-
Notifications
You must be signed in to change notification settings - Fork 1
/
ggformat.R
101 lines (66 loc) · 2.94 KB
/
ggformat.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#' FormatCode
#'
#' Call this function as an addin -- "Reformat ggplot2 code" -- to reformat selected code
#'
#' @export
FormatCode <- function() {
context <- rstudioapi::getActiveDocumentContext()
text <- context$selection[[1]]$text
if(nchar(text) == 0) stop("The selection is empty -- make sure the cursor is in the highlighted selection before running the addin.")
# GENERAL PREP AND CLEAN UP BEFORE SPLITTING LINES
# combine into one string
text <- paste(text, collapse = "")
# remove line breaks and trailing white space
text <- trimws(gsub("\\n", "", text))
# replace double +'s with single +'s
text <- gsub("\\s*\\+\\s*\\+\\s*", " \\+ ", text)
# remove + before split words
splitwords <- c("geom_", "stat_", "coord_", "facet_", "scale_", "xlim\\(",
"ylim\\(", "ggtitle\\(", "labs\\(", "xlab\\(", "ylab\\(",
"annotate\\(", "guides", "theme_", "theme\\(")
split_regex <- paste(splitwords, sep = "", collapse = "|")
text <- gsub(paste("\\+\\s*(", split_regex, ")", sep=""), "\\1", text)
# remove + at the very end
text <- sub("\\s*\\+$", "", text)
# remove spaces after (
text <- gsub("\\(\\s+", "\\(", text)
# remove spaces before )
text <- gsub("\\s+\\)", "\\)", text)
# remove extra spaces after ,
text <- gsub("\\,\\s+", "\\, ", text)
# SPLITS
# split after magrittr or native pipes
text <- unlist(strsplit(text, split = "(?<=%>%)|(?<=\\|>)", perl = TRUE))
# split at ggplot2 functions, keeping delimiters
text <- strsplit(text, split = paste0("(?<=.)(?=", split_regex, ")"), perl = TRUE)
text <- trimws(unlist(text))
# remove blank lines
text <- text[text != ""]
# CREATE DATA FRAME WHICH TO BE USED FOR ORDERING LINES
df <- data.frame(text)
nr <- nrow(df)
# set sort order
orderwords <- c("firstline", "%>%", "\\|>", "ggplot\\(", splitwords)
#writeLines(orderwords, "orderwords.txt") # uncomment, run, and knit Readme.Rmd if orderwords are changed
# manually remove "\\" from "\\|>" until this is fixed
order_regex <- paste(orderwords, sep = "", collapse = "|")
# create a column of tokens for ordering purposes
df$token <- sub(paste(".*(", order_regex, ").*", sep=""), "\\1", text)
# override token for first line (in case it's something like g + that is, no special words)
df$token[1] <- "firstline"
# set factor levels
df$token <- factor(df$token, levels = gsub("\\\\", "", orderwords))
# order by factor level
df <- df[order(df$token),]
# add + to end of lines except last line
df$text[1:(nr-1)] <- paste(df$text[1:(nr-1)], "+")
# remove + after pipes or <- or = (easier than testing first...)
df$text <- sub("%>% \\+", "%>%", df$text)
df$text <- sub("\\|> \\+", "|>", df$text)
df$text <- sub("<- \\+", "<-", df$text)
df$text <- sub("= \\+", "=", df$text)
# indent 2nd line on
df$text[2:nr] <- paste(" ", df$text[2:nr], sep = "")
# replace text
rstudioapi::selectionSet(value = df$text, id = context$id)
}