Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: R Notebook #394

Draft
wants to merge 79 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
8adbe76
Use proposed api
renkun-ken Aug 10, 2020
b677ebc
Use RNotebookProvider
renkun-ken Aug 10, 2020
0525207
Read Rmd into cells
renkun-ken Aug 11, 2020
6378bec
Fix code
renkun-ken Aug 11, 2020
493eb5a
Add simple notebook kernel script
renkun-ken Aug 11, 2020
b95d003
Fix openNotebook
renkun-ken Aug 11, 2020
b6c9fc6
Start R from script
renkun-ken Aug 11, 2020
c4ecfed
Use single quotes
renkun-ken Aug 11, 2020
504ece8
Rename notebook
renkun-ken Aug 11, 2020
b46d1b3
Update notebook.ts
renkun-ken Aug 11, 2020
bdec79b
Update folder
renkun-ken Aug 11, 2020
d97ae29
Update notebook.ts
renkun-ken Aug 11, 2020
a2cb420
Update notebook server
renkun-ken Aug 11, 2020
24a3c6d
Update notebook
renkun-ken Aug 11, 2020
20a5b4b
Update notebook
renkun-ken Aug 12, 2020
cd90c18
Update notebook
renkun-ken Aug 12, 2020
54ec035
Update socket
renkun-ken Aug 12, 2020
577e98b
Update notebook
renkun-ken Aug 12, 2020
3d2c61a
Update R/notebook.R
renkun-ken Aug 12, 2020
af838cd
Implement saveNotebook
renkun-ken Aug 13, 2020
ec170d2
Update save notebook
renkun-ken Aug 13, 2020
0b882c9
Update notebook
renkun-ken Aug 13, 2020
c5eb58f
Update notebook
renkun-ken Aug 13, 2020
c58ac7c
Update notebook
renkun-ken Aug 13, 2020
435674d
Update eval
renkun-ken Aug 13, 2020
53e1ac0
Handle error and output
renkun-ken Aug 13, 2020
f3f1555
Store Rmd chunk header and footer
renkun-ken Aug 13, 2020
a716867
Fix lint
renkun-ken Aug 13, 2020
d9da970
Update notebook
renkun-ken Aug 13, 2020
7c8741c
Update notebook
renkun-ken Aug 16, 2020
bf5665c
Add initial capability of plot
renkun-ken Aug 16, 2020
4213381
Update notebook
renkun-ken Aug 16, 2020
d588e41
Update notebook
renkun-ken Aug 16, 2020
c2be46e
Use svglite for plot
renkun-ken Aug 17, 2020
9526454
Update svglite usage
renkun-ken Aug 17, 2020
9fb31ab
Update notebook
renkun-ken Aug 17, 2020
41f5283
Capture viewer, page_viewer, and browser request
renkun-ken Aug 17, 2020
503d242
Initialize cell metadata
renkun-ken Aug 26, 2020
5dd3a91
Update vscode.proposed.d.ts
renkun-ken Aug 26, 2020
3e517d9
Refine notebook
renkun-ken Aug 26, 2020
abf9db8
Fix request
renkun-ken Aug 26, 2020
b45a89f
Update notebook
renkun-ken Aug 26, 2020
2c3ae3b
Update vscode.proposed.d.ts
renkun-ken Aug 27, 2020
6027f4b
Update logging in notebook.R
renkun-ken Aug 27, 2020
f483aa6
Register R kernel
renkun-ken Aug 27, 2020
c2a8afe
Fix kernel viewType
renkun-ken Aug 27, 2020
c9cd51c
Fix reading cells from rmd
renkun-ken Aug 30, 2020
c366b31
Experiment with callr session
renkun-ken Sep 13, 2020
3d383d4
Update notebook2
renkun-ken Sep 14, 2020
3de3650
Update notebook2
renkun-ken Sep 14, 2020
1c1a87e
Update notebook2
renkun-ken Sep 14, 2020
a08a53c
Update notebook2
renkun-ken Sep 14, 2020
0283fb3
Update notebook2
renkun-ken Sep 14, 2020
24ed50a
Support cancel
renkun-ken Sep 14, 2020
241a728
Remove uri
renkun-ken Sep 14, 2020
ff5587e
Rename scripts
renkun-ken Sep 14, 2020
7950418
Update eval
renkun-ken Sep 14, 2020
70ae405
Use onNotebook:r-notebook
renkun-ken Sep 14, 2020
cb06e7c
Update src/notebook.ts
renkun-ken Sep 14, 2020
9e2a72d
Update vscode.proposed.d.ts
renkun-ken Sep 19, 2020
77b4c01
Update vscode.proposed.d.ts
renkun-ken Oct 12, 2020
87a4c8a
Rename interface
renkun-ken Oct 12, 2020
8e73f03
updates vscode proposed
markbaas Feb 3, 2021
8c35e79
missing some things after rebase
markbaas Feb 3, 2021
87fe395
allows output tables
markbaas Feb 3, 2021
0349010
adds command for restarting kernel
markbaas Feb 4, 2021
3c9f018
fixes plots not being displayed and adding cleaner solution for plots.
markbaas Feb 4, 2021
84f57df
allows viewer output
markbaas Feb 5, 2021
9f9e8cd
prettier output tables
markbaas Feb 5, 2021
fc47817
implements table renderer
markbaas Feb 9, 2021
ba7672a
proper implementation for the viewer
markbaas Feb 9, 2021
3ce52a5
disable other output formats
markbaas Feb 9, 2021
694e60b
fixes some types
markbaas Feb 10, 2021
8c6d6b7
refactored some deprecates
markbaas Feb 10, 2021
138f387
Refine code
renkun-ken Feb 10, 2021
4643031
should load outputs and metadata from json file.
markbaas Feb 10, 2021
ae075b3
Merge branch 'notebook' of https://github.com/renkun-ken/vscode-R int…
markbaas Feb 10, 2021
b86f9fb
saving and loading output works now.
markbaas Feb 12, 2021
2621bc8
update to latest proposed api.
markbaas Feb 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ tmp.*
temp.*
tmp
temp
.Rhistory
.Rproj.user
8 changes: 8 additions & 0 deletions R/client.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
con <- socketConnection(host = "127.0.0.1", port = 8708,
blocking = TRUE, server = FALSE, open = "r+")
request <- list(time = format(Sys.time()), expr = "1+1")
json <- jsonlite::toJSON(request, auto_unbox = TRUE)
writeLines(json, con)
response <- readLines(con, n = 1)
response
close(con)
188 changes: 188 additions & 0 deletions R/notebook.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
requireNamespace("jsonlite")
requireNamespace("callr")

