192 comments

[ 2.9 ms ] story [ 186 ms ] thread
how would compare that to something like YouCompleteMe?
YouCompleteMe will know the specifics of the language you are in so it will be much better at simple syntax, this will be able to learn how you generally do things and repeated patterns, which usually also will get a good bit of the syntax down.
YouCompleteMe will be better than TabNine for API exploration.

TabNine will be more reliable (it will work correctly with malformed, ill-typed, or half-written code) and it can find patterns in your code, like you can see in the pictures on the website.

Hopefully it'd be faster. YouCompleteMe is painfully slow, even after some effort to tweak it.
This is really, really cool and I thank you for this!

I'm seriously hyped, I just hope it works as well as it claims.

edit: Can you provide some help/FAQ on using it from the CLI? I'd like to add support for my own editor, but I'm not yet sure if that's possible.

Thanks!

Thanks for the kind words! I'll write a guide within the next couple of days on how to write a client.
Awesome plugin Jacob. I have a question about the full version, is it per editor? Eg., I use Sublime Text most of the time, but occassionally vim, do I need to buy 2 licenses? Also are these licenses transferrable between machines (work vs home)?
It's per user/email. I just purchased and installed it on my VS Code, and two separate vim installations/instances and they all worked.
Cool technology. Yet, no Emacs support yet... oops :(
Wouldn't we be able to add Emacs support? That's my hope, as my editor isn't on that list either. I'm checking out the install now.
Sorry :( Emacs support is coming within a couple months. You can sign up at https://tabnine.com/install to be notified when it's released.
I'll buy your tool immediately when the emacs support lands. Subscribed already to the email list.
Why is there a premium version ?
To allow the person(s) who implemented it to get paid for their efforts and hard work?
It's also a very competitive price. $29 is excellent for a piece of software that helps my day to day. It's really a sweet spot between very reasonable, and a bit pricey. I'm so happy about this project, and hope it works well (I'll be trying it tonight after work)
I'm going to give it a try tomorrow at work.
No craftsman of any kind would whine about a (good) tool that costs $29 and makes him more productive. I do not see why a progrommer should do that.
On that same note, I wish we were more willing to pay for our tools as a community. If we were, I think more neat and productive projects like this might exist. Yet, developers seem to be historically cheap, and our love for open source (which I do love) seems to be mixed in with our willingness to spend money on our tooling.
I was hoping there was a version that worked with Webstorm or Phpstorm. I can't wait to try this out.
> your software will automatically update to the full released version at no additional charge.

So, give your proprietary software both network access and access to all my source code?

I have very few complaints about the Jedi autocomplete library, which is neither proprietary nor requires network access.

I welcome innovation in dev tools, but I wish you had found a monetization strategy that didn't require us to trust you so completely.

Your concerns are understandable. It is about as risky as installing an editor plugin which updates automatically.

The private keys used to sign releases are kept offline and would not be available to an attacker even if they compromised my online accounts.

Finally, TabNine will work correctly if you deny it network access (say, by blacklisting update.tabnine.com).

Wait, is the auto-update all that's needed for network? I assumed it was license validation or something. If it's just updating, couldn't you provide a different method of updating like manual update checking, and then peoples concerns would be solved?
No, it does use the network to validate registration keys. Presumably this means a TLS connection per invocation of the binary.

> TabNine makes web requests only for the purposes of downloading updates and validating registration keys.

from https://tabnine.com/faq

...as risky as installing a proprietary editor plugin which updates automatically, yes.

Also, AFAIK most understandings of MIT, BSD, and Apache 2.0 licenses require you to acknowledge the copyright holders of the source code you compile into your binary, even if the licenses permit binary distribution. I can't find your "Copyright (c) 2018 Tokio Contributors" or "Copyright (c) 2014 The Rust Project Developers" that I'd expect based on `strings TabNine | grep github`. Maybe you've got a lawyer that suggests otherwise? Your plea of "trust me, I have good hygiene" carries less weight when I have to `strings` your stuff to know what shoulders of which giants you're standing on.

As risky as ones that don't update automatically either. Just because a plugin doesn't update automatically doesn't mean it doesn't still have the capability of doing network access. Unless you're actually sandboxing all your IDE plugins and denying most of them network access (and verifying on every new IDE plugin you install whether it's allowed network access), but I don't believe that's how IDE plugins generally work.
> ...as risky as installing a proprietary editor plugin which updates automatically, yes.

Can't you make the same complaint about any auto-update functionality in any software? Even if it's BSD licensed, you're still counting on whomever has authority to push an update to not push malicious code.

