[关闭]
@Dubyoo 2014-06-17T22:02:12.000000Z 字数 10611 阅读 8733

vim 配置 YouCompleteMe

Linux


一、前期准备

作为一个c++程序员,要想尽可能地发挥YCM的功能,推荐安装以下软件:

  1. sudo apt-get install vim
  1. sudo apt-get install git
  1. sudo apt-get install cmake
  1. sudo apt-get install pylint python-dev

二、Vundle的安装:

Vundle是vim的一款进行插件管理的插件。它需要git的支持,git可以在各发行版软件源内找到并安装。除了安装时的一个命令,日常vundle的使用并不需要了解git命令。

以下安装流程参考自vundle的github简介。

1.使用git下载vundle
运行命令:

  1. git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

这样插件将被下载到 ~/.vim/bundle/vundle

2.编辑 .vimrc
~/.vimrc末尾添加以下内容:

  1. """"""""""""""""""""" Vundle
  2. set nocompatible
  3. filetype off
  4. set rtp+=~/.vim/bundle/vundle
  5. call vundle#rc()
  6. Bundle 'gmarik/vundle'
  7. Bundle 'Valloric/YouCompleteMe'
  8. Bundle 'Valloric/ListToggle'
  9. Bundle 'scrooloose/syntastic'
  10. filetype plugin indent on
  11. """"""""""""""""""""" Vundle

其中以Bundle开头的行,每一个Bundle代表一个vim插件,这些省略完整URL插件都是托管在https://github.com上的。如果想要安装新的插件,在“call vundle#rc()"”filetype plugin indent on"之间添加新的Bundle ‘插件名称’即可。
编辑完成后,在vim下运行下面的命令进行插件安装,请确保你的网络连接正常。

  1. :BundleInstall

如果安装成功,你将看到Done!的提示字样。在本例中,插件:YouCompleteMe, syntastic和ListToggle被安装进你的vim中。


三、YCM语法补全模块的编译

为了让YCM实现语法补全,还需要编译语法补全模块和编辑一个配置文件。
在终端下执行以下命令:

  1. $HOME/.vim/bundle/YouCompleteMe //切换到YCM主目录
  2. ./install.sh --clang-completer //编译耗时比较久

即可安装语法补全模块。


四、配置文件.ycm_extra_conf.py [重要]

这个文件决定了YCM在进行c系语言(c,c++,etc.) 语法补全时的行为。默认的样板配置文件在

  1. $HOME/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py

对于YCM来说,当打开一个代码文件时,插件将顺着文件所在的路径一直向上查找,如果搜索到第一个配置文件将立刻读入。如果一直搜索到根目录依旧无法找到配置文件,语法补全将不被启用。由此可知,文件所在目录的配置文件优先级最高,根目录的优先级最低。

  1. "一种比较好的使用方法是:
  2. 在每个项目中创建一个配置文件,
  3. 或者将项目根据语言进行分类,
  4. 在每个语言文件夹下建立一个配置文件。"

默认配置文件是支持c++的,但是需要修改一处地方。可以将该文件拷贝出来并编辑:

  1. cp $HOME/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py ~
  2. vim ~/.ycm_extra_conf.py

找到以下内容:

  1. # NOTE: This is just for YouCompleteMe; it's highly likely that your project
  2. # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
  3. # ycm_extra_conf IF YOU'RE NOT 100% YOU NEED IT.
  4. try:
  5. final_flags.remove( '-stdlib=libc++' )
  6. except ValueError:
  7. pass

将之删除后YCM才会补全c++标准库的内容。
这样,一个最小能用的配置文件就出炉了。


五、YCM变量配置:

在日常使用中,有一些建议修改的变量。本人的.vimrc中对YCM的配置如下:

  1. " YouCompleteMe
  2. nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
  3. nnoremap <F5> :YcmForceCompileAndDiagnostics<CR>
  4. "let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
  5. "Do not ask when starting vim
  6. let g:ycm_confirm_extra_conf = 0
  7. let g:syntastic_always_populate_loc_list = 1

其中,g:ycm_global_ycm_extra_conf 定义了全局配置文件,对于懒人来说是个好用的功能。当YCM在向上搜索的路径中找不到配置文件后,YCM将导入全局配置文件。

g:ycm_confirm_extra_conf 决定了在导入配置时是否需要手动确认。设置为0后YCM就不会老是在启动vim的时候来烦你了。

本示例中安装了syntastic插件进行语法检查,因此g:syntastic_always_populate_loc_list设置为1将更方便地使用其功能。又因为本示例安装了ListToggle,打开错误/警告提示面板将变成简单的一个快捷键。


六、我的.vimrc配置备份

  1. """"""""""""""""""""" Vundle
  2. set nocompatible " be iMproved
  3. filetype off " required!
  4. set rtp+=~/.vim/bundle/vundle/
  5. call vundle#rc()
  6. " let Vundle manage Vundle
  7. " required!
  8. Bundle 'gmarik/vundle'
  9. " My bundles here:
  10. "
  11. " original repos on GitHub
  12. Bundle 'tpope/vim-fugitive'
  13. Bundle 'Lokaltog/vim-easymotion'
  14. Bundle 'rstacruz/sparkup', {'rtp': 'vim/'}
  15. Bundle 'tpope/vim-rails.git'
  16. Bundle 'molokai'
  17. " vim-scripts repos
  18. Bundle 'Valloric/YouCompleteMe'
  19. Bundle 'Valloric/ListToggle'
  20. "Bundle 'scrooloose/syntastic'
  21. Bundle 'L9'
  22. Bundle 'FuzzyFinder'
  23. " non-GitHub repos
  24. Bundle 'git://git.wincent.com/command-t.git'
  25. " Git repos on your local machine (i.e. when working on your own plugin)
  26. " ...
  27. filetype plugin indent on " required!
  28. """"""""""""""""""""" Vundle
  29. " YouCompleteMe
  30. nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
  31. " "nnoremap <F5> :YcmForceCompileAndDiagnostics<CR>
  32. let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
  33. " "Do not ask when starting vim
  34. let g:ycm_confirm_extra_conf = 0
  35. let g:syntastic_always_populate_loc_list = 1
  36. map <F9> :call SaveInputData()<CR>
  37. func! SaveInputData()
  38. exec "tabnew"
  39. exec 'normal "+gP'
  40. exec "w! /tmp/input_data"
  41. endfunc
  42. colorscheme desert
  43. "colorscheme molokai
  44. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  45. " 显示相关
  46. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  47. set go= " 不要图形按钮
  48. syntax on " 语法高亮
  49. autocmd InsertLeave * se nocul " 用浅色高亮当前行
  50. autocmd InsertEnter * se cul " 用浅色高亮当前行
  51. set showcmd " 输入的命令显示出来,看的清楚些
  52. set novisualbell " 不要闪烁(不明白)
  53. set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} "状态行显示的内容
  54. set laststatus=1 " 启动显示状态行(1),总是显示状态行(2)
  55. set foldenable " 允许折叠
  56. set foldmethod=manual " 手动折叠
  57. set nocompatible "去掉讨厌的有关vi一致性模式,避免以前版本的一些bug和局限
  58. " 显示中文帮助
  59. if version >= 603
  60. set helplang=cn
  61. set encoding=utf-8
  62. endif
  63. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  64. "
  65. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  66. function! s:insert_gates()
  67. let gatename = substitute(toupper(expand("%:t")), "\\.", "_", "g")
  68. call setline(1, "/*************************************************************************")
  69. call append(line("."), " > File Name: ".expand("%"))
  70. call append(line(".")+1, " > Author: Dubyoo")
  71. call append(line(".")+2, " > Mail:wangwei1543@gmail.com ")
  72. call append(line(".")+3, " > Created Time: ".strftime("%c"))
  73. call append(line(".")+4, " ************************************************************************/")
  74. call append(line(".")+5, "")
  75. execute "normal! Go__"
  76. execute "normal! Gi#ifndef __" .gatename
  77. execute "normal! Go__"
  78. execute "normal! Gi#define __" .gatename
  79. execute "normal! Go"
  80. execute "normal! Go"
  81. execute "normal! Go#endif"
  82. normal! kk
  83. endfunction
  84. autocmd BufNewFile *.{h,hpp,H} call <SID>insert_gates()
  85. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  86. """""新文件标题
  87. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  88. "新建.c,.h,.sh,.java文件,自动插入文件头
  89. "autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec ":call SetTitle()"
  90. autocmd BufNewFile *.cpp,*.c,*.sh,*.java exec ":call SetTitle()"
  91. ""定义函数SetTitle,自动插入文件头
  92. func SetTitle()
  93. "如果文件类型为.sh文件
  94. if &filetype == 'sh'
  95. call setline(1,"\#########################################################################")
  96. call append(line("."), "\# File Name: ".expand("%"))
  97. call append(line(".")+1, "\# Author: Dubyoo")
  98. call append(line(".")+2, "\# mail: wangwei1543@gmail.com")
  99. call append(line(".")+3, "\# Created Time: ".strftime("%c"))
  100. call append(line(".")+4, "\#########################################################################")
  101. call append(line(".")+5, "\#!/bin/bash")
  102. call append(line(".")+6, "")
  103. else
  104. call setline(1, "/*************************************************************************")
  105. call append(line("."), " > File Name: ".expand("%"))
  106. call append(line(".")+1, " > Author: Dubyoo")
  107. call append(line(".")+2, " > Mail:wangwei1543@gmail.com ")
  108. call append(line(".")+3, " > Created Time: ".strftime("%c"))
  109. call append(line(".")+4, " ************************************************************************/")
  110. call append(line(".")+5, "")
  111. endif
  112. if &filetype == 'cpp'
  113. call append(line(".")+6, "#include <iostream>")
  114. call append(line(".")+7, "using namespace std;")
  115. call append(line(".")+8, "")
  116. endif
  117. if &filetype == 'c'
  118. call append(line(".")+6, "#include <stdio.h>")
  119. call append(line(".")+7, "")
  120. endif
  121. " if &filetype == 'java'
  122. " call append(line(".")+6,"public class ".expand("%"))
  123. " call append(line(".")+7,"")
  124. " endif
  125. "新建文件后,自动定位到文件末尾
  126. autocmd BufNewFile * normal G
  127. endfunc
  128. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  129. "键盘命令
  130. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  131. nmap <leader>w :w!<cr>
  132. nmap <leader>f :find<cr>
  133. " 映射全选+复制 ctrl+a
  134. map <C-A> ggVGY
  135. map! <C-A> <Esc>ggVGY
  136. map <F12> gg=G
  137. " 选中状态下 Ctrl+c 复制
  138. vmap <C-c> "+y
  139. "去空行
  140. nnoremap <F2> :g/^\s*$/d<CR>
  141. "比较文件
  142. nnoremap <C-F2> :vert diffsplit
  143. "新建标签
  144. map <M-F2> :tabnew<CR>
  145. "列出当前目录文件
  146. map <F3> :tabnew .<CR>
  147. "打开树状文件目录
  148. map <C-F3> \be
  149. "C,C++ 按F5编译运行
  150. map <F5> :call CompileRunGcc()<CR>
  151. func! CompileRunGcc()
  152. exec "w"
  153. if &filetype == 'c'
  154. exec "!g++ % -o %<"
  155. exec "! ./%<"
  156. elseif &filetype == 'cpp'
  157. exec "!g++ % -o %<"
  158. exec "! ./%<"
  159. elseif &filetype == 'java'
  160. exec "!javac %"
  161. exec "!java %<"
  162. elseif &filetype == 'sh'
  163. :!./%
  164. elseif &filetype == 'py'
  165. exec "!python %"
  166. exec "!python %<"
  167. endif
  168. endfunc
  169. "C,C++的调试
  170. map <F8> :call Rungdb()<CR>
  171. func! Rungdb()
  172. exec "w"
  173. exec "!g++ % -g -o %<"
  174. exec "!gdb ./%<"
  175. endfunc
  176. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  177. ""实用设置
  178. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  179. " 设置当文件被改动时自动载入
  180. set autoread
  181. " quickfix模式
  182. autocmd FileType c,cpp map <buffer> <leader><space> :w<cr>:make<cr>
  183. "代码补全
  184. set completeopt=preview,menu
  185. "允许插件
  186. filetype plugin on
  187. "共享剪贴板
  188. set clipboard+=unnamed
  189. "从不备份
  190. set nobackup
  191. "make 运行
  192. :set makeprg=g++\ -Wall\ \ %
  193. "自动保存
  194. set autowrite
  195. set ruler " 打开状态栏标尺
  196. set cursorline " 突出显示当前行
  197. set magic " 设置魔术
  198. set guioptions-=T " 隐藏工具栏
  199. set guioptions-=m " 隐藏菜单栏
  200. "set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %c:%l/%L%)\
  201. " 设置在状态行显示的信息
  202. set foldcolumn=0
  203. set foldmethod=indent
  204. set foldlevel=3
  205. set foldenable " 开始折叠
  206. " 不要使用vi的键盘模式,而是vim自己的
  207. set nocompatible
  208. " 语法高亮
  209. set syntax=on
  210. " 去掉输入错误的提示声音
  211. set noeb
  212. " 在处理未保存或只读文件的时候,弹出确认
  213. set confirm
  214. " 自动缩进
  215. set autoindent
  216. set cindent
  217. " Tab键的宽度
  218. set tabstop=4
  219. " 统一缩进为4
  220. set softtabstop=4
  221. set shiftwidth=4
  222. " 不要用空格代替制表符
  223. set noexpandtab
  224. " 在行和段开始处使用制表符
  225. set smarttab
  226. " 显示行号
  227. set number
  228. " 历史记录数
  229. set history=1000
  230. "禁止生成临时文件
  231. set nobackup
  232. set noswapfile
  233. "搜索忽略大小写
  234. set ignorecase
  235. "搜索逐字符高亮
  236. set hlsearch
  237. set incsearch
  238. "行内替换
  239. set gdefault
  240. "编码设置
  241. set enc=utf-8
  242. set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936
  243. "语言设置
  244. set langmenu=zh_CN.UTF-8
  245. set helplang=cn
  246. " 我的状态行显示的内容(包括文件类型和解码)
  247. "set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")}
  248. "set statusline=[%F]%y%r%m%*%=[Line:%l/%L,Column:%c][%p%%]
  249. " 总是显示状态行
  250. set laststatus=2
  251. " 命令行(在状态行下)的高度,默认为1,这里是2
  252. set cmdheight=2
  253. " 侦测文件类型
  254. filetype on
  255. " 载入文件类型插件
  256. filetype plugin on
  257. " 为特定文件类型载入相关缩进文件
  258. filetype indent on
  259. " 保存全局变量
  260. set viminfo+=!
  261. " 带有如下符号的单词不要被换行分割
  262. set iskeyword+=_,$,@,%,#,-
  263. " 字符间插入的像素行数目
  264. set linespace=0
  265. " 增强模式中的命令行自动完成操作
  266. set wildmenu
  267. " 使回格键(backspace)正常处理indent, eol, start等
  268. set backspace=2
  269. " 允许backspace和光标键跨越行边界
  270. set whichwrap+=<,>,h,l
  271. " 可以在buffer的任何地方使用鼠标(类似office中在工作区双击鼠标定位)
  272. """""""""""""""""""??????????????
  273. "set mouse=a
  274. "set selection=exclusive
  275. "set selectmode=mouse,key
  276. """""""""""""""""""??????????????
  277. " 通过使用: commands命令,告诉我们文件的哪一行被改变过
  278. set report=0
  279. " 在被分割的窗口间显示空白,便于阅读
  280. set fillchars=vert:\ ,stl:\ ,stlnc:\
  281. " 高亮显示匹配的括号
  282. set showmatch
  283. " 匹配括号高亮的时间(单位是十分之一秒)
  284. set matchtime=1
  285. " 光标移动到buffer的顶部和底部时保持3行距离
  286. set scrolloff=3
  287. " C程序提供自动缩进
  288. set smartindent
  289. " 高亮显示普通txt文件(需要txt.vim脚本)
  290. au BufRead,BufNewFile * setfiletype txt
  291. "自动补全
  292. :inoremap ( ()<ESC>i
  293. :inoremap ) <c-r>=ClosePair(')')<CR>
  294. ":inoremap { {<CR>}<ESC>O
  295. ":inoremap } <c-r>=ClosePair('}')<CR>
  296. :inoremap [ []<ESC>i
  297. :inoremap ] <c-r>=ClosePair(']')<CR>
  298. :inoremap " ""<ESC>i
  299. :inoremap ' ''<ESC>i
  300. function! ClosePair(char)
  301. if getline('.')[col('.') - 1] == a:char
  302. return "\<Right>"
  303. else
  304. return a:char
  305. endif
  306. endfunction
  307. filetype plugin indent on
  308. "打开文件类型检测, 加了这句才可以用智能补全
  309. set completeopt=longest,menu
  310. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  311. "NERDtee设定
  312. let NERDChristmasTree=1
  313. let NERDTreeAutoCenter=1
  314. let NERDTreeBookmarksFile=$VIM.'\Data\NerdBookmarks.txt'
  315. let NERDTreeMouseMode=2
  316. let NERDTreeShowBookmarks=1
  317. let NERDTreeShowFiles=1
  318. let NERDTreeShowHidden=1
  319. let NERDTreeShowLineNumbers=1
  320. let NERDTreeWinPos='left'
  321. let NERDTreeWinSize=31
  322. nnoremap f :NERDTreeToggle
  323. map <F7> :NERDTree<CR>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注