29 comments

[ 3.1 ms ] story [ 81.4 ms ] thread
This whole time I had no idea vim could autocomplete
This is classic "string-based" autocomplete. It completes based on strings it knows about but doesn't take into account the context. I've used for years but yesterday I realized that since Vim version 7 there's a more intelligent kind of autocomplete triggered by C-x C-o that is context-aware. It can complete object methods, HTML tag attribtes, CSS properties, etc. For info:

    :help new-omni-completion
I think it must take into account some level of context because I've noticed that it tends to give me exactly what I want the first time I press it.
Bonus: If you have set up a tags file, the symbols there will also be available by default with autocomplete. This can help fill out a lot of potential functions and keywords which might not normally be set up (for Python, I set up a tagfile for both the standard library and site packages).

See ':help cpt' and ':help ins-completion'

YouCompleteMe is a good plugin for expanding out autocompletion for a lot more languages, but the built-in autocompletion is remarkably good out of the box.

If you have a tags file set up, vim omnicomplete (<C-x><C-o>) for C and C++ (at least) will also be able to complete struct/class members and other context sensitive.

Additionally, I set the user complete mode (<C-x><C-u>) to use vim's built in syntax complete (`:set completefunc=syntaxcomplete#Complete`), which is super helpful with e.g. config files because Vim is aware of all the available completion options.

Of course there's filename complete too (<C-x><C-f>).

These three modes can get some intelligent completion done but quite frankly the default local keyword completion covers 90% of my use cases.

Here is a way to bind autocomplete to TAB such that you still get TAB unless you are at the end of a word to complete. It's super convenient.

    function! InsertTabWrapper()
      let col = col('.') - 1
      if !col || getline('.')[col - 1] !~ '\k'
        return "\<tab>"
      else
        return "\<c-p>"
      endif
    endfunction
    inoremap <tab> <c-r>=InsertTabWrapper()<cr>
I made a plugin [1] similar to this which offers more options when you press the Tab key. For instance, if you're typing a file path, you get Ctrl-X Ctrl-f completion (vim's file path completion) instead of the regular keyword completion. And if you type a period (configurable) and press Tab in filetypes like C, Python, Ruby, etc, you get omni completion (vim's semi-intelligent completion, which offers methods on classes, looks in ctags files, etc).

The great thing is that I was able to do this in less than 100 lines of code, and I love using it myself every day at work. Just goes to show that Vim has a pretty good completion system already and you don't need to use some bloated plugin system like YouCompleteMe or Neocomplete.

[1]: https://github.com/ajh17/VimCompletesMe

What's wrong with these others? I'm reacting to the word "bloat," which is frequently thrown around on HN. To me, generally bloat is probably a good thing, as it means additional functionality and nice-ites.
There's also mu-complete[1] which is much like VimCompletes me - small and lightweight using only vim's built-in functionality. Doesn't work very well with vim < 7.3

(I haven't actually checked yours out, but I assume they're very similar in what they offer)

[1]: https://github.com/lifepillar/vim-mucomplete

I got that one some time ago from https://github.com/garybernhardt/dotfiles/blob/master/.vimrc... which offers several other useful functions and settings.
It's nice to point that out. It shows the binding for shift-tab, as well.

  function! InsertTabWrapper()
        let col = col('.') - 1
        if !col || getline('.')[col - 1] !~ '\k'
                return "\<tab>"
        else
                return "\<c-p>"
        endif
  endfunction
  inoremap <expr> <tab> InsertTabWrapper()
  inoremap <s-tab> <c-n>
What is xctrl?
That was meant to represent hitting Ctrl-x then Ctrl-f without letting go of the Ctrl key.
That's not actually necessary, so it was probably just to show a sequence of keypresses.
You mean `Ctrl-xCtrl-f`? That's `Ctrl-x Ctrl-f`. In terms of how it parses, after `Ctrl-`, the next token must be a single character (a key) is accepted. So `Ctrl-x` completes that particular accord and `Ctrl-f` is the accord following it.
Thanks ... that was puzzling me too. And I think you mean "chord" rather than "accord" :-)
Vim's autocomplete is alright, but it can definitely be super-charged by plugins like vim-autocomplpop[0], superTab, and language specific plugins like vim-racer[1].

Vim-autocomplpop is a fairly old plugin, but it still works just fine. It automatically shows autocompletion options as you type like an IDE. This is very handy.

The only downside is that external autocompletion engines like ctags and rope can sometimes cause performance issues. For example, python.vim uses rope to analyze a file, but that can take a while to initialize and crawl directories if you're editing a file in your home directory. Since it's a plugin written before Vim/Neovim's async code, it tends to make Vim unresponsive, so I only enable vim-autocomplpop on projects I'm working on. This isn't an issue if you use Vim's built-in autocomplete (instead of python.vim). I'll get around to rewriting autocomplpop someday and working on a solution to mitigate external autocomplete providers slowing down Vim.

0: https://github.com/othree/vim-autocomplpop 1: https://github.com/racer-rust/vim-racer

Have you tried YouCompleteMe? I'm surprised you didn't mention it.
YCM is really painful to set up, but once it's running, I found myself unable to go back to anything else (even deoplete). It's auto completion for C++ based on the cmake configuration is extremely powerful.
It works surprisingly well for languages like JavaScript and rust as well.
I've used YCM quite a bit in the past, but I haven't had it installed on my new laptop (Dell XPS 13). It uses racer for Rust and Jedi for Python, both of which I already use. I should look into it again.
Long time emacs user here. I had an aha moment yesterday, when after several months of using God mode I said "I should rebind C-t to generic transpose and use a follow-up key to specify char, word, sexp, etc." If I understand correctly, this is sort of how VIM works. I want to try EVIL now. Anyone here that's made the switch in this direction and can talk about it?
I switched to Evil mode and after a year I love it. I wrote the book to help me learn more about it!
I used emacs for 20 years. Around about 2007 I started doing all of my development on a tiny netbook and emacs was using too much memory. I switched to vim. It took me a good year to get used to it, but now I'm hooked on that way of thinking. About a year ago I switched back to emacs with evil mode. It is close enough to vim that I can barely tell the difference. If you are already familiar with emacs and have a setup that works for you, then switching to evil should be less painful than someone switching from vim.

I think the biggest thing to accept is that you will not be proficient with your editor for quite a long time. I recommend practicing with vim tutorials until it feels reasonably good before taking the plunge entirely. One very important thing is to keep looking for efficient ways to work with it. It's a bit like emacs in that if you ever think, "Oh, this is just painful. There must be a better way", then there is almost guaranteed to be a better way. Stop, find out what it is. Practice it.

My last piece of advice is that vim-style editing is a little bit different that emacs-style editing (at least for me). With emacs, I find that I memorise keybindings and practice using them. With vim, it's much more about the context -- when you are in situation X, you do this kind of thing. So it needs more practice (again IMO). However, once you have your brain oriented (orientated? :-) ), there is this sense of freedom. You are working with larger blocks of abstraction, rather than just the character level. Some people feel this is more efficient (i.e. faster), but I'm not sure. For me it's rather that it is closer to what I'm actually thinking when I'm programming. YMMV and I should warn you again that it takes considerable practice to get to the point where it starts to feel good.

As I like to say about so many things, "The Vim is large, and I'm so very small." Been using Vim, or vi since the eighties, and I didn't know there was any kind of auto/omnicomplete. Or maybe I knew and forgot. I forget.