1. 程式人生 > >Vim程式碼補全外掛:YouCompleteMe

Vim程式碼補全外掛:YouCompleteMe

Vim的程式碼補全一般有兩種實現方案:
1. 第一種是採用ctags + OmniCppComplete ,參考:http://blog.chinaunix.net/uid-20737871-id-3402590.html
2. 第二種是採用YouCompleteMe: https://github.com/Valloric/YouCompleteMe
兩種方案都有其優缺點,第一種方案需要手動去建立tag,每天增加檔案後都要重建索引,當然也有人使用指令碼自動完成這種任務,第二種方案配置相對比較麻煩,而且容易出錯,但是補全的效果比較好。
關於YouCompleteMe的安裝網上有各種各樣的教程,但是很多人在安裝的過程中都遇到各種各樣的問題,在這裡我不再描述該外掛的詳細安裝步驟,本文提供的是YouCompleteMe的自動化安裝方案。
1.下載Vim配置和外掛安裝附件

http://pan.baidu.com/s/1i3JIwE5

2.解壓後發現有以下檔案:
這裡寫圖片描述
檔案說明:
libclang3.3是YouCompleteMe的依賴庫
vim包含各種外掛
.vimrc是vim的配置檔案
install.sh是安裝指令碼
readme.txt是安裝說明

3.詳細閱讀安裝指令碼

#!/bin/bash
echo "安裝將花費一定時間,請耐心等待直到安裝完成^_^"

echo "正在安裝必備的軟體^_^"
if which apt-get >/dev/null; then
    sudo apt-get update -y vi
    sudo
