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

move R code into hera #130

Draft
wants to merge 57 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
e24ca01
ignore R project
romainfrancois Feb 6, 2025
187dd8d
:baby: :package:
romainfrancois Feb 6, 2025
176225b
packages imports
romainfrancois Feb 6, 2025
f94f5cb
move utils to hera
romainfrancois Feb 6, 2025
22e9e1f
placeholder for when loading hera
romainfrancois Feb 6, 2025
b568c2e
interpreter::configure_impl() should just be loading the hera package…
romainfrancois Feb 6, 2025
e91284b
.xeus_call -> hera:::hera_call
romainfrancois Feb 6, 2025
f57ce32
ignore .Rhistory
romainfrancois Feb 6, 2025
993ea51
+ hera_dot_call()
romainfrancois Feb 6, 2025
f2bd5db
move comm code to hera using hera_dot_call
romainfrancois Feb 6, 2025
e351248
move completion code to hera
romainfrancois Feb 6, 2025
d76fe9f
move inspect code to hera
romainfrancois Feb 6, 2025
5737a26
init_options() happens as part of loading the package
romainfrancois Feb 6, 2025
6251a80
njo longer need these
romainfrancois Feb 6, 2025
4554ed4
move log code to hera
romainfrancois Feb 6, 2025
911a001
no longer need to be here
romainfrancois Feb 6, 2025
fff3ae4
comment
romainfrancois Feb 6, 2025
e74ebc5
moving cell_options() to here
romainfrancois Feb 6, 2025
4ed6e86
the$frame_cell_execute
romainfrancois Feb 6, 2025
26b37bf
more moving things around
romainfrancois Feb 6, 2025
bd1c548
oopsy
romainfrancois Feb 6, 2025
55b0507
pkg stuff
romainfrancois Feb 6, 2025
08684ca
empty NAMESPACE for now
romainfrancois Feb 6, 2025
7661b4b
move the before other files
romainfrancois Feb 6, 2025
6abcb83
ignore
romainfrancois Feb 7, 2025
12cf499
using roxygen
romainfrancois Feb 7, 2025
a2624fd
rename to avoid check errors
romainfrancois Feb 7, 2025
081e9a1
import pdf and png
romainfrancois Feb 7, 2025
ecb8c9b
more hera_dot_call
romainfrancois Feb 7, 2025
e700738
passing check
romainfrancois Feb 7, 2025
13dac5b
no configure in hera
romainfrancois Feb 7, 2025
9ca0655
workaround for now
romainfrancois Feb 10, 2025
9826c5f
correctly set R_INCLUDE_DIR to R_HOME/include
romainfrancois Feb 11, 2025
e91248f
ignore default paths
romainfrancois Feb 11, 2025
52df11e
addding R package dependencies of hera
romainfrancois Feb 11, 2025
b41efe9
+ dependencies of hera
romainfrancois Feb 11, 2025
c3b8671
locally install R package hera
romainfrancois Feb 11, 2025
bcaca39
Merge branch 'main' into uncouple_hera
romainfrancois Feb 11, 2025
a5448f9
skip some tests for now
romainfrancois Feb 11, 2025
bdb41fb
🫣
romainfrancois Feb 11, 2025
efbcca7
adding some documentatio to complete()
romainfrancois Feb 11, 2025
e98be91
bring back completion tests
romainfrancois Feb 11, 2025
f7ea1ae
export and document clear_output()
romainfrancois Feb 11, 2025
9500f75
Fix and export is_xeusr()
romainfrancois Feb 11, 2025
9129136
Fix and test is_xeusr()
romainfrancois Feb 11, 2025
26cf448
bring back code_clear_output test
romainfrancois Feb 11, 2025
7c746f3
abort hera_dot_call() when !xeusr
romainfrancois Feb 11, 2025
0f47dbc
bring back code_display_data
romainfrancois Feb 11, 2025
378d54c
mkdir temp_r_lib
romainfrancois Feb 12, 2025
b273bdc
ignore tgz
romainfrancois Feb 12, 2025
022c8c9
install hera
romainfrancois Feb 12, 2025
1e42249
making temp_r_lib on actions
romainfrancois Feb 12, 2025
d9999a9
here too
romainfrancois Feb 12, 2025
96188a8
trying a different way
romainfrancois Feb 12, 2025
fb715cd
not needed
romainfrancois Feb 12, 2025
f534fd9
improve msg
romainfrancois Feb 12, 2025
1877bc1
rm resources mounting
romainfrancois Feb 12, 2025
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ bld
Untitled*.ipynb
*.log
/*.ipynb
.Rproj.user
.Rhistory
hera.Rcheck
hera_*.tar.gz
hera_*.tgz
12 changes: 10 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,16 @@ message(STATUS "R_LDFLAGS = ${R_LDFLAGS}")
message(STATUS "R_LIBRARY_BASE = ${R_LIBRARY_BASE}")
message(STATUS "R_LIBRARY_BLAS = ${R_LIBRARY_BLAS}")
message(STATUS "R_LIBRARY_LAPACK = ${R_LIBRARY_LAPACK}")
message(STATUS "R_VERSION_MAJOR = ${R_VERSION_MAJOR}")
message(STATUS "R_VERSION_MINOR = ${R_VERSION_MINOR}")
message(STATUS "R_VERSION_MAJOR = ${R_VERSION_MAJOR}")
message(STATUS "R_VERSION_MINOR = ${R_VERSION_MINOR}")

# Install R package hera
# ======================

message(STATUS "Installing R 📦 hera to temporary library")
execute_process(COMMAND ${R_COMMAND} CMD INSTALL --preclean --no-staged-install --library=temp_r_lib --build ../hera)
install(DIRECTORY temp_r_lib/ DESTINATION ${R_HOME}/library)
execute_process(COMMAND ${R_SCRIPT_COMMAND} -e "writeLines(paste('Installed 📦 hera version', as.character(packageVersion('hera'))))")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After these, we get 3 things:

  • the (binary) 📦 is installed where it needs to for local use, e.g. ${R_HOME}/library
  • the (binary) 📦 is also in the temp_r_lib/hera directory:
(xeusr2025) romainfrancois@tada build % tree temp_r_lib/hera
temp_r_lib/hera
├── DESCRIPTION
├── INDEX
├── LICENSE
├── Meta
│   ├── Rd.rds
│   ├── features.rds
│   ├── hsearch.rds
│   ├── links.rds
│   ├── nsInfo.rds
│   └── package.rds
├── NAMESPACE
├── R
│   ├── hera
│   ├── hera.rdb
│   └── hera.rdx
├── help
│   ├── AnIndex
│   ├── aliases.rds
│   ├── hera.rdb
│   ├── hera.rdx
│   └── paths.rds
└── html
    ├── 00Index.html
    └── R.css

5 directories, 20 files
  • because of the --build option, we get the hera_****.tgz file as well, if that makes it easier for EMSCRIPTING it, whatever that means :p

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For EMSCRIPTING, having hera installed in ${R_HOME}/library should be enough

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @IsabelParedes I'll simplify then

Copy link
Contributor Author

@romainfrancois romainfrancois Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So now we have two things:

  • the .tgz but if we don't need it, we can remove the --build option if it's not needed.
  • the binary 📦 installed in {R_HOME}/library, i.e.
(xeusr2025) romainfrancois@tada build % tree /Users/romainfrancois/miniforge3/envs/xeusr2025/lib/R/library/hera
/Users/romainfrancois/miniforge3/envs/xeusr2025/lib/R/library/hera
├── DESCRIPTION
├── INDEX
├── LICENSE
├── Meta
│   ├── Rd.rds
│   ├── features.rds
│   ├── hsearch.rds
│   ├── links.rds
│   ├── nsInfo.rds
│   └── package.rds
├── NAMESPACE
├── R
│   ├── hera
│   ├── hera.rdb
│   └── hera.rdx
├── help
│   ├── AnIndex
│   ├── aliases.rds
│   ├── hera.rdb
│   ├── hera.rdx
│   └── paths.rds
└── html
    ├── 00Index.html
    └── R.css

5 directories, 20 files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a look at the failures in the Build and Deploy workflow, but I think I'm now stuck on how to move this forward. cc @SylvainCorlay @IsabelParedes happy to jump on a call.


# Configuration
# =============
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Then you can compile the sources (replace `$CONDA_PREFIX` with a custom installa
prefix if need be)

```bash
mkdir build && cd build
mkdir build && cd build && mkdir temp_r_lib
cmake .. -D CMAKE_PREFIX_PATH=$CONDA_PREFIX -D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX -D CMAKE_INSTALL_LIBDIR=lib
make && make install
```
Expand Down
9 changes: 5 additions & 4 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ dependencies:
- nlohmann_json=3.11.3
- r-base >=4
# Run dependencies
- r-rlang
- r-cli
- r-evaluate
- r-jsonlite
- r-glue
- r-cli
- r-repr
- r-IRdisplay
- r-jsonlite
- r-r6
- r-repr
- r-rlang
# Test dependencies
- pytest
- jupyter_kernel_test>=0.5,<0.6
Expand Down
2 changes: 2 additions & 0 deletions environment-wasm-host.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ dependencies:
# Run dependencies
- r-rlang
- r-evaluate
- r-glue
- r-r6
- r-jsonlite
- r-glue
- r-cli >=3.6.3
Expand Down
3 changes: 3 additions & 0 deletions hera/.Rbuildignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
^LICENSE\.md$
^.*\.Rproj$
^\.Rproj\.user$
22 changes: 22 additions & 0 deletions hera/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Package: hera
Title: Companion to the 'xeus-r' 'Jupyter' kernel for R
Version: 0.0.0.9000
Authors@R: c(
person("Romain", "François", email = "[email protected]", role = c("aut", "cre"))
)
Description: Set of R functions to be coupled with the xeus-r jupyter kernel for R.
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
Imports:
cli,
evaluate,
glue,
IRdisplay,
jsonlite,
R6,
repr,
rlang,
tools,
utils
2 changes: 2 additions & 0 deletions hera/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
YEAR: 2025
COPYRIGHT HOLDER: Quantstack
21 changes: 21 additions & 0 deletions hera/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# MIT License

Copyright (c) 2025 Quantstack

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
17 changes: 17 additions & 0 deletions hera/NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by roxygen2: do not edit by hand

export(View)
export(clear_output)
export(complete)
export(display_data)
export(is_xeusr)
importFrom(R6,R6Class)
importFrom(grDevices,pdf)
importFrom(grDevices,png)
importFrom(jsonlite,fromJSON)
importFrom(jsonlite,toJSON)
importFrom(jsonlite,unbox)
importFrom(rlang,caller_env)
importFrom(utils,capture.output)
importFrom(utils,head)
importFrom(utils,tail)
2 changes: 2 additions & 0 deletions hera/R/00_init.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NAMESPACE <- environment()
the <- NULL
3 changes: 3 additions & 0 deletions hera/R/cell_options.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cell_options <- function(...) {
rlang::local_options(..., .frame = the$frame_cell_execute)
}
86 changes: 44 additions & 42 deletions share/jupyter/kernels/xr/resources/comm.R → hera/R/comm.R
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
comm_target_env <- new.env()

.CommManager__register_target_callback <- function(comm, request) {
target_callback <- comm_target_env[[request$content$target_name]]
target_callback(comm, request)
}

CommManagerClass <- R6::R6Class("CommManagerClass",
CommManagerClass <- R6Class("CommManagerClass",
public = list(
initialize = function() {
private$targets <- new.env()
Expand All @@ -12,90 +14,90 @@ CommManagerClass <- R6::R6Class("CommManagerClass",

register_comm_target = function(target_name, callback) {
private$targets[[target_name]] <- callback
invisible(.Call("CommManager__register_target", target_name, PACKAGE = "(embedding)"))
},
invisible(hera_dot_call("CommManager__register_target", target_name, PACKAGE = "(embedding)"))
},

unregister_comm_target = function(target_name) {
rm(list = target_name, private$targets)
invisible(.Call("CommManager__unregister_target", target_name, PACKAGE = "(embedding)"))
},
invisible(hera_dot_call("CommManager__unregister_target", target_name))
},

new_comm = function(target_name) {
xp <- .Call("CommManager__new_comm", target_name, PACKAGE = "(embedding)")
xp <- hera_dot_call("CommManager__new_comm", target_name)
if (is.null(xp)) {
stop(glue::glue("No target '{target_name}' registered"))
}
Comm$new(xp = xp)
}
),
),

private = list(
targets = NULL,
targets = NULL,
comms = NULL
)
)
CommManager <- CommManagerClass$new()

Comm <- R6::R6Class("Comm",
Comm <- R6Class("Comm",
public = list(
initialize = function(xp) {
private$xp <- xp
},
},

open = function(metadata = NULL, data = NULL) {
js_metadata <- jsonlite::toJSON(metadata)
js_data <- jsonlite::toJSON(data)
js_metadata <- toJSON(metadata)
js_data <- toJSON(data)

invisible(.Call("Comm__open", private$xp, js_metadata, js_data, PACKAGE = "(embedding)"))
},
invisible(hera_dot_call("Comm__open", private$xp, js_metadata, js_data))
},

close = function(metadata = NULL, data = NULL) {
js_metadata <- jsonlite::toJSON(metadata)
js_data <- jsonlite::toJSON(data)
js_metadata <- toJSON(metadata)
js_data <- toJSON(data)

invisible(.Call("Comm__close", private$xp, js_metadata, js_data, PACKAGE = "(embedding)"))
},
invisible(hera_dot_call("Comm__close", private$xp, js_metadata, js_data))
},

send = function(metadata = NULL, data = NULL) {
js_metadata <- jsonlite::toJSON(metadata)
js_data <- jsonlite::toJSON(data)
js_metadata <- toJSON(metadata)
js_data <- toJSON(data)

invisible(.Call("Comm__send", private$xp, js_metadata, js_data, PACKAGE = "(embedding)"))
},
invisible(hera_dot_call("Comm__send", private$xp, js_metadata, js_data))
},

on_close = function(handler) {
private$close_handler <- handler
invisible(.Call("Comm__on_close", private$xp, handler, PACKAGE = "(embedding)"))
},
invisible(hera_dot_call("Comm__on_close", private$xp, handler))
},

on_message = function(handler) {
private$message_handler <- handler
invisible(.Call("Comm__on_message", private$xp, handler, PACKAGE = "(embedding)"))
invisible(hera_dot_call("Comm__on_message", private$xp, handler))
}
),
),

active = list(
id = function() {
.Call("Comm__id", private$xp, PACKAGE = "(embedding)")
},
hera_dot_call("Comm__id", private$xp)
},

target_name = function() {
.Call("Comm__target_name", private$xp, PACKAGE = "(embedding)")
hera_dot_call("Comm__target_name", private$xp)
}
),

private = list(
xp = NULL,
close_handler = NULL,
xp = NULL,
close_handler = NULL,
message_handler = NULL
)
)

Message <- R6::R6Class("Message",
Message <- R6Class("Message",
public = list(
initialize = function(xp) {
private$xp <- xp
},
},

print = function() {
print(cli::rule("$content"))
Expand All @@ -110,23 +112,23 @@ Message <- R6::R6Class("Message",
print(cli::rule("$metadata"))
str(self$metadata)
}
),
),

active = list(
content = function() {
jsonlite::fromJSON(.Call("Message__get_content", private$xp, PACKAGE = "(embedding)"))
},
fromJSON(hera_dot_call("Message__get_content", private$xp))
},

header = function() {
jsonlite::fromJSON(.Call("Message__get_header", private$xp, PACKAGE = "(embedding)"))
},
fromJSON(hera_dot_call("Message__get_header", private$xp))
},

parent_header = function() {
jsonlite::fromJSON(.Call("Message__get_parent_header", private$xp, PACKAGE = "(embedding)"))
},
fromJSON(hera_dot_call("Message__get_parent_header", private$xp))
},

metadata = function() {
jsonlite::fromJSON(.Call("Message__get_metadata", private$xp, PACKAGE = "(embedding)"))
fromJSON(hera_dot_call("Message__get_metadata", private$xp))
}
),

Expand Down
51 changes: 51 additions & 0 deletions hera/R/completion.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
triple_colon <- function(pkg, fun) {
eval(rlang::call2(":::", as.symbol(pkg), as.symbol(fun)))
}

utils___assignLineBuffer <- triple_colon("utils", ".assignLinebuffer")
utils___assignEnd <- triple_colon("utils", ".assignEnd")
utils___guessTokenFromLine <- triple_colon("utils", ".guessTokenFromLine")
utils___completeToken <- triple_colon("utils", ".completeToken")
utils___retrieveCompletions <- triple_colon("utils", ".retrieveCompletions")

#' Code completion
#'
#' @param code R code to complete
#' @param cursor_pos position of the cursor
#'
#' @return a list that contains potential completions as the first item
#'
#' @export
complete <- function(code, cursor_pos = nchar(code)) {
# Find which line we're on and position within that line
lines <- strsplit(code, '\n', fixed = TRUE)[[1]]
chars_before_line <- 0L
for (line in lines) {
new_cursor_pos <- cursor_pos - nchar(line) - 1L # -1 for the newline
if (new_cursor_pos < 0L) {
break
}
cursor_pos <- new_cursor_pos
chars_before_line <- chars_before_line + nchar(line) + 1L
}

# guard from errors when completion is invoked in empty cells
if (is.null(line)) {
line <- ''
}

utils___assignLineBuffer(line)
utils___assignEnd(cursor_pos)

info <- utils___guessTokenFromLine(update = FALSE)
utils___guessTokenFromLine()
utils___completeToken()

start_position <- chars_before_line + info$start
comps <- utils___retrieveCompletions()

list(
comps,
c(start_position, start_position + nchar(info$token))
)
}
Loading
Loading