├── LICENSE
├── .travis.yml
├── .gitignore
├── NEWS.md
├── .Rbuildignore
├── inst
├── media
│ ├── addin.png
│ └── addins-menu.png
├── rstudio
│ └── addins.dcf
└── gadgets
│ └── addinslist
│ ├── css
│ └── app.css
│ ├── js
│ └── shinyjs-funcs.js
│ └── lib
│ └── sweetalert-1.0.1
│ ├── sweetalert.min.css
│ └── sweetalert.min.js
├── NAMESPACE
├── man
└── addinslistAddin.Rd
├── DESCRIPTION
├── R
├── utils.R
└── addin.R
└── README.md
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2016
2 | COPYRIGHT HOLDER: Dean Attali
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: r
2 | sudo: false
3 | cache: packages
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | *.Rproj
6 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # addinslist 0.2 2016-09-28
2 |
3 | - remove deprecated xml2 function
4 |
--------------------------------------------------------------------------------
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^\.travis\.yml$
4 | ^cran-comments\.md$
--------------------------------------------------------------------------------
/inst/media/addin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nevrome/addinslist/master/inst/media/addin.png
--------------------------------------------------------------------------------
/inst/media/addins-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nevrome/addinslist/master/inst/media/addins-menu.png
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(addinslistAddin)
4 | import(shiny)
5 |
--------------------------------------------------------------------------------
/inst/rstudio/addins.dcf:
--------------------------------------------------------------------------------
1 | Name: Browse RStudio addins
2 | Description: Discover and install useful RStudio addins
3 | Binding: addinslistAddin
4 | Interactive: true
--------------------------------------------------------------------------------
/man/addinslistAddin.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/addin.R
3 | \name{addinslistAddin}
4 | \alias{addinslistAddin}
5 | \title{Addin for browsing and installing RStudio addins}
6 | \usage{
7 | addinslistAddin()
8 | }
9 | \description{
10 | This addin allows you to interactively browse through the list of existing
11 | addins, see which ones you already have installed, and let you
12 | install/uninstall the corresponding package of each addin. This addin can be
13 | invoked from RStudio's "Addins" menu.
14 | }
15 | \examples{
16 | if (interactive()) {
17 | addinslistAddin()
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: addinslist
2 | Title: Discover and Install Useful RStudio Addins
3 | Version: 0.2
4 | Authors@R: person("Dean", "Attali", email = "daattali@gmail.com",
5 | role = c("aut", "cre"))
6 | Description: Browse through a continuously updated list of existing RStudio
7 | addins and install/uninstall their corresponding packages.
8 | URL: https://github.com/daattali/addinslist
9 | BugReports: https://github.com/daattali/addinslist/issues
10 | Depends:
11 | R (>= 3.1.0)
12 | Imports:
13 | curl,
14 | devtools,
15 | DT (>= 0.1),
16 | miniUI (>= 0.1),
17 | shiny (>= 0.13.2),
18 | shinyjs (>= 0.6),
19 | rappdirs (>= 0.3.1),
20 | rmarkdown,
21 | rvest (>= 0.3.1),
22 | utils,
23 | xml2 (>= 0.1.2)
24 | License: MIT + file LICENSE
25 | LazyData: true
26 | RoxygenNote: 5.0.1
27 |
--------------------------------------------------------------------------------
/inst/gadgets/addinslist/css/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #FAFAFA;
3 | }
4 |
5 | #top-section {
6 | background: #fdfdfd;
7 | padding: 5px 15px;
8 | border-bottom: 1px solid #bbb;
9 | }
10 |
11 | #title {
12 | margin-top: 0;
13 | text-align: center;
14 | font-weight: bold;
15 | }
16 |
17 | #addinstable {
18 | padding: 15px;
19 | background: #FAFAFA;
20 | font-size: 16px;
21 | }
22 |
23 | #addinstable table {
24 | border: 1px solid #666;
25 | background: white;
26 | }
27 |
28 | #addinstable .dataTables_info {
29 | font-weight: bold;
30 | padding: 0;
31 | margin-top: 5px;
32 | margin-bottom: 10px;
33 | }
34 |
35 | #addinstable tbody tr.pkgrow {
36 | cursor: pointer;
37 | }
38 |
39 | #addinstable tbody tr.pkgrow:hover,
40 | #addinstable tbody tr.installed {
41 | background: lightgreen;
42 | }
43 |
44 | #addinstable tbody tr.installed:hover {
45 | background: #EE9C90;
46 | }
47 |
48 | #installing-overlay {
49 | position: fixed;
50 | top: 0;
51 | bottom: 0;
52 | left: 0;
53 | right: 0;
54 | background: rgba(0, 0, 0, 0.8);
55 | text-align: center;
56 | z-index: 2;
57 | }
58 |
59 | #installing-msg {
60 | margin-top: 100px;
61 | font-size: 37px;
62 | color: white;
63 | font-weight: bold;
64 | }
65 |
66 | #refresh {
67 | margin-left: 5px;
68 | }
69 |
70 | #last-updated {
71 | position: absolute;
72 | top: 10px;
73 | font-style: italic;
74 | right: 15px;
75 | }
--------------------------------------------------------------------------------
/inst/gadgets/addinslist/js/shinyjs-funcs.js:
--------------------------------------------------------------------------------
1 | shinyjs.init = function() {
2 | // Close the addin when Esc key is pressed
3 | $(document).keyup(function(e) {
4 | if (e.keyCode == 27) {
5 | Shiny.onInputChange('cancel', 1);
6 | }
7 | });
8 |
9 | // When clicking on a row in the table, tell Shiny what package was chosen
10 | $('#addinstable').on('click', 'tbody tr.pkgrow', function(event) {
11 | var target = event.target;
12 | var row;
13 | if (target.nodeName == 'A') { // ignore clicks on links
14 | return;
15 | } else if (target.nodeName == 'TR') {
16 | row = $(target);
17 | } else {
18 | row = $($(target).closest('tr'));
19 | }
20 | var pkgname = row.data('pkgname');
21 | Shiny.onInputChange('rowclick', [pkgname, Math.random()]);
22 | });
23 | };
24 |
25 | // Show a sweetalerts message
26 | shinyjs.swal = function(params) {
27 | var defaultParams = {
28 | title: null,
29 | text: null,
30 | type: null
31 | };
32 | params = shinyjs.getParams(params, defaultParams);
33 | swal(params);
34 | };
35 |
36 | // show a sweetalerts confirmation box (for installing/uninstalling a package)
37 | shinyjs.confirmation = function(params) {
38 | var defaultParams = {
39 | type: null,
40 | package: null
41 | };
42 | params = shinyjs.getParams(params, defaultParams);
43 | if (params.type == 'install') {
44 | params.colour = 'green';
45 | } else {
46 | params.colour = '#DD6B55';
47 | }
48 |
49 | swal({
50 | title: 'Are you sure you want to ' + params.type + ' ' + params.package + '?',
51 | type: 'warning',
52 | showCancelButton: true,
53 | confirmButtonColor: params.colour,
54 | confirmButtonText: 'Yes, ' + params.type + ' away!',
55 | closeOnConfirm: true,
56 | html: true
57 | }, function() {
58 | Shiny.onInputChange(params.type, [params.package, Math.random()]);
59 | });
60 | };
--------------------------------------------------------------------------------
/R/utils.R:
--------------------------------------------------------------------------------
1 | .addinsrepo_globals <- new.env(parent = emptyenv())
2 | .addinsrepo_globals$ttl <- 60*60*24 # Expire list after 24 hours
3 |
4 | # Update the list of addins
5 | update_addins_list <- function(force = FALSE) {
6 | # force means grab the latest list from online even if the existing list is recent
7 | if (force) {
8 | update_addins_file()
9 | update_addins_list_helper()
10 | } else {
11 | if (is.null(.addinsrepo_globals$addins_list)) {
12 | update_addins_list_helper()
13 | } else {
14 | if (is_expired(.addinsrepo_globals$last_refresh)) {
15 | update_addins_list_helper()
16 | } else {
17 | update_addins_installed_field()
18 | }
19 | }
20 | }
21 | }
22 |
23 | # Download a new version of the addins list and store it in a local file
24 | update_addins_file <- function() {
25 | datapath <- get_files_path()
26 | dir.create(datapath, showWarnings = FALSE, recursive = TRUE)
27 | mdfile <- get_md_file()
28 | htmlfile <- get_html_file()
29 | url <- "https://raw.githubusercontent.com/daattali/rstudio-addins/master/README.md"
30 | writeLines("% addinslist", mdfile)
31 | curl::curl_download(url, destfile = mdfile, mode = "ab")
32 | rmarkdown::pandoc_convert(mdfile, to = "html", output = htmlfile,
33 | options = "-s")
34 | }
35 |
36 | # Assuming the addins list file exists, parse the markdown table and
37 | # update the list objects
38 | update_addins_list_helper <- function() {
39 | htmlfile <- get_html_file()
40 | lastrefresh <- file.mtime(htmlfile)
41 | .addinsrepo_globals$last_refresh <- lastrefresh
42 |
43 | html <- xml2::read_html(htmlfile)
44 | headerNames <- xml2::xml_text(xml2::xml_find_all(html, "//thead//th"))
45 |
46 | cranColumnId <- which(grepl("cran", headerNames, ignore.case = TRUE))
47 | packageColumnId <- which(grepl("package", headerNames, ignore.case = TRUE))
48 | .addinsrepo_globals$headerNames <- headerNames
49 | .addinsrepo_globals$cranColumnId <- cranColumnId
50 | .addinsrepo_globals$packageColumnId <- packageColumnId
51 |
52 | rows <- xml2::xml_find_all(html, "//tbody/tr")
53 |
54 | cells <- lapply(rows, function(x){ rvest::html_nodes(x, xpath = ".//td|.//th") })
55 |
56 | installed_pkgs <- rownames(utils::installed.packages(noCache = TRUE))
57 | out <- matrix(NA_character_, nrow = length(rows), ncol = length(headerNames) + 3)
58 | colnames(out) <- c(headerNames, "internal_pkgname", "internal_github_repo",
59 | "internal_installed")
60 | for (i in seq_len(length(rows))) {
61 | row <- cells[[i]]
62 | values <- lapply(row, function(x) {
63 | paste(as.character(xml2::xml_contents(x)), collapse = " ")
64 | })
65 | values <- unlist(values)
66 |
67 | if (values[cranColumnId] == ":x:") {
68 | oncran <- FALSE
69 | } else if (values[cranColumnId] == ":white_check_mark:") {
70 | oncran <- TRUE
71 | } else {
72 | stop("catch this error so that other rows still work!")
73 | }
74 | values[cranColumnId] <- oncran
75 | pkg <- xml2::xml_text(row[[packageColumnId]])
76 | pkg_url <- xml2::xml_attr(xml2::xml_find_first(row[[packageColumnId]], "a"), "href")
77 | github <- gsub("(.*)(github.com/)([^/]+)/([^/@#]+)(.*)", "\\3/\\4", pkg_url )
78 | is_installed <- pkg %in% installed_pkgs
79 |
80 | values <- c(values, pkg, github, is_installed)
81 | out[i, ] <- values
82 | }
83 | out <- as.data.frame(out, stringsAsFactors = FALSE)
84 | out$internal_installed <- as.logical(out$internal_installed)
85 |
86 | .addinsrepo_globals$addins_list <- out
87 |
88 | packageNameColumnId <- which(colnames(out) == "internal_pkgname")
89 | .addinsrepo_globals$packageNameColumnId <- packageNameColumnId
90 | }
91 |
92 | # When the list objects already exist, sometimes we just need to update
93 | # whether or not each package is installed on our system
94 | update_addins_installed_field <- function() {
95 | installed_pkgs <- rownames(utils::installed.packages(noCache = TRUE))
96 | .addinsrepo_globals$addins_list$internal_installed <-
97 | .addinsrepo_globals$addins_list$internal_pkgname %in% installed_pkgs
98 | }
99 |
100 | # Return TRUE if a new addins list needs to be downloaded
101 | is_addins_file_outdated <- function() {
102 | htmlfile <- get_html_file()
103 |
104 | if (!file.exists(htmlfile)) {
105 | return(TRUE)
106 | }
107 |
108 | lastrefresh <- file.mtime(htmlfile)
109 | return(is_expired(lastrefresh))
110 | }
111 |
112 | # Check if a time stamp is expired
113 | is_expired <- function(time) {
114 | as.numeric(Sys.time() - time, units = "secs") > .addinsrepo_globals$ttl
115 | }
116 |
117 | get_files_path <- function() {
118 | rappdirs::user_data_dir("addinsrepo", "daattali")
119 | }
120 |
121 | get_html_file <- function() {
122 | datapath <- get_files_path()
123 | htmlfile <- file.path(datapath, "addins.html")
124 | htmlfile
125 | }
126 |
127 | get_md_file <- function() {
128 | datapath <- get_files_path()
129 | mdfile <- file.path(datapath, "addins.md")
130 | mdfile
131 | }
132 |
--------------------------------------------------------------------------------
/R/addin.R:
--------------------------------------------------------------------------------
1 | #' Addin for browsing and installing RStudio addins
2 | #'
3 | #' This addin allows you to interactively browse through the list of existing
4 | #' addins, see which ones you already have installed, and let you
5 | #' install/uninstall the corresponding package of each addin. This addin can be
6 | #' invoked from RStudio's "Addins" menu.
7 | #' @export
8 | #' @examples
9 | #' if (interactive()) {
10 | #' addinslistAddin()
11 | #' }
12 | #' @import shiny
13 | addinslistAddin <- function() {
14 | resourcePath <- system.file("gadgets", "addinslist", package = "addinslist")
15 | system.file("lib", "sweetalert-1.0.1", package = "addinslist")
16 | addResourcePath("addinslistres", resourcePath)
17 |
18 | ui <- miniUI::miniPage(
19 | shinyjs::useShinyjs(),
20 | shinyjs::extendShinyjs(
21 | script = file.path(resourcePath, "js", "shinyjs-funcs.js"),
22 | functions = c("swal", "confirmation")
23 | ),
24 | tags$head(
25 | includeScript(file.path(resourcePath, "lib", "sweetalert-1.0.1", "sweetalert.min.js")),
26 | includeCSS(file.path(resourcePath, "lib", "sweetalert-1.0.1", "sweetalert.min.css")),
27 | includeCSS(file.path(resourcePath, "css", "app.css"))
28 | ),
29 | miniUI::miniContentPanel(
30 | padding = 0,
31 | shinyjs::hidden(
32 | div(
33 | id = "installing-overlay",
34 | div(id = "installing-msg",
35 | span(id = "overlay-text"),
36 | icon("spinner", class="fa-spin"))
37 | )
38 | ),
39 | div(
40 | id = "top-section",
41 | h2(id = "title", "RStudio addins"),
42 | div(id = "last-updated",
43 | span("Last updated ",
44 | textOutput("updated_time", inline = TRUE)),
45 | actionLink("refresh", label = "", icon = icon("refresh"), title = "Refresh")
46 | ),
47 | checkboxInput(
48 | "confirmation",
49 | "Ask for confirmation before installing or uninstalling a package",
50 | TRUE,
51 | width = "auto"
52 | ),
53 | selectInput("download_from", NULL,
54 | c("Download from CRAN when possible" = "cran",
55 | "Always download from GitHub" = "github"))
56 | ),
57 | div(style = "display: none;", icon("check")),
58 | DT::dataTableOutput("addinstable")
59 | )
60 | )
61 |
62 | server <- function(input, output, session) {
63 |
64 | # values used throughout the app
65 | values <- reactiveValues(addins_data = NULL, last_refresh = NULL,
66 | install_pkg = NULL, uninstall_pkg = NULL)
67 |
68 | # Function to update the addins list and the corresponding reactive values
69 | update_addins_list_values <- function(...) {
70 | update_addins_list(...)
71 | values$addins_data <- .addinsrepo_globals$addins_list
72 | values$last_refresh <- .addinsrepo_globals$last_refresh
73 | }
74 |
75 | # Function to refresh the addins list and show the user a loading message
76 | refresh_list <- function() {
77 | shinyjs::show("installing-overlay")
78 | shinyjs::html("overlay-text", "Refreshing addins list...")
79 | update_addins_list_values(force = TRUE)
80 | shinyjs::hide("installing-overlay")
81 | }
82 |
83 | # When the app starts, ensure the data is up-to-date
84 | if (is_addins_file_outdated()) {
85 | refresh_list()
86 | } else {
87 | update_addins_list_values()
88 | }
89 |
90 |
91 | # Show when the list was last updated
92 | output$updated_time <- renderText({
93 | if (!is.null(values$last_refresh)) {
94 | paste(
95 | round(Sys.time() - values$last_refresh),
96 | units(Sys.time() - values$last_refresh),
97 | "ago"
98 | )
99 | }
100 | })
101 |
102 | # User wants to refresh the list of addins
103 | observeEvent(input$refresh, {
104 | refresh_list()
105 | })
106 |
107 | # JS sent a message to Shiny to install/uninstall a package (after user confirm)
108 | observeEvent(input$install, {
109 | values$install_pkg <- input$install[1]
110 | })
111 | observeEvent(input$uninstall, {
112 | values$uninstall_pkg <- input$uninstall[1]
113 | })
114 |
115 | # Install/uninstall a package
116 | observeEvent(values$install_pkg, {
117 | shinyjs::show("installing-overlay")
118 | shinyjs::html("overlay-text", paste0("Installing ", values$install_pkg, "..."))
119 |
120 | # Figure out which package to install and attempt to install it
121 | idx <- which(values$addins_data$internal_pkgname == values$install_pkg)[1]
122 | tryCatch({
123 | if(values$addins_data[idx, .addinsrepo_globals$cranColumnId] == TRUE && (input$download_from == "cran")) {
124 | utils::install.packages(values$install_pkg)
125 | } else {
126 | devtools::install_github(values$addins_data$internal_github_repo[idx])
127 | }
128 | }, error = function(err) {
129 | shinyjs::js$swal(title = "Error", text = err$message, type = "error")
130 | })
131 |
132 | shinyjs::hide("installing-overlay")
133 | values$install_pkg <- NULL
134 | update_addins_list_values()
135 | })
136 | observeEvent(values$uninstall_pkg, {
137 | shinyjs::show("installing-overlay")
138 | shinyjs::html("overlay-text", paste0("Uninstalling ", values$uninstall_pkg, "..."))
139 |
140 | # Figure out which package to uninstall and do it
141 | idx <- which(values$addins_data$internal_pkgname == values$uninstall_pkg)[1]
142 | utils::remove.packages(values$addins_data[idx, 'internal_pkgname'])
143 |
144 | values$uninstall_pkg <- NULL
145 | shinyjs::hide("installing-overlay")
146 | update_addins_list_values()
147 | })
148 |
149 | # User clicked on a row in the table; need to install/uninstall based on selection
150 | observeEvent(input$rowclick, {
151 | pkg <- input$rowclick[1]
152 | if (pkg == "shinyjs") {
153 | shinyjs::js$swal(title = "", text = "Cannot uninstall shinyjs, it is required for the current app to work",
154 | type = "info")
155 | return()
156 | }
157 | if (pkg == "addinslist") {
158 | shinyjs::js$swal(title = "", text = "Cannot uninstall addinslist, it is required for the current app to work",
159 | type = "info")
160 | return()
161 | }
162 |
163 | # Figure out which package was selected and ask for confirmation/do it
164 | idx <- which(values$addins_data$internal_pkgname == pkg)[1]
165 | if (input$confirmation) {
166 | if (!values$addins_data[idx, 'internal_installed']) {
167 | shinyjs::js$confirmation("install", pkg)
168 | } else {
169 | shinyjs::js$confirmation("uninstall", pkg)
170 | }
171 | } else {
172 | if (!values$addins_data[idx, 'internal_installed']) {
173 | values$install_pkg <- pkg
174 | } else {
175 | values$uninstall_pkg <- pkg
176 | }
177 | }
178 | })
179 |
180 | # Render the table
181 | output$addinstable <- DT::renderDataTable({
182 | DT::datatable(
183 | values$addins_data,
184 | escape = FALSE,
185 | rownames = FALSE,
186 | selection = "none",
187 | class = 'stripe',
188 | options = list(
189 | dom = "iftlp",
190 | language = list(
191 | zeroRecords = "No addins found",
192 | info = "_TOTAL_ addins found",
193 | infoFiltered = "",
194 | infoPostFix = " (click any row to install/uninstall the addin's package)",
195 | infoEmpty = "No addins found",
196 | search = "",
197 | searchPlaceholder = "Search..."
198 | ),
199 | columnDefs = list(
200 | list(
201 | # show a checkmark or an X in the column for "is on CRAN?"
202 | targets = .addinsrepo_globals$cranColumnId - 1,
203 | render = DT::JS(
204 | "function(data, type, row, meta) {",
205 | "return data === 'TRUE' ?",
206 | "'' : ",
207 | "'';",
208 | "}")
209 | ),
210 | list(
211 | # don't show the internal variables
212 | targets = seq(length(.addinsrepo_globals$headerNames),
213 | ncol(values$addins_data) - 1),
214 | visible = FALSE
215 | )
216 | ),
217 | searching = TRUE,
218 | paging = FALSE,
219 | rowCallback = DT::JS(
220 | # add the package name and whether or not it's installed to every row
221 | "function(row, data) {
222 | $(row).addClass('pkgrow');
223 | var pkgname = data[", .addinsrepo_globals$packageNameColumnId - 1 ,"];
224 | $(row).attr('data-pkgname', pkgname);
225 | var isinstalled = data[", ncol(values$addins_data) - 1, "].toString().trim().toLowerCase();
226 | if (isinstalled == 'true') {
227 | $(row).addClass('installed');
228 | }
229 | }")
230 | )
231 | )
232 | })
233 | }
234 |
235 | # Run the addin
236 | app <- shinyApp(ui = ui, server = server)
237 | viewer <- dialogViewer("Discover and install useful RStudio addins", width = 1200, height = 900)
238 | runGadget(app, viewer = viewer, stopOnCancel = TRUE)
239 | }
--------------------------------------------------------------------------------
/inst/gadgets/addinslist/lib/sweetalert-1.0.1/sweetalert.min.css:
--------------------------------------------------------------------------------
1 | body.stop-scrolling{height:100%;overflow:hidden}.sweet-overlay{background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";background-color:rgba(0,0,0,.4);position:fixed;left:0;right:0;top:0;bottom:0;display:none;z-index:10000}.sweet-alert{background-color:#fff;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;width:478px;padding:17px;border-radius:5px;text-align:center;position:fixed;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;display:none;z-index:99999}@media all and (max-width:540px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px}}.sweet-alert h2{color:#575757;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:25px 0;padding:0;line-height:40px;display:block}.sweet-alert p{color:#797979;font-size:16px;font-weight:300;position:relative;text-align:inherit;float:none;margin:0;padding:0;line-height:normal}.sweet-alert fieldset{border:none;position:relative}.sweet-alert .sa-error-container{background-color:#f1f1f1;margin-left:-17px;margin-right:-17px;overflow:hidden;padding:0 10px;max-height:0;webkit-transition:padding .15s,max-height .15s;transition:padding .15s,max-height .15s}.sweet-alert .sa-error-container.show{padding:10px 0;max-height:100px;webkit-transition:padding .2s,max-height .2s;transition:padding .25s,max-height .25s}.sweet-alert .sa-error-container .icon{display:inline-block;width:24px;height:24px;border-radius:50%;background-color:#ea7d7d;color:#fff;line-height:24px;text-align:center;margin-right:3px}.sweet-alert .sa-error-container p{display:inline-block}.sweet-alert .sa-input-error{position:absolute;top:29px;right:26px;width:20px;height:20px;opacity:0;-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transition:all .1s;transition:all .1s}.sweet-alert .sa-input-error::after,.sweet-alert .sa-input-error::before{content:"";width:20px;height:6px;background-color:#f06e57;border-radius:3px;position:absolute;top:50%;margin-top:-4px;left:50%;margin-left:-9px}.sweet-alert .sa-input-error::before{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .sa-input-error::after{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .sa-input-error.show{opacity:1;-webkit-transform:scale(1);transform:scale(1)}.sweet-alert input{width:100%;box-sizing:border-box;border-radius:3px;border:1px solid #d7d7d7;height:43px;margin-top:10px;margin-bottom:17px;font-size:18px;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);padding:0 12px;display:none;-webkit-transition:all .3s;transition:all .3s}.sweet-alert input:focus{outline:0;box-shadow:0 0 3px #c4e6f5;border:1px solid #b4dbed}.sweet-alert input:focus::-moz-placeholder{transition:opacity .3s .03s ease;opacity:.5}.sweet-alert input:focus:-ms-input-placeholder{transition:opacity .3s .03s ease;opacity:.5}.sweet-alert input:focus::-webkit-input-placeholder{transition:opacity .3s .03s ease;opacity:.5}.sweet-alert input::-moz-placeholder{color:#bdbdbd}.sweet-alert input:-ms-input-placeholder{color:#bdbdbd}.sweet-alert input::-webkit-input-placeholder{color:#bdbdbd}.sweet-alert.show-input input{display:block}.sweet-alert button{background-color:#AEDEF4;color:#fff;border:none;box-shadow:none;font-size:17px;font-weight:500;-webkit-border-radius:4px;border-radius:5px;padding:10px 32px;margin:26px 5px 0;cursor:pointer}.sweet-alert button:focus{outline:0;box-shadow:0 0 2px rgba(128,179,235,.5),inset 0 0 0 1px rgba(0,0,0,.05)}.sweet-alert button:hover{background-color:#a1d9f2}.sweet-alert button:active{background-color:#81ccee}.sweet-alert button.cancel{background-color:#D0D0D0}.sweet-alert button.cancel:hover{background-color:#c8c8c8}.sweet-alert button.cancel:active{background-color:#b6b6b6}.sweet-alert button.cancel:focus{box-shadow:rgba(197,205,211,.8) 0 0 2px,rgba(0,0,0,.0470588) 0 0 0 1px inset!important}.sweet-alert button::-moz-focus-inner{border:0}.sweet-alert[data-has-cancel-button=false] button{box-shadow:none!important}.sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false]{padding-bottom:40px}.sweet-alert .sa-icon{width:80px;height:80px;border:4px solid gray;-webkit-border-radius:40px;border-radius:50%;margin:20px auto;padding:0;position:relative;box-sizing:content-box}.sweet-alert .sa-icon.sa-error{border-color:#F27474}.sweet-alert .sa-icon.sa-error .sa-x-mark{position:relative;display:block}.sweet-alert .sa-icon.sa-error .sa-line{position:absolute;height:5px;width:47px;background-color:#F27474;display:block;top:37px;border-radius:2px}.sweet-alert .sa-icon.sa-error .sa-line.sa-left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.sweet-alert .sa-icon.sa-error .sa-line.sa-right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.sweet-alert .sa-icon.sa-warning{border-color:#F8BB86}.sweet-alert .sa-icon.sa-warning .sa-body{position:absolute;width:5px;height:47px;left:50%;top:10px;-webkit-border-radius:2px;border-radius:2px;margin-left:-2px;background-color:#F8BB86}.sweet-alert .sa-icon.sa-warning .sa-dot{position:absolute;width:7px;height:7px;-webkit-border-radius:50%;border-radius:50%;margin-left:-3px;left:50%;bottom:10px;background-color:#F8BB86}.sweet-alert .sa-icon.sa-info{border-color:#C9DAE1}.sweet-alert .sa-icon.sa-info::before{content:"";position:absolute;width:5px;height:29px;left:50%;bottom:17px;border-radius:2px;margin-left:-2px;background-color:#C9DAE1}.sweet-alert .sa-icon.sa-info::after{content:"";position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px;background-color:#C9DAE1}.sweet-alert .sa-icon.sa-success{border-color:#A5DC86}.sweet-alert .sa-icon.sa-success::after,.sweet-alert .sa-icon.sa-success::before{content:'';position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .sa-icon.sa-success::before{-webkit-border-radius:120px 0 0 120px;border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.sweet-alert .sa-icon.sa-success::after{-webkit-border-radius:0 120px 120px 0;border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.sweet-alert .sa-icon.sa-success .sa-placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);-webkit-border-radius:40px;border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.sweet-alert .sa-icon.sa-success .sa-fix{width:5px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .sa-icon.sa-success .sa-line{height:5px;background-color:#A5DC86;display:block;border-radius:2px;position:absolute;z-index:2}.sweet-alert .sa-icon.sa-success .sa-line.sa-tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .sa-icon.sa-success .sa-line.sa-long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .sa-icon.sa-custom{background-size:contain;border-radius:0;border:none;background-position:center center;background-repeat:no-repeat}@-webkit-keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}45%{transform:scale(1.05);-webkit-transform:scale(1.05)}80%{transform:scale(.95);-webkit-transform:scale(.95)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}45%{transform:scale(1.05);-webkit-transform:scale(1.05)}80%{transform:scale(.95);-webkit-transform:scale(.95)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@-webkit-keyframes slideFromTop{0%{top:0}100%{top:50%}}@keyframes slideFromTop{0%{top:0}100%{top:50%}}@-webkit-keyframes slideToTop{0%{top:50%}100%{top:0}}@keyframes slideToTop{0%{top:50%}100%{top:0}}@-webkit-keyframes slideFromBottom{0%{top:70%}100%{top:50%}}@keyframes slideFromBottom{0%{top:70%}100%{top:50%}}@-webkit-keyframes slideToBottom{0%{top:50%}100%{top:70%}}@keyframes slideToBottom{0%{top:50%}100%{top:70%}}.showSweetAlert[data-animation=pop]{-webkit-animation:showSweetAlert .3s;animation:showSweetAlert .3s}.showSweetAlert[data-animation=none]{-webkit-animation:none;animation:none}.showSweetAlert[data-animation=slide-from-top]{-webkit-animation:slideFromTop .3s;animation:slideFromTop .3s}.showSweetAlert[data-animation=slide-from-bottom]{-webkit-animation:slideFromBottom .3s;animation:slideFromBottom .3s}.hideSweetAlert[data-animation=pop]{-webkit-animation:hideSweetAlert .2s;animation:hideSweetAlert .2s}.hideSweetAlert[data-animation=none]{-webkit-animation:none;animation:none}.hideSweetAlert[data-animation=slide-from-top]{-webkit-animation:slideToTop .4s;animation:slideToTop .4s}.hideSweetAlert[data-animation=slide-from-bottom]{-webkit-animation:slideToBottom .3s;animation:slideToBottom .3s}@-webkit-keyframes animateSuccessTip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@keyframes animateSuccessTip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@-webkit-keyframes animateSuccessLong{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@keyframes animateSuccessLong{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@-webkit-keyframes rotatePlaceholder{0%,5%{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}100%,12%{transform:rotate(-405deg);-webkit-transform:rotate(-405deg)}}@keyframes rotatePlaceholder{0%,5%{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}100%,12%{transform:rotate(-405deg);-webkit-transform:rotate(-405deg)}}.animateSuccessTip{-webkit-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.animateSuccessLong{-webkit-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}.sa-icon.sa-success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}@-webkit-keyframes animateErrorIcon{0%{transform:rotateX(100deg);-webkit-transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);-webkit-transform:rotateX(0deg);opacity:1}}@keyframes animateErrorIcon{0%{transform:rotateX(100deg);-webkit-transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);-webkit-transform:rotateX(0deg);opacity:1}}.animateErrorIcon{-webkit-animation:animateErrorIcon .5s;animation:animateErrorIcon .5s}@-webkit-keyframes animateXMark{0%,50%{transform:scale(.4);-webkit-transform:scale(.4);margin-top:26px;opacity:0}80%{transform:scale(1.15);-webkit-transform:scale(1.15);margin-top:-6px}100%{transform:scale(1);-webkit-transform:scale(1);margin-top:0;opacity:1}}@keyframes animateXMark{0%,50%{transform:scale(.4);-webkit-transform:scale(.4);margin-top:26px;opacity:0}80%{transform:scale(1.15);-webkit-transform:scale(1.15);margin-top:-6px}100%{transform:scale(1);-webkit-transform:scale(1);margin-top:0;opacity:1}}.animateXMark{-webkit-animation:animateXMark .5s;animation:animateXMark .5s}@-webkit-keyframes pulseWarning{0%{border-color:#F8D486}100%{border-color:#F8BB86}}@keyframes pulseWarning{0%{border-color:#F8D486}100%{border-color:#F8BB86}}.pulseWarning{-webkit-animation:pulseWarning .75s infinite alternate;animation:pulseWarning .75s infinite alternate}@-webkit-keyframes pulseWarningIns{0%{background-color:#F8D486}100%{background-color:#F8BB86}}@keyframes pulseWarningIns{0%{background-color:#F8D486}100%{background-color:#F8BB86}}.pulseWarningIns{-webkit-animation:pulseWarningIns .75s infinite alternate;animation:pulseWarningIns .75s infinite alternate}
--------------------------------------------------------------------------------
/inst/gadgets/addinslist/lib/sweetalert-1.0.1/sweetalert.min.js:
--------------------------------------------------------------------------------
1 | !function(e,t,n){"use strict";!function o(e,t,n){function a(s,l){if(!t[s]){if(!e[s]){var i="function"==typeof require&&require;if(!l&&i)return i(s,!0);if(r)return r(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=t[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return a(n?n:t)},c,c.exports,o,e,t,n)}return t[s].exports}for(var r="function"==typeof require&&require,s=0;s=0;)n=n.replace(" "+t+" "," ");e.className=n.replace(/^\s+|\s+$/g,"")}},i=function(e){var n=t.createElement("div");return n.appendChild(t.createTextNode(e)),n.innerHTML},u=function(e){e.style.opacity="",e.style.display="block"},c=function(e){if(e&&!e.length)return u(e);for(var t=0;t0?setTimeout(o,t):e.style.display="none"});o()},h=function(n){if("function"==typeof MouseEvent){var o=new MouseEvent("click",{view:e,bubbles:!1,cancelable:!0});n.dispatchEvent(o)}else if(t.createEvent){var a=t.createEvent("MouseEvents");a.initEvent("click",!1,!1),n.dispatchEvent(a)}else t.createEventObject?n.fireEvent("onclick"):"function"==typeof n.onclick&&n.onclick()},g=function(t){"function"==typeof t.stopPropagation?(t.stopPropagation(),t.preventDefault()):e.event&&e.event.hasOwnProperty("cancelBubble")&&(e.event.cancelBubble=!0)};a.hasClass=r,a.addClass=s,a.removeClass=l,a.escapeHtml=i,a._show=u,a.show=c,a._hide=d,a.hide=f,a.isDescendant=p,a.getTopMargin=m,a.fadeIn=v,a.fadeOut=y,a.fireClick=h,a.stopEventPropagation=g},{}],5:[function(t,o,a){Object.defineProperty(a,"__esModule",{value:!0});var r=t("./handle-dom"),s=t("./handle-swal-dom"),l=function(t,o,a){var l=t||e.event,i=l.keyCode||l.which,u=a.querySelector("button.confirm"),c=a.querySelector("button.cancel"),d=a.querySelectorAll("button[tabindex]");if(-1!==[9,13,32,27].indexOf(i)){for(var f=l.target||l.srcElement,p=-1,m=0;m"),i.innerHTML=e.html?e.text:s.escapeHtml(e.text||"").split("\n").join("
"),e.text&&s.show(i),e.customClass)s.addClass(t,e.customClass),t.setAttribute("data-custom-class",e.customClass);else{var d=t.getAttribute("data-custom-class");s.removeClass(t,d),t.setAttribute("data-custom-class","")}if(s.hide(t.querySelectorAll(".sa-icon")),e.type&&!a.isIE8()){var f=function(){for(var o=!1,a=0;ao;o++)n=parseInt(e.substr(2*o,2),16),n=Math.round(Math.min(Math.max(0,n+n*t),255)).toString(16),a+=("00"+n).substr(n.length);return a};o.extend=a,o.hexToRgb=r,o.isIE8=s,o.logStr=l,o.colorLuminance=i},{}]},{},[1]),"function"==typeof define&&define.amd?define(function(){return sweetAlert}):"undefined"!=typeof module&&module.exports&&(module.exports=sweetAlert)}(window,document);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Discover and install useful RStudio addins
2 |
3 | [](https://travis-ci.org/daattali/addinslist)
5 | [](https://cran.r-project.org/package=addinslist)
7 | [](https://saythanks.io/to/daattali)
8 |
9 | > *Copyright 2016 [Dean Attali](http://deanattali.com). Licensed under the MIT license.*
10 |
11 | [RStudio addins](https://rstudio.github.io/rstudioaddins/) were released in early 2016 to provide anyone with the ability to add "extensions" to RStudio. This feature has quickly become popular, but discoverability was a problem: **there's just no easy way to know what addins exist.**
12 |
13 | The `addinslist` package solves that problem in two ways:
14 |
15 | - This package provides a continuously updated list of RStudio addins that you can browse through ([below](#addinslist-table)).
16 |
17 | - After installing this package (`install.packages('addinslist')`), your RStudio will get populated with a new addin called "Browse RStudio addins". This addin allows you to interactively browse through the list of addins, see which ones you already have installed, and let you install/uninstall the corresponding package of each addin. The following image shows how to access this "addin of addins" in RStudio.
18 |
19 | 
20 |
21 | List of addins
22 |
23 | If you made a useful RStudio addin, feel free to make a pull request [on GitHub](https://github.com/daattali/addinslist#readme) to add it to the list.
24 |
25 | | Name | Date Added | Description | Package | On CRAN? | Author | More links | Notes |
26 | |------|------|------|------|------|------|------|------|
27 | | Add Crossref Citations | 2016-07-25 | Add a new bibliography entry through Crossref DOI | [rcrossref](https://github.com/ropensci/rcrossref) | :white_check_mark: | [Hao Zhu](https://github.com/haozhu233) |[Screenshoot](https://pbs.twimg.com/media/CoOo82NUEAAxHUF.jpg:large) | |
28 | | Add GIFs | 2016-08-10 | Search GIFs through Giphy API and use them in Rmarkdown documents | [giphyr](https://github.com/haozhu233/giphyr) | :white_check_mark: | [Hao Zhu](https://github.com/haozhu233) | [Screenshot](https://raw.githubusercontent.com/haozhu233/giphyr/master/img/Screenshot.png) | |
29 | | Addin Manager | 2016-04-01 | Install and remove addins | [addinmanager](https://github.com/csgillespie/addinmanager) | :x: | Colin Gillespie | [Blog post](https://csgillespie.wordpress.com/2016/04/01/rstudio-addins-manager/) | |
30 | | addinit | 2018-06-06 | Initialize an 'RStudio' Project | [addinit](https://github.com/dreamRs/addinit) | :x: | [dreamRs](https://github.com/dreamRs) | | |
31 | | Align Assign | 2016-10-03 | Align the assignment operators within a highlighted area | [AlignAssign](https://github.com/seasmith/AlignAssign) | :x: | [Luke Smith](https://github.com/seasmith) | [Demo gif](https://raw.githubusercontent.com/seasmith/AlignAssign/master/inst/media/demo.gif) | |
32 | | ARIMA Picker | 2016-04-25 | Interactively pick ARIMA parameters | [arimaUI](https://github.com/YvesCR/arimaUI) | :x: | [Yves crutain](https://github.com/YvesCR) | [Blog post](http://data-laborer.eu/statistic/ARIMA_Picker) | |
33 | | Assign default values | 2016-03-30 | Set function arguments in selection to their default values | [jadd](https://github.com/jennybc/jadd) | :x: | [Jenny Bryan](https://github.com/jennybc) | [Demo GIF](https://raw.githubusercontent.com/jennybc/jadd/master/internal/assign_defaults.gif) | |
34 | | assignparams | 2016-06-29 | Evaluate function parameter in global environment | [assignparams](https://github.com/petermeissner/assignparams) | :x: | [Peter Meissner](https://github.com/petermeissner) | [DemoVideo](https://raw.githubusercontent.com/petermeissner/assignparams/master/extra/assign_params.gif) | |
35 | | beautifyR | 2018-04-21 | Format RMarkdown tables beautifully | [beautifyR](https://github.com/mwip/beautifyR) | :x: | [Matthias Weigand](https://github.com/mwip/) | [Demo GIF](https://github.com/mwip/beautifyR#beautifyr-in-action) | |
36 | | Browse RStudio addins | 2016-03-30 | Browse and install RStudio addins | [addinslist](https://github.com/daattali/addinslist) | :white_check_mark: | [Dean Attali](http://deanattali.com/) | [Screenshot](https://raw.githubusercontent.com/daattali/addinslist/master/inst/media/addin.png) | |
37 | | Case converter | 2018-09-20 | Convert text cases to lower, upper, snake, camel cases | [caseconverter](https://github.com/strboul/caseconverter) | :x: | [strboul](https://github.com/strboul) | [Demo GIF](https://raw.githubusercontent.com/strboul/caseconverter/master/inst/media/caseconverter.gif) | |
38 | | Colour picker | 2016-03-30 | Lets you easily select colours | [colourpicker](https://github.com/daattali/colourpicker) | :white_check_mark: | [Dean Attali](http://deanattali.com/) | [Screenshot](https://raw.githubusercontent.com/daattali/colourpicker/master/inst/img/colourpickerscrnshot.png), [Demo video](https://raw.githubusercontent.com/daattali/colourpicker/master/inst/img/colourPickerGadget.gif) | |
39 | | compareAreas | 2018-11-26 | Compare areas across square meters, kilometers, feet, miles, and acres | [compareAreas](https://github.com/daranzolin/compareAreas) | :x: | [David Ranzolin](https://daranzolin.github.io/) | | |
40 | | Convert slash | 2016-05-10 | Reverse slashes (eg in file paths) | [snippetsaddin](https://github.com/sfr/RStudio-Addin-Snippets) | :x: | [Juraj Sofranko](https://github.com/sfr) | | Clipboard is Windows only |
41 | | Convert Variable type | 2016-08-05 | Convert variables' type into either factor, character or numeric in a data frame | [commonUtilAddins](https://github.com/sarupurisailalith/commonUtilAddins) | :x: | [sarupurisailalith](https://github.com/sarupurisailalith) | | |
42 | | Copy Frame to Clipboard | 2016-03-30 | Copy a `data.frame` to the clipboard | [copydat](https://github.com/BAAQMD/copydat) | :x: | [Bay Area Air Quality Management District](https://github.com/BAAQMD) | | Doesn't work on Windows |
43 | | Copy value | 2016-05-10 | Copy data to clipboard (arrays, data frames, matrices, tables, vectors) | [snippetsaddin](https://github.com/sfr/RStudio-Addin-Snippets) | :x: | [Juraj Sofranko](https://github.com/sfr) | | Windows only |
44 | | CRANsearcher | 2017-09-17 | RStudio addin to search CRAN packages titles and descriptions | [CRANsearcher](https://github.com/RhoInc/CRANsearcher) | :white_check_mark: | [Rho Inc](https://github.com/RhoInc) | | |
45 | | datapasta | 2016-09-28 |Keyboard shortcuts for pasting clipboard data as nicely formatted R vectors/tibbles. | [datapasta](https://github.com/MilesMcBain/datapasta) | :white_check_mark: | [Miles McBain](https://github.com/milesmcbain) | [Demo Gif](https://raw.githubusercontent.com/milesmcbain/datapasta/master/inst/media/tribble_paste.gif) | |
46 | | datasets.load | 2016-12-15 | Loading datasets from all installed packages | [datasets.load](https://github.com/bquast/datasets.load) | :white_check_mark: | [Bastiaan Quast](http://qua.st/) | [Demo Video](https://www.youtube.com/watch?v=dl_bYlDLydI) | |
47 | | Document This | 2016-03-30 | Auto-generate Roxygen skeletons for functions and data | [docthis](https://github.com/mdlincoln/docthis) | :x: | [Matthew Lincoln](http://matthewlincoln.net/) | | |
48 | | Enhanced View | 2018-07-12 | Enhanced data viewer, allows column selection and filtering | [viewenhance](https://github.com/kieranjmartin/viewenhance) | :x: | [Kieran Martin](https://github.com/kieranjmartin) | | |
49 | | ermoji | 2018-04-24 | Search and Copy Emoji | [ermoji](https://github.com/gadenbuie/ermoji) | :x: | [Garrick Aden-Buie](https://www.garrickadenbuie.com) | [Screenshots](https://github.com/gadenbuie/ermoji/#usage) | |
50 | | Escape strings | 2018-09-17 | Convert non-ASCII strings to a portable format | [uniscape](https://github.com/mvkorpel/uniscape) | :x: | [Mikko Korpela](https://github.com/mvkorpel) | [Screenshot](https://raw.githubusercontent.com/mvkorpel/uniscape/master/media/escape_strings.png) | |
51 | | esquisse | 2018-06-06 | Make plots with ggplot2 | [esquisse](https://github.com/dreamRs/esquisse) | :white_check_mark: | [dreamRs](https://github.com/dreamRs) | | |
52 | | extraInserts | 2017-12-26 | Insert various (pipe) operators | [extraInserts](https://github.com/konradedgar/extraInserts) | :x: | [Konrad Zdeb](https://github.com/konradedgar) | | |
53 | | get_fn_args | 2018-07-12 | Reads highlighted default values into console, translating commas to semi colons | [getfunctionargs](https://github.com/kieranjmartin/getfunctionargs) | :x: | [Kieran Martin](https://github.com/kieranjmartin) | | |
54 | | ggedit | 2017-05-04 | Reproducible layer, scale and theme editing for ggplot2 | [ggedit](https://github.com/metrumresearchgroup/ggedit) | :white_check_mark: | [Jonathan Sidi](https://yonicd.netlify.com/) | [Youtube Clip](https://www.youtube.com/watch?v=693XhHt8fug) | |
55 | | ggplot Theme Assist | 2016-03-30 | Customize your ggplot theme | [ggThemeAssist](https://github.com/calligross/ggthemeassist) | :white_check_mark: | [Calli Gross](https://github.com/calligross) | [Demo GIF](https://raw.githubusercontent.com/calligross/ggthemeassist/master/examples/ggThemeAssist2.gif) | |
56 | | ggplot2 Marginal Plots | 2016-03-30 | Add marginal plots to ggplot2 | [ggExtra](https://github.com/daattali/ggExtra) | :white_check_mark: | [Dean Attali](http://deanattali.com/) | [Screenshot](https://raw.githubusercontent.com/daattali/ggExtra/master/inst/img/ggmarginal-gadget.png) | |
57 | | gitgadget | 2016-09-16 | Version Control and Assignment Management using Git | [gitgadget](https://github.com/vnijs/gitgadget) | :white_check_mark: | [Vincent Nijs](https://github.com/vnijs) | | |
58 | | Google API Auth | 2016-05-03 | Authenticate with Google APIs | [googleAuthR](https://github.com/MarkEdmondson1234/googleAuthR) | :white_check_mark: | [Mark Edmondson](https://github.com/MarkEdmondson1234) | | |
59 | | Gotta Read 'Em All | 2016-05-10 | RStudio Add-In to interactively read ALL the data into R| [GREA](https://github.com/Stan125/GREA) | :x: | [Stanislaus Stadlmann](https://github.com/Stan125) | | |
60 | | Hist Add-In | 2016-03-31 | Interactively create histograms with ggplot2 and obtain the R Code | [limoaddin](https://github.com/Stan125/limoaddin) | :x: | [Stanislaus Stadlmann](https://github.com/Stan125) | | |
61 | | Input LaTeX Math | 2016-04-25 | Input math expressions via the MathQuill library | [bookdown](https://github.com/rstudio/bookdown) | :white_check_mark: | [RStudio](https://github.com/rstudio/) | | |
62 | | Insert %>% | 2016-05-10 | Insert pipe + reformat surrounding | [snippetsaddin](https://github.com/sfr/RStudio-Addin-Snippets) | :x: | [Juraj Sofranko](https://github.com/sfr) | | |
63 | | Insert citations | 2016-06-28 | Search a BibTeX-file and insert formatted Markdown citations | [citr](https://github.com/crsh/citr) | :white_check_mark: | [Frederik Aust](https://github.com/crsh/) | [Demo gif](https://raw.githubusercontent.com/crsh/citr/master/tools/images/addin_demo.gif) | |
64 | | insertImage | 2017-03-02 | Insert image into R Markdown with file chooser. Copy image file to project. | [insertImage](https://github.com/LudvigOlsen/insertImage) | :x: | [Ludvig R Olsen](http://ludvigolsen.dk/?lang=en) | | |
65 | | inserttable | 2018-04-07 | RStudio add-in facilitating insertion of nicely formatted tables in R markdown documents or plain R scripts. | [inserttable](https://github.com/lbusett/insert_table) | :x: | [Lorenzo Busetto](https://github.com/lbusett/) | [Blog Post](https://lbusett.netlify.com/post/a-new-rstudio-addin-to-facilitate-inserting-tables-in-rmarkdown-documents/) | |
66 | | Lattice Plotting | 2016-03-30 | Interactively build plots using the `lattice` system | [addinplots](https://github.com/homerhanumat/addinplots/) | :x: | [Homer White](http://statistics.rainandrhino.org) | | |
67 | | Levels ordering | 2016-04-06 | Interactively generate code to reorder factor levels | [questionr](https://github.com/juba/questionr) | :white_check_mark: | [Julien Barnier](https://github.com/juba/) | [Demo video](https://video.twimg.com/ext_tw_video/709748628911484928/pu/vid/874x720/ufNktJLtpIdP2fem.mp4) | |
68 | | Levels recoding | 2016-04-06 | Interactively generate code to edit factor levels | [questionr](https://github.com/juba/questionr) | :white_check_mark: | [Julien Barnier](https://github.com/juba/) | [Demo video](https://video.twimg.com/ext_tw_video/709748109992185856/pu/vid/874x720/bLPgibM_9K_2pRHa.mp4) | |
69 | | littleboxes | 2016-06-09 | Easily add a boxed title in R scripts | [littleboxes](https://github.com/ThinkRstat/littleboxes) | :x: | [thinkr](http://thinkr.fr) | | |
70 | | makeOxygen | 2017-04-12 | Self-populating roxygen2 skeletons | [sinew](https://github.com/metrumresearchgroup/sinew) | :white_check_mark: | [Jonathan Sidi](https://yonicd.netlify.com/) | [Demo Gif](https://github.com/metrumresearchgroup/sinew/blob/master/Miscellaneous/makeOxygen.gif?raw=true) | |
71 | | Merge data frames | 2016-08-05 | Perform Inner, left, Right and Full Joins and create a new data frame | [commonUtilAddins](https://github.com/sarupurisailalith/commonUtilAddins) | :x: | [sarupurisailalith](https://github.com/sarupurisailalith) | | |
72 | | mischelper | 2016-07-30 | microbenchmark, profvis selected code, remove unneeded hard line breaks, flip windows path separator | [mischelper](https://github.com/dracodoc/mischelper) | :x: | [dracodoc](https://github.com/dracodoc) | | |
73 | | mufflr | 2016-08-30 | Keyboard shortcuts for quieter and speedier pipelines | [mufflr](https://github.com/MilesMcBain/mufflr) | :x: | [Miles McBain](https://github.com/milesmcbain) | [Demo Gif](https://raw.githubusercontent.com/milesmcbain/mufflr/master/inst/media/mufflr.gif) | |
74 | | namebrowser | 2016-08-18 | Browse or search all installed packages for function names, insert library(pkg) or pkg:: prefix | [namebrowser](https://github.com/dracodoc/namebrowser) | :x: | [dracodoc](https://github.com/dracodoc) | | |
75 | | Plot Colour Helper | 2016-03-30 | Interactively pick colours to use in your plot | [colourpicker](https://github.com/daattali/colourpicker) | :white_check_mark: | [Dean Attali](http://deanattali.com/) | [Screenshot](https://raw.githubusercontent.com/daattali/colourpicker/master/inst/img/plothelper-demo.png), [Demo video](https://raw.githubusercontent.com/daattali/colourpicker/master/inst/img/plothelper-demo.gif) | |
76 | | prefixer | 2018-06-06 | Prefix function with their namespace | [prefixer](https://github.com/dreamRs/prefixer) | :x: | [dreamRs](https://github.com/dreamRs) | | |
77 | | Preview R-markdown Book | 2016-04-25 | Run bookdown's serve_book() to live preview a book | [bookdown](https://github.com/rstudio/bookdown) | :white_check_mark: | [RStudio](https://github.com/rstudio/) | | |
78 | | QRAGadget | 2016-06-28 | A Shiny Gadget for Interactive QRA Visualizations | [QRAGadget](https://github.com/paulgovan/QRAGadget) | :white_check_mark: | [Paul Govan](https://github.com/paulgovan) | [Screenshot](https://github.com/paulgovan/QRAGadget/blob/master/inst/images/map.PNG?raw=true) | |
79 | | Quick View Data Frame | 2016-05-17 | Quickly render a data frame, or the code which generates it, in the RStudio View window | [RStudioAddIns](https://github.com/digital-dharma/RStudioAddIns) | :x: | [digital-dharma](https://github.com/digital-dharma) | | |
80 | | radiant | 2016-06-30 | A Shiny interface for business analytics in R | [radiant](https://github.com/radiant-rstats/radiant) | :x: | [Vincent Nijs](http://rady.ucsd.edu/faculty/directory/nijs) | [Documentation](https://radiant-rstats.github.io/docs) | |
81 | | radiant.data | 2016-06-30 | A Shiny interface to visualize, summarize, transform, and combine data | [radiant.data](https://github.com/radiant-rstats/radiant.data) | :x: | [Vincent Nijs](http://rady.ucsd.edu/faculty/directory/nijs) | [Documentation](https://radiant-rstats.github.io/docs) | |
82 | | rdoxygen | 2017-08-14 | Create doxygen documentation for source code | [rdoxygen](https://github.com/nevrome/rdoxygen) | :white_check_mark: | [Clemens Schmid](https://github.com/nevrome) | | |
83 | | RegExplain | 2018-04-04 | Interactive regular expression utility belt | [regexplain](https://github.com/gadenbuie/regexplain) | :x: | [Garrick Aden-Buie](https://www.garrickadenbuie.com) | [Demo gifs](https://github.com/gadenbuie/regexplain/#overview) | |
84 | | remedy | 2017-09-08 | RStudio Addins to Simplify Markdown Writing | [remedy](https://github.com/ThinkR-open/remedy) | :x: | [ThinkR](https://thinkr.fr/) | [How it works](https://github.com/ThinkR-open/remedy/blob/master/README.md) | |
85 | | Render Rmd in Console | 2016-03-30 | Render an R Markdown document in the global environment | [RStudioConsoleRender](https://github.com/jeffjjohnston/RStudioConsoleRender) | :x: | [Jeff Johnston](https://github.com/jeffjjohnston) | [Blog post](https://jeffjjohnston.github.io/rstudio/rmarkdown/2016/03/01/faster-rendering-in-rstudio.html) | |
86 | | rpivotGadget | 2016-04-04 | Add-in wrapper around the rpivotTable HTML widget | [rpivotGadget](https://github.com/dkilfoyle/rpivotGadget) | :x: | [Dean Kilfoyle](https://github.com/dkilfoyle) | | |
87 | | rsam | 2018-01-14 | Manage installed RStudio addins keyboard shortcuts and IDE dropdown list | [rsam](https://github.com/yonicd/rsam) | :x: | [Jonathan Sidi](https://yonicd.netlify.com/) | [YouTube](https://www.youtube.com/watch?v=-XZWv7CJrs8) | Writes to Disk |
88 | | Schedule R scripts on Linux/Unix | 2016-03-30 | Use cron to schedule your R scripts (Linux/Unix) | [cronR](https://github.com/bnosac/cronR) | :white_check_mark: | [jwijffels](https://github.com/jwijffels) | [Screenshot](https://raw.githubusercontent.com/bnosac/cronR/master/vignettes/cronR-rstudioaddin.png) | |
89 | | Schedule R scripts on Windows | 2016-03-30 | Use Windows task scheduler to schedule your R scripts (Windows) | [taskscheduleR](https://github.com/bnosac/taskscheduleR) | :white_check_mark: | [jwijffels](https://github.com/jwijffels) | [Screenshot](https://raw.githubusercontent.com/bnosac/taskscheduleR/master/vignettes/taskscheduleR-rstudioaddin.png) | |
90 | | SeaClass | 2017-08-08 | An interactive R GUI for classification problems | [SeaClass](https://github.com/ChrisDienes/SeaClass) | :x: | [Chris Dienes](https://github.com/ChrisDienes) | [Screenshots](https://github.com/ChrisDienes/SeaClass/blob/master/screen_shots.png) | |
91 | | shinyExams | 2018-06-27 | RStudio addin to create exercises | [shinyExams](https://github.com/flaviobarros/shinyExams) | :x: | [Flavio Barros](https://www.rmining.net) | [Demo GIF](https://github.com/flaviobarros/shinyExams#usage) | |
92 | | Snake caser | 2016-05-06 | Convert a character string to snake_case | [snakecaser](https://github.com/benmarwick/snakecaser) | :x: | [Ben Marwick](https://github.com/benmarwick) | | |
93 | | sortLines | 2017-03-11 | Sort selected lines in the editor with a number-smart algorithm. | [sortLines](https://github.com/dcomtois/sortLines) | :x: | [Dominic Comtois](https://github.com/dcomtois) | [Demo Gif](https://raw.githubusercontent.com/dcomtois/sortLines/master/inst/media/sortLinesDemo.gif) | |
94 | | splitChunk | 2017-02-22 | Split code chunk in R Markdown | [splitChunk](https://github.com/LudvigOlsen/splitChunk) | :x: | [Ludvig R Olsen](http://ludvigolsen.dk/?lang=en) | | |
95 | | straddin | 2017-12-17 | Peek at objects with a keystroke. | [straddin](https://github.com/famuvie/straddin) | :x: | [Facundo Munoz](https://github.com/famuvie) | | |
96 | | strcode | 2016-12-02 | Insert code block separators and section titles | [strcode](https://github.com/lorenzwalthert/strcode) | :x: | [Lorenz Walthert](http://lorenzwalthert.github.io/) | [Demo GIF](https://raw.githubusercontent.com/lorenzwalthert/strcode/master/demos/strcode_v0.2.0_video_to_gif2_large.gif) | |
97 | | styler | 2017-11-28 | RStudio Addin to provide non-invasive pretty-printing of R source code while adhering to the tidyverse formatting rules. | [styler](https://github.com/r-lib/styler) | :white_check_mark: | [R infrastructure](https://github.com/r-lib) | [Demo gif](https://raw.githubusercontent.com/lorenzwalthert/some_raw_data/master/styler_0.1.gif) | |
98 | | testthis | 2017-01-28 | Utility functions and Rstudio addins to make using the testthat package even more fun | [testthis](https://github.com/s-fleck/testthis) | :white_check_mark: | | | |
99 | | Tidy Data | 2016-03-30 | Interactively build tidyr function call (gather) | [tidyshiny](https://github.com/MangoTheCat/tidyshiny/) | :x: | [Mango Solutions](http://www.mango-solutions.com) | | |
100 | | TODOr | 2017-11-13 | Finds all TODO, FIXME, CHANGED etc. comments in your project and shows them as markers. | [TODOr](https://github.com/dokato/todor) | :x: | [Dominik Krzeminski](https://github.com/dokato) | | |
101 | | typeStringsGadget | 2017-02-18 | Type strings unencumbered | [typeStringsGadget](https://github.com/daranzolin/typeStringsGadget) | :x: | [David Ranzolin](http://daranzolin.github.io) | | |
102 | | upnews GitHub pkgs | 2018-11-15 | Display news and update outdated github R packages | [upnews](https://github.com/ginolhac/upnews) | :x: | [Aurelien Ginolhac](https://github.com/ginolhac) | [Demo gif](https://raw.githubusercontent.com/ginolhac/upnews/master/docs/demo.gif) | |
103 | | Variable cutting | 2016-04-06 | Interactively generate `cut()` code | [questionr](https://github.com/juba/questionr) | :white_check_mark: | [Julien Barnier](https://github.com/juba/) | [Demo video](https://video.twimg.com/ext_tw_video/709749076225560576/pu/vid/874x720/jzl490qfQaJIJjWC.mp4) | |
104 | | ViewPipeSteps | 2018-02-23 | Create View Tabs of Each Piped Step | [ViewPipeSteps](https://github.com/daranzolin/ViewPipeSteps) | :x: | [David Ranzolin](https://daranzolin.github.io/) | [Demo gif](https://media.giphy.com/media/24p7Q2DkFpy5slRhOy/giphy.gif) | |
105 | | viewxl | 2018-06-06 | Open data.frame(s) in Excel | [viewxl](https://github.com/dreamRs/viewxl) | :x: | [dreamRs](https://github.com/dreamRs) | | |
106 | | wellspell.addin | 2018-12-15 | Quick spellcheck with hunspell | [wellspell.addin](https://github.com/nevrome/wellspell.addin) | :x: | [Clemens Schmid](https://github.com/nevrome) | | |
107 | | Word count add-in | 2016-05-06 | Count non-code words in Rmd documents | [wordcountaddin](https://github.com/benmarwick/wordcountaddin) | :x: | [Ben Marwick](https://github.com/benmarwick) |[Screenshot](https://github.com/benmarwick/wordcountaddin/raw/master/inst/wordcountaddin.gif) | |
108 | | Wrap Rmd | 2016-03-30 | Wrap selected R Markdown text but don't insert lines breaks into inline R code | [WrapRmd](https://github.com/tjmahr/WrapRmd) | :x: | [TJ Mahr](http://tjmahr.com/) | | |
109 |
--------------------------------------------------------------------------------