gpt4 book ai didi

r - R 包可以将代码片段添加到用户的片段文件吗?

转载 作者:行者123 更新时间:2023-12-05 00:56:38 25 4
gpt4 key购买 nike

有几个代码片段对我的工作流程非常宝贵,并且可以很好地与我的自定义 R 包中的函数配合使用。我可以在我的 R 包中包含这些代码片段,以便在用户安装我的包时将它们添加到用户的代码片段中(当然还有权限)?

创建 sql block 的 Rmd 片段示例:

snippet sql
```{sql, connection = conn, output.var = "${1:df}"}
${2}
```

最佳答案

简短回答:是的

实现您想要的(适用于我的包)的一种方法是:

  1. 将包片段定义存储在包inst/ 目录中某处的两个文本文件中。片段完全遵循格式规则很重要(例如,行首的制表符,而不是空格)。我有一个 R 代码片段文件和一个 Markdown 文件。

  2. 定义一个函数来读取这些文件并将其内容复制到 RStudios user 片段文件中。这些文件是在第一次尝试编辑片段时生成的(工具 -> 全局选项 -> 代码 -> 编辑片段)(我认为 RStudio 在尝试编辑之前使用了另一个非用户公开的文件,但不确定)。在 ubuntu 上,RStudio 文件称为“r.snippets”和“markdown.snippets”,位于“~/.R/snippets/”中。我还检查了截断的定义是否已经存在,并在使用 cat(..., append=TRUE) 添加包片段定义之前仔细检查行首的选项卡。

  3. 我首先使用了一个复杂的 .onLoad 函数和配置,但现在我只是导出了一个 addPackageSnippets 函数;)

编辑

一些代码:

检查现有片段定义的部分:我刚刚阅读了 rstudio 文件并提取了以“snippet”开头的行。我对包snipptes定义文件做同样的事情并使用setdiff(人们可能还想在列表中使用trimws,以防有一些尾随空格)

# load package snippets definitions
#
pckgSnippetsFileContent <- readLines(pckgSnippetsFilesPath)

# Extract names of package snippets
#
pckgSnippetsFileDefinitions <- pckgSnippetsFileContent[grepl("^snippet (.*)", pckgSnippetsFileContent)]

# Extract 'names' of already existing snitppets
#
rstudioSnippetsFileContent <- readLines(rstudioSnippetsFilePath)
rstudioSnippetDefinitions <- rstudioSnippetsFileContent[grepl("^snippet (.*)", rstudioSnippetsFileContent)]

# find definitions appearing in packageSnippets but not in rstudioSnippets
# if no snippets are missing go to next file
#
snippetsToCopy <- setdiff(pckgSnippetsFileDefinitions, rstudioSnippetDefinitions)