This doesn't seem to have anything to do with the fact that his code is proprietary nor his monetisation strategy, so why are you singling him out for those?

Proprietary - Can't patch out the autoupdate, which I might be tempted to do if something else in my toolchain did things at someone else's leisure.

DRM/monetisation - the product as of my comment didn't seem to acknowledge the open source works compiled into the binary, and I didn't think that was a good look for someone with the authority to push out malicious code.

MIT only requires source attribution. It's the BSD licenses that require attribution for binary forms of redistribution. Still, it is good manners and good cover-your-arse practice to attribute whatever free software work they used (Google does this with their giant "open source licenses" page).
MIT has no special language regarding source or binary distribution, it simply states:

> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

It's up to a court to decide what "copies or substantial portions of the Software" means.

Personally, I've always very much interpreted that to mean both binary and source.

Well, you could argue that the notice is "present" (in a very esoteric sense) in a binary distribution of the software because it was present in the source code used to build it. You could also argue that a compiled version of a program isn't a "copy or substantial portion" of the Software (compilation is effectively a form of translation, which is a derivative work under the Copyright Act in the US -- and not just a copy).

Personally I would still include it in both, but I always had the impression that MIT was looser than BSD-2-Clause about this. BSD-2-Clause explicitly states that binary distribution needs to include the notice in "the documentation and/or other materials provided with the distribution", and I have a feeling that the license authors might've had a reason to want to be explicit about it.

Does the Vim version autoupdate? I'd rather it wait for me to run my plugin manager- I specifically don't want anything on my machine to update when I'm on-call or traveling.
> Finally, TabNine will work correctly if you deny it network access (say, by blacklisting update.tabnine.com).

Just to clarify - would it still work if I deny network acess for the TabNine binary, _after_ validating my license key? Or is the key validation invoked on every launch (hence requiring network access)?

Yes, it will still work.

(License key validation requests go to tabnine.com, so you should blacklist that too if you want to deny all network access.)

Thanks! Purchased a copy :)
I agree with your concerns - I wonder what could be written to alleviate them? This brings up an interesting problem.

Ie, could we write a monitoring proxy where if enabled, all traffic goes through this proxy. This proxy enables the end user to monitor 100% of traffic, all http requests, and could even have a secondary documentation flow that explains the I/O for security minded individuals.

Then you'd shut off remote network access to the binary, monitor all traffic, and feel secure knowing that it's only sending what it says it's sending, and why.

With that said, I imagine you could do the same thing with a sniffer. Perhaps a documentation standard could be built into request/responses, so a monitoring program like Wireshark could snuff the I/O and see what it is.

Do you have any thoughts on how someone could both network-license, and make you feel secure in their I/O? Ie, no trust needed?

I don't think a DRM solution that is both robust against an adversary and inspectable by a stakeholder can be engineered. Software can't look out for both the person running it and the person selling it simultaneously when their needs are mutually exclusive. Cory Doctorow has some eloquent content on the topic, ie at [0].

In this particular case, the use of TLS (good!) makes it relatively challenging to inspect. Assuming the author isn't shipping a cert in his binary (doesn't look like it) - I'd have to spinup a new VM, load a custom root cert, and mess with a TLS terminating proxy / forwarding solution, and hope he's not using a secondary stream cipher on top of TLS. Maybe I get lucky and https://mitmproxy.org/ or something just works out of the box. In any case, lots of effort to know he's not siphoning up all the source code on the local machine and using it to train v2 of his project. And the more robust the DRM solution, the less feasible it is to inspect.

[0] https://github.com/jwise/28c3-doctorow/blob/master/transcrip...

If the amount of traffic is predictably small though, you can be confident that it’s not uploading the entirety of your source code, so perhaps some mechanism to estqblish that would help?
Some code is a lot more valuable than other code. For example, token files for connecting to remote servers.
There is no good reason for authentication secrets to be in your source tree though.

I’m not suggesting this is perfect in any case, but it would at least place an upper bound on whatever amount of IP leakage you think might happen.

But do you ever edit your authentication secrets in your text editor? I edit my .env file in vim all the time.
A combo of two applications: main app and network agent. Main app writes to a file with request, registration check or update, in JSON or other text-format for user inspection. It loads the agent which reads same file, applies operations, sends them to 3rd party, and writes result into another file. Main app reads that the second it appears. To keep it simple and not have to delete, the files might be numbered with old exchanges kept unless admin/owner deletes them.

