-
Notifications
You must be signed in to change notification settings - Fork 69
/
findAndReplaceAddin.R
96 lines (77 loc) · 2.41 KB
/
findAndReplaceAddin.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
#' Find and Replace Tokens in a Document
#'
#' Call this as an addin to replace occurrences of a particular sequence of
#' characters in a document with a new sequence of characters.
#'
#' @export
findAndReplaceAddin <- function() {
ui <- miniPage(
includeHighlightJs(),
gadgetTitleBar("Find and Replace"),
miniContentPanel(
h4("Replace the text 'from' with the text 'to'."),
hr(),
stableColumnLayout(
checkboxInput("boundaries", "Use Word Boundaries?", value = TRUE),
uiOutput("changes")
),
stableColumnLayout(
textInput("from", "From:"),
textInput("to", "To:")
),
uiOutput("document", container = rCodeContainer)
)
)
server <- function(input, output, session) {
context <- rstudioapi::getActiveDocumentContext()
original <- context$contents
reactiveRefactor <- reactive({
from <- input$from
to <- input$to
boundaries <- input$boundaries
valid <- nzchar(from) && nzchar(to)
if (valid)
return(performRefactor(original, from, to, boundaries))
else
return(list(refactored = original, changes = 0))
})
output$changes <- renderUI({
spec <- reactiveRefactor()
if (spec$changes == 0)
return(div("No changes to be made."))
instances <- if (spec$changes == 1) "instance" else "instances"
div(paste(spec$changes, instances, "will be replaced."))
})
output$document <- renderCode({
spec <- reactiveRefactor()
highlightCode(session, "document")
paste(spec$refactored, collapse = "\n")
})
observeEvent(input$done, {
spec <- reactiveRefactor()
transformed <- paste(spec$refactored, collapse = "\n")
rstudioapi::setDocumentContents(transformed, id = context$id)
invisible(stopApp())
})
}
viewer <- dialogViewer("Find and Replace", width = 1000, height = 800)
runGadget(ui, server, viewer = viewer)
}
performRefactor <- function(contents, from, to, useWordBoundaries = TRUE) {
reFrom <- if (useWordBoundaries)
paste("\\b", from, "\\b", sep = "")
else
from
reTo <- to
matches <- gregexpr(reFrom, contents, perl = TRUE)
changes <- sum(unlist(lapply(matches, function(x) {
if (x[[1]] == -1) 0 else length(x)
})))
refactored <- unlist(lapply(contents, function(x) {
gsub(reFrom, reTo, x, perl = TRUE)
}))
list(
refactored = refactored,
changes = changes
)
}