首先插件需要安裝一些dependencies。包括build-essential单默,cmake抛猖,python-dev魏颓, python3-dev岭辣。在MacOS底下xcode-select --install
取代 Linux底下的‘sudo apt install build-essential’。python 和python 3之前安裝vim和macvim的時(shí)候其實(shí)已經(jīng)裝完了甸饱,缺少的只有cmake這個(gè)插件沦童。
brew install cmake
然后在 /.vimrc
文件中加入
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py'}
帶特定語言支持的安裝方式,上面語句改為
C-family languages
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --clang-completer'}
C# supportbrew install Mono
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --cs-completer'}
Go support
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --go-completer'}
Rust support: support brew install rust
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --rust-completer'}
Java support: support brew cask install java8
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --java-completer'}
全部安裝
Plug 'Valloric/YouCompleteMe',{'do':'python3 install.py --all'}
打開vim叹话,輸入
:PlugInstall
自動(dòng)安裝所有偷遗。
/.vimrc
文件中 YouCompleteMe的常用設(shè)置, 配置來源 http://howiefh.github.io/2015/05/22/vim-install-youcompleteme-plugin/
set completeopt=longest,menu "讓Vim的補(bǔ)全菜單行為與一般IDE一致(參考VimTip1228)
autocmd InsertLeave * if pumvisible() == 0|pclose|endif "離開插入模式后自動(dòng)關(guān)閉預(yù)覽窗口
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>" "回車即選中當(dāng)前項(xiàng)
"上下左右鍵的行為 會顯示其他信息
inoremap <expr> <Down> pumvisible() ? "\<C-n>" : "\<Down>"
inoremap <expr> <Up> pumvisible() ? "\<C-p>" : "\<Up>"
inoremap <expr> <PageDown> pumvisible() ? "\<PageDown>\<C-p>\<C-n>" : "\<PageDown>"
inoremap <expr> <PageUp> pumvisible() ? "\<PageUp>\<C-p>\<C-n>" : "\<PageUp>"
" 跳轉(zhuǎn)到定義處
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
nnoremap <F6> :YcmForceCompileAndDiagnostics<CR> "force recomile with syntastic
" nnoremap <leader>lo :lopen<CR> "open locationlist
" nnoremap <leader>lc :lclose<CR> "close locationlist
inoremap <leader><leader> <C-x><C-o>
let g:ycm_global_ycm_extra_conf = '~/.vim/.ycm_extra_conf.py'
" 不顯示開啟vim時(shí)檢查ycm_extra_conf文件的信息
let g:ycm_confirm_extra_conf=0
" 開啟基于tag的補(bǔ)全,可以在這之后添加需要的標(biāo)簽路徑
let g:ycm_collect_identifiers_from_tags_files=1
"注釋和字符串中的文字也會被收入補(bǔ)全
let g:ycm_collect_identifiers_from_comments_and_strings = 0
" 輸入第2個(gè)字符開始補(bǔ)全
let g:ycm_min_num_of_chars_for_completion=2
" 禁止緩存匹配項(xiàng),每次都重新生成匹配項(xiàng)
let g:ycm_cache_omnifunc=0
" 開啟語義補(bǔ)全
let g:ycm_seed_identifiers_with_syntax=1
"在注釋輸入中也能補(bǔ)全
let g:ycm_complete_in_comments = 1
"在字符串輸入中也能補(bǔ)全
let g:ycm_complete_in_strings = 1
" 設(shè)置在下面幾種格式的文件上屏蔽ycm
let g:ycm_filetype_blacklist = {
\ 'tagbar' : 1,
\ 'nerdtree' : 1,
\}
"youcompleteme 默認(rèn)tab s-tab 和 ultisnips 沖突
let g:ycm_key_list_select_completion = ['<Down>']
let g:ycm_key_list_previous_completion = ['<Up>']
" 修改對C函數(shù)的補(bǔ)全快捷鍵渣刷,默認(rèn)是CTRL + space鹦肿,修改為ALT + ;
let g:ycm_key_invoke_completion = '<M-;>'
" SirVer/ultisnips 代碼片斷
" Trigger configuration. Do not use <tab> if you use https://github.com/Valloric/YouCompleteMe.
let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
let g:UltiSnipsListSnippets="<c-e>"
"定義存放代碼片段的文件夾,使用自定義和默認(rèn)的辅柴,將會的到全局箩溃,有沖突的會提示
let g:UltiSnipsSnippetDirectories=["plugged/vim-snippets/UltiSnips"]
" 參考https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-62941322
" 解決ultisnips和ycm tab沖突,如果不使用下面的辦法解決可以參考
" https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-63205056的配置
" begin
" let g:ycm_key_list_select_completion=['<C-n>', '<Down>']
" let g:ycm_key_list_previous_completion=['<C-p>', '<Up>']
" let g:UltiSnipsExpandTrigger="<Tab>"
" let g:UltiSnipsJumpForwardTrigger="<Tab>"
" let g:UltiSnipsJumpBackwardTrigger="<S-Tab>"
" end
" UltiSnips completion function that tries to expand a snippet. If there's no
" snippet for expanding, it checks for completion window and if it's
" shown, selects first element. If there's no completion window it tries to
" jump to next placeholder. If there's no placeholder it just returns TAB key
function! g:UltiSnips_Complete()
call UltiSnips#ExpandSnippet()
if g:ulti_expand_res == 0
if pumvisible()
return "\<C-n>"
else
call UltiSnips#JumpForwards()
if g:ulti_jump_forwards_res == 0
return "\<TAB>"
endif
endif
endif
return ""
endfunction
au BufEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=g:UltiSnips_Complete()<cr>"
" Expand snippet or return
let g:ulti_expand_res = 1
function! Ulti_ExpandOrEnter()
call UltiSnips#ExpandSnippet()
if g:ulti_expand_res
return ''
else
return "\<return>"
endfunction
" Set <space> as primary trigger
inoremap <return> <C-R>=Ulti_ExpandOrEnter()<CR>
~/.vim/.ycm_extra_conf.py文件示范
import os
import os.path
import fnmatch
import logging
import ycm_core
import re
BASE_FLAGS = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-ferror-limit=10000',
'-DNDEBUG',
'-std=c++11',
'-xc++',
'-I/usr/lib/',
'-I/usr/include/'
]
SOURCE_EXTENSIONS = [
'.cpp',
'.cxx',
'.cc',
'.c',
'.m',
'.mm'
]
SOURCE_DIRECTORIES = [
'src',
'lib'
]
HEADER_EXTENSIONS = [
'.h',
'.hxx',
'.hpp',
'.hh'
]
HEADER_DIRECTORIES = [
'include'
]
def IsHeaderFile(filename):
extension = os.path.splitext(filename)[1]
return extension in HEADER_EXTENSIONS
def GetCompilationInfoForFile(database, filename):
if IsHeaderFile(filename):
basename = os.path.splitext(filename)[0]
for extension in SOURCE_EXTENSIONS:
# Get info from the source files by replacing the extension.
replacement_file = basename + extension
if os.path.exists(replacement_file):
compilation_info = database.GetCompilationInfoForFile(replacement_file)
if compilation_info.compiler_flags_:
return compilation_info
# If that wasn't successful, try replacing possible header directory with possible source directories.
for header_dir in HEADER_DIRECTORIES:
for source_dir in SOURCE_DIRECTORIES:
src_file = replacement_file.replace(header_dir, source_dir)
if os.path.exists(src_file):
compilation_info = database.GetCompilationInfoForFile(src_file)
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile(filename)
def FindNearest(path, target, build_folder):
candidate = os.path.join(path, target)
if(os.path.isfile(candidate) or os.path.isdir(candidate)):
logging.info("Found nearest " + target + " at " + candidate)
return candidate;
parent = os.path.dirname(os.path.abspath(path));
if(parent == path):
raise RuntimeError("Could not find " + target);
if(build_folder):
candidate = os.path.join(parent, build_folder, target)
if(os.path.isfile(candidate) or os.path.isdir(candidate)):
logging.info("Found nearest " + target + " in build folder at " + candidate)
return candidate;
return FindNearest(parent, target, build_folder)
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 FlagsForClangComplete(root):
try:
clang_complete_path = FindNearest(root, '.clang_complete')
clang_complete_flags = open(clang_complete_path, 'r').read().splitlines()
return clang_complete_flags
except:
return None
def FlagsForInclude(root):
try:
include_path = FindNearest(root, 'include')
flags = []
for dirroot, dirnames, filenames in os.walk(include_path):
for dir_path in dirnames:
real_path = os.path.join(dirroot, dir_path)
flags = flags + ["-I" + real_path]
return flags
except:
return None
def FlagsForCompilationDatabase(root, filename):
try:
# Last argument of next function is the name of the build folder for
# out of source projects
compilation_db_path = FindNearest(root, 'compile_commands.json', 'build')
compilation_db_dir = os.path.dirname(compilation_db_path)
logging.info("Set compilation database directory to " + compilation_db_dir)
compilation_db = ycm_core.CompilationDatabase(compilation_db_dir)
if not compilation_db:
logging.info("Compilation database file found but unable to load")
return None
compilation_info = GetCompilationInfoForFile(compilation_db, filename)
if not compilation_info:
logging.info("No compilation info for " + filename + " in compilation database")
return None
return MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_)
except:
return None
def FlagsForFile(filename):
root = os.path.realpath(filename);
compilation_db_flags = FlagsForCompilationDatabase(root, filename)
if compilation_db_flags:
final_flags = compilation_db_flags
else:
final_flags = BASE_FLAGS
clang_flags = FlagsForClangComplete(root)
if clang_flags:
final_flags = final_flags + clang_flags
include_flags = FlagsForInclude(root)
if include_flags:
final_flags = final_flags + include_flags
return {
'flags': final_flags,
'do_cache': True
}