With such a setup, users can see exactly what data is outgoing, have a reasonable belief they know what's incoming is harmess, main app gets no network access, agent has no access to secrets/system, and agent can be open source (entirely or mostly).

So, there's a quick brainstorm from how I did privilege-minimization for high-assurance security. This is basically a proxy architecture. That's a generic pattern you can always consider since it can help protect lots of risky apps both ways.

Quoting the author from r/rust[0]

> Its paid features are always enabled when completing Rust code, in acknowledgment of the fact that TabNine could not exist without the Rust ecosystem.

Thanks for this, Jacob!

[0] - https://www.reddit.com/r/rust/comments/9uhc1x/tabnine_an_aut...

That's odd, because it could indeed exist without the Rust ecosystem. The author just opted to write it in Rust.
Theoretically we don't even need programming languages or compilers at all. REAL programmers used a magnetized needle and a steady hand. [1]

Following your logic, nobody should show appreciation for anything.

[1] https://xkcd.com/378/

what he meant is you could develop something similar in many other languages with the same complexity / time taken in rust.
I meant he could have said: "Because I love Rust, I'm giving this for free to be used in Rust codebases", instead of "this would never exist if not for Rust".

Or maybe he's serious, maybe the Rust ecosystem literally saved him from death or something like that.

The saying is perfectly standard and meaning has been granted equivalence to your alternative, through common usage. It’s really not a point worth making, or arguing.

Alternatively you could read it as “I wouldn’t have bothered doing this if rust wasn’t there.”

(comment deleted)
Ah, got it! You were being literal and he was not. That's where the confusion is coming from. Your comment came across as mildly aggressive which is probably why you're getting downvoted, but you were just pointing out that what he said made no sense in literal terms which is true.

I don't think it was intended to be interpreted literally. The intent and the feeling behind what he was communicating was represented clearly.

Think of it like "I couldn't have done it without you" when people accept awards. Sure they could have, it's just an expression of appreciation.

He might also not have chased the project if he weren't working in an ecosystem he particularly liked, so who knows, maybe it wouldn't have happened without Rust.

Yeah, you're right. Probably I didn't get the correct linguistic context.

But you never know, maybe in another language he would have done a much better project, maybe not. Actually, in alternative universes everything would probably be different. If Python didn't exist this project would maybe not exist too, and would be at least a little different in any case, so he could have opened the full version to Python codebases too, and that applies to all other languages.

I disagree. I believe most people accepting awards really wouldn't have done it without other people.

Actors do not win Oscars doing great performances in bad movies.

Scientists do not win Nobel prizes working alone or in bad work conditions.

I always take these appreciations at face value.

And programmers build on other peoples work. If you take away Rust? Sure he could have done it. If you take away previous work? No way.
Sure, makes sense. The original argument was that an ecosystem like Python's could have been a possible substitution for Rust, as an example, and therefore it was a baseless statement. Think the analogy with yours would be an equally good screenwriter or scientific collaborator. You need one, but technically maybe not exactly the one you had.

That said, not trying to undercut anyone's appreciative statements, especially the one from OP in his repo towards Rust! Obviously people (and programming languages, for that matter) aren't simple drop-in replacements for each other in real life. You have to be inspired and empowered by them.

That personal motivation or rapport component is probably what was being missed in the post to which I replied.

No, it sounds like TabNine is built using a feature unique to Rust, which is not the case.
And Rails could have been written in C. The reason why it wasn't should be clear. Different languages enable different ways of thinking, and what is hard to express in one can come out easily in another.

This is valid for both programming and human languages.

Not everyone has infinite time for development. If Rust was the only language they could get to the performance they want, with all the features, in the time available then the statement is valid.

Note that they talk about the ecosystem, not just the language. If you want a high performance, compiled language, with a good ecosystem of packages that you can leverage then Rust is a great choice. Arguably Go is the only other language that would fit the bill, but for some people the simpler type system doesn't allow the abstractions they want.

So you can just rename your source file to .rs and use all the paid features.
>TabNine is 11,000 lines of Rust. In recognition of the fact that TabNine could not exist without the Rust ecosystem, TabNine's paid features are always enabled when completing Rust code.

This makes me very happy as a new Rust learner.

Just installed the Sublime Text version.

It seems to work as promised. Would be great if it could support unsaved files too.

I've been using TabNine for a few weeks, and it's really cool how well it works. My first "woah" moment with it was writing a function where the first thing I wanted to do was take the length of the array, and once I started typing

def foo(bar):

    n
it suggested the entire completion of "= len(bar)". It has a really cool way of picking up your coding style that makes it stand out to me.