args <- commandArgs(trailingOnly = TRUE)
exprs <- parse(text = args, keep.source = FALSE)
env <- new.env()
for (expr in exprs) {
eval(expr, env)
}

r <- callr::r_session$new(
callr::r_session_options(
system_profile = TRUE, user_profile = TRUE, supervise = TRUE),
wait = TRUE, wait_timeout = 3000
)

r$run(function() {
requireNamespace("jsonlite")

.vscNotebook <- local({
viewer_file <- NULL
browser_url <- NULL
plot.new.called <- FALSE

set_plot_new <- function() {
plot.new.called <<- TRUE
}
setHook("before.plot.new", set_plot_new)
setHook("before.grid.newpage", set_plot_new)

options(
viewer = function(url, ...) {
viewer_file <<- url
},
page_viewer = function(url, ...) {
viewer_file <<- url
},
browser = function(url, ...) {
browser_url <<- url
}
)

evaluate <- function(id, expr) {
plot_dir <- tempdir()
plot_file <- file.path(plot_dir, "plot%03d.svg")

viewer_file <<- NULL
browser_url <<- NULL
error <- NULL

res <- tryCatch({
svg(plot_file, width = 12, height = 8)
expr <- parse(text = expr)
out <- withVisible(eval(expr, globalenv()))
text <- utils::capture.output(print(out$value, view = TRUE))
}, error = function(e) {
error <<- list(
id = id,
type = "error",
result = list(error = conditionMessage(e))
)
}, finally = {
graphics.off()
})

if (!is.null(error)) {
error
} else if (plot.new.called) {
plot.new.called <<- FALSE

list(
id = id,
type = "plot",
# FIXME: support multiple plots
result = list(plot = list.files(plot_dir, pattern = ".*\\.svg", full.names = TRUE))
)
} else if (!is.null(viewer_file)) {
list(
id = id,
type = "viewer",
result = list(file = viewer_file)
)
} else if (!is.null(browser_url)) {
list(
id = id,
type = "browser",
result = list(url = browser_url)
)
} else if (out$visible) {
if (is.data.frame(out$value)) {
table <- head(out$value, 10)
list(
id = id,
type = "table",
result = list(
markdown = paste0(knitr::kable(table, format = "markdown"), collapse = "\n"),
data = head(out$value, 1000)
)
)
} else {
list(
id = id,
type = "text",
result = list(text = paste0(text, collapse = "\n"))
)
}
} else {
list(
id = id,
type = "text",
result = list(text = "")
)
}
}

environment()
})

attach(environment(), name = "tools:vscNotebook")
NULL
})

con <- socketConnection(host = "127.0.0.1", port = env$port, open = "r+b")
running_request <- NULL

while (TRUE) {
response <- NULL
if (socketSelect(list(con), timeout = 0)) {
header <- readLines(con, 1, encoding = "UTF-8")
n <- as.integer(gsub("^Content-Length\\: (\\d+)$", "\\1", header))
content <- readChar(con, n, useBytes = TRUE)
Encoding(content) <- "UTF-8"
cat(content, "\n", sep = "")

request <- jsonlite::fromJSON(content, simplifyVector = FALSE)
if (request$type == "eval") {
response <- tryCatch({
r$call(function(id, expr) {
.vscNotebook$evaluate(id, expr)
}, list(id = request$id, expr = request$expr))
running_request <- request
NULL
}, error = function(e) {
list(
id = request$id,
type = "error",
result = conditionMessage(e)
)
})
} else if (request$type == "cancel") {
r$interrupt()
}
}

if (!is.null(running_request)) {
result <- r$read()
if (!is.null(result)) {
print(result)
if (is.list(result$result)) {
response <- result$result
} else {
if (is.null(result$error)) {
response <- list(
id = running_request$id,
type = "text",
result = result$message
)
} else {
response <- list(
id = running_request$id,
type = "error",
result = conditionMessage(result$error)
)
}
}
running_request <- NULL
}

if (!is.null(response)) {
response <- jsonlite::toJSON(response,
auto_unbox = TRUE, force = TRUE)
cat("response: ", response, "\n")
writeLines(response, con)
}
}

Sys.sleep(0.05)
}
Loading