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.[so|dylib] 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 flags  in 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
  }


你可能感兴趣的:(mac)