Wednesday, March 22, 2017

How to Install YouCompleteMe Vim Plugin for Linux

***If you are like me, using vim as the main editor for coding, then I highly recommend that you read this post.

 Here, I will go through a step by step guide for installing YouCompleteMe plugin for vim with C-family support, i.e., C/C++/Objective-C/Objective-C++. Detailed instruction is given in its Github repo, but it took me quite a while to figure out how to do this right, so I just think it will be helpful to other people as well.

First, you will need to install Vundle. Run the following:
$ git clone ~/.vim/bundle/Vundle.vim

Next, copy and paste the following at the top of ~/.vimrc file:
set nocompatible              " be iMproved, required
filetype off                  " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'
Plugin 'Valloric/YouCompleteMe'

" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
" Brief help
" :PluginList       - lists configured plugins
" :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line

Next, install Vundle and YouCompleteMe in vim. To do this, open up vim and install plugins:
$ vim

This command within vim will install Vundle and YouCompleteMe plugins directly from the Github repositories, so make sure that you have Internet connection. Wait until it says "Done" at the bottom of vim.

You are not done yet. You will need to install necessary packages to configure YouCompleteMe.
$ sudo apt-get install build-essential cmake python-dev python3-dev

Next, you will need to change directory to where the YouCompleteMe is installed and setup clang-completion for C-family:
$ cd ~/.vim/bundle/YouCompleteMe
$ ./ --clang-completer

This will take a while, so be patient. When this is done, you are done with the installation, but you are not done with C-family auto-completion features just yet. For more info, you will need to read the official documentation regarding the part.

Basically, you will need to let clang know how to compile your project, so that it can suggest auto-completion methods or fields. If your simply want to skip all and see it in action, then create ~/.vim/bundle/YouCompleteMe/ with the following:
def FlagsForFile( filename, **kwargs ):
  return {
    'flags': [ '-x', 'c++', '-Wall', '-Wextra', '-Werror' ],

Also, append the following line to ~/.vimrc
let g:ycm_global_ycm_extra_conf = '~/.vim/bundle/YouCompleteMe/'

Now, start editing a C++ file in the same directory with vim
$ vim hello.cpp

As you edit, you will see YouCompleteMe in action with auto-completion for C++ functions!

For Python development, I have a dedicated post here too. By the way, you may wish to read here when using Python modules. It explains how to set the python executable path.

Also, if you are a Mac user, you may want to checkout this post by Oliver.


  1. Works perfectly! I have a small doubt though. For YCM to work, do I have create all my .cpp projects only in '/.vim/bundle/YouCompleteMe'?

  2. This comment has been removed by the author.

  3. Thanks Sir,
    Finally have autocompletion working on my MacVim setup! :D

  4. It only works for C++. Why doesn't it work for C.
    Look the message, it's when I try to assign a string to a pointer for the first time.

    #include "apue.h"

    int main(int argc, char *argv[])
    int i;
    struct stat buf;
    char *ptr;

    for (i = 1; i < argc; i++) {
    printf("%s: ", argv[i]);
    if (lstat(argv[i], &buf) < 0) {
    err_ret("lstat error");

    if (S_ISREG(buf.st_mode))
    ptr = "regular";
    else if (S_ISDIR(buf.st_mode))
    ptr = "directory";
    else if (S_ISCHR(buf.st_mode))
    ptr = "character special";
    else if (S_ISFIFO(buf.st_mode))
    ptr = "fifo";
    else if (S_ISLNK(buf.st_mode))
    ptr = "symbolic link";
    else if (S_ISSOCK(buf.st_mode))
    ptr = "socket";
    ptr = "** unknown mode **";
    printf("%s\n", ptr);



    ISO C++11 does not allow conversion from string literal to 'char *'

  5. This works, thank you kindly sir!