[ESS] Support for more R completion features in ESS

Deepayan Sarkar deep@y@n@@@rk@r @end|ng |rom gm@||@com
Tue Dec 22 15:17:24 CET 2020


Dear All,

Background: Some new experimental completion facilities in R cannot be
currently used in ESS. I was able to come up with small hacks to
enable them, but in the case of company-mode I needed to disable
caching, which is probably not a good idea. I was wondering if it
would make sense to at least have the option of activating these
features through a user-customizable variable.

New completion features:

1. The first one has been around for a while, and is activated by setting

rc.settings(fuzzy = TRUE)

This offers completions like

getany -> getAnywhere
library_dynam -> library.dynam

This is not "fuzzy" completion in the sense used in the Emacs world,
but rather what company-mode refers to as non-prefix completion. The
first example can be made to work (for both built-in completion and
company-mode) by simply setting

(setq completion-ignore-case t)

The second one is (I think) not possible at all with the built-in
completion, but is in principle supported by company-mode.

2. The other new feature, potentially much more useful, is the
possibility of allowing user-provided completion functions to
supplement the built-in completions provided by R. This requires a
very recent R-devel (>= r79644). A simple prototype showing how this
feature might be useful is available here:

https://raw.githubusercontent.com/deepayan/misc/master/experiments/custom-completions.R

After sourcing this file, the following completions should work with
the readline interface:

(a) with(faithful, erup -> eruptions
(b) with(faithful, mean(erup -> eruptions
(c) faithful |>  transform(wroot = sqrt(waiting)) |> with(wro -> wroot

Changes required in ESS:

1. The "default" completion, which is what I use most of the time,
actually needs very little change. It already supports (a), and (b)
and (c) will work with the following change here:

https://github.com/emacs-ess/ESS/blob/master/lisp/ess-r-completion.el#L151

-      (let* ((funstart (cdr (ess--fn-name-start)))
-             (completions (ess-r-get-rcompletions funstart))
+      (let* ((completions (ess-r-get-rcompletions))

(essentially let R figure out the starting point).

This should have minimal performance impact.

2. company-mode

This is too complicated for me to understand in any depth, but a
minimal change that seems to support both user-supplied completion as
well as non-prefix completion is in the company-R-objects backend:

https://github.com/emacs-ess/ESS/blob/master/lisp/ess-r-completion.el#L359

     (candidates (let ((proc (ess-get-next-available-process)))
                  (when proc
-                    (with-current-buffer (process-buffer proc)
-                      (all-completions arg
(ess--get-cached-completions arg))))))
+                    (cdr (ess-r-get-rcompletions)))))

Obviously this is not a good idea always, but maybe this behaviour
could be customizable (with a proper implementation).

Apart from not using the cache, this is also doing something weird at
the beginning of a function. Compare trying to complete:

with(faithful, mean(wait
with(faithful, mean(

with the cursor just after "mean(" in both cases.

But I don't think this is due to my change. Even without the change, I
get a bunch of spurious completions that seem to come from my TAGS
file.

Regards,
-Deepayan



More information about the ESS-help mailing list