Full disclosure that I know the author.

I agree that is worthy of a "woah".

Thinking about it more, I wonder how useful that type of autocompletion is for those who can type fast. I wonder how much time it takes my brain to context switch away from "code authoring and typing mode" to recognize the " = len(bar)" in the autocomplete options list. It seems like it would be faster to just type out the " = len(bar)" for those who type a solid 60+ words a minute?

I'm trying it out now. If it works well $30 is nothing for this magic. Especially in VSCode, my favorite editor. I have a problem with many languages not having the support I need. And I also don't have the best memory, so autocompletion makes me much faster and costs me less frustration with Googling.
How does TabNine work for all languages? Curious about implementation details and use with dynamic languages. I would HAPPILY pay $29 if it works well for Ruby.
I've been using it for Python mainly but I find it's really helpful. It can often infer arguments for functions or functions to use based on the variable names. I've used Ruby lots in the past and I think it would work just as well based on my experience. I would give the free version a try and see what you think.
Awesome. Excellent work.

It seems to work with a small Ruby app, but not with a big Ruby on Rails application. Is it because it's too large? How can I check for errors or index status?

Using it with Sublime Text.

I suppose you are running into the index size limitation that is mentioned here: https://tabnine.com/buy
I suppose it's that. I wonder why I don't see any error messages tough. I don't want to buy it if it won't work for my project. It's more than 200kb and 15mb but the .rb are way less.

[edit] Ok, it just took a bit before showing the tab competitions and the license message. Will be useful to know where the index process is at.

[edit2] Just bought a license. Keep up the good work!

I'm also interested in using it for a Rails application. Does it work well with the payed version?
>> with the payed version?

with the paid version

First impression is that this is insanely fast and is actually giving recommendations based on context, without setting up additional files. So, it's doing exactly as advertised.

I'm using this in Vim and would like to know if there's a way to configure it such that the dropdown does not show up until I hit <C-n> or <C-p>? I realize that this is supposed to be a zero-config tool, and I'm asking for a configuration!

Great job with pricing as well. Going to use this for a week before I commit to the license but $29 is a no-brainer for how much use I'll get out of this autocomplete.

I don't think it's supposed to be zero-config, it's just supposed to come with sane defaults.
To answer my own question, the Vim plugin is a fork of YouCompleteMe, so you can configure it as per YouCompleteMe's docs.
I've written a vim plugin for people who use deoplete and YCM would conflict: https://github.com/tbodt/deoplete-tabnine
Thank you for this. The deoplete defaults are much more sane than ycm. I've started using your plugin. I'm glad to see the author of tabnine has asked to feature it on his site.
I wish someone would figure out the right UX for partial autocompletion. e.g. I type "wo" and my phone suggests ("would", "work", "wonder"), there should be an easy way to say I'm trying to type "working" rather than clicking the "work" autocomplete then backspace, then "ing".

I'd imaging TabNine has this problem in spades, since it does such long autocompletes. It could suggest "unsigned long long" when I've typed "unsi" and I really want "unsigned long int". Seems like a tough UX problem. ¯\_(ツ)_/¯

This can work with camel casing. So you type UnsiLI, then enter.
Fwiw, if there are competing `unsigned long int` autocompletes, it looks like it will shorten the recommendation to `unsigned long `, which is really neat.

This is just based on the site, I've not tried it yet. YMMV

Typing an 'r' is faster than clicking on "work" then backspacing.
Which doesn't have anything to do with the problem decribed. He doesn't want to write "wor" but "working".
That can lead to ("Work", "Worry", "Word") so you'd then have to type the 'k'. Now you could have ("Work", "Worker", "Worked") and still are missing the variant you want.

It'd be nice to long press "Work" at step one, get that completed without a space being inserted, then tap 'i' to get ("Working", "Workings", "Workingmen")

Whilst they're doing that how about adding caret-placement sensitivity:

When I click just after the initial letter (pipe representing caret that would be) eg "w|orking" the chances of me wanting to type "worked" are pretty slim; instead it should offer "Dorking" (a UK placename), "borking" and such; according to my frecency scores.

Similarly if I click to place the caret at "work|s" I'm probably after "words" or "worts" (beer stuff), or similar. Again "working|" and I'm probably going to change to a different suffix - works, workers, worked.

I'm amazed that gboard (Google's Android keyboard) doesn't already do that? Perhaps I missed a setting.

