Skip to content

Commit

Permalink
Move flush_console() to its own file
Browse files Browse the repository at this point in the history
* Make it more self-contained
* Add a test
  • Loading branch information
hadley committed Jun 17, 2024
1 parent b2a2689 commit ab688e1
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 1 deletion.
33 changes: 33 additions & 0 deletions R/flush-console.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#' 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() {
if (!is.null(.env$output_handler)) {
.env$output_handler()
}
invisible()
}

.env = new.env()
.env$output_handler <- NULL

set_output_handler <- function(handler) {
old <- .env$output_handler
.env$output_handler <- handler
invisible(old)

Check warning on line 26 in R/flush-console.R

View check run for this annotation

Codecov / codecov/patch

R/flush-console.R#L24-L26

Added lines #L24 - L26 were not covered by tests
}

local_output_handler <- function(handler, frame = parent.frame()) {
old <- set_output_handler(handler)
defer(set_output_handler(old), frame)
invisible()

Check warning on line 32 in R/flush-console.R

View check run for this annotation

Codecov / codecov/patch

R/flush-console.R#L30-L32

Added lines #L30 - L32 were not covered by tests
}
4 changes: 4 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
defer <- function(expr, frame = parent.frame(), after = FALSE) {
thunk <- as.call(list(function() expr))
do.call(on.exit, list(thunk, TRUE, after), envir = frame)

Check warning on line 3 in R/utils.R

View check run for this annotation

Codecov / codecov/patch

R/utils.R#L2-L3

Added lines #L2 - L3 were not covered by tests
}
15 changes: 14 additions & 1 deletion man/flush_console.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions tests/testthat/test-flush-console.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
test_that("flush_console() is a null op at top-level", {
expect_no_error(flush_console())

})

test_that("can use flush_console() inside evaluate", {
test <- function() {
cat("hi")
flush_console()
cat("bye")
}
ev <- evaluate("test()")
expect_equal(ev[[2]], "hi")
expect_equal(ev[[3]], "bye")
})

0 comments on commit ab688e1

Please sign in to comment.