mainLoop <- function(io) {
while(TRUE) {
- tryCatch(dispatch(io, readPacket(io)),
- swankTopLevel=function(c) NULL)
+ withRestarts(tryCatch(dispatch(io, readPacket(io)),
+ swankTopLevel=function(c) NULL),
+ abort="return to SLIME's toplevel")
}
}
ok <- TRUE
}, error=function(c) {
newSldbState <- makeSldbState(c, if(is.null(sldbState)) 0 else sldbState$level+1, id)
- sldbLoop(io, newSldbState, id) })},
+ withRestarts(sldbLoop(io, newSldbState, id), abort=paste("return to sldb level", newSldbState$level)) })},
finally=sendToEmacs(io, list(quote(`:return`), if(ok) list(quote(`:ok`), value) else list(quote(`:abort`)), id)))
}
makeSldbState <- function(condition, level, id) {
- ret <- list(condition=condition, level=level, id=id)
+ calls <- rev(sys.calls())[-1]
+ frames <- rev(sys.frames())[-1]
+ restarts <- rev(computeRestarts(condition))[-1]
+ ret <- list(condition=condition, level=level, id=id, restarts=restarts, calls=calls, frames=frames)
class(ret) <- c("sldbState", class(ret))
ret
}
sldbLoop <- function(io, sldbState, id) {
- sendToEmacs(io, c(list(quote(`:debug`), id, sldbState$level), debuggerInfoForEmacs(sldbState)))
- sendToEmacs(io, list(quote(`:debug-activate`), id, sldbState$level, FALSE))
- while(TRUE) {
- dispatch(io, readPacket(io), sldbState)
- }
+ tryCatch({
+ sendToEmacs(io, c(list(quote(`:debug`), id, sldbState$level), debuggerInfoForEmacs(sldbState)))
+ sendToEmacs(io, list(quote(`:debug-activate`), id, sldbState$level, FALSE))
+ while(TRUE) {
+ dispatch(io, readPacket(io), sldbState)
+ }
+ }, finally=sendToEmacs(io, c(list(quote(`:debug-return`), id, sldbState$level, FALSE))))
}
debuggerInfoForEmacs <- function(sldbState, from=0, to=NULL) {
backtraceForEmacs <- function() {
- calls <- sys.calls()
+ calls <- sldbState$calls
if(is.null(to)) to <- length(calls)
from <- from+1
calls <- lapply(calls[from:to], { frameNumber <- from-1;
function (x) { ret <- list(frameNumber, paste(format(x), sep="", collapse=" ")); frameNumber <<- 1+frameNumber; ret }})
}
computeRestartsForEmacs <- function () {
- lapply(computeRestarts(sldbState$condition),
+ lapply(sldbState$restarts,
function(x) {
## this is all a little bit internalsy
restartName <- x[[1]][[1]]
writeSexpToStringLoop(obj)
}
+printToString <- function(val) {
+ f <- fifo("")
+ sink(f)
+ print(val)
+ sink()
+ readLines(f)
+}
+
`swank:connection-info` <- function (io, sldbState) {
list(quote(`:pid`), Sys.getpid(),
quote(`:package`), list(quote(`:name`), "R", quote(`:prompt`), "R> "),
`swank:listener-eval` <- function(io, sldbState, string) {
val <- eval(parse(text=string), envir = globalenv())
- f <- fifo("")
- sink(f)
- print(val)
- sink()
- lines <- readLines(f)
- list(quote(`:values`), paste(lines, collapse="\n"))
+ string <- printToString(val)
+ list(quote(`:values`), paste(string, collapse="\n"))
}
`swank:autodoc` <- function(io, sldbState, rawForm, ...) {
"No Arglist Information"
}
+`swank:operator-arglist` <- function(io, sldbState, op, package) {
+ list()
+}
+
`swank:throw-to-toplevel` <- function(io, sldbState) {
condition <- simpleCondition("Throw to toplevel")
class(condition) <- c("swankTopLevel", class(condition))
`swank:invoke-nth-restart-for-emacs` <- function(io, sldbState, level, n) {
if(sldbState$level == level) {
- invokeRestart(computeRestarts()[[n+1]])
+ invokeRestart(sldbState$restarts[[n+1]])
+ }
+}
+
+`swank:buffer-first-change` <- function(io, sldbState, filename) {
+ FALSE
+}
+
+`swank:frame-locals-and-catch-tags` <- function(io, sldbState, index) {
+ str(sldbState$frames)
+ frame <- sldbState$frames[[1+index]]
+ objs <- ls(envir=frame)
+ list(lapply(objs, function(name) { list(quote(`:name`), name,
+ quote(`:id`), 0,
+ quote(`:value`), paste(printToString(eval(parse(text=name), envir=frame)), sep="", collapse="\n")) }),
+ list())
+}
+
+`swank:simple-completions` <- function(io, sldbState, prefix, package) {
+ ## fails multiply if prefix contains regexp metacharacters
+ matches <- apropos(sprintf("^%s", prefix), ignore.case=FALSE)
+ nmatches <- length(matches)
+ if(nmatches == 0) {
+ list(list(), "")
+ } else {
+ longest <- matches[order(nchar(matches))][1]
+ while(length(grep(sprintf("^%s", longest), matches)) < nmatches) {
+ longest <- substr(longest, 1, nchar(longest)-1)
+ }
+ list(as.list(matches), longest)
}
}