The way I use autocomplete is that I type the entire word I mean really quickly. I get most (or all) of it wrong, but the autocompleter has enough information to substitute that with the correct word. It's much faster than the read-evaluate-correct loop you're describing.
It turns out that iOS prediction will make a provisional guess based on what you typed and will go back and adjust its autocorrections as you type subsequent words. You can see this more clearly if you use dictation, but allegedly it won't do as well if you use the word corrections every time.
I’ve noticed that. All my work-related jargon is suggested pretty damn well when it’s appropriate.

What I fear is that the autocomplete can reveal my NSFW jargon. It’s the same keyboard even when Safari is in Private Mode, right?

I feel the same way. Wish I could force/long tap the proper root word and then select the proper 'conjugation'.
UX-wise holding tab would be the best, meaning tab => use completion (like it works now), holding tab => use this completion but show me further possible completions of that word; if it doesn't have any just keep the caret there (for me to finish it writing manually)
Sounds like what you want is fuzzy searching (say fzf [0]) over autocomplete suggestion results. You could type the prefix, and then fuzzy search by typing the suffix to get your desired word (while letting autocomplete fill in the middle of the word).

[0] https://github.com/junegunn/fzf

Xcode has handled this for years. In Xcode, when autocompletion is presented, hitting Tab will complete the longest unique prefixed subword for the currently-selected tab item. If this results in only having one completion option left, then it completes the whole thing (e.g. adding method arguments and whatnot). Similarly, hitting Return will just complete the whole entry instead of the longest unique prefixed subword.

By that I mean if you have 2 autocompletion options `addDefaultFoo()` and `addDefaultBar()`, and you type `add` to get those options, hitting Tab will fill in `addDefault`, and then hitting Tab again will fill in the rest of the selection.

*nix shells typically do something very similar, where hitting tab auto-completes up to the first forking character
After recently binge-watching The Good Place, this comment rattled me :)
Lol, I wasn't the only one!

Which is The Good Place of computer languages?

Lisp? Up front appears to be written with one thing in mind: Infuriate you with brackets.

Then, once you've worked out how to deal with the brackets, it's pretty forking sweet.

Never seen The Good Place so I'm just trying to figure out what the frak you all are taking about.
(comment deleted)
The longest-unique-prefixed-subword is the completion that bash (and tcsh and many other shells) have had for ~30 years now. The non-uniques are listed on the 2nd tab.
Will it work with the existing autocomplete mechanism in vscode python extension?
Any thoughts on how this performs vs deoplete? I've really enjoyed deoplete. It makes my coding quite a bit faster. However I've recently become pretty frustrated with all the gocode forks and go module interaction, so there's definitely room for improvement.
Tabnine and something like deoplete are not directly comparable in my opinion. Deoplete is a completion framework (with dictionary based language specific systems) and tabnine is an intelligent language-agnostic completion system. You could theoretically have Tabnine support deoplete (it is currently YCM based). As the author mentioned in an other reply, dictionary based completion systems are good for api exploration, while tabnine is for more contextual completion.
Deoplete is not dictionary based. Deoplete sources are python classes that yield lists of 'matches' (some are language specific and some are not). You can make it give you back quite about anything.

(Disclaimer: I wrote deoplete's original version of the "file" source, which completes file paths).

Apparently I see two drop downs for auto completion, Since I installed TabNine :/.
Really nice. Good job!

I tested it in Sublime Text, and it's a bit odd that i can tab after i first pressed the tab button and the autocomplete window disappeared, but i think i can work with that :)

Why is the paid index limit 15MB? Why does the paid version have a limit?
I was wondering the same thing. I have a huge project that I would love to TabNine. Since they are still on beta, it's possible to be a product limitation rather than a business limitation.
TabNine will still work on projects of 15MB or more, it will index the 15MB of files that are most relevant to the files you are editing (determined by distance in the directory tree).

The limit exists because otherwise latency or RAM usage might be too high.

Any chance this could be a configuration option?
A configuration option would indeed be nice. I have more than enough memory for tools providing a high value for my daily work. Kudos for setting same defaults!
I tried the free version and immediately jumped to premium.

Very impressive work. Best software purchase in a long time.

This looks great. Giving it a try right now.

Also really awesome of you to provide premium features to the Rust ecosystem for free.

“If TabNine does not work as soon as you install it, this is a bug and you should file an issue.”

Just wonderful. All dev tools should be like this.

I got great results for a PHP/JS project straight away — an instant upgrade for me just to support continued development.

This sounds like a cool idea for an open-source project. :-)
Looks neat! Is there a way to make the autocomplete popup in sublime text look like the original one? Mine looks terrible right now.