Skip to content

Commit 860c8d5

Browse files
author
Tal Hadad
committed
graceful detach that restoring the previous hooks/handlers before vsc
1 parent 2a6681c commit 860c8d5

File tree

2 files changed

+71
-15
lines changed

2 files changed

+71
-15
lines changed

R/session/init_late.R

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ exports <- local({
2222
.vsc.browser <- .vsc$show_browser
2323
.vsc.viewer <- .vsc$show_viewer
2424
.vsc.page_viewer <- .vsc$show_page_viewer
25-
View <- .vsc.view
2625
environment()
2726
})
2827
attach(exports, name = .vsc.name, warn.conflicts = FALSE)

R/session/vsc.R

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,24 @@ request_file <- file.path(dir_watcher, "request.log")
99
request_lock_file <- file.path(dir_watcher, "request.lock")
1010
settings_file <- file.path(dir_watcher, "settings.json")
1111
request_tcp_connection <- NA
12+
request_is_attached <- FALSE
13+
before_attach_options <- list()
14+
options_when_connected_list <- list()
15+
options_when_connected <- function(...) {
16+
l <- list(...)
17+
mapply(function(option, value) {
18+
options_when_connected_list[[option]] <<- value
19+
}, names(l), l)
20+
}
21+
before_attach_hooks <- list()
22+
hooks_when_connected_list <- list()
23+
hook_when_connected <- function(hook, cb) {
24+
hooks_when_connected_list[[hook]] <<- cb
25+
}
1226
user_options <- names(options())
27+
created_devices <- c()
28+
View_impl <- NULL
29+
old_view_impl <- View
1330

