vim安装 YCM 过程记录

时间:2020-12-02 05:37:15
YCM(YouComplateMe) 属于Vim中大神级的插件,提供了类似于巨硬爸爸的VS中的代码补全,但是其安装方式也是比较复杂,因此特意写下一篇记录,记录下我自己如何安装这一插件的过程;
  1. 检查自己的vim版本是否在7.9版本之上、是否支持Pthon很幸运我的vim版本是8.0
 vim --version    #查看vim版本以及是否支持Python 支持的话会在前方出现一个‘+’字符
  2.  安装各类可能需要的环境
 

编译 YouCompleteMe 插件时需要依赖 cmake 构建 Makefile,且依赖 Python 源码头文件,Ubuntu 系统可以使用以下命令安装相关依赖。

 sudo apt-get install build-essential cmake python-dev python3-dev
 
  1. 安装git 和 Vundle
   sudo apt-get install git
vim官方推荐一个插件“vundle”用于管理vim的其他插件,这个插件的安装使用git 克隆到自己的本地文件夹,后面这个Vundle.vim就是vim的插件文件。*此路径  :~/.vim/bundle/Vundle.vim 是vim的插件默认路径
     git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
 
  1. 下载YouComplateMe源码 等待编译
 git clone https://github.com/Valloric/YouCompleteMe.git ~/.vim/bundle/YouCompleteMe
 
  1. 下载YouComplateMe可能需要的安装环境
下载需要的安装环境需要跳转到YouComplateMe所在目录
 
        cd ~/.vim/bundle/YouCompleteMe
git submodule update --init --recursive
  1. 编译YCM(YouComplateMe)
在YCM所在目录下执行
  ./install.py --clang-completer
期间如果出现错误,参考:https://www.cnblogs.com/dakewei/p/10491373.html 解决错误;
 
  1. 如果出现 AttributeError: 'module' object has no attribute 'FlagsForFile' 错误;

需要添加一个配置文件,在这里添加一个 C family 类型文件模板

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
}
  1. 将以上代码写入到这个文件
    ~/.ycm_c-c++_conf.py
 
  1. 打开 .vimrc 配置文件 加入如下语句:
    let g:ycm_global_ycm_extra_conf = "~/.ycm_c-c++_conf.py"
 
 
  1. 安装 NERDTree 插件显示当前目录下的目录树
    cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdtree.git
  1. 在.vimrc文件Vundle管理中添加插件
Plugin 'scrooloose/nerdtree'
  1. 添加相对应 NERDTree的自定义设置,例如默认开启
"--------------NERD TREE SETTING---------------
"自动启动文件树
autocmd vimenter * NERDTree
"设置快捷按键打开关闭文件树
map <C-t> :NERDTreeToggle<CR>
"关闭vim时,如果打开的文件除了NERDTree没有其他文件时,它自动关闭,减少多次按:q!
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType")&&b:NERDTreeType == "primary") | q | endif

  

最后把自己配置的.vimrc 文件po出来供大家使用
 set nocompatible              " 去除VI一致性,必须要添加
filetype off " 必须要添加 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 显示相关 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" "set shortmess=atI " 启动的时候不显示那个援助乌干达儿童的提示 "winpos 5 5 " 设定窗口位置 "set lines=40 columns=155 " 设定窗口大小 set nu " 显示行号 set go= " 不要图形按钮 "color asmanian2 " 设置背景主题 set guifont=Consolas:h10:cANSI " 设置字体 "syntax on " 语法高亮 autocmd InsertLeave * se nocul " 用浅色高亮当前行 autocmd InsertEnter * se cul " 用浅色高亮当前行 "set ruler " 显示标尺 set showcmd " 输入的命令显示出来,看的清楚些 "set cmdheight=1 " 命令行(在状态行下)的高度,设置为1 "set whichwrap+=<,>,h,l " 允许backspace和光标键跨越行边界(不建议) set scrolloff= " 光标移动到buffer的顶部和底部时保持3行距离 set novisualbell " 不要闪烁(不明白) set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} "状态行显示的内容 set laststatus= " 启动显示状态行(1),总是显示状态行(2) set foldenable " 允许折叠 set foldmethod=manual " 手动折叠 "set background=dark "背景使用黑色 set nocompatible "去掉讨厌的有关vi一致性模式,避免以前版本的一些bug和局限 " 显示中文帮助 if version >= set helplang=cn set encoding=utf- endif " 设置配色方案 "colorscheme murphy "字体 "if (has("gui_running")) " set guifont=Bitstream\ Vera\ Sans\ Mono\ 10 "endif set fencs=utf-,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 set termencoding=utf- set encoding=utf- set fileencodings=ucs-bom,utf-,cp936 set fileencoding=utf- """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""新文件标题"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" "新建.c,.h,.sh,.java文件,自动插入文件头 autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec ":call SetTitle()" ""定义函数SetTitle,自动插入文件头 func SetTitle() "如果文件类型为.sh文件 if &filetype == 'sh' call setline(,"\#########################################################################") call append(line("."), "\# File Name: ".expand("%")) call append(line(".")+, "\# Author: kimalittlestar") call append(line(".")+, "\# mail: kimalittlestar@gmail.com") call append(line(".")+, "\# Created Time: ".strftime("%c")) call append(line(".")+, "\#########################################################################") call append(line(".")+, "\#!/bin/bash") call append(line(".")+, "") else call setline(, "/*************************************************************************") call append(line("."), " > File Name: ".expand("%")) call append(line(".")+, " > Author: kimalittlestar") call append(line(".")+, " > Mail: kimalittlestar@gmail.com ") call append(line(".")+, " > Created Time: ".strftime("%c")) call append(line(".")+, " ************************************************************************/") call append(line(".")+, "") endif " if &filetype == 'cpp' " " call append(line(".")+6, "#include<iostream>") " " call append(line(".")+7, "using namespace std;") " " call append(line(".")+8, "") " " endif " " if &filetype == 'c' " " call append(line(".")+6, "#include<stdio.h>") " " call append(line(".")+7, "") " " endif "新建文件后,自动定位到文件末尾 autocmd BufNewFile * normal G endfunc """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" "键盘命令 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" nmap <leader>w :w!<cr> nmap <leader>f :find<cr> " 映射全选+复制 ctrl+a map <C-A> ggVGY map! <C-A> <Esc>ggVGY map <F12> gg=G " 选中状态下 Ctrl+c 复制 vmap <C-c> "+y "去空行 nnoremap <F2> :g/^\s*$/d<CR> "比较文件 nnoremap <C-F2> :vert diffsplit "新建标签 map <M-F2> :tabnew<CR> "列出当前目录文件 map <F3> :tabnew .<CR> "打开树状文件目录 map <C-f> \be "C,C++ 按F5编译运行 map <F5> :call CompileRunGcc()<CR> func! CompileRunGcc() exec "w" if &filetype == 'c' exec "!g++ % -o %<" exec "! ./%<" elseif &filetype == 'cpp' exec "!g++ % -o %<" exec "! ./%<" elseif &filetype == 'java' exec "!javac %" exec "!java %<" elseif &filetype == 'sh' :!./% endif endfunc "C,C++的调试 map <F8> :call Rungdb()<CR> func! Rungdb() exec "w" exec "!g++ % -g -o %<" exec "!gdb ./%<" endfunc """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" ""实用设置 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 设置当文件被改动时自动载入 set autoread " quickfix模式 autocmd FileType c,cpp map <buffer> <leader><space> :w<cr>:make<cr> "代码补全 set completeopt=preview,menu "允许插件 filetype plugin on "共享剪贴板 set clipboard+=unnamed "从不备份 set nobackup "make 运行 :set makeprg=g++\ -Wall\ \ % "自动保存 set autowrite set ruler " 打开状态栏标尺 set cursorline " 突出显示当前行 set magic " 设置魔术 set guioptions-=T " 隐藏工具栏 set guioptions-=m " 隐藏菜单栏 "set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %c:%l/%L%)\ " 设置在状态行显示的信息 set foldcolumn= set foldmethod=indent set foldlevel= set foldenable " 开始折叠 " 不要使用vi的键盘模式,而是vim自己的 set nocompatible " 语法高亮 set syntax=on " 去掉输入错误的提示声音 set noeb " 在处理未保存或只读文件的时候,弹出确认 set confirm " 自动缩进 set autoindent set cindent " Tab键的宽度 set tabstop= " 统一缩进为4 set softtabstop= set shiftwidth= " 不要用空格代替制表符 set noexpandtab " 在行和段开始处使用制表符 set smarttab " 显示行号 set number " 历史记录数 set history= "禁止生成临时文件 set nobackup set noswapfile "搜索忽略大小写 set ignorecase "搜索逐字符高亮 set hlsearch set incsearch "行内替换 set gdefault "编码设置 set enc=utf- set fencs=utf-,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 "语言设置 set langmenu=zh_CN.UTF- set helplang=cn " 我的状态行显示的内容(包括文件类型和解码) "set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} "set statusline=[%F]%y%r%m%*%=[Line:%l/%L,Column:%c][%p%%] " 总是显示状态行 set laststatus= " 命令行(在状态行下)的高度,默认为1,这里是2 set cmdheight= " 侦测文件类型 filetype on " 载入文件类型插件 filetype plugin on " 为特定文件类型载入相关缩进文件 filetype indent on " 保存全局变量 set viminfo+=! " 带有如下符号的单词不要被换行分割 set iskeyword+=_,$,@,%,#,- " 字符间插入的像素行数目 set linespace= " 增强模式中的命令行自动完成操作 set wildmenu " 使回格键(backspace)正常处理indent, eol, start等 set backspace= " 允许backspace和光标键跨越行边界 set whichwrap+=<,>,h,l " 可以在buffer的任何地方使用鼠标(类似office中在工作区双击鼠标定位) set mouse=a set selection=exclusive set selectmode=mouse,key " 通过使用: commands命令,告诉我们文件的哪一行被改变过 set report= " 在被分割的窗口间显示空白,便于阅读 set fillchars=vert:\ ,stl:\ ,stlnc:\ " 高亮显示匹配的括号 set showmatch " 匹配括号高亮的时间(单位是十分之一秒) set matchtime= " 光标移动到buffer的顶部和底部时保持3行距离 set scrolloff= " 为C程序提供自动缩进 set smartindent " 高亮显示普通txt文件(需要txt.vim脚本) au BufRead,BufNewFile * setfiletype txt "自动补全 :inoremap ( ()<ESC>i :inoremap ) <c-r>=ClosePair(')')<CR> :inoremap { {<CR>}<ESC>O :inoremap } <c-r>=ClosePair('}')<CR> :inoremap [ []<ESC>i :inoremap ] <c-r>=ClosePair(']')<CR> :inoremap " ""<ESC>i :inoremap ' ''<ESC>i function! ClosePair(char) if getline('.')[col('.') - ] == a:char return "\<Right>" else return a:char endif endfunction filetype plugin indent on "打开文件类型检测, 加了这句才可以用智能补全 set completeopt=longest,menu """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " CTags的设定 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" let Tlist_Sort_Type = "name" " 按照名称排序 let Tlist_Use_Right_Window = " 在右侧显示窗口 let Tlist_Compart_Format = " 压缩方式 let Tlist_Exist_OnlyWindow = " 如果只有一个buffer,kill窗口也kill掉buffer let Tlist_File_Fold_Auto_Close = " 不要关闭其他文件的tags let Tlist_Enable_Fold_Column = " 不要显示折叠树 autocmd FileType java set tags+=D:\tools\java\tags "autocmd FileType h,cpp,cc,c set tags+=D:\tools\cpp\tags "let Tlist_Show_One_File=1 "不同时显示多个文件的tag,只显示当前文件的 "设置tags set tags=tags "set autochdir """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" "其他东东 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" "默认打开Taglist let Tlist_Auto_Open= """""""""""""""""""""""""""""" " Tag list (ctags) """""""""""""""""""""""""""""""" let Tlist_Ctags_Cmd = '/usr/bin/ctags' let Tlist_Show_One_File = "不同时显示多个文件的tag,只显示当前文件的 let Tlist_Exit_OnlyWindow = "如果taglist窗口是最后一个窗口,则退出vim let Tlist_Use_Right_Window = "在右侧窗口中显示taglist窗口 " minibufexpl插件的一般设置 let g:miniBufExplMapWindowNavVim = let g:miniBufExplMapWindowNavArrows = let g:miniBufExplMapCTabSwitchBufs = let g:miniBufExplModSelTarget = "----------------设置包括vundle和初始化相关的runtime path---------------------- set rtp+=~/.vim/bundle/Vundle.vim call vundle#begin() " 另一种选择, 指定一个vundle安装插件的路径 "call vundle#begin('~/some/path/here') " 让vundle管理插件版本,必须 Plugin 'VundleVim/Vundle.vim' Plugin 'Valloric/YouCompleteMe' Plugin 'scrooloose/nerdtree' " " 以下范例用来支持不同格式的插件安装. " " 请将安装插件的命令放在vundle#begin和vundle#end之间. " " Github上的插件 " " 格式为 Plugin '用户名/插件仓库名' " Plugin 'tpope/vim-fugitive' " " 来自 http://vim-scripts.org/vim/scripts.html 的插件 " " Plugin '插件名称' 实际上是 Plugin 'vim-scripts/插件仓库名' " 只是此处的用户名可以省略 " Plugin 'L9' " " 由Git支持但不再github上的插件仓库 Plugin 'git clone 后面的地址' " Plugin 'git://git.wincent.com/command-t.git' " " 本地的Git仓库(例如自己的插件) Plugin 'file:///+本地插件仓库绝对路径' " Plugin 'file:///home/gmarik/path/to/plugin' " " 插件在仓库的子目录中. " " 正确指定路径用以设置runtimepath. 以下范例插件在sparkup/vim目录下 " Plugin 'rstacruz/sparkup', {'rtp': 'vim/'} " " 安装L9,如果已经安装过这个插件,可利用以下格式避免命名冲突 " Plugin 'ascenator/L9', {'name': 'newL9'} " 你的所有插件需要在下面这行之前 call vundle#end() " 必须 filetype plugin indent on " 必须 " 加载vim自带和插件相应的语法和文件类型相关脚本 " 忽视插件改变缩进,可以使用以下替代: "filetype plugin on " " 常用的命令 " :PluginList - 列出所有已配置的插件 " :PluginInstall - 安装插件,追加 `!` 用以更新或使用 :PluginUpdate " :PluginSearch foo - 搜索 foo ; 追加 `!` 清除本地缓存 " :PluginClean - 清除未使用插件,需要确认; 追加 `!` " 自动批准移除未使用插件 "-----------------youcompleteme-----------------" "默认配置文件路径" let g:ycm_global_ycm_extra_conf = '~/.vim/bundle/YouCompleteMe/.ycm_extra_conf.py' "配置全局路径 "log" let g:ycm_server_keep_logfiles= let g:ycm_sever_log_level='debug' "打开vim时不再询问是否加载ycm_extra_conf.py配置" "let g:ycm_confirm_extra_conf=0 "set completeopt=longest,menu "python解释器路径" let g:ycm_path_to_python_interpreter='/usr/bin/python' "let g:ycm_python_binary_path = '/home/wdh/anaconda3/bin/python3' "python 环境 "是否开启语义补全" let g:ycm_seed_identifiers_with_syntax= "是否在注释中也开启补全" let g:ycm_complete_in_comments= let g:ycm_collect_identifiers_from_comments_and_strings = "开始补全的字符数" let g:ycm_min_num_of_chars_for_completion= "补全后自动关机预览窗口" "let g:ycm_autoclose_preview_window_after_completion=1 "禁止缓存匹配项,每次都重新生成匹配项" let g:ycm_cache_omnifunc= "字符串中也开启补全" let g:ycm_complete_in_strings = let g:ycm_seed_identifiers_with_syntax= "补全关键字 "离开插入模式后自动关闭预览窗口" autocmd InsertLeave * if pumvisible() == |pclose|endif "设置C 系列语言格式配置文件路径 let g:ycm_global_ycm_extra_conf = "~/.vim/plugged/YouCompleteMe/.ycm_c-c++_conf.py" "按下2个字母后自动语意补全(检测上下文环境) let g:ycm_semantic_triggers = { \ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'], \ 'cs,lua,javascript': ['re!\w{2}'], \ } "设置提示高亮背景颜色 highlight PMenu ctermfg= ctermbg= guifg=black guibg=darkgrey highlight PMenuSel ctermfg= ctermbg= guifg=darkgrey guibg=black "文件类型白名单,这些文件后缀会被解析 let g:ycm_filetype_whitelist = { \ "c":, \ "h":, \ "py":, \ "cpp":, \ "hpp":, \ "objc":, \ "sh":, \ "zsh":, \ "zimbu":, \ } "回车即选中当前项" " inoremap <expr> <CR> pumvisible() ? '<C-y>' : '\<CR>' "上下左右键行为" 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>'\ "--------------NERD TREE SETTING--------------- "自动启动文件树 autocmd vimenter * NERDTree "设置快捷按键打开关闭文件树 map <C-t> :NERDTreeToggle<CR> "关闭vim时,如果打开的文件除了NERDTree没有其他文件时,它自动关闭,减少多次按:q! autocmd bufenter * if (winnr("$") == && exists("b:NERDTreeType")&&b:NERDTreeType == "primary") | q | endif
 
贴图:

vim安装 YCM 过程记录