nyjwgbhdsx 发表于 2016-5-17 11:40:37

Mac安装YouCompleteMe插件

参考: http://valloric.github.io/YouCompleteMe/
http://blog.marchtea.com/archives/161

一, 安装准备:

1,Vim 版本 7.3.584+   编译时 添加 +python 标识
// 安装python-dev2.7 mac默认已安装

命令行 vim —version 查看 vim 版本 或进入vim 后输入:version
查看是否支持 python   :echo has('python') 输出1表示支持输入0则否

Mac通过 brew install vim 安装最新的7.4 版本的vim : /usr/local/Cellar/vim/7.4.335/bin
在~/.bash_profile 添加:export PATH=/usr/local/Cellar/vim/7.4.335/bin:$PATH

2, 安装cmake
查看 which cmake 是否 已安装,http://www.cmake.org下载 cmake-2.6.4.tar.gz
tar -xzvf cmake-2.6.4.tar.gz
cd cmake-2.6.4
./bootstrap
make
make install

3, 下载 clang binary版本 3.2以上版本    官网 http://clang.llvm.org
将clang+llvm-3.3-x86_64-apple-darwin12.tar 解压到 ~/ycm_temp/llvm_root_dir目录
// ~/ycm_temp/llvm_root_dir (with bin, lib, include etc. right inside that folder)

4,安装vundle插件利用 vundle 安装 YCM插件
    $ git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
   配置~/.vimrc   参考: http://valloric.github.io/YouCompleteMe/

二,安装

1, 执行 vim +PluginInstall +qall让vundle把YCM插件下载到本地,网速慢等待比较久
      YCM下载到~/.vim/bundle之后,开始编译 YCM
--> cd ~&& mkdir ycm_build
--> cd ycm_build
   
   -->cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir    .   ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp   // 注意 llvm_root_dir.~/

--> make ycm_support_libs

   -->make
// it will also place the libclang. in the YouCompleteMe/python folder for you if you compiled with clang support (it needs to be there for YCM to work).

    如果没提示报错,则安装编译成功

2,配置   
YCM looks for a .ycm_extra_conf.py file in the directory of the opened file or in any directory above it in the hierarchy (recursively);

Don't just copy/paste that file somewhere and expect things to magically work;
your project needs different flags.
Hint: just replace the strings in the flags variable with compilation flags necessary for your project.

:YcmDiags//to see if any errors or warnings were detected in your file.
:YcmForceCompileAndDiagnostics // recompile
:YcmDebugInfo
:messages

" let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
let g:ycm_collect_identifiers_from_tags_files = 1
let g:ycm_seed_identifiers_with_syntax = 1
let g:ycm_confirm_extra_conf = 0
let g:ycm_key_invoke_completion = '<C-/>'" 或 '<M-/>'   默认是CTRL + space

导航定义和声明
nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR>
nnoremap <leader>gf :YcmCompleter GoToDefinition<CR>
nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR>

nnoremap <F5> :YcmForceCompileAndDiagnostics<CR>


YCM提供的跳跃功能采用了vim的jumplist,往前跳和往后跳的快捷键为Ctrl+O以及Ctrl+I.

问题: 找不到STL相关定义:
解决方法:
call echo | clang -v -E -x c++ - and look at the paths under the #include <...> search starts here: heading.
You should take those paths, prepend -isystem to each individual path and append them all to the list of flagsin your .ycm_extra_conf.py file.

将flags 一些无用的 -I-isystem 需要清理掉.

string str;需要 std::string str;才会补全。




.ycm_extra_conf.py 文件一览:
flags = [ ] 中的路径根据具体情况配置

~/ 根路径放置一个 fallback ycm_extra_conf.py
然后在每个项目路径放置一个各自的ycm_extra_conf.py

# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>

import os
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',
#'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-stdlib=libc++',
#'-DNDEBUG',
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
# source code needs it.
#'-DUSE_CLANG_COMPLETER',
# 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++',
'-I',
'.',
'-isystem',
'/System/Library/Frameworks/Python.framework/Headers',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.0/include',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks',
]


# 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
#
# You can get CMake to generate this file for you by adding:
#   set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
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 )


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_ )

    # NOTE: This is just for YouCompleteMe; it's highly likely that your project
    # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
    # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
    #try:
    #final_flags.remove( '-stdlib=libc++' )
    #except ValueError:
    #pass
else:
    relative_to = DirectoryOfThisScript()
    final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )

return {
    'flags': final_flags,
    'do_cache': True
}
页: [1]
查看完整版本: Mac安装YouCompleteMe插件