Skip to content

UI suggestion: allow a tab with no more suggestions to fill in "$"

4 messages · Timothy Bates, Simon Urbanek

#
Like most of us I am sure, I use the tab completion system a lot, not just to complete object names, but to pick from the drop-list created when one hits tab after a $ sign.

Current situation to get to  "object$part1$level2? the user currently has to type:
1. "obj?" (completed to "object")
2. Type "$?" and pick part1
3. Type "$?" and pick level2

Suggestion: make a second "tab" press fill in the $-sign. That would reduce the above to:
1. "obj?" (completed to "object")
2. Type "? ?" and pick part1
3. Type "? ?" and pick level2

MUCH quicker, as the dollar sign involves lifting finger off tab key, hitting (for English) shift-4 (a two hand operation, or an awkward one-hand stretch), then moving back to the tab key.

Users of the @ accessor  might feel left out - perhaps give them shift-tab :-)

PS: Still be nice bump up the font size in the bottom tool-tip bar, if only back to the old physical height (or perhaps just re-use the RStudio tool-tip completion system)
3 days later
#
Tim,

but how should be determine that you want $? If it's a matrix, maybe you want [ ... if it's a function maybe you want ( ... it looks like a hornet's nest to me, but if you provide logic, we may be able to code it up ;)

Cheers,
Simon
On May 20, 2016, at 8:08 AM, Timothy Bates <tim.bates at ed.ac.uk> wrote:

            
#
On 24 May 2016, at 12:59 am, Simon Urbanek <simon.urbanek at r-project.org> wrote:
Hi Simon,

My logic is as follows:

1. When a name is already complete, when the user pushes tab again, they are expecting ?more? name completion, i.e.,  they want to access a $ or @ sub-component. Currently, nothing happens, and the user feels ?thwarted?? like the typing ?Simon" but then having to type a space and a tab to get "Urbanek" :-)

2. Most object components are $ indexed rather than @ indexed), so $ is the best guess.

Based on this, a simple logic of "append $ if the current name is a valid name" would be an advance in many cases. I can?t see a downside.

A smarter logic would call .DollarNames() on the current word and if it found $ items, then append the $ and display the dropdown, if not, beep.

Re ?why not offer mtcars[] instead of mtcars$?? or adding the round brackets to a function, I think the answer is that while perhaps an appropriately smart version of rcompgen could support this, users are expecting tab completion to complete names and in R, that means a complete addressable name for an object component.

So I think that having tab add a $ accessor would seem natural, whereas having one tab complete the name, and the next one add brackets would not.

Currently, I find that the mental context switch from completing a name to accessing or filling in parameters is sufficiently ?different? that typing the bracket ending seems natural, and it?s nice that R.app gives us the closing bracket for free.

Cheers, tim

https://stat.ethz.ch/R-manual/R-devel/library/utils/html/rcompgen.html

PS: Indeed, a type-aware completion system would be great (as you imply). I enjoy the feature in RStudio now where valid completions are given, for instance, within a square bracket context. i.e., mtcars[1,?] gives a drop down of column names - much easier than running names() in the terminal to remember what is what.

  
    
#
That seems like a very strong assumption and my point questioning that assumption. For a lot of objects $ makes no sense which is why I'm reluctant to add $ unconditionally. Really, it only makes sense for lists (and some subclasses) - anything else gets a bit dodgy (it works for some but not others).

That said, I suppose one possible approach would be to catch any completion that yields just the items itself and if that happens attempt a completion with $ appended and see what it yields. If it yields anything additional, return that result instead. You can test whether you like that by using something like the following:


add.fn("rcompgen.completion", function (x)
{
    comp <- function(x) {
         utils:::.assignLinebuffer(x)
         utils:::.assignEnd(nchar(x))
         utils:::.guessTokenFromLine()
         utils:::.completeToken()
         utils:::.CompletionEnv[["comps"]]
    }
    res <- unique(comp(x))
    if (nzchar(x) && identical(res, x) && !identical(substr(x, nchar(x), nchar(x) + 1L), "$")) {
       rc <- comp(paste0(x, "$"))
       if (!identical(substr(rc, nchar(rc), nchar(rc) + 1L), "$")) res <- rc
    }
    res
})

Obviously, you can eve spin that further and carry on with @ if $ doesn't work.

Cheers,
Simon