header <- readChunk(io, 6)
len <- strtoi(header, base=16)
payload <- readChunk(io, len)
- readSexpFromString(payload)
+ sexp <- readSexpFromString(payload)
+ sexp
}
readChunk <- function(io, len) {
- buffer <- readChar(io, len)
+ buffer <- readChar(io, len, useBytes=TRUE)
if(length(buffer) == 0) {
condition <- simpleCondition("End of file on io")
class(condition) <- c("endOfFile", class(condition))
signalCondition(condition)
}
- if(nchar(buffer) != len) {
- stop("short read in readChunk")
- }
+ ## FIXME: with the useBytes argument to readChar, it is normal for
+ ## the buffer returned to be fewer character than bytes were read,
+ ## given the possibility of multibyte characters. However, that
+ ## means we can’t detect at all the case where there is actually a
+ ## short read (though empirically the readChar call blocks rather
+ ## than returning early).
+ ##
+ ## if(nchar(buffer) != len) {
+ ## stop("short read in readChunk")
+ ## }
buffer
}
`swank:connection-info` <- function (slimeConnection, sldbState) {
list(quote(`:pid`), Sys.getpid(),
quote(`:package`), list(quote(`:name`), "R", quote(`:prompt`), "R> "),
- quote(`:version`), "2012-04-23",
+ quote(`:version`), "2014-09-13",
quote(`:encoding`), list(quote(`:coding-systems`), list("utf-8-unix")),
quote(`:lisp-implementation`), list(quote(`:type`), "R",
quote(`:name`), "R",
list("R", "R")
}
+`swank-repl:create-repl` <- `swank:create-repl`
+
makeReplResult <- function(value) {
string <- printToString(value)
list(quote(`:write-string`), string,
list()
}
+`swank-repl:listener-eval` <- `swank:listener-eval`
+
+`swank:clear-repl-variables` <- function(slimeConnection, sldbState) {
+ list()
+}
+
`swank:autodoc` <- function(slimeConnection, sldbState, rawForm, ...) {
list("No Arglist Information", TRUE)
}
helpFilesWithTopicString(value)
}
+`swank:apropos-list-for-emacs` <- function(slimeConnection, sldbState, name, onlyExternal, package, caseSensitive) {
+ x <- help.search(name, fields="alias", package=.packages())$matches
+ brieflyDescribe <- function(name, title) {
+ if (exists(name, globalenv())) {
+ val <- get(name, globalenv())
+ kind <- if("function" %in% class(val)) quote(`:function`) else quote(`:variable`)
+ list(quote(`:designator`), name, kind, title)
+ } else {
+ ## maybe
+ list(quote(`:designator`), name, quote(`:type`), title)
+ }
+ }
+ mapply(brieflyDescribe, x[,"name"], x[,"title"], SIMPLIFY=FALSE)
+}
+
+`swank:describe-definition-for-emacs` <- function(slimeConnection, sldbState, name, kind) {
+ `swank:describe-symbol`(slimeConnection, sldbState, name, NULL)
+}
+
`swank:throw-to-toplevel` <- function(slimeConnection, sldbState) {
condition <- simpleCondition("Throw to toplevel")
class(condition) <- c("swankTopLevel", class(condition))
list())
}
-`swank:simple-completions` <- function(slimeConnection, sldbState, prefix, package) {
- symbolFieldsCompletion <- function(object, rest) {
- ## FIXME: this is hacky, ignoring several syntax issues (use of
- ## and/or necessity for backquoting identifiers: e.g. fields
- ## containing hyphens)
- if((dollar <- regexpr("$", rest, fixed=TRUE)) == -1) {
- matches <- grep(sprintf("^%s", literal2rx(rest)), names(object), value=TRUE)
- matches <- sprintf("%s$%s", gsub("\\$[^$]*$", "", prefix), matches)
- returnMatches(matches)
+symbolFieldsCompletion <- function(object, prefix, rest) {
+ ## FIXME: this is hacky, ignoring several syntax issues (use of
+ ## and/or necessity for backquoting identifiers: e.g. fields
+ ## containing hyphens)
+ if((dollar <- regexpr("$", rest, fixed=TRUE)) == -1) {
+ matches <- grep(sprintf("^%s", literal2rx(rest)), names(object), value=TRUE)
+ matches <- sprintf("%s$%s", gsub("\\$[^$]*$", "", prefix), matches)
+ returnMatches(matches)
+ } else {
+ if(exists(substr(rest, 1, dollar-1), object)) {
+ symbolFieldsCompletion(get(substr(rest, 1, dollar-1), object), prefix, substr(rest, dollar+1, nchar(rest)))
} else {
- if(exists(substr(rest, 1, dollar-1), object)) {
- symbolFieldsCompletion(get(substr(rest, 1, dollar-1), object), substr(rest, dollar+1, nchar(rest)))
- } else {
- returnMatches(character(0))
- }
+ returnMatches(character(0))
}
}
- returnMatches <- function(matches) {
- nmatches <- length(matches)
- if(nmatches == 0) {
- list(list(), "")
- } else {
- longest <- matches[order(nchar(matches))][1]
- while(length(grep(sprintf("^%s", literal2rx(longest)), matches)) < nmatches) {
- longest <- substr(longest, 1, nchar(longest)-1)
- }
- list(as.list(matches), longest)
+}
+
+returnMatches <- function(matches) {
+ nmatches <- length(matches)
+ if(nmatches == 0) {
+ list(list(), "")
+ } else {
+ longest <- matches[order(nchar(matches))][1]
+ while(length(grep(sprintf("^%s", literal2rx(longest)), matches)) < nmatches) {
+ longest <- substr(longest, 1, nchar(longest)-1)
}
+ list(as.list(matches), longest)
}
- literal2rx <- function(string) {
- ## list of ERE metacharacters from ?regexp
- gsub("([.\\|()[{^$*+?])", "\\\\\\1", string)
- }
+}
+
+literal2rx <- function(string) {
+ ## list of ERE metacharacters from ?regexp
+ gsub("([.\\|()[{^$*+?])", "\\\\\\1", string)
+}
+
+`swank:simple-completions` <- function(slimeConnection, sldbState, prefix, package) {
matches <- apropos(sprintf("^%s", literal2rx(prefix)), ignore.case=FALSE)
nmatches <- length(matches)
if((nmatches == 0) && ((dollar <- regexpr("$", prefix, fixed=TRUE)) > -1)) {
- symbolFieldsCompletion(globalenv(), prefix)
+ symbolFieldsCompletion(globalenv(), prefix, prefix)
} else {
returnMatches(matches)
}