apt-get install -y vim ctags cscope build-essential cmake python-dev elif which yum >/dev/null; then sudo apt-get update -y vi sudo yum install -y gcc vim ctags cscope cmake gcc-c++ python-devel sudo yum groupinstall -y "Development Tools" fi sudo ln -s /usr/bin/ctags /usr/local/bin/ctags echo
"正在編譯安裝libclang3.3,大約二十分鐘..." cd ./libclang3.3 sudo chmod +x ./install.sh ./install.sh echo "libclang3.3安裝完成。^_^" cd .. echo "正在拷貝vim的外掛和配置檔案..." rm -Rf ~/.vim* mkdir ~/.vim cp -R ./vim/* ~/.vim cp ./.vimrc ~/ echo "vim外掛和配置檔案拷貝完成^_^" echo "正在安裝YouCompleteMe外掛..." cd ~/.vim/bundle/YouCompleteMe sudo chmod +x ./install.sh sudo chmod +x ./third_party/ycmd/build.sh ./install.sh --clang-completer --system-libclang echo "YouCompleteMe安裝完成" echo "安裝成功^_^"

(1)首先指令碼會安裝必要的軟體,包括vim ctags cscope build-essential cmake python-dev,如果已經安裝可以註釋這個部分。
(2)然後編譯安裝libclang3.3,該庫是YouCompleteMe需要的,也可以通過其他途徑安裝該庫,比如在ubuntu下可以直接使用sudo apt-get install clang進行安裝。如已經安裝可註釋該部分。
(3)接著是vim外掛和配置檔案的拷貝,注意這個操作會將原本的vim配置和外掛全部刪掉,請謹慎,如有特殊要求請自行復制。
(4)進行YouCompleteMe的編譯安裝。
4.安裝完成,請看效果圖。
這裡寫圖片描述

注:該自動化安裝在ubuntu 12.04和centos 7上測試通過,應該也支援其他的linux發行版本。

5.常用快捷鍵(僅限於附件對應的vim配置檔案)

1. 開啟和關閉左邊的目錄視窗:F2

2. 視窗切換: ctrl + w + 方向(支援h j k l)

3. 開啟右邊的函式列表視窗:在普通模式下按 tb

4. 跳轉到函式定義:在普通模式下按 ,jd  (別忽略逗號)
需要在.vimrc上加上:
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>

5. 游標跳轉:上一個位置 ctrl+o  下一個位置ctrl+i

6. 程式碼註釋:在普通模式下 ,cc (註釋)  ,cu(取消註釋)  (記得不要忘記逗號哦,)

6.vim的配置檔案

" =============================================================================
"        << 判斷作業系統是 Windows 還是 Linux 和判斷是終端還是 Gvim >>
" =============================================================================

" -----------------------------------------------------------------------------
"  < 判斷作業系統是否是 Windows 還是 Linux >
" -----------------------------------------------------------------------------
let g:iswindows = 0
let g:islinux = 0
if(has("win32") || has("win64") || has("win95") || has("win16"))
    let g:iswindows = 1
else
    let g:islinux = 1
endif

" -----------------------------------------------------------------------------
"  < 判斷是終端還是 Gvim >
" -----------------------------------------------------------------------------
if has("gui_running")
    let g:isGUI = 1
else
    let g:isGUI = 0
endif


" =============================================================================
"                          << 以下為軟體預設配置 >>
" =============================================================================

" -----------------------------------------------------------------------------
"  < Windows Gvim 預設配置> 做了一點修改
" -----------------------------------------------------------------------------
if (g:iswindows && g:isGUI)
    source $VIMRUNTIME/vimrc_example.vim
    source $VIMRUNTIME/mswin.vim
    behave mswin
    set diffexpr=MyDiff()

    function MyDiff()
        let opt = '-a --binary '
        if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
        if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
        let arg1 = v:fname_in
        if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
        let arg2 = v:fname_new
        if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
        let arg3 = v:fname_out
        if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
        let eq = ''
        if $VIMRUNTIME =~ ' '
            if &sh =~ '\<cmd'
                let cmd = '""' . $VIMRUNTIME . '\diff"'
                let eq = '"'
            else
                let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
            endif
        else
            let cmd = $VIMRUNTIME . '\diff'
        endif
        silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3 . eq
    endfunction
endif

" -----------------------------------------------------------------------------
"  < Linux Gvim/Vim 預設配置> 做了一點修改
" -----------------------------------------------------------------------------
if g:islinux
    set hlsearch        "高亮搜尋
    set incsearch       "在輸入要搜尋的文字時,實時匹配

    " Uncomment the following to have Vim jump to the last position when
    " reopening a file
    if has("autocmd")
        au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
    endif

    if g:isGUI
        " Source a global configuration file if available
        if filereadable("/etc/vim/gvimrc.local")
            source /etc/vim/gvimrc.local
        endif
    else
        " This line should not be removed as it ensures that various options are
        " properly set to work with the Vim-related packages available in Debian.
        runtime! debian.vim

        " Vim5 and later versions support syntax highlighting. Uncommenting the next
        " line enables syntax highlighting by default.
        if has("syntax")
            syntax on
        endif

        set mouse=a                    " 在任何模式下啟用滑鼠
        set t_Co=256                   " 在終端啟用256色
        set backspace=2                " 設定退格鍵可用

        " Source a global configuration file if available
        if filereadable("/etc/vim/vimrc.local")
            source /etc/vim/vimrc.local
        endif
    endif
endif


" =============================================================================
"                          << 以下為使用者自定義配置 >>
" =============================================================================

" -----------------------------------------------------------------------------
"  < Vundle 外掛管理工具配置 >
" -----------------------------------------------------------------------------
" 用於更方便的管理vim外掛,具體用法參考 :h vundle 幫助
" Vundle工具安裝方法為在終端輸入如下命令
" git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
" 如果想在 windows 安裝就必需先安裝 "git for window",可查閱網上資料

set nocompatible                                      "禁用 Vi 相容模式
filetype off                                          "禁用檔案型別偵測

if g:islinux
    set rtp+=~/.vim/bundle/vundle/
    call vundle#rc()
else
    set rtp+=$VIM/vimfiles/bundle/vundle/
    call vundle#rc('$VIM/vimfiles/bundle/')
endif

" 使用Vundle來管理外掛,這個必須要有。
Bundle 'gmarik/vundle'

" 以下為要安裝或更新的外掛,不同倉庫都有(具體書寫規範請參考幫助)
Bundle 'a.vim'
Bundle 'Align'
Bundle 'jiangmiao/auto-pairs'
Bundle 'bufexplorer.zip'
Bundle 'ccvext.vim'
Bundle 'cSyntaxAfter'
Bundle 'ctrlpvim/ctrlp.vim'
Bundle 'mattn/emmet-vim'
Bundle 'Yggdroot/indentLine'
Bundle 'vim-javacompleteex'
Bundle 'Mark--Karkat'
Bundle 'scrooloose/nerdcommenter'
Bundle 'scrooloose/nerdtree'
Bundle 'Lokaltog/vim-powerline'
Bundle 'repeat.vim'
Bundle 'msanders/snipmate.vim'
Bundle 'wesleyche/SrcExpl'
Bundle 'std_c.zip'
Bundle 'tpope/vim-surround'
Bundle 'scrooloose/syntastic'
Bundle 'majutsushi/tagbar'
Bundle 'taglist.vim'
Bundle 'TxtBrowser'
Bundle 'ZoomWin'
Bundle 'Valloric/YouCompleteMe'

" -----------------------------------------------------------------------------
"  < 編碼配置 >
" -----------------------------------------------------------------------------
" 注:使用utf-8格式後,軟體與程式原始碼、檔案路徑不能有中文,否則報錯
set encoding=utf-8                                    "設定gvim內部編碼,預設不更改
set fileencoding=utf-8                                "設定當前檔案編碼,可以更改,如:gbk(同cp936)
set fileencodings=ucs-bom,utf-8,gbk,cp936,latin-1     "設定支援開啟的檔案的編碼

" 檔案格式,預設 ffs=dos,unix
set fileformat=unix                                   "設定新(當前)檔案的<EOL>格式,可以更改,如:dos(windows系統常用)
set fileformats=unix,dos,mac                          "給出檔案的<EOL>格式型別

if (g:iswindows && g:isGUI)
    "解決選單亂碼
    source $VIMRUNTIME/delmenu.vim
    source $VIMRUNTIME/menu.vim

    "解決consle輸出亂碼
    language messages zh_CN.utf-8
endif

" -----------------------------------------------------------------------------
"  < 編寫檔案時的配置 >
" -----------------------------------------------------------------------------
filetype on                                           "啟用檔案型別偵測
filetype plugin on                                    "針對不同的檔案型別載入對應的外掛
filetype plugin indent on                             "啟用縮排
set smartindent                                       "啟用智慧對齊方式
set expandtab                                         "將Tab鍵轉換為空格
set tabstop=4                                         "設定Tab鍵的寬度,可以更改,如:寬度為2
set shiftwidth=4                                      "換行時自動縮排寬度,可更改(寬度同tabstop)
set smarttab                                          "指定按一次backspace就刪除shiftwidth寬度
set foldenable                                        "啟用摺疊
set foldmethod=indent                                 "indent 摺疊方式
set foldlevel=9999                                    " 摺疊的層次,開啟檔案時預設不折疊

" 常規模式下用空格鍵來開關游標行所在摺疊(注:zR 展開所有摺疊,zM 關閉所有摺疊)
nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo')<CR>

" 當檔案在外部被修改,自動更新該檔案
set autoread

" 常規模式下輸入 cS 清除行尾空格
nmap cS :%s/\s\+$//g<CR>:noh<CR>

" 常規模式下輸入 cM 清除行尾 ^M 符號
nmap cM :%s/\r$//g<CR>:noh<CR>

set ignorecase                                        "搜尋模式裡忽略大小寫
set smartcase                                         "如果搜尋模式包含大寫字元,不使用 'ignorecase' 選項,只有在輸入搜尋模式並且開啟 'ignorecase' 選項時才會使用
" set noincsearch                                       "在輸入要搜尋的文字時,取消實時匹配

" Ctrl + K 插入模式下游標向上移動
imap <c-k> <Up>

" Ctrl + J 插入模式下游標向下移動
imap <c-j> <Down>

" Ctrl + H 插入模式下游標向左移動
imap <c-h> <Left>

" Ctrl + L 插入模式下游標向右移動
imap <c-l> <Right>

" Ctrl + f 游標跳轉到行頭
imap <c-f> <ESC>0i

" Ctrl + e 游標跳轉到行尾
imap <c-e> <ESC>$i

" 全選
nmap <c-a> ggVG$
imap <c-a> <ESC>ggVG$


" 啟用每行超過80列的字元提示(字型變藍並加下劃線),不啟用就註釋掉
au BufWinEnter * let w:m2=matchadd('Underlined', '\%>' . 80 . 'v.\+', -1)

" -----------------------------------------------------------------------------
"  < 介面配置 >
" -----------------------------------------------------------------------------
set number                                            "顯示行號
set laststatus=2                                      "啟用狀態列資訊
set cmdheight=2                                       "設定命令列的高度為2,預設為1
set cursorline                                        "突出顯示當前行
" set guifont=YaHei_Consolas_Hybrid:h10                 "設定字型:字號(字型名稱空格用下劃線代替)
set nowrap                                            "設定不自動換行
set shortmess=atI                                     "去掉歡迎介面

" 設定 gVim 視窗初始位置及大小
if g:isGUI
    " au GUIEnter * simalt ~x                           "視窗啟動時自動最大化
    winpos 100 10                                     "指定窗口出現的位置,座標原點在螢幕左上角
    set lines=38 columns=120                          "指定視窗大小,lines為高度,columns為寬度
endif

" 設定程式碼配色方案
if g:isGUI
    colorscheme Tomorrow-Night-Eighties               "Gvim配色方案
else
    colorscheme Tomorrow-Night-Eighties               "終端配色方案
endif

" 顯示/隱藏選單欄、工具欄、滾動條,可用 Ctrl + F11 切換
if g:isGUI
    set guioptions-=m
    set guioptions-=T
    set guioptions-=r
    set guioptions-=L
    nmap <silent> <c-F11> :if &guioptions =~# 'm' <Bar>
        \set guioptions-=m <Bar>
        \set guioptions-=T <Bar>
        \set guioptions-=r <Bar>
        \set guioptions-=L <Bar>
    \else <Bar>
        \set guioptions+=m <Bar>
        \set guioptions+=T <Bar>
        \set guioptions+=r <Bar>
        \set guioptions+=L <Bar>
    \endif<CR>
endif

" -----------------------------------------------------------------------------
"  < 編譯、連線、執行配置 (目前只配置了C、C++、Java語言)>
" -----------------------------------------------------------------------------
" F5 一鍵儲存、編譯、連線存並執行
nmap <F5> :call Run()<CR>
imap <F5> <ESC>:call Run()<CR>

" Ctrl + F5 一鍵儲存並編譯
nmap <c-F5> :call Compile()<CR>
imap <c-F5> <ESC>:call Compile()<CR>

"C,C++的除錯
map <F6> :call Rungdb()<CR>
imap <F6> <ESC>:call Rungdb()<CR>

" Ctrl + F6 一鍵儲存並連線
nmap <c-F6> :call Link()<CR>
imap <c-F6> <ESC>:call Link()<CR>

let s:LastShellReturn_C = 0
let s:LastShellReturn_L = 0
let s:ShowWarning = 1
let s:Obj_Extension = '.o'
let s:Exe_Extension = '.exe'
let s:Class_Extension = '.class'
let s:Sou_Error = 0

let s:windows_CFlags = 'gcc\ -fexec-charset=gbk\ -Wall\ -g\ -O0\ -c\ %\ -o\ %<.o'
let s:linux_CFlags = 'gcc\ -Wall\ -g\ -O0\ -c\ %\ -o\ %<.o'

let s:windows_CPPFlags = 'g++\ -fexec-charset=gbk\ -Wall\ -g\ -O0\ -c\ %\ -o\ %<.o'
let s:linux_CPPFlags = 'g++\ -Wall\ -g\ -O0\ -c\ %\ -o\ %<.o'

let s:JavaFlags = 'javac\ %'

func! Compile()
    exe ":w"
    exe ":ccl"
    exe ":update"
    let s:Sou_Error = 0
    let s:LastShellReturn_C = 0
    let Sou = expand("%:p")
    let v:statusmsg = ''
    if expand("%:e") == "c" || expand("%:e") == "cpp" || expand("%:e") == "cxx"
        let Obj = expand("%:p:r").s:Obj_Extension
        let Obj_Name = expand("%:p:t:r").s:Obj_Extension
        if !filereadable(Obj) || (filereadable(Obj) && (getftime(Obj) < getftime(Sou)))
            redraw!
            if expand("%:e") == "c"
                if g:iswindows
                    exe ":setlocal makeprg=".s:windows_CFlags
                else
                    exe ":setlocal makeprg=".s:linux_CFlags
                endif
                echohl WarningMsg | echo " compiling..."
                silent make
            elseif expand("%:e") == "cpp" || expand("%:e") == "cxx"
                if g:iswindows
                    exe ":setlocal makeprg=".s:windows_CPPFlags
                else
                    exe ":setlocal makeprg=".s:linux_CPPFlags
                endif
                echohl WarningMsg | echo " compiling..."
                silent make
            endif
            redraw!
            if v:shell_error != 0
                let s:LastShellReturn_C = v:shell_error
            endif
            if g:iswindows
                if s:LastShellReturn_C != 0
                    exe ":bo cope"
                    echohl WarningMsg | echo " compilation failed"
                else
                    if s:ShowWarning
                        exe ":bo cw"
                    endif
                    echohl WarningMsg | echo " compilation successful"
                endif
            else
                if empty(v:statusmsg)
                    echohl WarningMsg | echo " compilation successful"
                else
                    exe ":bo cope"
                endif
            endif
        else
            echohl WarningMsg | echo ""Obj_Name"is up to date"
        endif
    elseif expand("%:e") == "java"
        let class = expand("%:p:r").s:Class_Extension
        let class_Name = expand("%:p:t:r").s:Class_Extension
        if !filereadable(class) || (filereadable(class) && (getftime(class) < getftime(Sou)))
            redraw!
            exe ":setlocal makeprg=".s:JavaFlags
            echohl WarningMsg | echo " compiling..."
            silent make
            redraw!
            if v:shell_error != 0
                let s:LastShellReturn_C = v:shell_error
            endif
            if g:iswindows
                if s:LastShellReturn_C != 0
                    exe ":bo cope"
                    echohl WarningMsg | echo " compilation failed"
                else
                    if s:ShowWarning
                        exe ":bo cw"
                    endif
                    echohl WarningMsg | echo " compilation successful"
                endif
            else
                if empty(v:statusmsg)
                    echohl WarningMsg | echo " compilation successful"
                else
                    exe ":bo cope"
                endif
            endif
        else
            echohl WarningMsg | echo ""class_Name"is up to date"
        endif
    else
        let s:Sou_Error = 1
        echohl WarningMsg | echo " please choose the correct source file"
    endif
    exe ":setlocal makeprg=make"
endfunc

func! Link()
    call Compile()
    if s:Sou_Error || s:LastShellReturn_C != 0
        return
    endif
    if expand("%:e") == "c" || expand("%:e") == "cpp" || expand("%:e") == "cxx"
        let s:LastShellReturn_L = 0
        let Sou = expand("%:p")
        let Obj = expand("%:p:r").s:Obj_Extension
        if g:iswindows
            let Exe = expand("%:p:r").s:Exe_Extension
            let Exe_Name = expand("%:p:t:r").s:Exe_Extension
        else
            let Exe = expand("%:p:r")
            let Exe_Name = expand("%:p:t:r")
        endif
        let v:statusmsg = ''
        if filereadable(Obj) && (getftime(Obj) >= getftime(Sou))
            redraw!
            if !executable(Exe) || (executable(Exe) && getftime(Exe) < getftime(Obj))
                if expand("%:e") == "c"
                    setlocal makeprg=gcc\ -o\ %<\ %<.o
                    echohl WarningMsg | echo " linking..."
                    silent make
                elseif expand("%:e") == "cpp" || expand("%:e") == "cxx"
                    setlocal makeprg=g++\ -o\ %<\ %<.o
                    echohl WarningMsg | echo " linking..."
                    silent make
                endif
                redraw!
                if v:shell_error != 0
                    let s:LastShellReturn_L = v:shell_error
                endif
                if g:iswindows
                    if s:LastShellReturn_L != 0
                        exe ":bo cope"
                        echohl WarningMsg | echo " linking failed"
                    else
                        if s:ShowWarning
                            exe ":bo cw"
                        endif
                        echohl WarningMsg | echo " linking successful"
                    endif
                else
                    if empty(v:statusmsg)
                        echohl WarningMsg | echo " linking successful"
                    else
                        exe ":bo cope"
                    endif
                endif
            else
                echohl WarningMsg | echo ""Exe_Name"is up to date"
            endif
        endif
        setlocal makeprg=make
    elseif expand("%:e") == "java"
        return
    endif
endfunc

func! Run() 
    if expand("%:e") == "py"
        exe ":w"
        exe ":!python %"
        return
    endif

    let s:ShowWarning = 0
    call Link()
    let s:ShowWarning = 1
    if s:Sou_Error || s:LastShellReturn_C != 0 || s:LastShellReturn_L != 0
        return
    endif
    let Sou = expand("%:p")
    if expand("%:e") == "c" || expand("%:e") == "cpp" || expand("%:e") == "cxx"
        let Obj = expand("%:p:r").s:Obj_Extension
        if g:iswindows
            let Exe = expand("%:p:r").s:Exe_Extension
        else
            let Exe = expand("%:p:r")
        endif
        if executable(Exe) && getftime(Exe) >= getftime(Obj) && getftime(Obj) >= getftime(Sou)
            redraw!
            echohl WarningMsg | echo " running..."
            if g:iswindows
                exe ":!%<.exe"
            else
                if g:isGUI
                    exe ":!gnome-terminal -x bash -c './%<; echo; echo 請按 Enter 鍵繼續; read'"
                else
                    exe ":!clear; ./%<"
                endif
            endif
            redraw!
            echohl WarningMsg | echo " running finish"
        endif
    elseif expand("%:e") == "java"
        let class = expand("%:p:r").s:Class_Extension
        if getftime(class) >= getftime(Sou)
            redraw!
            echohl WarningMsg | echo " running..."
            if g:iswindows
                exe ":!java %<"
            else
                if g:isGUI
                    exe ":!gnome-terminal -x bash -c 'java %<; echo; echo 請按 Enter 鍵繼續; read'"
                else
                    exe ":!clear; java %<"
                endif
            endif
            redraw!
            echohl WarningMsg | echo " running finish"
        endif
    endif
endfunc

func! Rungdb()
    if g:islinux
        if expand("%:e") == "c" || expand("%:e") == "cpp" || expand("%:e") == "cxx"
            call Link()
            exec "!gdb ./%<"
        else
            echohl WarningMsg | echo " only .c,.cpp or .cxx file can use gdb"
        endif
    else
        echohl WarningMsg | echo " gdb must be called in Linux"
    endif
endfunc

" -----------------------------------------------------------------------------
"  < 新檔案標題 >
" -----------------------------------------------------------------------------
"新建.c,.h,.sh,.java檔案,自動插入檔案頭 
autocmd BufNewFile *.cpp,*.[ch],*.sh,*.rb,*.java,*.py exec ":call SetTitle()" 
""定義函式SetTitle,自動插入檔案頭 
func SetTitle() 
    "如果檔案型別為.sh檔案 
    if &filetype == 'sh' 
        call setline(1,"\#!/bin/bash") 
        call append(line("."), "") 
    elseif &filetype == 'python'
        call setline(1,"#!/usr/bin/env python")
        call append(line("."),"# coding=utf-8")
        call append(line(".")+1, "") 

    elseif &filetype == 'ruby'
        call setline(1,"#!/usr/bin/env ruby")
        call append(line("."),"# encoding: utf-8")
        call append(line(".")+1, "")

"    elseif &filetype == 'mkd'
"        call setline(1,"<head><meta charset=\"UTF-8\"></head>")
    else 
        call setline(1, "/*************************************************************************") 
        call append(line("."), "    > File Name: ".expand("%")) 
        call append(line(".")+1, "  > Author: Hou") 
        call append(line(".")+2, "  > Mail: [email protected]") 
        call append(line(".")+3, "  > Created Time: ".strftime("%c")) 
        call append(line(".")+4, " ************************************************************************/") 
        call append(line(".")+5, "")
    endif
    if expand("%:e") == '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
    if expand("%:e") == 'h'
        call append(line(".")+6, "#ifndef _".toupper(expand("%:r"))."_H")
        call append(line(".")+7, "#define _".toupper(expand("%:r"))."_H")
        call append(line(".")+8, "#endif")
    endif
    if &filetype == 'java'
        call append(line(".")+6,"public class ".expand("%:r"))
        call append(line(".")+7,"")
    endif
    "新建檔案後,自動定位到檔案末尾
