1#' Interact with Documents open in RStudio 2#' 3#' Use these functions to interact with documents open in RStudio. 4#' 5#' @param location An object specifying the positions, or ranges, wherein text 6#' should be inserted. See \bold{Details} for more information. 7#' 8#' @param text A character vector, indicating what text should be inserted at 9#' each aforementioned range. This should either be length one (in which case, 10#' this text is applied to each range specified); otherwise, it should be the 11#' same length as the \code{ranges} list. 12#' 13#' @param id The document id. When \code{NULL} or blank, the requested operation 14#' will apply to the currently open, or last focused, RStudio document. 15#' 16#' @param position The cursor position, typically created through 17#' \code{\link{document_position}()}. 18#' 19#' @param ranges A list of one or more ranges, typically created 20#' through \code{\link{document_range}()}. 21#' 22#' @param type The type of document to be created. 23#' 24#' @param execute Should the code be executed after the document 25#' is created? 26#' 27#' @param allowConsole Allow the pseudo-id `#console` to be returned, if the \R 28#' console is currently focused? Set this to `FALSE` if you'd always like to 29#' target the currently-active or last-active editor in the Source pane. 30#' 31#' @details 32#' 33#' \code{location} should be a (list of) \code{\link{document_position}} or 34#' \code{\link{document_range}} object(s), or numeric vectors coercable to 35#' such objects. 36#' 37#' To operate on the current selection in a document, call \code{insertText()} 38#' with only a text argument, e.g. 39#' 40#' \preformatted{ 41#' insertText("# Hello\\n") 42#' insertText(text = "# Hello\\n") 43#' } 44#' 45#' Otherwise, specify a (list of) positions or ranges, as in: 46#' 47#' \preformatted{ 48#' # insert text at the start of the document 49#' insertText(c(1, 1), "# Hello\\n") 50#' 51#' # insert text at the end of the document 52#' insertText(Inf, "# Hello\\n") 53#' 54#' # comment out the first 5 rows 55#' pos <- Map(c, 1:5, 1) 56#' insertText(pos, "# ") 57#' 58#' # uncomment the first 5 rows, undoing the previous action 59#' rng <- Map(c, Map(c, 1:5, 1), Map(c, 1:5, 3)) 60#' modifyRange(rng, "") 61#' } 62#' 63#' \code{modifyRange} is a synonym for \code{insertText}, but makes its intent 64#' clearer when working with ranges, as performing text insertion with a range 65#' will replace the text previously existing in that range with new text. For 66#' clarity, prefer using \code{insertText} when working with 67#' \code{\link{document_position}}s, and \code{modifyRange} when working with 68#' \code{\link{document_range}}s. 69#' 70#' @note 71#' The \code{insertText}, \code{modifyRange} and \code{setDocumentContents} 72#' functions were added with version 0.99.796 of RStudio. 73#' 74#' The \code{setCursorPosition} and \code{setSelectionRanges} functions were 75#' added with version 0.99.1111 of RStudio. 76#' 77#' The \code{documentSave} and \code{documentSaveAll} functions were added 78#' with version 1.1.287 of RStudio. 79#' 80#' The \code{documentId} and \code{documentPath} functions were added with 81#' version 1.4.843 of RStudio. 82#' 83#' @name rstudio-documents 84NULL 85 86#' @name rstudio-documents 87#' @export 88insertText <- function(location = NULL, 89 text = NULL, 90 id = NULL) 91{ 92 # unfortunate gymnastics needed for older versions of RStudio 93 if (getVersion() < "1.4") 94 { 95 if (is.null(location) && is.null(text)) 96 { 97 callFun("insertText", 98 id = id) 99 } 100 else if (is.null(location)) 101 { 102 callFun("insertText", 103 text = text, 104 id = id) 105 } 106 else if (is.null(text)) 107 { 108 callFun("insertText", 109 location = location, 110 id = id) 111 } 112 else 113 { 114 callFun("insertText", 115 location = location, 116 text = text, 117 id = id) 118 } 119 } 120 else 121 { 122 callFun("insertText", 123 location = location, 124 text = text, 125 id = id) 126 } 127} 128 129#' @name rstudio-documents 130#' @export 131modifyRange <- insertText 132 133#' @name rstudio-documents 134#' @export 135setDocumentContents <- function(text, id = NULL) { 136 137 location <- document_range( 138 document_position(1, 1), 139 document_position(Inf, 1) 140 ) 141 142 insertText(location, text, id) 143} 144 145#' @name rstudio-documents 146#' @export 147setCursorPosition <- function(position, id = NULL) { 148 callFun("setSelectionRanges", position, id) 149} 150 151#' @name rstudio-documents 152#' @export 153setSelectionRanges <- function(ranges, id = NULL) { 154 callFun("setSelectionRanges", ranges, id) 155} 156 157#' @name rstudio-documents 158#' @export 159documentId <- function(allowConsole = TRUE) { 160 callFun("documentId", allowConsole = allowConsole) 161} 162 163#' @name rstudio-documents 164#' @export 165documentPath <- function(id = NULL) { 166 callFun("documentPath", id = id) 167} 168 169#' @name rstudio-documents 170#' @export 171documentSave <- function(id = NULL) { 172 callFun("documentSave", id) 173} 174 175#' @name rstudio-documents 176#' @export 177documentSaveAll <- function() { 178 callFun("documentSaveAll") 179} 180 181#' Retrieve Information about an RStudio Editor 182#' 183#' Returns information about an RStudio editor. 184#' 185#' The \code{selection} field returned is a list of document selection objects. 186#' A document selection is just a pairing of a document \code{range}, and the 187#' \code{text} within that range. 188#' 189#' @note 190#' The \code{getActiveDocumentContext} function was added with version 0.99.796 191#' of RStudio, while the \code{getSourceEditorContext} and the \code{getConsoleEditorContext} 192#' functions were added with version 0.99.1111. 193#' 194#' @return A \code{list} with elements: 195#' \tabular{ll}{ 196#' \code{id} \tab The document ID.\cr 197#' \code{path} \tab The path to the document on disk.\cr 198#' \code{contents} \tab The contents of the document.\cr 199#' \code{selection} \tab A \code{list} of selections. See \bold{Details} for more information.\cr 200#' } 201#' 202#' @rdname rstudio-editors 203#' @name rstudio-editors 204#' @export 205getActiveDocumentContext <- function() { 206 getDocumentContext("getActiveDocumentContext") 207} 208 209#' @name rstudio-editors 210#' @export 211getSourceEditorContext <- function() { 212 getDocumentContext("getSourceEditorContext") 213} 214 215#' @name rstudio-editors 216#' @export 217getConsoleEditorContext <- function() { 218 getDocumentContext("getConsoleEditorContext") 219} 220 221#' @note The \code{documentNew} function was introduced in RStudio 1.2.640. 222#' 223#' @name rstudio-documents 224#' @export 225documentNew <- function( 226 text, 227 type = c("r", "rmarkdown", "sql"), 228 position = document_position(0, 0), 229 execute = FALSE) 230{ 231 type <- match.arg(type) 232 callFun("documentNew", type, text, position[1], position[2], execute) 233} 234 235#' @param save Whether to commit unsaved changes to the document before closing it. 236#' 237#' @note The \code{documentClose} function was introduced in RStudio 1.2.1255 238#' 239#' @details 240#' 241#' \code{documentClose} accepts an ID of an open document rather than a path. 242#' You can retrieve the ID of the active document using the \code{documentId()} 243#' function. 244#' 245#' Closing is always done non-interactively; that is, no prompts are given to 246#' the user. If the user has made changes to the document but not saved them, 247#' then the \code{save} parameter governs the behavior: when \code{TRUE}, 248#' unsaved changes are committed, and when \code{FALSE} they are discarded. 249#' 250#' @name rstudio-documents 251#' @export 252documentClose <- function(id = NULL, save = TRUE) { 253 callFun("documentClose", id, save) 254} 255