├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── R ├── globals.R ├── snippet_add.R ├── snippet_remove.R ├── snippets_get.R ├── snippets_install.R ├── snippets_read.R ├── snippets_write.R └── utilities.R ├── README.Rmd ├── README.md ├── inst └── test_data │ └── test.snippets ├── man-roxygen └── language.R ├── man ├── github_GET.Rd ├── snippet_add.Rd ├── snippet_prepare.Rd ├── snippet_remove.Rd ├── snippets_add.Rd ├── snippets_get.Rd ├── snippets_install_gist.Rd ├── snippets_install_github.Rd ├── snippets_install_url.Rd ├── snippets_parse.Rd ├── snippets_path.Rd ├── snippets_read.Rd └── snippets_write.Rd ├── snippr.Rproj ├── tests ├── testthat.R └── testthat │ ├── test_install.R │ └── test_snippets.R └── vignettes ├── installing.Rmd └── snippet_files.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | man-roxygen 4 | ^README\.Rmd$ 5 | ^README-*\.png$ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | inst/doc 5 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: snippr 2 | Type: Package 3 | Title: Manage, share, and install RStudio snippets 4 | Version: 0.0.0.9000 5 | Date: 2015-04-13 6 | Authors@R: c(person("David", "Robinson", email = "admiral.david@gmail.com", role = c("aut", "cre"))) 7 | Maintainer: David Robinson 8 | Description: Manage, share, and install snippets for the RStudio IDE. Allows snippets 9 | to be added and installed from GitHub repositories or gists. 10 | License: GPL (>= 2) 11 | Imports: dplyr, 12 | stringr, 13 | httr, 14 | jsonlite, 15 | devtools 16 | LazyData: TRUE 17 | URL: http://github.com/dgrtwo/snippr 18 | BugReports: http://github.com/dgrtwo/snippr/issues 19 | Suggests: testthat, 20 | knitr 21 | VignetteBuilder: knitr 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2 (4.1.0): do not edit by hand 2 | 3 | export(snippet_add) 4 | export(snippet_prepare) 5 | export(snippet_remove) 6 | export(snippets_add) 7 | export(snippets_get) 8 | export(snippets_install_gist) 9 | export(snippets_install_github) 10 | export(snippets_install_url) 11 | export(snippets_read) 12 | export(snippets_write) 13 | import(dplyr) 14 | import(httr) 15 | import(stringr) 16 | -------------------------------------------------------------------------------- /R/globals.R: -------------------------------------------------------------------------------- 1 | globalVariables(c("snippet")) 2 | -------------------------------------------------------------------------------- /R/snippet_add.R: -------------------------------------------------------------------------------- 1 | #' Add a snippet to a .snippets file. 2 | #' 3 | #' @param name of the snippet to add 4 | #' @param text text of the snippet to add, as a character vector 5 | #' 6 | #' @template language 7 | #' 8 | #' @examples 9 | #' 10 | #' \dontrun{ 11 | #' 12 | #' # add a .r snippet 13 | #' snippet_add("dplyr", "${1:object} <- ${1:object} %>%\n${2:function}") 14 | #' 15 | #' # update the snippet, adding whitespace 16 | #' snippet_add("dplyr", "${1:object} <- ${1:object} %>%\n${2:function}") 17 | #' 18 | #' # add an HTML snippet 19 | #' snippet_add("copyright", "Copyright 2015", language = "html") 20 | #' 21 | #' } 22 | #' 23 | #' @export 24 | snippet_add <- function(name, text, language = "r", 25 | path = snippets_path(language)) { 26 | current <- snippets_read(path = path) 27 | if (!is.null(current[[name]])) { 28 | message("Replacing existing snippet ", name) 29 | } 30 | current[[name]] <- snippet_prepare(text) 31 | 32 | # replace contents of file 33 | snippets_write(current, path = path) 34 | } 35 | 36 | 37 | #' Add a list of snippets to a .snippets file. 38 | #' 39 | #' Add multiple snippets, in the form of a named list, to a .snippets file. 40 | #' 41 | #' @param snippets list of snippets to add 42 | #' @template language 43 | #' 44 | #' @examples 45 | #' 46 | #' \dontrun{ 47 | #' 48 | #' # add a .r snippet 49 | #' snippets_add(list(dplyr = "${1:object} <- ${1:object} %>%\n${2:function}")) 50 | #' 51 | #' # add an HTML snippet 52 | #' snp <- "Copyright 2015" 53 | #' snippet_add(list("copyright", snp, language = "html")) 54 | #' 55 | #' } 56 | #' 57 | #' @export 58 | snippets_add <- function(snippets, language = "r", 59 | path = snippets_path(language)) { 60 | current <- snippets_read(path = path) 61 | current <- modifyList(current, snippets) 62 | snippets_write(current, path = path) 63 | } 64 | -------------------------------------------------------------------------------- /R/snippet_remove.R: -------------------------------------------------------------------------------- 1 | #' Remove a snippet from a .snippets file. 2 | #' 3 | #' Remove a snippet from a .snippets file, raising an error if the 4 | #' snippet is not found in the file. 5 | #' 6 | #' @param name of the snippet to remove 7 | #' 8 | #' @template language 9 | #' 10 | #' @param error whether to raise an error if the snippet is not found 11 | #' 12 | #' @examples 13 | #' 14 | #' \dontrun{ 15 | #' 16 | #' # add a .r snippet 17 | #' snippet_add("dplyr", "${1:object} <- ${1:object} %>%\n${2:function}") 18 | #' 19 | #' # remove the snippet 20 | #' snippet_remove("dplyr") 21 | #' 22 | #' } 23 | #' 24 | #' @export 25 | snippet_remove <- function(name, language = "r", path = snippets_path(language), 26 | error = TRUE) { 27 | current <- snippets_read(path = path) 28 | if (is.null(current[[name]])) { 29 | if (error) { 30 | stop("Snippet ", name, " not found to remove") 31 | } 32 | return() 33 | } 34 | current[[name]] <- NULL 35 | 36 | # replace contents of file 37 | snippets_write(current, path = path) 38 | } 39 | -------------------------------------------------------------------------------- /R/snippets_get.R: -------------------------------------------------------------------------------- 1 | #' Retrieve a current snippet 2 | #' 3 | #' @param name snippet name: if missing, returns a list of all snippets 4 | #' 5 | #' @template language 6 | #' 7 | #' @examples 8 | #' 9 | #' \dontrun{ 10 | #' snippet_get("fun") 11 | #' 12 | #' # assuming a c_cpp .snippets file exists: 13 | #' snippet_get("cls", language = "c_cpp") 14 | #' 15 | #' # get a list of all snippets 16 | #' snippet_get() 17 | #' 18 | #' } 19 | #' 20 | #' @export 21 | snippets_get <- function(name, language = "r", path = snippets_path(language)) { 22 | snippets <- snippets_read(language = language, path = path) 23 | if (missing(name)) { 24 | snippets 25 | } else { 26 | ret <- snippets[[name]] 27 | if (is.null(ret)) { 28 | stop("Snippet ", name, " not found") 29 | } 30 | ret 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /R/snippets_install.R: -------------------------------------------------------------------------------- 1 | #' Install one or more snippets from a URL. 2 | #' 3 | #' Install one or more snippets by downloading them from a URL. 4 | #' 5 | #' @param url URL to install from 6 | #' @param name name of snippet to install. If NULL, installs all snippets from 7 | #' the URL. 8 | #' @template language 9 | #' 10 | #' @import httr 11 | #' 12 | #' @export 13 | snippets_install_url <- function(url, name = NULL, language = "r", path = snippets_path(language)) { 14 | req <- httr::GET(url) 15 | txt <- httr::content(req, as = "text") 16 | snippets <- snippets_parse(txt) 17 | if (!is.null(name)) { 18 | if (is.null(snippets[[name]])) { 19 | stop("Snippet ", name, " not found") 20 | } 21 | snippets <- snippets[name] 22 | } 23 | snippets_add(snippets, path = path) 24 | } 25 | 26 | 27 | #' Install one or more snippets from a GitHub Gist 28 | #' 29 | #' Install one or more snippets uploaded as a GitHub Gist 30 | #' 31 | #' @param gist Identifier of the gist. For example, if the gist is 32 | #' https://gist.githubusercontent.com/dgrtwo/ecc6aec8d37af42cdd83, then 33 | #' the gist ID would be 'ecc6aec8d37af42cdd83'. 34 | #' @param name name of snippet to install. If NULL, installs all snippets from 35 | #' the Gist. 36 | #' @template language 37 | #' 38 | #' @import httr 39 | #' 40 | #' @examples 41 | #' 42 | #' \dontrun{ 43 | #' snippets_install_gist('ecc6aec8d37af42cdd83') 44 | #' } 45 | #' 46 | #' @export 47 | snippets_install_gist <- function(gist, name = NULL, language = "r", 48 | path = snippets_path(language)) { 49 | # need to get redirect to full gist ID (which includes username) 50 | url <- paste0("https://gist.githubusercontent.com/", gist) 51 | req <- httr::GET(url) 52 | url <- file.path(req$url, "raw") 53 | 54 | snippets_install_url(url) 55 | } 56 | 57 | 58 | #' Install one or more snippets from a GitHub repository 59 | #' 60 | #' Install one or more snippets from a GitHub repository. These should be in 61 | #' the form of one or more .snippets files in the top-level directory. 62 | #' .snippets files that are not 63 | #' 64 | #' @param repo Username and repository name, e.g. "dgrtwo/snippets" 65 | #' @param name name of snippet to install, which must be given along with a language. 66 | #' If NULL, installs all snippets from the language. 67 | #' @param language Language from repo to install. If NULL, installs all snippets 68 | #' @param directory Directory to install snippets to 69 | #' 70 | #' @details The \code{directory} argument is available mainly for testing purposes. 71 | #' 72 | #' @import httr 73 | #' 74 | #' @examples 75 | #' 76 | #' \dontrun{ 77 | #' 78 | #' snippets_install_github("dgrtwo/snippets") 79 | #' 80 | #' # install just R or C/C++ 81 | #' snippets_install_github("dgrtwo/snippets", language = "r") 82 | #' snippets_install_github("dgrtwo/snippets", language = "c_cpp") 83 | #' 84 | #' # install just a single snippet 85 | #' snippets_install_github("dgrtwo/snippets", language = "r", name = "S3") 86 | #' 87 | #' } 88 | #' 89 | #' @export 90 | snippets_install_github <- function(repo, name = NULL, language = NULL, 91 | directory = SNIPPET_DIRECTORY) { 92 | if (is.null(language) && !is.null(name)) { 93 | stop("Cannot provide snippet name without language to ", 94 | "snippets_install_github") 95 | } 96 | 97 | # retrieve files 98 | files <- github_GET(file.path("repos", repo, "contents")) 99 | if (!is.null(language)) { 100 | fname <- paste0(language, ".snippets") 101 | files <- Filter(function(f) f$name == fname, files) 102 | if (length(files) == 0) { 103 | stop("Language ", language, " not found in ", repo) 104 | } 105 | } 106 | for (f in files) { 107 | if (f$type != "file" || !str_detect(f$name, "\\.snippets$")) { 108 | message("Skipping ", f$name) 109 | next; 110 | } 111 | language <- str_replace(f$name, ".snippets$", "") 112 | path <- file.path(directory, paste0(language, ".snippets")) 113 | 114 | snippets_install_url(f$download_url, name = name, path = path) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /R/snippets_read.R: -------------------------------------------------------------------------------- 1 | #' Parse the current snippets file into a list of snippets. 2 | #' 3 | #' @template language 4 | #' 5 | #' @return A named list of snippets, each of which is a single string 6 | #' that includes tabs at the start of each line. 7 | #' 8 | #' @import stringr 9 | #' @import dplyr 10 | #' 11 | #' @export 12 | snippets_read <- function(language = "r", path = snippets_path(language)) { 13 | lines <- readLines(path) 14 | snippets_parse(lines) 15 | } 16 | 17 | 18 | #' Parse a character vector of snippets. 19 | #' 20 | #' @param txt character vector of snippets 21 | #' 22 | #' @import stringr 23 | snippets_parse <- function(txt) { 24 | # if it's not already split by newlines, do so 25 | lines <- do.call(c, stringr::str_split(txt, "\\n")) 26 | d <- dplyr::data_frame(line = lines, 27 | snippet = str_match(line, "^snippet (.*)")[, 2], 28 | group = cumsum(!is.na(snippet))) 29 | snippets <- d %>% split(d$group) %>% 30 | lapply(function(d) paste(d$line[-1], collapse = "\n")) 31 | # remove missing snippets 32 | snippets <- Filter(function(s) s != "", snippets) 33 | names(snippets) <- d$snippet[!is.na(d$snippet)] 34 | snippets 35 | } 36 | -------------------------------------------------------------------------------- /R/snippets_write.R: -------------------------------------------------------------------------------- 1 | #' Write a list of snippets to a file. 2 | #' 3 | #' This overwrites the file if it exists. To append/edit a snippet, use 4 | #' \code{\link{snippet_add}} instead. 5 | #' 6 | #' @param snippets named list of snippets 7 | #' @param path path to the file to write to 8 | #' 9 | #' @export 10 | snippets_write <- function(snippets, path) { 11 | snippet_txt <- paste0("snippet ", names(snippets), "\n", 12 | as.character(snippets), collapse = "\n") 13 | writeLines(snippet_txt, path) 14 | } 15 | -------------------------------------------------------------------------------- /R/utilities.R: -------------------------------------------------------------------------------- 1 | SNIPPET_DIRECTORY <- file.path("~", ".R", "snippets") 2 | 3 | #' Find the path to a .snippets file. 4 | #' 5 | #' Find the path to the snippet file of the given language on this computer 6 | #' (e.g. so that it can be read from or replaced) 7 | #' 8 | #' @param language language of snippet file to find 9 | snippets_path <- function(language = "r") { 10 | path <- file.path(SNIPPET_DIRECTORY, paste0(language, ".snippets")) 11 | 12 | if (!(file.exists(path))) { 13 | stop("snippets file ", path, "not found") 14 | } 15 | 16 | path 17 | } 18 | 19 | 20 | #' Prepare a snippet for a .snippets file. 21 | #' 22 | #' @param text snippet text 23 | #' 24 | #' @export 25 | snippet_prepare <- function(text) { 26 | # if any lines don't start with a tab, add a tab to all 27 | lines <- do.call(c, str_split(text, "\\n")) 28 | if (!all(str_detect(lines[lines != ""], "^\t"))) { 29 | lines <- paste0("\t", lines) 30 | } 31 | 32 | # end with a length 1 character vector 33 | paste(lines, collapse = "\n") 34 | } 35 | 36 | 37 | #' GET request to GitHub 38 | #' 39 | #' This function is taken directly from devtools (under GPL) 40 | #' 41 | #' @param path API path 42 | #' @param ... extra arguments passed to httr::GET 43 | #' @param pat GitHub personal access token. If missing, uses 44 | #' \code{github_pat()} from devtools. 45 | #' 46 | #' @import httr 47 | github_GET <- function(path, ..., pat) { 48 | if (missing(pat)) { 49 | pat <- devtools::github_pat() 50 | } 51 | if (!is.null(pat)) { 52 | auth <- httr::authenticate(pat, "x-oauth-basic", "basic") 53 | } else { 54 | auth <- NULL 55 | } 56 | 57 | req <- httr::GET("https://api.github.com/", path = path, auth, ...) 58 | 59 | text <- httr::content(req, as = "text") 60 | parsed <- jsonlite::fromJSON(text, simplifyVector = FALSE) 61 | 62 | if (httr::status_code(req) >= 400) { 63 | stop("Request failed (", httr::status_code(req), ")\n", parsed$message, 64 | call. = FALSE) 65 | } 66 | 67 | parsed 68 | } 69 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | md_document: 4 | variant: markdown_github 5 | --- 6 | 7 | 8 | 9 | ```{r, echo = FALSE} 10 | knitr::opts_chunk$set( 11 | collapse = TRUE, 12 | comment = "#>", 13 | fig.path = "README-" 14 | ) 15 | ``` 16 | 17 | snippr: publish, install, and share RStudio code snippets 18 | ------------------------------------------ 19 | 20 | snippr provides tools to manage and install [RStudio code snippets](http://blog.rstudio.org/2015/04/13/rstudio-v0-99-preview-code-snippets/), including installing them from public repositories. 21 | 22 | ### Setup 23 | 24 | You can install `snippr` with the [devtools](https://github.com/hadley/devtools) package: 25 | 26 | ```{r eval = FALSE} 27 | devtools::install_github("dgrtwo/snippr") 28 | ``` 29 | 30 | ### Sharing and installing snippets 31 | 32 | snippr lets you share RStudio snippets with others by publishing them as a [GitHub repository](https://github.com/) or a [Gist](https://gist.github.com/). 33 | 34 | To share your snippets, create a GitHub repository with one or more `.snippets` file at the top level: see the [dgrtwo/snippets](https://github.com/dgrtwo/snippets) repository for an example. Anyone can then install your snippets using the code: 35 | 36 | ```{r eval = FALSE} 37 | library(snippr) 38 | snippets_install_github("dgrtwo/snippets") 39 | ``` 40 | 41 | Note that you may need to restart RStudio for the snippets to load. If you want to install only for one of the languages in the repo, you can use the `language` argument: 42 | 43 | ```{r eval = FALSE} 44 | snippets_install_github("dgrtwo/snippets", language = "r") 45 | ``` 46 | 47 | Or you can choose to install only a single snippet: 48 | 49 | ```{r eval = FALSE} 50 | snippets_install_github("dgrtwo/snippets", language = "r", name = "S3") 51 | ``` 52 | 53 | If you prefer, you can share one .snippets file as a GitHub Gist (like [this one](https://gist.github.com/dgrtwo/ecc6aec8d37af42cdd83)), and install it with its ID: 54 | 55 | ```{r eval = FALSE} 56 | snippets_install_gist("ecc6aec8d37af42cdd83", language = "r") 57 | ``` 58 | 59 | See the vignettes for more. 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | snippr: publish, install, and share RStudio code snippets 3 | --------------------------------------------------------- 4 | 5 | snippr provides tools to manage and install [RStudio code snippets](http://blog.rstudio.org/2015/04/13/rstudio-v0-99-preview-code-snippets/), including installing them from public repositories. 6 | 7 | ### Setup 8 | 9 | You can install `snippr` with the [devtools](https://github.com/hadley/devtools) package: 10 | 11 | ``` r 12 | devtools::install_github("dgrtwo/snippr") 13 | ``` 14 | 15 | ### Sharing and installing snippets 16 | 17 | snippr lets you share RStudio snippets with others by publishing them as a [GitHub repository](https://github.com/) or a [Gist](https://gist.github.com/). 18 | 19 | To share your snippets, create a GitHub repository with one or more `.snippets` file at the top level: see the [dgrtwo/snippets](https://github.com/dgrtwo/snippets) repository for an example. Anyone can then install your snippets using the code: 20 | 21 | ``` r 22 | library(snippr) 23 | snippets_install_github("dgrtwo/snippets") 24 | ``` 25 | 26 | Note that you may need to restart RStudio for the snippets to load. If you want to install only for one of the languages in the repo, you can use the `language` argument: 27 | 28 | ``` r 29 | snippets_install_github("dgrtwo/snippets", language = "r") 30 | ``` 31 | 32 | Or you can choose to install only a single snippet: 33 | 34 | ``` r 35 | snippets_install_github("dgrtwo/snippets", language = "r", name = "S3") 36 | ``` 37 | 38 | If you prefer, you can share one .snippets file as a GitHub Gist (like [this one](https://gist.github.com/dgrtwo/ecc6aec8d37af42cdd83)), and install it with its ID: 39 | 40 | ``` r 41 | snippets_install_gist("ecc6aec8d37af42cdd83", language = "r") 42 | ``` 43 | 44 | See the vignettes for more. 45 | -------------------------------------------------------------------------------- /inst/test_data/test.snippets: -------------------------------------------------------------------------------- 1 | snippet lib 2 | library(${1:package}) 3 | 4 | snippet req 5 | require(${1:package}) 6 | 7 | snippet sg 8 | setGeneric("${1:generic}", function(${2:x, ...}) { 9 | standardGeneric("${1:generic}") 10 | }) 11 | 12 | snippet sm 13 | setMethod("${1:generic}", ${2:class}, function(${2:x, ...}) { 14 | ${0} 15 | }) 16 | -------------------------------------------------------------------------------- /man-roxygen/language.R: -------------------------------------------------------------------------------- 1 | #' @param language language of the snippet. Choices are "r", "c_cpp", "html", 2 | #' "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 3 | #' is specified. 4 | #' @param path path to .snippets file 5 | #' 6 | #' @details Note that a .snippets file for a language may not yet exist. If 7 | #' it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 8 | #' make a trivial change to the language of choice (for example, a new 9 | #' empty line), and click Save. This will create the language file in 10 | #' ~/.R/snippets/.snippets with defaults included. 11 | -------------------------------------------------------------------------------- /man/github_GET.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/utilities.R 3 | \name{github_GET} 4 | \alias{github_GET} 5 | \title{GET request to GitHub} 6 | \usage{ 7 | github_GET(path, ..., pat) 8 | } 9 | \arguments{ 10 | \item{path}{API path} 11 | 12 | \item{...}{extra arguments passed to httr::GET} 13 | 14 | \item{pat}{GitHub personal access token. If missing, uses 15 | \code{github_pat()} from devtools.} 16 | } 17 | \description{ 18 | This function is taken directly from devtools (under GPL) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /man/snippet_add.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippet_add.R 3 | \name{snippet_add} 4 | \alias{snippet_add} 5 | \title{Add a snippet to a .snippets file.} 6 | \usage{ 7 | snippet_add(name, text, language = "r", path = snippets_path(language)) 8 | } 9 | \arguments{ 10 | \item{name}{of the snippet to add} 11 | 12 | \item{text}{text of the snippet to add, as a character vector} 13 | 14 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 15 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 16 | is specified.} 17 | 18 | \item{path}{path to .snippets file} 19 | } 20 | \description{ 21 | Add a snippet to a .snippets file. 22 | } 23 | \details{ 24 | Note that a .snippets file for a language may not yet exist. If 25 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 26 | make a trivial change to the language of choice (for example, a new 27 | empty line), and click Save. This will create the language file in 28 | ~/.R/snippets/.snippets with defaults included. 29 | } 30 | \examples{ 31 | \dontrun{ 32 | 33 | # add a .r snippet 34 | snippet_add("dplyr", "${1:object} <- ${1:object} \%>\%\\n${2:function}") 35 | 36 | # update the snippet, adding whitespace 37 | snippet_add("dplyr", "${1:object} <- ${1:object} \%>\%\\n${2:function}") 38 | 39 | # add an HTML snippet 40 | snippet_add("copyright", "Copyright 2015", language = "html") 41 | 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /man/snippet_prepare.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/utilities.R 3 | \name{snippet_prepare} 4 | \alias{snippet_prepare} 5 | \title{Prepare a snippet for a .snippets file.} 6 | \usage{ 7 | snippet_prepare(text) 8 | } 9 | \arguments{ 10 | \item{text}{snippet text} 11 | } 12 | \description{ 13 | Prepare a snippet for a .snippets file. 14 | } 15 | 16 | -------------------------------------------------------------------------------- /man/snippet_remove.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippet_remove.R 3 | \name{snippet_remove} 4 | \alias{snippet_remove} 5 | \title{Remove a snippet from a .snippets file.} 6 | \usage{ 7 | snippet_remove(name, language = "r", path = snippets_path(language), 8 | error = TRUE) 9 | } 10 | \arguments{ 11 | \item{name}{of the snippet to remove} 12 | 13 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 14 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 15 | is specified.} 16 | 17 | \item{path}{path to .snippets file} 18 | 19 | \item{error}{whether to raise an error if the snippet is not found} 20 | } 21 | \description{ 22 | Remove a snippet from a .snippets file, raising an error if the 23 | snippet is not found in the file. 24 | } 25 | \details{ 26 | Note that a .snippets file for a language may not yet exist. If 27 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 28 | make a trivial change to the language of choice (for example, a new 29 | empty line), and click Save. This will create the language file in 30 | ~/.R/snippets/.snippets with defaults included. 31 | } 32 | \examples{ 33 | \dontrun{ 34 | 35 | # add a .r snippet 36 | snippet_add("dplyr", "${1:object} <- ${1:object} \%>\%\\n${2:function}") 37 | 38 | # remove the snippet 39 | snippet_remove("dplyr") 40 | 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /man/snippets_add.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippet_add.R 3 | \name{snippets_add} 4 | \alias{snippets_add} 5 | \title{Add a list of snippets to a .snippets file.} 6 | \usage{ 7 | snippets_add(snippets, language = "r", path = snippets_path(language)) 8 | } 9 | \arguments{ 10 | \item{snippets}{list of snippets to add} 11 | 12 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 13 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 14 | is specified.} 15 | 16 | \item{path}{path to .snippets file} 17 | } 18 | \description{ 19 | Add multiple snippets, in the form of a named list, to a .snippets file. 20 | } 21 | \details{ 22 | Note that a .snippets file for a language may not yet exist. If 23 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 24 | make a trivial change to the language of choice (for example, a new 25 | empty line), and click Save. This will create the language file in 26 | ~/.R/snippets/.snippets with defaults included. 27 | } 28 | \examples{ 29 | \dontrun{ 30 | 31 | # add a .r snippet 32 | snippets_add(list(dplyr = "${1:object} <- ${1:object} \%>\%\\n${2:function}")) 33 | 34 | # add an HTML snippet 35 | snp <- "Copyright 2015" 36 | snippet_add(list("copyright", snp, language = "html")) 37 | 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /man/snippets_get.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_get.R 3 | \name{snippets_get} 4 | \alias{snippets_get} 5 | \title{Retrieve a current snippet} 6 | \usage{ 7 | snippets_get(name, language = "r", path = snippets_path(language)) 8 | } 9 | \arguments{ 10 | \item{name}{snippet name: if missing, returns a list of all snippets} 11 | 12 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 13 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 14 | is specified.} 15 | 16 | \item{path}{path to .snippets file} 17 | } 18 | \description{ 19 | Retrieve a current snippet 20 | } 21 | \details{ 22 | Note that a .snippets file for a language may not yet exist. If 23 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 24 | make a trivial change to the language of choice (for example, a new 25 | empty line), and click Save. This will create the language file in 26 | ~/.R/snippets/.snippets with defaults included. 27 | } 28 | \examples{ 29 | \dontrun{ 30 | snippet_get("fun") 31 | 32 | # assuming a c_cpp .snippets file exists: 33 | snippet_get("cls", language = "c_cpp") 34 | 35 | # get a list of all snippets 36 | snippet_get() 37 | 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /man/snippets_install_gist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_install.R 3 | \name{snippets_install_gist} 4 | \alias{snippets_install_gist} 5 | \title{Install one or more snippets from a GitHub Gist} 6 | \usage{ 7 | snippets_install_gist(gist, name = NULL, language = "r", 8 | path = snippets_path(language)) 9 | } 10 | \arguments{ 11 | \item{gist}{Identifier of the gist. For example, if the gist is 12 | https://gist.githubusercontent.com/dgrtwo/ecc6aec8d37af42cdd83, then 13 | the gist ID would be 'ecc6aec8d37af42cdd83'.} 14 | 15 | \item{name}{name of snippet to install. If NULL, installs all snippets from 16 | the Gist.} 17 | 18 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 19 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 20 | is specified.} 21 | 22 | \item{path}{path to .snippets file} 23 | } 24 | \description{ 25 | Install one or more snippets uploaded as a GitHub Gist 26 | } 27 | \details{ 28 | Note that a .snippets file for a language may not yet exist. If 29 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 30 | make a trivial change to the language of choice (for example, a new 31 | empty line), and click Save. This will create the language file in 32 | ~/.R/snippets/.snippets with defaults included. 33 | } 34 | \examples{ 35 | \dontrun{ 36 | snippets_install_gist('ecc6aec8d37af42cdd83') 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /man/snippets_install_github.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_install.R 3 | \name{snippets_install_github} 4 | \alias{snippets_install_github} 5 | \title{Install one or more snippets from a GitHub repository} 6 | \usage{ 7 | snippets_install_github(repo, name = NULL, language = NULL, 8 | directory = SNIPPET_DIRECTORY) 9 | } 10 | \arguments{ 11 | \item{repo}{Username and repository name, e.g. "dgrtwo/snippets"} 12 | 13 | \item{name}{name of snippet to install, which must be given along with a language. 14 | If NULL, installs all snippets from the language.} 15 | 16 | \item{language}{Language from repo to install. If NULL, installs all snippets} 17 | 18 | \item{directory}{Directory to install snippets to} 19 | } 20 | \description{ 21 | Install one or more snippets from a GitHub repository. These should be in 22 | the form of one or more .snippets files in the top-level directory. 23 | .snippets files that are not 24 | } 25 | \details{ 26 | The \code{directory} argument is available mainly for testing purposes. 27 | } 28 | \examples{ 29 | \dontrun{ 30 | 31 | snippets_install_github("dgrtwo/snippets") 32 | 33 | # install just R or C/C++ 34 | snippets_install_github("dgrtwo/snippets", language = "r") 35 | snippets_install_github("dgrtwo/snippets", language = "c_cpp") 36 | 37 | # install just a single snippet 38 | snippets_install_github("dgrtwo/snippets", language = "r", name = "S3") 39 | 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /man/snippets_install_url.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_install.R 3 | \name{snippets_install_url} 4 | \alias{snippets_install_url} 5 | \title{Install one or more snippets from a URL.} 6 | \usage{ 7 | snippets_install_url(url, name = NULL, language = "r", 8 | path = snippets_path(language)) 9 | } 10 | \arguments{ 11 | \item{url}{URL to install from} 12 | 13 | \item{name}{name of snippet to install. If NULL, installs all snippets from 14 | the URL.} 15 | 16 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 17 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 18 | is specified.} 19 | 20 | \item{path}{path to .snippets file} 21 | } 22 | \description{ 23 | Install one or more snippets by downloading them from a URL. 24 | } 25 | \details{ 26 | Note that a .snippets file for a language may not yet exist. If 27 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 28 | make a trivial change to the language of choice (for example, a new 29 | empty line), and click Save. This will create the language file in 30 | ~/.R/snippets/.snippets with defaults included. 31 | } 32 | 33 | -------------------------------------------------------------------------------- /man/snippets_parse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_read.R 3 | \name{snippets_parse} 4 | \alias{snippets_parse} 5 | \title{Parse a character vector of snippets.} 6 | \usage{ 7 | snippets_parse(txt) 8 | } 9 | \arguments{ 10 | \item{txt}{character vector of snippets} 11 | } 12 | \description{ 13 | Parse a character vector of snippets. 14 | } 15 | 16 | -------------------------------------------------------------------------------- /man/snippets_path.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/utilities.R 3 | \name{snippets_path} 4 | \alias{snippets_path} 5 | \title{Find the path to a .snippets file.} 6 | \usage{ 7 | snippets_path(language = "r") 8 | } 9 | \arguments{ 10 | \item{language}{language of snippet file to find} 11 | } 12 | \description{ 13 | Find the path to the snippet file of the given language on this computer 14 | (e.g. so that it can be read from or replaced) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /man/snippets_read.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_read.R 3 | \name{snippets_read} 4 | \alias{snippets_read} 5 | \title{Parse the current snippets file into a list of snippets.} 6 | \usage{ 7 | snippets_read(language = "r", path = snippets_path(language)) 8 | } 9 | \arguments{ 10 | \item{language}{language of the snippet. Choices are "r", "c_cpp", "html", 11 | "css", "java", "javascript", "python", and "sql". Ignored if \code{path} 12 | is specified.} 13 | 14 | \item{path}{path to .snippets file} 15 | } 16 | \value{ 17 | A named list of snippets, each of which is a single string 18 | that includes tabs at the start of each line. 19 | } 20 | \description{ 21 | Parse the current snippets file into a list of snippets. 22 | } 23 | \details{ 24 | Note that a .snippets file for a language may not yet exist. If 25 | it does not exist, go to Preferences->Code->Edit Snippets in RStudio, 26 | make a trivial change to the language of choice (for example, a new 27 | empty line), and click Save. This will create the language file in 28 | ~/.R/snippets/.snippets with defaults included. 29 | } 30 | 31 | -------------------------------------------------------------------------------- /man/snippets_write.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.0): do not edit by hand 2 | % Please edit documentation in R/snippets_write.R 3 | \name{snippets_write} 4 | \alias{snippets_write} 5 | \title{Write a list of snippets to a file.} 6 | \usage{ 7 | snippets_write(snippets, path) 8 | } 9 | \arguments{ 10 | \item{snippets}{named list of snippets} 11 | 12 | \item{path}{path to the file to write to} 13 | } 14 | \description{ 15 | This overwrites the file if it exists. To append/edit a snippet, use 16 | \code{\link{snippet_add}} instead. 17 | } 18 | 19 | -------------------------------------------------------------------------------- /snippr.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 4 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace,vignette 22 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(snippr) 3 | 4 | test_check("snippr") 5 | -------------------------------------------------------------------------------- /tests/testthat/test_install.R: -------------------------------------------------------------------------------- 1 | # test tools for installing snippets 2 | 3 | context("Installing Snippets") 4 | 5 | test_directory <- system.file("test_data", package = "snippr") 6 | test_file <- file.path(test_directory, "test.snippets") 7 | 8 | tmp <- ".test.snippets" 9 | if (file.exists(tmp)) { 10 | unlink(tmp) 11 | } 12 | file.copy(test_file, tmp) 13 | 14 | gist_id <- "ecc6aec8d37af42cdd83" 15 | test_that("can install snippets from a URL", { 16 | url <- paste0("https://gist.githubusercontent.com/dgrtwo/", gist_id, "/raw") 17 | snippets_install_url(url, path = tmp) 18 | 19 | sn <- snippets_get("S3", path = tmp) 20 | expect_true(grepl("function\\(", sn)) 21 | }) 22 | 23 | 24 | test_that("can install snippets from a gist", { 25 | snippets_install_gist(gist_id, path = tmp) 26 | 27 | sn <- snippets_get("S3", path = tmp) 28 | expect_true(grepl("function\\(", sn)) 29 | }) 30 | 31 | unlink(tmp) 32 | 33 | test_that("can install snippets from a GitHub repository", { 34 | # temporary directory 35 | tmpdir <- "tmpdir" 36 | unlink(tmpdir, recursive = TRUE) 37 | r_snippets <- file.path(tmpdir, "r.snippets") 38 | c_cpp_snippets <- file.path(tmpdir, "c_cpp.snippets") 39 | 40 | # create empty snippet files 41 | dir.create(tmpdir, showWarnings = FALSE) 42 | writeLines("", r_snippets) 43 | writeLines("", c_cpp_snippets) 44 | 45 | expect_message(snippets_install_github("dgrtwo/snippets", directory = tmpdir), 46 | "Skipping README.md") 47 | 48 | # confirm we now have them 49 | expect_equal(length(snippets_get(path = r_snippets)), 2) 50 | expect_equal(length(snippets_get(path = c_cpp_snippets)), 1) 51 | 52 | # reset, install only one language 53 | writeLines("", r_snippets) 54 | writeLines("", c_cpp_snippets) 55 | 56 | suppressMessages(snippets_install_github("dgrtwo/snippets", directory = tmpdir, language = "r")) 57 | expect_equal(length(snippets_read(path = r_snippets)), 2) 58 | expect_equal(length(snippets_read(path = c_cpp_snippets)), 0) 59 | 60 | # reset, install only one snippet 61 | writeLines("", r_snippets) 62 | writeLines("", c_cpp_snippets) 63 | suppressMessages(snippets_install_github("dgrtwo/snippets", directory = tmpdir, 64 | language = "r", name = "S3")) 65 | expect_equal(length(snippets_read(path = r_snippets)), 1) 66 | 67 | # clean up 68 | unlink(tmpdir, recursive = TRUE) 69 | }) 70 | -------------------------------------------------------------------------------- /tests/testthat/test_snippets.R: -------------------------------------------------------------------------------- 1 | # test tools for working with snippet text and files 2 | 3 | context("Snippet files") 4 | 5 | test_that("snippet_prepare can prepare text for a .snippets file", { 6 | snippet_text <- "myfunc <- function() {\n\ta <- 1\n}" 7 | snippet_result <- "\tmyfunc <- function() {\n\t\ta <- 1\n\t}" 8 | expect_equal(snippet_prepare(snippet_text), snippet_result) 9 | 10 | # if there already are tabs, no need to add any 11 | expect_equal(snippet_prepare(snippet_result), snippet_result) 12 | 13 | # might be given as separate lines 14 | snippet_text <- c("myfunc <- function() {", "\ta <- 1", "}") 15 | expect_equal(snippet_prepare(snippet_text), snippet_result) 16 | }) 17 | 18 | 19 | test_directory <- system.file("test_data", package = "snippr") 20 | test_file <- file.path(test_directory, "test.snippets") 21 | 22 | test_that("snippet_read can read a file of snippets", { 23 | snippets <- snippets_read(path = test_file) 24 | expect_equal(length(snippets), 4) 25 | expect_equal(names(snippets), c("lib", "req", "sg", "sm")) 26 | }) 27 | 28 | 29 | test_that("can add and remove snippets", { 30 | tmp <- ".test.snippets" 31 | if (file.exists(tmp)) { 32 | unlink(tmp) 33 | } 34 | file.copy(test_file, tmp) 35 | 36 | expect_equal(length(snippets_read(path = tmp)), 4) 37 | fun <- "\t${1:name} <- function(${2:variables}) {\n\t\t${0}\n\t}\n" 38 | snippet_add("fun", fun, path = tmp) 39 | sn <- snippets_read(path = tmp) 40 | expect_equal(length(sn), 5) 41 | expect_equal(sn$fun, fun) 42 | 43 | # change the function to use = instead of <- 44 | fun2 <- "\t${1:name} <- function(${2:variables}) {\n\t\t${0}\n\t}\n" 45 | expect_message(snippet_add("fun", fun2, path = tmp), "Replacing existing snippet fun") 46 | sn <- snippets_read(path = tmp) 47 | expect_equal(length(sn), 5) 48 | expect_equal(sn$fun, fun2) 49 | 50 | # remove the "fun" snippet 51 | snippet_remove("fun", path = tmp) 52 | sn <- snippets_read(path = tmp) 53 | expect_equal(length(sn), 4) 54 | expect_true(is.null(sn$fun)) 55 | 56 | # use snippets_add to add multiple 57 | snippets_add(list(myfun = fun, myfun2 = fun2), path = tmp) 58 | sn <- snippets_read(path = tmp) 59 | expect_equal(length(sn), 6) 60 | expect_equal(sn$myfun, fun) 61 | expect_equal(sn$myfun2, fun2) 62 | 63 | # clean up 64 | unlink(tmp) 65 | }) 66 | -------------------------------------------------------------------------------- /vignettes/installing.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Installing snippets" 3 | author: "David Robinson" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Installing snippets} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | \usepackage[utf8]{inputenc} 10 | --- 11 | 12 | ```{r, echo = FALSE} 13 | library(knitr) 14 | # eval is false so that we're not messing with the installer's snippets 15 | opts_chunk$set(eval = FALSE) 16 | ``` 17 | 18 | You can share your RStudio snippets with others by publishing them as a [GitHub repository](https://github.com/) or a [Gist](https://gist.github.com/). 19 | 20 | ### Install from GitHub 21 | 22 | To share your snippets, create a GitHub repository with one or more `.snippets` file at the top level: see the [dgrtwo/snippets](https://github.com/dgrtwo/snippets) repository for an example. (You can have other files or folders in the repository, such as a `README.md`, and they will be skipped). 23 | 24 | Anyone can then install your snippets using the code: 25 | 26 | ```{r} 27 | library(snippr) 28 | snippets_install_github("dgrtwo/snippets") 29 | ``` 30 | 31 | If you want to install only for one of the languages in the repo, you can use the `language` argument: 32 | 33 | ```{r} 34 | snippets_install_github("dgrtwo/snippets", language = "r") 35 | 36 | # or 37 | 38 | snippets_install_github("dgrtwo/snippets", language = "c_cpp") 39 | ``` 40 | 41 | Finally, you can choose to install only a single snippet: 42 | 43 | ```{r} 44 | snippets_install_github("dgrtwo/snippets", language = "r", name = "S3") 45 | ``` 46 | 47 | ### Installing from a GitHub Gist 48 | 49 | You can also share one or more snippets as a one-file Gist, such as can be found [here](https://gist.github.com/dgrtwo/ecc6aec8d37af42cdd83). To install that snippet, do: 50 | 51 | ```{r} 52 | snippets_install_gist("ecc6aec8d37af42cdd83", language = "r") 53 | ``` 54 | 55 | As of now Gist snippets must be a single file (and language), and the language should be specified manually. 56 | 57 | ### Future Work 58 | 59 | * Categories or tags for snippets 60 | * Snippets installed from a package 61 | * Functions to publish to a GitHub repository or Gist 62 | -------------------------------------------------------------------------------- /vignettes/snippet_files.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Working with .snippet files" 3 | author: "David Robinson" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Working with .snippet files} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | \usepackage[utf8]{inputenc} 10 | --- 11 | 12 | ```{r, echo = FALSE} 13 | library(knitr) 14 | # eval is false so that we're not messing with the installer's snippets 15 | opts_chunk$set(eval = FALSE) 16 | ``` 17 | 18 | While most users will probably need `snippr` only to install published snippets, it provides tools for working directly with `.snippets` files and text. 19 | 20 | ### Adding and Removing snippets 21 | 22 | Suppose we write a snippet for creating an S3 generic: 23 | 24 | ```{r} 25 | snip <- '${1:funcname} <- function(${2:args}, ...) UseMethod("${1:funcname}")' 26 | ``` 27 | 28 | We can now save that function to our `.snippets` file: 29 | 30 | ```{r} 31 | library(snippr) 32 | snippet_add("S3", snip) 33 | ``` 34 | 35 | If you restart RStudio you'll reload the snippets, after which you can access the snippet by typing `S3` then hitting Tab. You can replace an existing snippet simply by re-running `snippet_add`. For example, if you want to add curly brackets to the above snippet, do: 36 | 37 | ```{r} 38 | snip <- '${1:funcname} <- function(${2:args}, ...) { 39 | UseMethod("${1:funcname}") 40 | }' 41 | snippet_add("S3", snip) 42 | ``` 43 | 44 | You can remove the snippet with: 45 | 46 | ```{r} 47 | snippet_remove("S3") 48 | ``` 49 | 50 | ### Retrieving Snippets 51 | 52 | To get a list of the current snippets, do: 53 | 54 | ```{r} 55 | snippets <- snippets_get() 56 | head(snippets) 57 | ``` 58 | 59 | Or to retrieve a single one: 60 | 61 | ```{r} 62 | snippet_apply <- snippets_get("apply") 63 | ``` 64 | 65 | You can retrieve snippets for other languages with the `language` argument: 66 | 67 | ```{r} 68 | html_snippets <- snippets_get(language = "html") 69 | head(html_snippets) 70 | ``` 71 | --------------------------------------------------------------------------------