endfunc 
autocmd BufNewFile * normal G


" -----------------------------------------------------------------------------
"  < 在瀏覽器中預覽 Html 或 PHP 檔案 >
" -----------------------------------------------------------------------------
" 修改前請先通讀此模組,明白了再改以避免錯誤

" F9 加瀏覽器名稱縮寫呼叫瀏覽器預覽,啟用前先確定有安裝相應瀏覽器,並在下面的配置好其安裝目錄
if g:iswindows
    "以下為只支援Windows系統的瀏覽器

    " 呼叫系統IE瀏覽器預覽,如果已解除安裝可將其註釋
    nmap <F9>ie :call ViewInBrowser("ie")<cr>
    imap <F9>ie <ESC>:call ViewInBrowser("ie")<cr>

    " 呼叫IETester(IE測試工具)預覽,如果有安裝可取消註釋
    " nmap <F9>ie6 :call ViewInBrowser("ie6")<cr>
    " imap <F9>ie6 <ESC>:call ViewInBrowser("ie6")<cr>
    " nmap <F9>ie7 :call ViewInBrowser("ie7")<cr>
    " imap <F9>ie7 <ESC>:call ViewInBrowser("ie7")<cr>
    " nmap <F9>ie8 :call ViewInBrowser("ie8")<cr>
    " imap <F9>ie8 <ESC>:call ViewInBrowser("ie8")<cr>
    " nmap <F9>ie9 :call ViewInBrowser("ie9")<cr>
    " imap <F9>ie9 <ESC>:call ViewInBrowser("ie9")<cr>
    " nmap <F9>ie10 :call ViewInBrowser("ie10")<cr>
    " imap <F9>ie10 <ESC>:call ViewInBrowser("ie10")<cr>
    " nmap <F9>iea :call ViewInBrowser("iea")<cr>
    " imap <F9>iea <ESC>:call ViewInBrowser("iea")<cr>
