Skip to content

Commit e0c0322

Browse files
committed
Merge branch 'notebook2' into notebook
2 parents 23c7a99 + 9871938 commit e0c0322

File tree

4 files changed

+510
-141
lines changed

4 files changed

+510
-141
lines changed

R/notebook2.R

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
requireNamespace("jsonlite")
2+
requireNamespace("callr")
3+
4+
args <- commandArgs(trailingOnly = TRUE)
5+
exprs <- parse(text = args, keep.source = FALSE)
6+
env <- new.env()
7+
for (expr in exprs) {
8+
eval(expr, env)
9+
}
10+
11+
r <- callr::r_session$new(
12+
callr::r_session_options(
13+
system_profile = TRUE, user_profile = TRUE, supervise = TRUE),
14+
wait = TRUE
15+
)
16+
17+
r$run(function() {
18+
requireNamespace("jsonlite")
19+
requireNamespace("svglite")
20+
21+
.vscNotebook <- local({
22+
null_dev_id <- c(pdf = 2L)
23+
null_dev_size <- c(7 + pi, 7 + pi)
24+
viewer_file <- NULL
25+
browser_url <- NULL
26+
27+
options(
28+
device = function(...) {
29+
pdf(NULL,
30+
width = null_dev_size[[1L]],
31+
height = null_dev_size[[2L]],
32+
bg = "white")
33+
dev.control(displaylist = "enable")
34+
},
35+
viewer = function(url, ...) {
36+
viewer_file <<- url
37+
},
38+
page_viewer = function(url, ...) {
39+
viewer_file <<- url
40+
},
41+
browser = function(url, ...) {
42+
browser_url <<- url
43+
}
44+
)
45+
46+
check_null_dev <- function() {
47+
identical(dev.cur(), null_dev_id) &&
48+
identical(dev.size(), null_dev_size)
49+
}
50+
51+
evaluate <- function(id, expr) {
52+
viewer_file <<- NULL
53+
browser_url <<- NULL
54+
res <- tryCatch({
55+
expr <- parse(text = expr)
56+
out <- withVisible(eval(expr, globalenv()))
57+
text <- utils::capture.output(print(out$value, view = TRUE))
58+
if (check_null_dev()) {
59+
record <- recordPlot()
60+
plot_file <- tempfile(fileext = ".svg")
61+
svglite::svglite(plot_file, width = 12, height = 8)
62+
replayPlot(record)
63+
graphics.off()
64+
list(
65+
id = id,
66+
type = "plot",
67+
result = plot_file
68+
)
69+
} else if (!is.null(viewer_file)) {
70+
list(
71+
id = id,
72+
type = "viewer",
73+
result = viewer_file
74+
)
75+
} else if (!is.null(browser_url)) {
76+
list(
77+
id = id,
78+
type = "browser",
79+
result = browser_url
80+
)
81+
} else if (out$visible) {
82+
list(
83+
id = id,
84+
type = "text",
85+
result = paste0(text, collapse = "\n")
86+
)
87+
} else {
88+
list(
89+
id = id,
90+
type = "text",
91+
result = ""
92+
)
93+
}
94+
}, error = function(e) {
95+
list(
96+
id = id,
97+
type = "error",
98+
result = conditionMessage(e)
99+
)
100+
})
101+
102+
res
103+
}
104+
105+
environment()
106+
})
107+
108+
attach(environment(), name = "tools:vscNotebook")
109+
NULL
110+
})
111+
112+
con <- socketConnection(host = "127.0.0.1", port = env$port, open = "r+b")
113+
running_request <- NULL
114+
115+
while (TRUE) {
116+
response <- NULL
117+
if (socketSelect(list(con), timeout = 0)) {
118+
header <- readLines(con, 1, encoding = "UTF-8")
119+
n <- as.integer(gsub("^Content-Length\\: (\\d+)$", "\\1", header))
120+
content <- readChar(con, n, useBytes = TRUE)
121+
Encoding(content) <- "UTF-8"
122+
cat(content, "\n", sep = "")
123+
124+
request <- jsonlite::fromJSON(content, simplifyVector = FALSE)
125+
if (request$type == "eval") {
126+
response <- tryCatch({
127+
r$call(function(id, expr) {
128+
.vscNotebook$evaluate(id, expr)
129+
}, list(id = request$id, expr = request$expr))
130+
running_request <- request
131+
NULL
132+
}, error = function(e) {
133+
list(
134+
id = request$id,
135+
type = "error",
136+
result = conditionMessage(e)
137+
)
138+
})
139+
} else if (request$type == "cancel") {
140+
r$interrupt()
141+
}
142+
}
143+
144+
if (!is.null(running_request)) {
145+
result <- r$read()
146+
if (!is.null(result)) {
147+
print(result)
148+
if (is.list(result$result)) {
149+
response <- result$result
150+
} else {
151+
if (is.null(result$error)) {
152+
response <- list(
153+
id = running_request$id,
154+
type = "text",
155+
result = result$message
156+
)
157+
} else {
158+
response <- list(
159+
id = running_request$id,
160+
type = "error",
161+
result = conditionMessage(result$error)
162+
)
163+
}
164+
}
165+
running_request <- NULL
166+
}
167+
168+
if (!is.null(response)) {
169+
response <- jsonlite::toJSON(response,
170+
auto_unbox = TRUE, force = TRUE)
171+
cat("response: ", response, "\n")
172+
writeLines(response, con)
173+
}
174+
}
175+
176+
Sys.sleep(0.1)
177+
}

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export function activate(context: ExtensionContext) {
207207
commands.registerCommand('r.runCommand', runCommand),
208208
window.onDidCloseTerminal(deleteTerminal),
209209
notebook.registerNotebookContentProvider('r-notebook',
210-
new RNotebookProvider(path.join(context.extensionPath, 'R', 'notebook.R'))),
210+
new RNotebookProvider(path.join(context.extensionPath, 'R', 'notebook2.R'))),
211211
);
212212

213213
if (config().get<boolean>('sessionWatcher')) {

0 commit comments

Comments
 (0)