[ESS] Easy argument list: r-autoyas
Vitalie Spinu
spinuvit.list at gmail.com
Thu Mar 10 17:28:16 CET 2011
Sven Hartenstein <lists at svenhartenstein.de> writes:
> Here is the code:
> http://www.svenhartenstein.de/Software/R-autoyas
>
> I'd love to receive your honest feedback!
Hi Sven,
A very nice attempt indeed. It can become a very useful addition to ESS.
One further step would be to have an option to scroll through methods
arguments, but that would take some considerable thinking.
Here are a couple of points of how to improve on what you did. The complete
code follows.
First, it would be probably more convenient if "(" key would directly invoke
the yas/expand. This is what I have in my .emacs:
(define-key ess-mode-map (kbd "(") '(lambda () (interactive)
(skeleton-pair-insert-maybe nil)
(r-autoyas-expand nil t))))
Second, it is nice to have C-g to delete all the remaining arguments (as
you've already suggested on your site). The easiest way I could find is to
advise yas/abort-snippet. Please see below.
Third, it is inconvenient to maintain both .emacs and .Rprofile, one way of
avoiding it is to "inject" the necessary commands each time R-session starts
by means of ess-post-run-hook.
This is the complete r-autoyas code which I have got in my .emacs:
;;;_ autoyas
(defun r-autoyas-exit-snippet-delete-remaining ()
"Exit yas snippet and delete the remaining argument list."
(interactive "*")
(let ((deletefrom (point)))
(yas/exit-all-snippets)
(delete-region deletefrom (point))))
(defun r-autoyas-expand (&optional funname no-paren)
"Insert argument list (in parentheses) of R function before the
point as intelligent yas snippets and expand the snippets."
(interactive "*")
(if (null funname)
(setq funname (ess-r-args-current-function)))
(ess-command (concat "r.autoyas.create('" funname "')\n")
(get-buffer-create "*r-autoyas*"))
(unless (null funname)
(let (snippet)
(with-current-buffer "*r-autoyas*"
(if (< (length (buffer-string)) 10);; '[1] " "' if no valid fun
(message "No valid function!")
(delete-region 1 6)
(goto-char (point-max))
(delete-backward-char 2)
(goto-char (point-min))
(replace-string "\\\"" "\"")
(goto-char (point-min))
(replace-string "\\\\" "\\")
(setq snippet (buffer-string))
(when no-paren
(setq snippet (substring snippet 1 -1)))
))
(when snippet
(yas/expand-snippet snippet)
))))
(defun r-autoyas-inject-commands ()
(process-send-string (get-process ess-current-process-name)
"r.autoyas.esc <- function(str) {
str <- gsub('$', '\\\\$', str, fixed=TRUE)
str <- gsub('`', '\\\\`', str, fixed=TRUE)
return(str)
};
r.autoyas.create <- function(funname) {
if (!existsFunction(funname)) return(' ')
formals <- formals(funname)
nr <- 0
closebrackets <- 0
str <- NULL
for (field in names(formals)) {
type <- typeof(formals[[field]])
if (type=='symbol' & field!='...') {
nr <- nr+1
str <- append(str, paste(', ${',nr,':',field,'}', sep=''))
} else if (type=='symbol' & field=='...') {
nr <- nr+2
str <- append(str, paste('${',nr-1,':, ${',nr,':',field,'}}', sep=''))
} else if (type=='character') {
nr <- nr+2
str <- append(str, paste('${',nr-1,':, ',field,'=${',nr,':\\'',gsub('\\'', '\\\\\\'', r.autoyas.esc(encodeString(formals[[field]])), fixed=TRUE),'\\'}}', sep=''))
} else if (type=='logical') {
nr <- nr+2
str <- append(str, paste('${',nr-1,':, ',field,'=${',nr,':',as.character(formals[[field]]),'}}', sep=''))
} else if (type=='double') {
nr <- nr+2
str <- append(str, paste('${',nr-1,':, ',field,'=${',nr,':',as.character(formals[[field]]),'}}', sep=''))
} else if (type=='NULL') {
nr <- nr+2
str <- append(str, paste('${',nr-1,':, ',field,'=${',nr,':NULL}}', sep=''))
} else if (type=='language') {
nr <- nr+2
str <- append(str, paste('${',nr-1,':, ',field,'=${',nr,':',r.autoyas.esc(deparse(formals[[field]])),'}}', sep=''))
}
}
str <- paste(str, sep='', collapse='')
if (grepl(', ', str, fixed=TRUE)) str <- sub(', ', '', str) # remove 1st ', ' (from 1st field)
str <- paste('(',str,')', sep='')
str
}\n")
)
(defadvice yas/abort-snippet (around r-delete-remaining)
(if (member major-mode '(ess-mode inferior-ess-mode))
(r-autoyas-exit-snippet-delete-remaining)
ad-do-it)
)
(ad-activate 'yas/abort-snippet)
(add-hook 'ess-post-run-hook 'r-autoyas-inject-commands)
(define-key ess-mode-map (kbd "C-M-<tab>")
'(lambda ()(interactive)(r-autoyas-expand nil t)))
(define-key ess-mode-map (kbd "(") '(lambda () (interactive)
(skeleton-pair-insert-maybe nil)
(r-autoyas-expand nil t)))
Best,
Vitalie.
>
> Sven
>
> ______________________________________________
> ESS-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/ess-help
More information about the ESS-help
mailing list