-
Notifications
You must be signed in to change notification settings - Fork 35
/
watcher.R
70 lines (60 loc) · 2.19 KB
/
watcher.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#' Watch for changes in output, text and graphical.
#'
#' @param debug activate debug mode where output will be both printed to
#' screen and captured.
#' @return list containing four functions: `get_new`, `pause`,
#' `unpause`, `close`.
#' @keywords internal
watchout <- function(debug = FALSE) {
output <- character()
prev <- character()
con <- textConnection("output", "wr", local = TRUE)
sink(con, split = debug)
list(
get_new = function(plot = FALSE, incomplete_plots = FALSE,
text_callback = identity, graphics_callback = identity) {
incomplete <- isIncomplete(con)
if (incomplete) cat("\n")
out <- list()
if (plot) {
out$graphics <- plot_snapshot(incomplete_plots)
if (!is.null(out$graphics)) graphics_callback(out$graphics)
}
n0 <- length(prev)
n1 <- length(output)
if (n1 > n0) {
new <- output[n0 + seq_len(n1 - n0)]
prev <<- output
out$text <- paste0(new, collapse = "\n")
if (!incomplete) out$text <- paste0(out$text, "\n")
text_callback(out$text)
}
unname(out)
},
pause = function() sink(),
unpause = function() sink(con, split = debug),
close = function() {
if (!isOpen(con))
stop("something bad happened... did you use closeAllConnections()?")
sink()
close(con)
output
},
get_con = function() con
)
}
.env = new.env()
.env$flush_console = function() {}
#' An emulation of flush.console() in evaluate()
#'
#' When [evaluate()] is evaluating code, the text output is diverted into
#' an internal connection, and there is no way to flush that connection. This
#' function provides a way to "flush" the connection so that any text output can
#' be immediately written out, and more importantly, the `text` handler
#' (specified in the `output_handler` argument of `evaluate()`) will
#' be called, which makes it possible for users to know it when the code
#' produces text output using the handler.
#' @note This function is supposed to be called inside `evaluate()` (e.g.
#' either a direct `evaluate()` call or in \pkg{knitr} code chunks).
#' @export
flush_console = function() .env$flush_console()