Christophe Weblog Wiki Code Publications Music
implement swank:interactive-eval and swank:eval-and-grab-output
[swankr.git] / swank.R
diff --git a/swank.R b/swank.R
index ddd1a0e5b64df12104370a3851e55cf3e9981379..18269449e914970f099c240fc916ead34f11c159 100644 (file)
--- a/swank.R
+++ b/swank.R
@@ -230,10 +230,8 @@ writeSexpToString <- function(obj) {
 
 printToString <- function(val) {
   f <- fifo("")
-  sink(f)
-  print(val)
-  sink()
-  readLines(f)
+  tryCatch({ sink(f); print(val); sink(); readLines(f) },
+           finally=close(f))
 }
 
 `swank:connection-info` <- function (io, sldbState) {
@@ -310,3 +308,37 @@ printToString <- function(val) {
     list(as.list(matches), longest)
   }
 }
+
+`swank:compile-string-for-emacs` <- function(io, sldbState, string, buffer, position, filename, policy) {
+  # FIXME: I think in parse() here we can use srcref to associate
+  # buffer/filename/position to the objects.  Or something.
+  withRestarts({ times <- system.time(eval(parse(text=string), envir = globalenv())) },
+               abort="abort compilation")
+  list(quote(`:compilation-result`), list(), TRUE, times[3])
+}
+
+`swank:interactive-eval` <-  function(io, sldbState, string) {
+  retry <- TRUE
+  value <- ""
+  while(retry) {
+    retry <- FALSE
+    withRestarts(value <- eval(parse(text=string), envir = globalenv()),
+                 retry=list(description="retry SLIME interactive evaluation request", handler=function() retry <<- TRUE))
+  }
+  printToString(value)
+}
+
+`swank:eval-and-grab-output` <- function(io, sldbState, string) {
+  retry <- TRUE
+  value <- ""
+  output <- NULL
+  f <- fifo("")
+  tryCatch({
+    sink(f)
+    while(retry) {
+      retry <- FALSE
+      withRestarts(value <- eval(parse(text=string), envir = globalenv()),
+                   retry=list(description="retry SLIME interactive evaluation request", handler=function() retry <<- TRUE))}},
+           finally={sink(); output <- readLines(f); close(f)})
+  list(output, printToString(value))
+}