YouCompleteMe
lastmod 2020-10-09created 2018-09-078 edits
YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for Vim. It has several completion engines: an identifier-based engine that works with every programming language, a semantic, Clang-based engine that provides native semantic code completion for C/C++/Objective-C/Objective-C++ (from now on referred to as "the C-family languages"), a Jedi-based completion engine for Python, an OmniSharp-based completion engine for C# and an omnifunc-based completer that uses data from Vim's omnicomplete system to provide semantic completions for many other languages (Ruby, PHP etc.).
Categories
- Opm:YouCompleteMe - settings previously used in opm.
How to install
After getting the plugin with NeoBundle or similar, run the following in its directory.
cd .vim/bundle/YouCompleteMe/
git submodule update --init --recursive
./install.sh --clang-completer
C-family Semantic Completion : Use a compilation database
Using a compilation database makes it simple. With Clang and CMake, just set the CMAKE_EXPORT_COMPILE_COMMANDS variable to ON. You can find the compile_commands.json file in the Build Directory (CMAKE_BINARY_DIR); place this file in the Working Directory where vim was launched, or create a symbolic link to it.
How to use
- Stackoverflow: Vim completion with YouCompleteMe on windows
- Stackoverflow: C-family Semantic Autocompletion Plugins for Vim Using Clang (clang_complete, YouCompleteMe)
You can download archives of drop-in YCM plugin containing binaries (ycm_core.pyd) from me: Vim YouCompleteMe for Windows. Both x86 and x64 architectures are provided.
If you also need bleeding-edge LLVM/Clang, you can download the binaries from me as well: LLVM for Windows. Both x86 and x64 architectures are provided.
If you are looking for up-to-date Vim with Python support, you can download the binaries from me once again: Vim for Windows. Both x86 and x64 architectures are provided, as well as support for both Python 2 (which is required by YCM) and Python 3 altogether.
Common Pitfalls
- Don't forget to have Python 2 DLL (e.g. python27.dll) and Python 2 Interpreter (python.exe) in the PATH environment variable;
- Don't forget to have libclang.dll in the PATH environment variable (recommended) OR right next to ycm_core.pyd;
- Make sure that architectures of all 3 components (LLVM/Clang, Vim, YCM) match;
- You can find some hints on configuration in my other answer.
vim setting
Finally, add the Python setting as shown below.
The contents of the Python file are as follows.
#!/usr/bin/env python
import os
import subprocess
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-fexceptions',
#'-DNDEBUG',
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don't want that so ALWAYS specify
# a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++11',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x', 'c++',
'-isystem', '/usr/include',
'-isystem', '/usr/local/include',
'-I', 'include',
'-I', '.',
]
# include-list파일은 GCC의 포함 파일 목록을 출력한다.
# 내부 내용은 아래와 같다.
# g++ -E -x c++ - -v < /dev/null
include_list = subprocess.check_output('include-list', shell=True)
include_array = include_list.split()
include_flag = '-I'
for directory_cursor in include_array :
flags += [ include_flag, directory_cursor ]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags.
compilation_database_folder = ''
if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )
# This is the entry point; this function is called by ycmd to produce flags for
# a file.
def FlagsForFile( filename, **kwargs ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
return None
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ )
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return {
'flags': final_flags,
'do_cache': True
}
Simple example
import os
import ycm_core
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-ferror-limit=10000',
'-DNDEBUG',
'-std=c99',
'-xc',
'-isystem/usr/include/',
]
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', ]
def FlagsForFile( filename, **kwargs ):
return {
'flags': flags,
'do_cache': True
}
Download
- Ycm-733de48-150419-x86.7z
- YCM Windows x86 pre-compiled version.
Troubleshooting
Could NOT find PythonLibs
The following message may be printed when running ./install.sh.
In this case, you need to install Python. On CentOS, install it as follows.
No module named future
If the above error occurs when running vim, you need to update the submodules.
See also
Favorite site
- YouCompleteMe project site
- Vim YouCompleteMe for Windows
- YouCompleteMe: a code-completion engine for Vim
- YouCompleteMe – Ultimate autocomplete plugin for Vim
- Note: Install YouCompleteMe on Windows
- CENTOS 6.X WITH YOUCOMPLETEME
- INSTALLING LINUX SOFTWARE WITHOUT ROOT PRIVILEGES: VIM + YCM
- YouCompleteMe (YCM) - Turning vim into a full-fledged IDE