1431
logger <- if (getOption("vsc.debug", FALSE)) {
1532
function(...) cat(..., "\n", sep = "")
@@ -64,7 +81,7 @@ load_settings <- function() {
6481
load_settings()
6582

6683
if (is.null(getOption("help_type"))) {
67-
options(help_type = "html")
84+
options_when_connected(help_type = "html")
6885
}
6986

7087
use_webserver <- isTRUE(getOption("vsc.use_webserver", FALSE))
@@ -389,10 +406,11 @@ removeTaskCallback("vsc.plot")
389406
use_httpgd <- identical(getOption("vsc.use_httpgd", FALSE), TRUE)
390407
show_plot <- !identical(getOption("vsc.plot", "Two"), FALSE)
391408
if (use_httpgd && "httpgd" %in% .packages(all.available = TRUE)) {
392-
options(device = function(...) {
409+
options_when_connected(device = function(...) {
393410
httpgd::hgd(
394411
silent = TRUE
395412
)
413+
created_devices <<- append(created_devices, dev.cur())
396414
.vsc$request("httpgd", url = httpgd::hgd_url())
397415
})
398416
} else if (use_httpgd) {
@@ -417,12 +435,13 @@ if (use_httpgd && "httpgd" %in% .packages(all.available = TRUE)) {
417435
}
418436
}
419437

420-
options(
438+
options_when_connected(
421439
device = function(...) {
422440
pdf(NULL,
423441
width = null_dev_size[[1L]],
424442
height = null_dev_size[[2L]],
425443
bg = "white")
444+
created_devices <<- append(created_devices, dev.cur())
426445
dev.control(displaylist = "enable")
427446
}
428447
)
@@ -436,7 +455,9 @@ if (use_httpgd && "httpgd" %in% .packages(all.available = TRUE)) {
436455
dev_args <- getOption("vsc.dev.args")
437456
do.call(png, c(list(filename = plot_file), dev_args))
438457
on.exit({
458+
cur_dev <- dev.cur()
439459
dev.off()
460+
created_devices <<- created_devices[created_devices != cur_dev]
440461
cat(get_timestamp(), file = plot_lock_file)
441462
if (!is.na(request_tcp_connection)) {
442463
tryCatch({
@@ -453,12 +474,12 @@ if (use_httpgd && "httpgd" %in% .packages(all.available = TRUE)) {
453474
TRUE
454475
}
455476

456-
setHook("plot.new", new_plot, "replace")
457-
setHook("grid.newpage", new_plot, "replace")
477+
hook_when_connected("plot.new", new_plot)
478+
hook_when_connected("grid.newpage", new_plot)
458479

459480
rebind(".External.graphics", function(...) {
460481
out <- .Primitive(".External.graphics")(...)
461-
if (check_null_dev()) {
482+
if (request_is_attached && check_null_dev()) {
462483
plot_updated <<- TRUE
463484
}
464485
out
@@ -646,17 +667,17 @@ if (show_view) {
646667
}
647668
}
648669

649-
rebind("View", show_dataview, "utils")
670+
View_impl <- show_dataview
650671
}
651672

652673
attach <- function(host = "127.0.0.1", port = NA) {
674+
if (request_is_attached) {
675+
detach()
676+
}
653677
load_settings()
654678
if (rstudioapi_enabled()) {
655679
rstudioapi_util_env$update_addin_registry(addin_registry)
656680
}
657-
if (!is.na(request_tcp_connection)) {
658-
detach()
659-
}
660681
if (!is.na(port)) {
661682
request_tcp_connection <<- socketConnection(
662683
host = host,
@@ -682,6 +703,23 @@ attach <- function(host = "127.0.0.1", port = NA) {
682703
token = parent$token
683704
) else NULL
684705
)
706+
if (!request_is_attached) {
707+
options_name <- names(options_when_connected_list)
708+
before_attach_options <<- setNames(lapply(options_name, function(option) getOption(option)), options_name)
709+
710+
hooks_name <- names(hooks_when_connected_list)
711+
before_attach_hooks <<- setNames(lapply(hooks_name, function(hook_name) getHook(hook_name)), hooks_name)
712+
713+
old_view_impl <<- View
714+
if (!is.null(View_impl)) {
715+
rebind("View", View_impl, "utils")
716+
}
717+
}
718+
do.call(options, options_when_connected_list)
719+
mapply(function(hook_name, cb) {
720+
setHook(hook_name, cb, "replace")
721+
}, hooks_name, hooks_when_connected_list)
722+
request_is_attached <<- TRUE
685723
}
686724

687725
detach <- function() {
@@ -690,6 +728,25 @@ detach <- function() {
690728
close(request_tcp_connection)
691729
request_tcp_connection <<- NA
692730
}
731+
if (request_is_attached) {
732+
# restore previous options
733+
options_name <- names(options_when_connected_list)
734+
do.call(options, setNames(before_attach_options[options_name], options_name))
735+
736+
# restore previous hooks
737+
hooks_name <- names(hooks_when_connected_list)
738+
mapply(function(hook_name, cbs) {
739+
setHook(hook_name, cbs, "replace")
740+
}, hooks_name, before_attach_hooks[hooks_name])
741+
742+
if (!is.null(View_impl)) {
743+
rebind("View", old_view_impl, "utils")
744+
}
745+
746+
lapply(created_devices, function(dev) dev.off(dev))
747+
created_devices <<- c()
748+
}
749+
request_is_attached <<- FALSE
693750
}
694751

695752
path_to_uri <- function(path) {
@@ -827,7 +884,7 @@ show_page_viewer <- function(url, title = NULL, ...,
827884
show_webview(url = url, title = title, ..., viewer = viewer)
828885
}
829886

830-
options(
887+
options_when_connected(
831888
browser = show_browser,
832889
viewer = show_viewer,
833890
page_viewer = show_page_viewer
@@ -882,7 +939,7 @@ if (rstudioapi_enabled()) {
882939
rstudioapi_env <- new.env(parent = rstudioapi_util_env)
883940
source(file.path(dir_init, "rstudioapi_util.R"), local = rstudioapi_util_env)
884941
source(file.path(dir_init, "rstudioapi.R"), local = rstudioapi_env)
885-
setHook(
942+
hook_when_connected(
886943
packageEvent("rstudioapi", "onLoad"),
887944
function(...) {
888945
rstudioapi_util_env$rstudioapi_patch_hook(rstudioapi_env)
@@ -900,7 +957,7 @@ if (rstudioapi_enabled()) {
900957

901958
print.help_files_with_topic <- function(h, ...) {
902959
viewer <- getOption("vsc.helpPanel", "Two")
903-
if (!identical(FALSE, viewer) && length(h) >= 1 && is.character(h)) {
960+
if (request_is_attached && !identical(FALSE, viewer) && length(h) >= 1 && is.character(h)) {
904961
file <- h[1]
905962
path <- dirname(file)
906963
dirpath <- dirname(path)
@@ -921,7 +978,7 @@ print.help_files_with_topic <- function(h, ...) {
921978

922979
print.hsearch <- function(x, ...) {
923980
viewer <- getOption("vsc.helpPanel", "Two")
924-
if (!identical(FALSE, viewer) && length(x) >= 1) {
981+
if (request_is_attached && !identical(FALSE, viewer) && length(x) >= 1) {
925982
requestPath <- paste0(
926983
"/doc/html/Search?pattern=",
927984
tools:::escapeAmpersand(x$pattern),

0 commit comments

Comments
 (0)