Skip to content

Fixing the namespace issue #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 100 additions & 101 deletions R/ggformat.R
Original file line number Diff line number Diff line change
@@ -1,101 +1,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)
}

#' 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(text)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why you took out removing the line breaks? (It may not be necessary to remove them but I haven't fully tested.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apolgize, I responded to another question instead of this about why I did this.

While I was testing on this example out of the readme, I accidentally selected #Before as well, and that put the mtcars variable in the comment, the line breaking did not persist some of the line breaks that already exist.
Since we're unlisting, breaking and putting the strings back together based on the operators in between, this didn't change anything. (atleast in the cases I tested.)

Removing the breaklines solved the issue like a charm, since the line break simply never got removed from the end of the comment.

# BEFORE
mtcars |> group_by(cyl) |> summarize(mean_mpg = mean(mpg)) |> ggplot(aes(factor(cyl),
mean_mpg)) + theme_bw(14) + geom_col() + labs(title = "mtcars", x = "number of cylinders", y = "average miles per gallon")

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds right... I will do a little more testing as soon as I get a chance.


# replace double +'s with single +'s
text <- gsub("\\s*\\+\\s*\\+\\s*", " \\+ ", text)

# remove + before split words
splitwords <- c("\\s\\w*:?:?geom_","stat_", "coord_", "facet_", "scale_", "xlim\\(",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the regex here partially works -- the problem is that the splitwords are also used for the token column later on for the purpose of sorting. We'll need to think about this. A minor issue: \\s shouldn't be there because it's not necessary for there to be a space before a geom.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair, I did make that assumption in most of the code I tested.
Let me try to come up with a different regex to solve this.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will work to keep "geom_" as a split word and add "\w*::geom_" as an additional one. Then in the section where df$token is created, remove \w*:: from the namespaced tokens so that all the tokens will be recognized as factor levels and the sort can be performed correctly.

"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)
}
Loading