I recently installed the Tabnine plugin for Sublime (Windows), and spent the last several weeks using it while coding on some of my side projects, just long enough to get a solid first impression of this tool: Tabnine is amazing.
Going in, I was a tad skeptical that a tool was going to be able to figure out what I was trying to do in my code fast enough to suggest anything more substantial than just completing the current identifier.
But I have been really pleasantly surprised, and delighted, by just how quickly this tool is learning my code—and how quickly I’m learning to use it!—to accelerate my coding. I wanted to share some examples I recently captured, to give you an idea of the kinds of things you may see if you use it.
Of course, this tool is powered by complex natural-language ML models and rulesets, and it learns from each project it’s used on, so… YMMV. But, I think if you give Tabnine (or Codota, depending on which editor you use) a try, I think you may be amazed at what pops into the autocomplete drop-down! Check it out.
The first example I want to show you came from a segment of logic I was writing which just happened to have a pretty clear structural pattern to it, though I didn’t plan it that way particularly. And I didn’t realize it at the time, but it seems like that was a really attractive opportunity for the Tabnine plugin to kick in with its powerful semantic analysis.
As you’ll see, it progressively figured out more of the structure as I went along, and made even more impressive suggestions at each juncture!
I had a bit of code logic that processing a couple of URLs that had been split into multiple parts (“protocol”, “origin”, and “path”), and I needed to compare these parts (including handling *
wildcards) to see if the URLs match.
The result should be a boolean (true
/ false
) if a match exists respectively for each part of the URLs.
As you can see in this screenshot, the plugin figured out that I wanted to use another variable called pageProtocol
for the comparison. You don’t see this in the screenshot, but that variable is declared a dozen or so lines above, in the same function, nearby where patternProtocol
is declared. So, Tabnine figured out that these two identifiers might have a relationship.
I hadn’t even typed p
yet, so it just made that guess not based on token completion but on semantics.
Continuing on, the next boolean I wanted to declared, I typed pat
, as you can see, and Tabnine (somehow, not quite sure!) figured out that I wanted to type pathMatches
! OK, now I’m impressed.
So I started to fill out this boolean’s matching logic, and…
Boom, it knew that I needed to do the wildcard check again. Notice how it knew that semantic, but it also knew that I needed patternPath
as the identifier! How!? My best guess is, it understood the relationship in the first declaration between protocolMatches
and patternProtocol
, and thus extrapolated that same relationship between pathMatches
and patternPath
. And as a bonus, it even added the ||
on the end.
I won’t lie, that was a little freaky at how good that suggestion was!
Continuing on, it seems to be understanding the structure of these comparisons, and how the different variables fit in, kinda like the semantic analysis results in a “template” that identifiers drop into:
Wow. This is really starting to be quite helpful.
Let’s keep going. Now I realized that I accidentally skipped over the “origin” matching boolean, so I went back to insert that in the middle:
Here it still understands enough to suggest the rest of that line of code as soon as I get to the “O”. Nice.
Then…
I typed just one letter, p
, and it knew the whole rest of the line! And it got both identifiers correct! This is really, really impressive. I’m hooked.
So here’s the completed snippet:
After I see the code snippet complete, then I realized something I hadn’t seen before… the plugin even understood that in each pair of comparisons, I was intentionally using ==
for one check and ===
for the other. That’s on purpose, because of the nature of the values that I know can be in each of those variables. I don’t think Tabnine used any type awareness for those suggestions, but it’s still cool that it respected how I was doing my comparisons.
OK, so… in that previous example, the structure was a little too convenient, and that ended up helping Tabnine make some pretty great suggestions. Right?
What if another chunk of code has a little less obvious structure to pick up on? Will I still get useful suggestions?
Check out how Tabnine here figured out that I might want to assign the value from the property that I did a check for in the surrounding if
statement. That’s indeed what I was going for, and Tabnine nailed it!
This example really amazed me… I sat there for a good several seconds doing a double and triple take, saying, like “Really, did it actually make that whole suggestion!?”
It clearly matched to the for
-loop from the earlier function, but look at how it correctly figured out that the method to call was getVideoTracks()
instead of just copying getAudioTracks()
. I guess it got the hint from the names of the functions I chose (which was accidental, I promise).
But it’s really pleasing to see the tool figuring these nuances out!
Here’s another example where a previous statement gave just enough of a hint to Tabnine:
Again, it figured out the relationship between the variable windowWidth
and the property name outerWidth
. We’ve already seen that.
But it also figured out that I was wanted to deal with height instead of width. How did it do that? I think it picked up on that detail from the previous two lines, which involved width
/ videoWidth
and height
/ videoHeight
, respectively. So it extrapolated that since I did “width”, then “height” before, that I probably wanted to do that again on these two lines.
Again, my only reaction is… just… wow. Cool.
So, obviously, this tool is learning, not just from all the public code the models were trained against, not just from the rules the Codota folks baked in, but also it’s learning from my project, my code. As I used Tabnine, it’s learning how to help me more effectively.
That’s just super satisfying to realize.
But there’s another effect here. As I get more used to using Tabnine, I am learning. I’m learning to use the tool more effectively. I’m actually sensing when and how I might be able to code in such a way as to give it enough hints that it’ll spit out a useful suggestion to save me some typing.
That’s not perfect or completely deterministic, of course—this is AI!—but, I’m finding that maybe 1 out of 3 times I try to get it to give me a specific suggestion, sure enough, it spits out something either spot on or pretty close.
So it’s like the Tabnine tool and I are mutually learning each other. This just feels really good. We’re both working together to make me more effective and efficient at coding.
I know this article focuses mostly on all the happy path examples I pulled out. You may still be skeptical, like I was. You may be wondering about the limitations and the times it gets it flat out wrong.
Yes, there are definitely limitations to this. Yes, it definitely spits out wrong suggestions a fair bit.
But, in my estimation so far, I’d say about 50-75% of the time that I see the autocomplete list popup a set of semantic suggestions from Tabnine, at least one of the suggestions is at least part of what I was likely going to type. And maybe 10-20% of the time, those suggestions are something I should type, but my brain hadn’t quite come up with yet!
Over time, I expect this tool will only get better at helping me out. And I’m really excited to be working with the folks at Codota to provide them feedback on how to improve the tool even further. There’s already a long list of fun and cool things we’re exploring, so stay tuned to this space!
If you try out the Tabnine (or Codota) plugin for your editor, and you give it a week or two to get used to (and for it to learn your coding), I think you’ll be really pleasantly surprised at how helpful you may find it. If so, I hope you’ll reach out to me via social media (@getify on Twitter, etc) and let me know what’s great and what you hope it can eventually do!