Mysteries of auto-completion

Sometimes it works, sometimes it doesn’t, I can never tell why. Some examples:

In 3.3.2 (270):


AutoCompletionTestClass = class()

function init(x)
    self.autocompletesInsideInstanceFunction = true
    self.completionAfterInstantiationAtRoot = false
    self.autocompletesInsideARootFunction = false
    end
    
    function AutoCompletionTestClass:testInsideInstanceFunction()
        succeedsInAutocompletion = self.autocompletesInsideInstanceFunction
        end
        
        instance = AutoCompletionTestClass()
        doesNotAutocompleteHere = instance.completionAfterInstantiationAtRoot
        
        function rootLevelFunctionAutocompletionTest()
            theFollowingVariableNameActuallyDoesAutocompleteHereIfYouCanBelieveIt = doesNotAutocompleteHere
            butHereAgainAutocompletionFails = instance.autocompletesInsideARootFunction
            end

Sorry for the screwy indentations but that’s a current Codea bug.

@UberGoober What are you trying to do or what are we supposed to do.

@UberGoober If you’re just showing a bunch of long names and wondering how autocomplete works, here’s the 2 rules that I know of.

  1. when you start keying something, autocomplete will list whatever begins with that letter or string of letters/numbers.

  2. as soon as an exact match happens somewhere, autocomplete stops matching anything.

Autocorrect is extremely flakey.

I was trying to figure out when it works and when it doesn’t.

This code demonstrates some cases where it fails, though probably not all.

If the meaning of the variable names is not apparent to you, you may have to type the code in to understand what’s happening, because then you’ll see Codea’s behavior as you type each letter.

But reading the names over may help make it clear happening in each case, without you having to manually type in anything.

In the cases of the variable names on the left side of the equals sign, they tell you whether the autocompletion attempted on that line succeeded.

So the line beginning succeedsInAutocompletion shows an instance where the autocompletion worked, in other words, when Codea noticed the letters for the beginning of the variable name on the right side of the equals sign being typed in, it suggested the correct completion.

The lines beginning with terms that indicate failure, such as doesNotAutocompleteHere and `butHereAgainCompletionFails," show instances where, when Codea noticed the letters for the beginning of the variable names on the right side of the equals sign being typed in, it did not suggest the correct completions.

In the same vein, the line beginning theFollowingVariableNameActuallyDoesAutocompleteHereIfYouCanBelieveIt indicates an instance in which, when Codea noticed the letters for the beginning of the variable name on the right side of the equals sign being typed in, it suggested the correct completion, and doing so was somewhat improbable, given that it did not correctly suggest completion for the variables on the right side of the equals sign in either the previous case or the following case.

So as you see, lines beginning with terms that indicate success signify that autocompletion performed correctly on them, and lines beginning with terms that indicate failure signify that autocompletion failed to perform correctly.

As for the names of the variables on the right side of the equals sign, in other words the variables that themselves either correctly or incorrectly triggered autocompletion suggestions, they describe the circumstances in which completion is being attempted.

So in the case of the line where self.autocompletesInsideInstanceFunction is on the right side of the equals sign, autocompletion is being attempted inside a function belonging to an instance of the class that declared the variable itself.

In the line where instance.completionAfterInstantiationAtRoot is on the right side of the equals sign, autocompletion is being attempted at the root level, after instantiating the class, on that instance of the class.

In the line where instance.autocompletesInsideARootFunction is on the right side of the equals sign, autocompletion is being attempted inside a root function, again on the same instance of that class.

@Simeon I don’t know if tuning-up autocompletion is any kind of priority, but personally, it sure helps a lot when it works. If that’s on your list, hopefully this can help in debugging it.

@UberGoober I think I tried everything. I keyed single letters, and some specific words and here’s what I got with autocomplete. I think everything showed the way it should. If something is missing, show me what you keyed and what should have showed up in autocomplete.

a           AutoCompletionTestClass
b           butHereAgainAutocompletionFails 
d           doesNotAutocompleteHere 
i           instance
r           rootLevelFunctionAutocompletionTest   
s           succeedsInAutocompletion  
t         theFollowingVariableNameActuallyDoesAutocompleteHereIfYouCanBelieveIt 

instance.   instance.autocompletesInsideARootFunction
instance.   instance.completionAfterInstantiationAtRoot
           
self.       self.autocompletesInsideARootFunction
self.       self.autocompletesInsideInstanceFunction
self.       self.completionAfterInstantiationAtRoot

@dave1707 …but you didn’t type it in the order I did.

You didn’t follow the order and you also didn’t follow the context.

My results happen when, for instance, rootLevelFunctionAutocompletionTest is typed in an actual root level function.

That’s why I did it that way.

@UberGoober I’ll have to say that what you’re showing is correct. I took your above code and copied it into a new project. I then commented it out and tried to key it line by line. I gave up after about 8 lines because the variable names were so long and similar and I couldn’t keep track of what was supposed to work and what wasn’t. I’ll let @Simeon figure it out.

Now I remember why I keep my variable names small.

@dave1707 ypu don’t have to use that exact combination of letters to see the effects I see, you just have to use names long enough to trigger autocomplete and use them in the order and contexts shown.

Thanks for such a thorough exploration @UberGoober, very helpful! Will debug it

@Simeon glad to help!

@dave1707 I tried to cut down the wordiness here:


AutoCompletionTestClass = class()

function init(x)
    self.apple = 0
    self.banana = 0
    self.coconut = 0
end
    
function AutoCompletionTestClass:instanceFunction()
    self.apple = 0 --autocompletes correctly
end

instance = AutoCompletionTestClass()

bananaClone = instance.banana --does not autocomplete
               
function rootLevelFunction()
    bananaClone = 0 --does autocomplete, surprisingly
    instance.coconut = 0 --does not autocomplete
end

@UberGoober the behaviour you describe in the last comment is correct

Lua is a dynamically typed language, so we have no idea what type instance is. However, I think we could probably just go the route of “complete everything” and expose every property to every dot-syntax completion weighted by how likely it is to be relevant

In your example the type is very clear but consider:

instance = AutoCompletionTestClass()

function foo(x) 
    x.banana -- We would have no idea here what `x` is
end

function bar()
    foo(instance)
end

I think there are probably some better heuristics we could apply to figure this out, or maybe just showing every possible completion as a fallback could work well

@UberGoober Your cut down version makes it a lot easier to see the problem. As Simeon said, it’s too hard to figure out every name that should show for autocomplete. Because I use such small variable names when I code, the way autocomplete works now gets in my way more than it helps. If there was an option to turn off autocomplete, I would probably do it.

@Simeon I understand what you mean about the challenges, and I am willing to live with an incomplete system, I was just curious about why it works sometimes and why it doesn’t.

Showing every possible combination would probably work well for small projects, and actually, since the results would get more accurate the more you typed, it might even work well for larger ones.

A few other thoughts:

  • you could prioritize completion of names the were on the current tab maybe?
  • since the environment already treats classes as special cases, there must be some kind of tracking of which variables are classes and which are not, no? If that was the case, would that enable tracking separately the names of variables attached to classes? Or maybe just the class variables contained in the init() for that class? This already seems to work sometimes but I can’t tell why.
  • would it be non-trivial to separate names that are defined at the root level from names defined one level deep? So the environment could track foo separately from bar.foo, and make suggestions equivalently?

Anyway it’s all up to you of course. I do think even just your omni-completion concept would be a huge help. Not having to switch to another tab when I can’t remember if a function was called selectFoo() or chooseFoo() would save a bunch of time.

The more I think about it the more it seems like doing every possible variable would be hugely helpful and a 1000% improvement on what we have now.

leading underbar on asset name foils autocomplete

All - out of curiosity, since I have an impression (that may be wrong). Is autocomplete context sensitive ?

I ask because I have seen variables in function searches in the past. The recent graphics images associated with autocomplete menus do help but tend to be scrollably long so many menu items may not be seen.

@dave1707 your single-letters work for me because you favor short-and-sweet code that doesn’t take me too long to decipher.

Something like SODA, on the other hand, is full of one-and-two letter variables floating unmoored amidst a sea of daunting complexity, at least to me.

I have an exceedingly poor memory, and I prefer verbose names, not just because it helps me understand other people’s code, but also because it helps me remember what the heck my own code is supposed to be doing. :wink:

@UberGoober The reason I use simple, small variable names is because I only write code while I’m watching TV. My iPad is sitting on the table next to the couch. If I’m on the couch then I’m watching TV and if I respond to a forum question or write code, then I’m doing it with the TV on. Right now I’m watching a rerun of Blue Bloods. If I write something that I think is important and fairly large, when I’m done I’ll go thru the code and expand on the names with something more appropriate. Also, small variable name lets me write code faster since I’m using the built in keyboard and one finger to type. I can probably type faster with one finger than most people can using as many fingers as they want.

@dave1707 makes sense. Also: impressive.

I’m finding the new auto-completion odd, in that it seems less useful, in many cases, than the old one. It seems to be offering all kinds of things that couldn’t possibly be useful. I suppose it’s just not context-sensitive, at least in some cases, but I’m glad there aren’t very many words other than aardvark that start with two letter a’s. :smiley: