├── 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 | [![Build 4 | Status](https://travis-ci.org/daattali/addinslist.svg?branch=master)](https://travis-ci.org/daattali/addinslist) 5 | [![CRAN 6 | version](http://www.r-pkg.org/badges/version/addinslist)](https://cran.r-project.org/package=addinslist) 7 | [![saythanks](http://i.imgur.com/L88apDa.png)](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 | ![Addins menu](https://raw.githubusercontent.com/daattali/addinslist/master/inst/media/addins-menu.png) 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 | --------------------------------------------------------------------------------