Commit f198b5e4 authored by Christophe Rhodes's avatar Christophe Rhodes
Browse files

rework `swank:simple-completions`

In the process, implement looking up foo$bar$baz, and passing those
completions back.  It's not completely robust to somewhat exotic
syntax, as it assumes that the text being completed can be used
directly as character vectors naming objects or fields; it is good
enough to get started, and now a lot less annoying to
use (particularly when lots of fields have underscores in them...)
parent 62734d71
......@@ -79,7 +79,7 @@
To reproduce, C-c I globalenv() RET, or hit RET on environment
presentations in the debugger (if presentations are on).
* OPEN #22 completion of named list fields :WISHLIST:
* RESOLVED #22 completion of named list fields :WISHLIST:FIXED:
It is very nice in ESS to be able to type df$ TAB and get a
completion list of the data frame's columns. Supporting it in
swankr should be really easy.
......
......@@ -455,20 +455,44 @@ computeRestartsForEmacs <- function (sldbState) {
}
`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)
} 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 <- 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)
}
matches <- apropos(sprintf("^%s", literal2rx(prefix)), ignore.case=FALSE)
nmatches <- length(matches)
if(nmatches == 0) {
list(list(), "")
if((nmatches == 0) && ((dollar <- regexpr("$", prefix, fixed=TRUE)) > -1)) {
symbolFieldsCompletion(globalenv(), prefix)
} 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(matches)
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment