Vim使用YouCompleteMe达到类似IDE的代码提示、补全,以及其他实用设置
接触Linux有两年了,vim还是只会简单的操作。最近实在受不了sublime的代码提示,决定花点时间来配置下vim。本文讲自己认为方便的vim配置,称不上完美,只讲究简单实用。
使用 ctags
主要参考 http://roclinux.cn/?p=424
1. ctags根据代码产生索引文件,支持ava, c, c++, python, perl, php, ruby, scheme, tcl, vim, yacc, bash/kron shell/zsh, cobol, awk, asp, lisp, pascal等等。可以通过自己的包管理器来安装。例如,对于Ubuntu sudo pat-get install ctags
2. vim通过taglist插件来使用ctags。到官网下载taglist,解压到用户家目录下的 .vim 文件夹下。这会生成 doc,plugin两个目录。
然后, cd .vim/doc
使用命令打开vim,在命令模式下执行 :helptags . 。
重启vim,taglist应该已经好了。
3. 使用 ctags+taglist
用vim打开源文件,光标定位到某个函数或者变量,按ctrl+],就可以跳转到定义。然后使用 ctrl-o或者ctrl-t。可以连续查询连续返回。
在vim中执行 :TlistToggle ,会在vim中出现宏、函数、变量列表。按ctrl-w再按w,可以连续在左右窗口切换。
配置YouCompleteMe
Ubuntu的源中已经有了, 为 vim-youcompleteme, 因为自己已经手动安装了,没有实测。不想折腾的朋友可以试一下。
1. 安装vundle
vundle是一个管理vim插件的工具,使用vundle安装YouCompleteMe比较方便。
按照作者在https://github.com/gmarik/Vundle.vim#about提供的方法安装好vundle。(主要是下载解压,病略微修改 .vimrc)
2. 使用vundle安装YouCompleteMe
主要根据作者自己的建议整理 https://github.com/Valloric/YouCompleteMe
在.vimrc中 vundle部分,添加一行:
Plugin 'Valloric/YouCompleteMe'
然后,打开vim,输入命令
:PluginInstall
就会开始自动安装vundle指定的各种插件。
由于要安装clang等,安装过程是非常久的,大概需要一个小时,这个时间完全可以去做些别的。
等安装好后,在.vim/vundle/YouCompleteMe目录下多了一堆目录和文件。
3. 使用YouCompleteMe
YouCompleteMe进行补全时需要查找一个 ycm_global_ycm_extra_conf文件。可以每次在工作目录中放置这个文件,也可以设置全局。全局设置要在.vimrc中添加一行
let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py'
4. 效果图
YCM作者主页的效果图
实用的 .vimrc 文件
主要参考http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html。 加入了前面介绍的ctags, YouCompleteMe的配置。
1 " Suzzz 2014.11.03 2 " 主要参考 http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html 3 " 额外添加了 ctags, YouCompleteMe等 4 " 主要特点 5 6 "1.按F5可以直接编译并执行C、C++、java代码以及执行shell脚本,按“F8”可进行C、C++代码的调试 7 "2.自动插入文件头 ,新建C、C++源文件时自动插入表头:包括文件名、作者、联系方式、建立时间等,读者可根据需求自行更改 8 "3.映射“Ctrl + A”为全选并复制快捷键,方便复制代码 9 "4.按“F2”可以直接消除代码中的空行 10 "5.“F3”可列出当前目录文件,打开树状文件目录 11 "6. 支持鼠标选择、方向键移动 12 "7. 代码高亮,自动缩进,显示行号,显示状态行 13 "8. 按“Ctrl + P”可自动补全 14 "9. []、{}、()、""、' '等都自动补全 --- 如果需要{}做函数形式的补全(右括号自动换行,加一个空行,光标定位到空行,可以看下面的修改提示) 15 "10. 使用YouCompleteMe提供C++的自动补全提示,效果类似 Visual Studio那种,可以解析系统头文件 16 17 18 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 19 " """""""""""""" Suzzz """"""""""""""""""""" 20 "Vundle相关。Vundle是vim插件管理器,使用它来管理插件很方便,而且功能强大 21 "https://github.com/gmarik/Vundle.vim#about 22 23 set nocompatible " be iMproved, required 24 filetype off " required 25 26 " set the runtime path to include Vundle and initialize 27 set rtp+=~/.vim/bundle/Vundle.vim 28 call vundle#begin() 29 30 " alternatively, pass a path where Vundle should install plugins 31 "call vundle#begin('~/some/path/here') 32 33 " let Vundle manage Vundle, required 34 Plugin 'gmarik/Vundle.vim' 35 36 " plugin on GitHub repo 添加github上的vimn插件,形式非常简单 37 Plugin 'tpope/vim-fugitive' 38 39 40 "语法检查 41 Plugin 'scrooloose/syntastic' 42 "让 syntastic忽略 python 文件 43 let g:syntastic_ignore_files=[".*\.py$"] 44 45 "补全 python 46 Plugin 'davidhalter/jedi' 47 48 Plugin 'rstacruz/sparkup', {'rtp': 'vim/'} 49 50 " YouCompleteMe插件,很好的智能提示,基本达到 IDE 级别 51 Plugin 'Valloric/YouCompleteMe' 52 53 54 " All of your Plugins must be added before the following line 所有Vundle管理的插件必须安装在这里之前 55 call vundle#end() " required 56 filetype plugin indent on " required 57 " To ignore plugin indent changes, instead use: 58 "filetype plugin on 59 " YouCompleteMe 通过这个cm_global_ycm_extra_conf来获得补全规则,可以如下指定,也可以每次放置在工作目录 60 let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py' 61 "让YouCompleteMe同时利用原来的ctags 62 let g:ycm_collect_identifiers_from_tag_files = 1 63 64 65 66 67 " """"""""""""" By ma6174 """"""""""""""""""""" 68 69 " 显示相关 70 71 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 72 73 "set shortmess=atI " 启动的时候不显示那个援助乌干达儿童的提示 74 75 "winpos 5 5 " 设定窗口位置 76 77 "set lines=40 columns=155 " 设定窗口大小 78 79 "set nu " 显示行号 80 81 set go= " 不要图形按钮 82 83 "color asmanian2 " 设置背景主题 84 85 set guifont=Courier_New:h10:cANSI " 设置字体 86 87 "syntax on " 语法高亮 88 89 autocmd InsertLeave * se nocul " 用浅色高亮当前行 90 91 autocmd InsertEnter * se cul " 用浅色高亮当前行 92 93 "set ruler " 显示标尺 94 95 set showcmd " 输入的命令显示出来,看的清楚些 96 97 "set cmdheight=1 " 命令行(在状态行下)的高度,设置为1 98 99 "set whichwrap+=<,>,h,l " 允许backspace和光标键跨越行边界(不建议) 100 101 "set scrolloff=3 " 光标移动到buffer的顶部和底部时保持3行距离 102 103 set novisualbell " 不要闪烁(不明白) 104 105 set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} "状态行显示的内容 106 107 set laststatus=1 " 启动显示状态行(1),总是显示状态行(2) 108 109 set foldenable " 允许折叠 110 111 set foldmethod=manual " 手动折叠 112 113 "set background=dark "背景使用黑色 114 115 set nocompatible "去掉讨厌的有关vi一致性模式,避免以前版本的一些bug和局限 116 117 " 显示中文帮助 118 119 if version >= 603 120 121 set helplang=cn 122 123 set encoding=utf-8 124 125 endif 126 127 " 设置配色方案 128 129 "colorscheme murphy 130 131 "字体 132 133 "if (has("gui_running")) 134 135 " set guifont=Bitstream\ Vera\ Sans\ Mono\ 10 136 137 "endif 138 139 140 141 set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 142 143 set termencoding=utf-8 144 145 set encoding=utf-8 146 147 set fileencodings=ucs-bom,utf-8,cp936 148 149 set fileencoding=utf-8 150 151 152 153 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 154 155 """""新文件标题"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 156 157 "新建.c,.h,.sh,.java文件,自动插入文件头 158 159 autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec ":call SetTitle()" 160 161 ""定义函数SetTitle,自动插入文件头 162 163 func SetTitle() 164 165 "如果文件类型为.sh文件 166 167 if &filetype == 'sh' 168 169 call setline(1,"\#########################################################################") 170 171 call append(line("."), "\# File Name: ".expand("%")) 172 173 call append(line(".")+1, "\# Author: YourName") 174 175 call append(line(".")+2, "\# mail: YourEmail") 176 177 "原来的时间形式比较复杂,不喜欢,改变一下 178 179 "call append(line(".")+3, "\# Created Time: ".strftime("%c")) 180 call append(line(".")+3, "\# Created Time: ".strftime("%Y-%m-%d",localtime())) 181 182 call append(line(".")+4, "\#########################################################################") 183 184 call append(line(".")+5, "\#!/bin/bash") 185 186 call append(line(".")+6, "") 187 188 else 189 190 call setline(1, "/*************************************************************************") 191 192 call append(line("."), " > File Name: ".expand("%")) 193 194 call append(line(".")+1, " > Author: YourName") 195 196 call append(line(".")+2, " > Mail: YourEmail ") 197 198 " 同样的 改变时间格式 199 "call append(line(".")+3, " > Created Time: ".strftime("%c")) 200 call append(line(".")+3, " > Created Time: ".strftime("%Y-%m-%d",localtime())) 201 202 call append(line(".")+4, " ************************************************************************/") 203 204 call append(line(".")+5, "") 205 206 endif 207 208 if &filetype == 'cpp' 209 210 call append(line(".")+6, "#include<iostream>") 211 212 call append(line(".")+7, "using namespace std;") 213 214 call append(line(".")+8, "") 215 216 endif 217 218 if &filetype == 'c' 219 220 call append(line(".")+6, "#include<stdio.h>") 221 222 call append(line(".")+7, "") 223 224 endif 225 226 "新建文件后,自动定位到文件末尾 227 228 autocmd BufNewFile * normal G 229 230 endfunc 231 232 " Suzzz: 模仿上面,新建python文件时,添加文件头 233 234 autocmd BufNewFile *py exec ":call SetPythonTitle()" 235 236 func SetPythonTitle() 237 call setline(1,"#!/usr/bin/env python") 238 call append( line("."),"#-*- coding: utf-8 -*-" ) 239 call append(line(".")+1," ") 240 call append(line(".")+2, "\# File Name: ".expand("%")) 241 call append(line(".")+3, "\# Author: YourName") 242 call append(line(".")+4, "\# mail: YourEmail") 243 call append(line(".")+5, "\# Created Time: ".strftime("%Y-%m-%d",localtime())) 244 endfunc 245 246 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 247 248 "键盘命令 249 250 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 251 252 253 254 nmap <leader>w :w!<cr> 255 256 nmap <leader>f :find<cr> 257 258 259 260 " 映射全选+复制 ctrl+a 261 262 map <C-A> ggVGY 263 264 map! <C-A> <Esc>ggVGY 265 266 map <F12> gg=G 267 268 " 选中状态下 Ctrl+c 复制 269 270 vmap <C-c> "+y 271 272 "去空行 273 274 nnoremap <F2> :g/^\s*$/d<CR> 275 276 "比较文件 277 278 nnoremap <C-F2> :vert diffsplit 279 280 "新建标签 281 282 map <M-F2> :tabnew<CR> 283 284 "列出当前目录文件 285 286 map <F3> :tabnew .<CR> 287 288 "打开树状文件目录 289 290 map <C-F3> \be 291 292 "C,C++ 按F5编译运行 293 294 map <F5> :call CompileRunGcc()<CR> 295 296 func! CompileRunGcc() 297 298 exec "w" 299 300 if &filetype == 'c' 301 302 exec "!g++ % -o %<" 303 304 exec "! ./%<" 305 306 elseif &filetype == 'cpp' 307 308 exec "!g++ % -o %<" 309 310 exec "! ./%<" 311 312 elseif &filetype == 'java' 313 314 exec "!javac %" 315 316 exec "!java %<" 317 318 elseif &filetype == 'sh' 319 320 :!./% 321 322 endif 323 324 endfunc 325 326 "C,C++的调试 327 328 map <F8> :call Rungdb()<CR> 329 330 func! Rungdb() 331 332 exec "w" 333 334 exec "!g++ % -g -o %<" 335 336 exec "!gdb ./%<" 337 338 endfunc 339 340 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 341 342 ""实用设置 343 344 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 345 346 " 设置当文件被改动时自动载入 347 348 set autoread 349 350 " quickfix模式 351 352 autocmd FileType c,cpp map <buffer> <leader><space> :w<cr>:make<cr> 353 354 "代码补全 355 356 set completeopt=preview,menu 357 358 "允许插件 359 360 filetype plugin on 361 362 "共享剪贴板 363 364 set clipboard+=unnamed 365 366 "从不备份 367 368 set nobackup 369 370 "make 运行 371 372 :set makeprg=g++\ -Wall\ \ % 373 374 "自动保存 375 376 set autowrite 377 378 set ruler " 打开状态栏标尺 379 380 set cursorline " 突出显示当前行 381 382 set magic " 设置魔术 383 384 set guioptions-=T " 隐藏工具栏 385 386 set guioptions-=m " 隐藏菜单栏 387 388 "set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %c:%l/%L%)\ 389 390 " 设置在状态行显示的信息 391 392 set foldcolumn=0 393 394 set foldmethod=indent 395 396 set foldlevel=3 397 398 set foldenable " 开始折叠 399 400 " 不要使用vi的键盘模式,而是vim自己的 401 402 set nocompatible 403 404 " 语法高亮 405 406 set syntax=on 407 408 " 去掉输入错误的提示声音 409 410 set noeb 411 412 " 在处理未保存或只读文件的时候,弹出确认 413 414 set confirm 415 416 " 自动缩进 417 418 set autoindent 419 420 set cindent 421 422 " Tab键的宽度 423 424 set tabstop=4 425 426 " 统一缩进为4 427 428 set softtabstop=4 429 430 set shiftwidth=4 431 432 " 不要用空格代替制表符 433 434 set noexpandtab 435 436 " 在行和段开始处使用制表符 437 438 set smarttab 439 440 " 显示行号 441 442 set number 443 444 " 历史记录数 445 446 set history=1000 447 448 "禁止生成临时文件 449 450 set nobackup 451 452 set noswapfile 453 454 "搜索忽略大小写 455 456 set ignorecase 457 458 "搜索逐字符高亮 459 460 set hlsearch 461 462 set incsearch 463 464 "行内替换 465 466 set gdefault 467 468 "编码设置 469 470 set enc=utf-8 471 472 set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 473 474 "语言设置 475 476 set langmenu=zh_CN.UTF-8 477 478 set helplang=cn 479 480 " 我的状态行显示的内容(包括文件类型和解码) 481 482 "set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} 483 484 "set statusline=[%F]%y%r%m%*%=[Line:%l/%L,Column:%c][%p%%] 485 486 " 总是显示状态行 487 488 set laststatus=2 489 490 " 命令行(在状态行下)的高度,默认为1,这里是2 491 492 set cmdheight=2 493 494 " 侦测文件类型 495 496 filetype on 497 498 " 载入文件类型插件 499 500 filetype plugin on 501 502 " 为特定文件类型载入相关缩进文件 503 504 filetype indent on 505 506 " 保存全局变量 507 508 set viminfo+=! 509 510 " 带有如下符号的单词不要被换行分割 511 512 set iskeyword+=_,$,@,%,#,- 513 514 " 字符间插入的像素行数目 515 516 set linespace=0 517 518 " 增强模式中的命令行自动完成操作 519 520 set wildmenu 521 522 " 使回格键(backspace)正常处理indent, eol, start等 523 524 set backspace=2 525 526 " 允许backspace和光标键跨越行边界 527 528 set whichwrap+=<,>,h,l 529 530 " 可以在buffer的任何地方使用鼠标(类似office中在工作区双击鼠标定位) 531 532 set mouse=a 533 534 set selection=exclusive 535 536 set selectmode=mouse,key 537 538 " 通过使用: commands命令,告诉我们文件的哪一行被改变过 539 540 set report=0 541 542 " 在被分割的窗口间显示空白,便于阅读 543 544 set fillchars=vert:\ ,stl:\ ,stlnc:\ 545 546 " 高亮显示匹配的括号 547 548 set showmatch 549 550 " 匹配括号高亮的时间(单位是十分之一秒) 551 552 set matchtime=1 553 554 " 光标移动到buffer的顶部和底部时保持3行距离 555 556 set scrolloff=3 557 558 " 为C程序提供自动缩进 559 560 set smartindent 561 562 " 高亮显示普通txt文件(需要txt.vim脚本) 563 564 au BufRead,BufNewFile * setfiletype txt 565 566 "自动补全 567 568 :inoremap ( ()<ESC>i 569 570 :inoremap ) <c-r>=ClosePair(')')<CR> 571 572 "by Suzzz: 原作者这种设置,输入{会自动补全,并且中间插入一个空行,将光标定位到空行。这对于函数是OK的,但是使用花括号初始化数组、vector时就不方便了。所以改为现在这种。只是补全,然后光标在左右括号中间。 573 ":inoremap { {<CR>}<ESC>O 574 :inoremap { {}<ESC>i 575 576 :inoremap } <c-r>=ClosePair('}')<CR> 577 578 :inoremap [ []<ESC>i 579 580 :inoremap ] <c-r>=ClosePair(']')<CR> 581 582 :inoremap " ""<ESC>i 583 584 :inoremap ' ''<ESC>i 585 586 function! ClosePair(char) 587 588 if getline('.')[col('.') - 1] == a:char 589 590 return "\<Right>" 591 592 else 593 594 return a:char 595 596 endif 597 598 endfunction 599 600 filetype plugin indent on 601 602 "打开文件类型检测, 加了这句才可以用智能补全 603 604 set completeopt=longest,menu 605 606 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 607 608 " CTags的设定 609 610 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 611 612 let Tlist_Sort_Type = "name" " 按照名称排序 613 614 let Tlist_Use_Right_Window = 1 " 在右侧显示窗口 615 616 let Tlist_Compart_Format = 1 " 压缩方式 617 618 let Tlist_Exist_OnlyWindow = 1 " 如果只有一个buffer,kill窗口也kill掉buffer 619 620 let Tlist_File_Fold_Auto_Close = 0 " 不要关闭其他文件的tags 621 622 let Tlist_Enable_Fold_Column = 0 " 不要显示折叠树 623 624 autocmd FileType java set tags+=D:\tools\java\tags 625 626 "autocmd FileType h,cpp,cc,c set tags+=D:\tools\cpp\tags 627 628 "let Tlist_Show_One_File=1 "不同时显示多个文件的tag,只显示当前文件的 629 630 "设置tags 631 632 set tags=tags 633 634 "set autochdir 635 636 637 638 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 639 640 "其他东东 641 642 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 643 644 "默认打开Taglist 645 646 let Tlist_Auto_Open=1 647 648 """""""""""""""""""""""""""""" 649 650 " Tag list (ctags) 651 652 """""""""""""""""""""""""""""""" 653 654 let Tlist_Ctags_Cmd = '/usr/bin/ctags' 655 656 let Tlist_Show_One_File = 1 "不同时显示多个文件的tag,只显示当前文件的 657 658 let Tlist_Exit_OnlyWindow = 1 "如果taglist窗口是最后一个窗口,则退出vim 659 660 let Tlist_Use_Right_Window = 1 "在右侧窗口中显示taglist窗口 661 662 " minibufexpl插件的一般设置 663 664 let g:miniBufExplMapWindowNavVim = 1 665 666 let g:miniBufExplMapWindowNavArrows = 1 667 668 let g:miniBufExplMapCTabSwitchBufs = 1 669 let g:miniBufExplModSelTarget = 1