elseif g:islinux
    "以下為只支援Linux系統的瀏覽器
    "暫未配置,待有時間再弄了
endif

"以下為支援Windows與Linux系統的瀏覽器

" 呼叫Firefox瀏覽器預覽,如果有安裝可取消註釋
" nmap <F9>ff :call ViewInBrowser("ff")<cr>
" imap <F9>ff <ESC>:call ViewInBrowser("ff")<cr>

" 呼叫Maxthon(遨遊)瀏覽器預覽,如果有安裝可取消註釋
" nmap <F9>ay :call ViewInBrowser("ay")<cr>
" imap <F9>ay <ESC>:call ViewInBrowser("ay")<cr>

" 呼叫Opera瀏覽器預覽,如果有安裝可取消註釋
" nmap <F9>op :call ViewInBrowser("op")<cr>
" imap <F9>op <ESC>:call ViewInBrowser("op")<cr>

" 呼叫Chrome瀏覽器預覽,如果有安裝可取消註釋
" nmap <F9>cr :call ViewInBrowser("cr")<cr>
" imap <F9>cr <ESC>:call ViewInBrowser("cr")<cr>

" 瀏覽器呼叫函式
function! ViewInBrowser(name)
    if expand("%:e") == "php" || expand("%:e") == "html"
        exe ":update"
        if g:iswindows
            "獲取要預覽的檔案路徑,並將路徑中的'\'替換為'/',同時將路徑文字的編碼轉換為gbk(同cp936)
            let file = iconv(substitute(expand("%:p"), '\', '/', "g"), "utf-8", "gbk")

            "瀏覽器路徑設定,路徑中使用'/'斜槓,更改路徑請更改雙引號裡的內容
            "下面只啟用了系統IE瀏覽器,如需啟用其它的可將其取消註釋(得先安裝,並配置好安裝路徑),也可按需增減
            let SystemIE = "C:/progra~1/intern~1/iexplore.exe"  "系統自帶IE目錄
            " let IETester = "F:/IETester/IETester.exe"           "IETester程式目錄(可按實際更改)
            " let Chrome = "F:/Chrome/Chrome.exe"                 "Chrome程式目錄(可按實際更改)
            " let Firefox = "F:/Firefox/Firefox.exe"              "Firefox程式目錄(可按實際更改)
            " let Opera = "F:/Opera/opera.exe"                    "Opera程式目錄(可按實際更改)
            " let Maxthon = "C:/Progra~2/Maxthon/Bin/Maxthon.exe" "Maxthon程式目錄(可按實際更改)

            "本地虛擬伺服器設定,我測試的是phpStudy2014,可根據自己的修改,更改路徑請更改雙引號裡的內容
            let htdocs ="F:/phpStudy2014/WWW/"                  "虛擬伺服器地址或目錄(可按實際更改)
            let url = "localhost"                               "虛擬伺服器網址(可按實際更改)
        elseif g:islinux
            "暫時還沒有配置,有時間再弄了。
        endif

        "瀏覽器呼叫縮寫,可根據實際增減,注意,上面瀏覽器路徑中沒有定義過的變數(等號右邊為變數)不能出現在下面喲(可將其註釋或刪除)
        let l:browsers = {}                             "定義縮寫字典變數,此行不能刪除或註釋
        " let l:browsers["cr"] = Chrome                   "Chrome瀏覽器縮寫
        " let l:browsers["ff"] = Firefox                  "Firefox瀏覽器縮寫
        " let l:browsers["op"] = Opera                    "Opera瀏覽器縮寫
        " let l:browsers["ay"] = Maxthon                  "遨遊瀏覽器縮寫
        let l:browsers["ie"] = SystemIE                 "系統IE瀏覽器縮寫
        " let l:browsers["ie6"] = IETester."-ie6"         "呼叫IETESTER工具以IE6預覽縮寫(變數加引數)
        " let l:browsers["ie7"] = IETester."-ie7"         "呼叫IETESTER工具以IE7預覽縮寫(變數加引數)
        " let l:browsers["ie8"] = IETester."-ie8"         "呼叫IETESTER工具以IE8預覽縮寫(變數加引數)
        " let l:browsers["ie9"] = IETester."-ie9"         "呼叫IETESTER工具以IE9預覽縮寫(變數加引數)
        " let l:browsers["ie10"] = IETester."-ie10"       "呼叫IETESTER工具以IE10預覽縮寫(變數加引數)
        " let l:browsers["iea"] = IETester."-al"          "呼叫IETESTER工具以支援的所有IE版本預覽縮寫(變數加引數)

        if stridx(file, htdocs) == -1   "檔案不在本地虛擬伺服器目錄,則直接預覽(但不能解析PHP檔案)
           exec ":silent !start ". l:browsers[a:name] ." file://" . file
        else    "檔案在本地虛擬伺服器目錄,則呼叫本地虛擬伺服器解析預覽(先啟動本地虛擬伺服器)
            let file = substitute(file, htdocs, "http://".url."/", "g")    "轉換檔案路徑為虛擬伺服器網址路徑
            exec ":silent !start ". l:browsers[a:name] file
        endif
    else
        echohl WarningMsg | echo " please choose the correct source file"
    endif
endfunction

" -----------------------------------------------------------------------------
"  < 其它配置 >
" -----------------------------------------------------------------------------
set writebackup                             "儲存檔案前建立備份,儲存成功後刪除該備份
set nobackup                                "設定無備份檔案
" set noswapfile                              "設定無臨時檔案
" set vb t_vb=                                "關閉提示音


" =============================================================================
"                          << 以下為常用外掛配置 >>
" =============================================================================

" -----------------------------------------------------------------------------
"  < a.vim 外掛配置 >
" -----------------------------------------------------------------------------
" 用於切換C/C++標頭檔案
" :A     ---切換標頭檔案並獨佔整個視窗
" :AV    ---切換標頭檔案並垂直分割視窗
" :AS    ---切換標頭檔案並水平分割視窗

" -----------------------------------------------------------------------------
"  < Align 外掛配置 >
" -----------------------------------------------------------------------------
" 一個對齊的外掛,用來——排版與對齊程式碼,功能強大,不過用到的機會不多

" -----------------------------------------------------------------------------
"  < auto-pairs 外掛配置 >
" -----------------------------------------------------------------------------
" 用於括號與引號自動補全,不過會與函式原型提示外掛echofunc衝突
" 所以我就沒有加入echofunc外掛

" -----------------------------------------------------------------------------
"  < BufExplorer 外掛配置 >
" -----------------------------------------------------------------------------
" 快速輕鬆的在快取中切換(相當於另一種多個檔案間的切換方式)
" <Leader>be 在當前視窗顯示快取列表並開啟選定檔案
" <Leader>bs 水平分割視窗顯示快取列表,並在快取列表視窗中開啟選定檔案
" <Leader>bv 垂直分割視窗顯示快取列表,並在快取列表視窗中開啟選定檔案

" -----------------------------------------------------------------------------
"  < ccvext.vim 外掛配置 >
" -----------------------------------------------------------------------------
" 用於對指定檔案自動生成tags與cscope檔案並連線
" 如果是Windows系統, 則生成的檔案在原始檔所在碟符根目錄的.symbs目錄下(如: X:\.symbs\)
" 如果是Linux系統, 則生成的檔案在~/.symbs/目錄下
" 具體用法可參考www.vim.org中此外掛的說明
" <Leader>sy 自動生成tags與cscope檔案並連線
" <Leader>sc 連線已存在的tags與cscope檔案

" -----------------------------------------------------------------------------
"  < cSyntaxAfter 外掛配置 >
" -----------------------------------------------------------------------------
" 高亮括號與運算子等
au! BufRead,BufNewFile,BufEnter *.{c,cpp,h,java,javascript} call CSyntaxAfter()

" -----------------------------------------------------------------------------
"  < ctrlp.vim 外掛配置 >
" -----------------------------------------------------------------------------
" 一個全路徑模糊檔案,緩衝區,最近最多使用,... 檢索外掛;詳細幫助見 :h ctrlp
" 常規模式下輸入:Ctrl + p 呼叫外掛

" -----------------------------------------------------------------------------
"  < emmet-vim(前身為Zen coding) 外掛配置 >
" -----------------------------------------------------------------------------
" HTML/CSS程式碼快速編寫神器,詳細幫助見 :h emmet.txt

" -----------------------------------------------------------------------------
"  < indentLine 外掛配置 >
" -----------------------------------------------------------------------------
" 用於顯示對齊線,與 indent_guides 在顯示方式上不同,根據自己喜好選擇了
" 在終端上會有螢幕重新整理的問題,這個問題能解決有更好了
" 開啟/關閉對齊線
nmap <leader>il :IndentLinesToggle<CR>

" 設定Gvim的對齊線樣式
if g:isGUI
    let g:indentLine_char = ""
    let g:indentLine_first_char = ""
endif

" 設定終端對齊線顏色,如果不喜歡可以將其註釋掉採用預設顏色
let g:indentLine_color_term = 239

" 設定 GUI 對齊線顏色,如果不喜歡可以將其註釋掉採用預設顏色
" let g:indentLine_color_gui = '#A4E57E'

" -----------------------------------------------------------------------------
"  < vim-javacompleteex(也就是 javacomplete 增強版)外掛配置 >
" -----------------------------------------------------------------------------
" java 補全外掛

" -----------------------------------------------------------------------------
"  < Mark--Karkat(也就是 Mark) 外掛配置 >
" -----------------------------------------------------------------------------
" 給不同的單詞高亮,表明不同的變數時很有用,詳細幫助見 :h mark.txt

" " -----------------------------------------------------------------------------
" "  < MiniBufExplorer 外掛配置 >
" " -----------------------------------------------------------------------------
" " 快速瀏覽和操作Buffer
" " 主要用於同時開啟多個檔案並相與切換

" " let g:miniBufExplMapWindowNavArrows = 1     "用Ctrl加方向鍵切換到上下左右的視窗中去
" let g:miniBufExplMapWindowNavVim = 1        "用<C-k,j,h,l>切換到上下左右的視窗中去
" let g:miniBufExplMapCTabSwitchBufs = 1      "功能增強(不過好像只有在Windows中才有用)
" "                                            <C-Tab> 向前迴圈切換到每個buffer上,並在但前視窗開啟
" "                                            <C-S-Tab> 向後迴圈切換到每個buffer上,並在當前視窗開啟

" 在不使用 MiniBufExplorer 外掛時也可用<C-k,j,h,l>切換到上下左右的視窗中去
noremap <c-k> <c-w>k
noremap <c-j> <c-w>j
noremap <c-h> <c-w>h
noremap <c-l> <c-w>l