这里的上下文是整个 'addPackageSnippets' 函数。该函数仅使用基本包,除了 getOS 它返回 'linux'、'windows' 或 'mac' 之一(即围绕 Sys.info() 的包装器

#' @title Export snippets
#'
#' @description \code{addPackageSnippets} copies all (missing) snippet definitions
#' in 'inst/rstudio/Rsnippets.txt' and 'Rmdsnippets.txt' to the RStudios user snippet location.
#'
#' @return boolean invisible(FALSE) if nothing was added, invisible(TRUE) if snipped definitions were added
#' @export
#'
#' @examples \dontrun{addPackageSnippets()}
addPackageSnippets <- function() {

added <- FALSE

# if not on RStudio or RStudioServer exit
#
if (!nzchar(Sys.getenv("RSTUDIO_USER_IDENTITY"))) {
return(NULL)
}

# Name of files containing snippet code to copy
#
pckgSnippetsFiles <- c("Rsnippets.txt", "Rmdsnippets.txt")

# Name of files to copy into. Order has to be the same
# as in 'pckgSnippetsFiles'
#
rstudioSnippetsFiles <- c("r.snippets", "markdown.snippets")

# Path to directory for RStudios user files depends on OS
#
if (getOS() == "linux") {
rstudioSnippetsPathBase <- "~/.R/snippets"
} else if (getOS() == "windows") {
rstudioSnippetsPathBase <- file.path(path.expand('~'), ".R", "snippets")
} else {
warning(paste0("goSnippets() is only implemented on linux and windows"))
return(NULL)
}

# Read each file in pckgSnippetsFiles and add its contents
#
for (i in seq_along(pckgSnippetsFiles)) {

# Try to get template, if template is not found skip it
#
pckgSnippetsFilesPath <- system.file("rstudio", pckgSnippetsFiles[i], package = "myFunc")
if (pckgSnippetsFilesPath == "") {
next()
}

# load package snippets definitions
#
pckgSnippetsFileContent <- readLines(pckgSnippetsFilesPath)

# Extract names of package snippets
#
pckgSnippetsFileDefinitions <- pckgSnippetsFileContent[grepl("^snippet (.*)", pckgSnippetsFileContent)]


# Construct path for destination file
#
rstudioSnippetsFilePath <- file.path(rstudioSnippetsPathBase, rstudioSnippetsFiles[i])

# If targeted RStudios user file does not exist, raise error (otherwise we would 'remove')
# the default snippets from the 'user file'
#
if (!file.exists(rstudioSnippetsFilePath)) {
stop(paste0( "'", rstudioSnippetsFilePath, "' does not exist yet\n.",
"Use RStudio -> Tools -> Global Options -> Code -> Edit Snippets\n",
"To initalize user defined snippets file by adding dummy snippet\n"))
}

# Extract 'names' of already existing snitppets
#
rstudioSnippetsFileContent <- readLines(rstudioSnippetsFilePath)
rstudioSnippetDefinitions <- rstudioSnippetsFileContent[grepl("^snippet (.*)", rstudioSnippetsFileContent)]

# replace two spaces with tab, ONLY at beginning of string
#
pckgSnippetsFileContentSanitized <- gsub("(?:^ {2})|\\G {2}|\\G\t", "\t", pckgSnippetsFileContent, perl = TRUE)

# find defintions appearing in packageSnippets but not in rstudioSnippets
# if no snippets are missing go to next file
#
snippetsToCopy <- setdiff(trimws(pckgSnippetsFileDefinitions), trimws(rstudioSnippetDefinitions))
snippetsNotToCopy <- intersect(trimws(pckgSnippetsFileDefinitions), trimws(rstudioSnippetDefinitions))
if (length(snippetsToCopy) == 0) {
# cat(paste0("(\nFollowing snippets will NOT be added because there is already a snippet with that name: ",
# paste0(snippetsNotToCopy, collapse=", ") ,")"))
next()
}

# Inform user about changes, ask to confirm action
#
if (interactive()) {
cat(paste0("You are about to add the following ", length(snippetsToCopy),
" snippets to '", rstudioSnippetsFilePath, "':\n",
paste0(paste0("-", snippetsToCopy), collapse="\n")))
if (length(snippetsNotToCopy) > 0) {
cat(paste0("\n(The following snippets will NOT be added because there is already a snippet with that name:\n",
paste0(snippetsNotToCopy, collapse=", ") ,")"))
}
answer <- readline(prompt="Do you want to procedd (y/n): ")
if (substr(answer, 1, 1) == "n") {
next()
}
}

# Create list of line numbers where snippet definitons start
# This list is used to determine the end of each definition block
#
allPckgSnippetDefinitonStarts <- grep("^snippet .*", pckgSnippetsFileContentSanitized)

for (s in snippetsToCopy) {
startLine <- grep(paste0("^", s, ".*"), pckgSnippetsFileContentSanitized)

# Find last line of snippet definition:
# First find start of next defintion and return
# previous line number or lastline if already in last definiton
#
endLine <- allPckgSnippetDefinitonStarts[allPckgSnippetDefinitonStarts > startLine][1] -1
if (is.na(endLine)) {
endLine <- length(pckgSnippetsFileContentSanitized)
}

snippetText <- paste0(pckgSnippetsFileContentSanitized[startLine:endLine], collapse = "\n")

# Make sure there is at least one empty line between entries
#
if (tail(readLines(rstudioSnippetsFilePath), n=1) != "") {
snippetText <- paste0("\n", snippetText)
}

# Append snippet block, print message
#
cat(paste0(snippetText, "\n"), file = rstudioSnippetsFilePath, append = TRUE)
cat(paste0("* Added '", s, "' to '", rstudioSnippetsFilePath, "'\n"))
added <- TRUE
}
}

if (added) {
cat("Restart RStudio to use new snippets")
}

return(invisible(added))

}

关于r - R 包可以将代码片段添加到用户的片段文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62220596/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com