首页 > 代码库 > vim--vim终极配置文件之最终极版

vim--vim终极配置文件之最终极版

"""""""""""""""""""""""""""""""""""""""""" Author   : lucasysfeng" Email    : lucasysfeng@gmail.com" Blog     : http://cnblogs.com/lucasysfeng" ReadMe   : README.md" Version  : 1.0 - Jan. 16,2014" Contents : -> 基础配置设置"            -> 自定义快捷键"            -> 主题颜色显示"            -> 其它杂项配置"            -> 插件管理配置"            -> 自定义的函数""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 基础配置设置"""""""""""""""""""""""""""""""""""""""""filetype on                      "检测文件类型filetype indent on               "针对不同的文件类型采用不同的缩进格式filetype plugin on               "允许插件filetype plugin indent on        "启动自动补全set nobackup                     "不自动保存"set pasteset relativenumber number        "相对行号,可用Ctrl+n在相对/绝对行号间切换set history=2000                 "history存储长度set nocompatible                 "非兼容vi模式,避免以前版本的一些bug和局限set autoread                     "文件修改之后自动载入set shortmess=atI                "启动的时候不显示那个援助索马里儿童的提示set t_ti= t_te=                  "退出vim后,内容显示在终端屏幕set title                        "change the terminal‘s titleset novisualbell                 "don‘t beepset noerrorbells                 "don‘t beepset t_vb=set tm=500set mat=2                        "Blink times every second when matching bracketsset showmatch                    "括号配对情况set hidden                       "A buffer becomes hidden when it is abandonedset wildmode=list:longestset ttyfastset wildignore=*.swp,*.,*.pyc,*.classset scrolloff=7                  "至少有7行在光标所在行上下set mouse=a                      "为所有模式启用鼠标set selection=oldset selectmode=mouse,keyset viminfo^=%                   "Remember info about open buffers on closeset magic                        "正则表达式匹配形式set backspace=eol,start,indent   "Configure backspace so it acts as it should actset whichwrap+=<,>,h,l" 搜索"""""""""""""""""""""""""""""""""""""""""set hlsearch                     "高亮search命中的文本。set ignorecase                   "搜索时忽略大小写set incsearch                    "随着键入即时搜索set smartcase                    "有一个或以上大写字母时仍大小写敏感" 折叠"""""""""""""""""""""""""""""""""""""""""set foldenableset foldmethod=indentset foldlevel=99" 缩进"""""""""""""""""""""""""""""""""""""""""set smartindent                  "智能缩进set autoindent                   "总是自动缩进set tabstop=4                    "设置Tab键的宽度(等同的空格个数)set shiftwidth=4                 "自动对齐的空格数set softtabstop=4                "按退格键时可以一次删掉4个空格set smarttab                     "insert tabs on the start of a line according to shiftwidth, not tabstopset expandtab                    "将Tab自动转化成空格(需要输入真正的Tab键时,使用Ctrl+V+Tab)set shiftround                   "Use multiple of shiftwidth when indenting with ‘<‘ and ‘>‘" 编码"""""""""""""""""""""""""""""""""""""""""set encoding=utf-8set fileencodings=ucs-bom,utf-8,cp936,gb18030,chinese,big5,euc-jp,euc-kr,latin1set fileencoding=utf-8set helplang=cnset termencoding=utf-8           "这句只影响普通模式 (非图形界面) 下的Vimset ffs=unix,dos,mac             "Use Unix as the standard file typeset formatoptions+=m             "如遇Unicode值大于255的文本,不必等到空格再折行。set formatoptions+=B             "合并两行中文时,不在中间加空格:" 语法"""""""""""""""""""""""""""""""""""""""""syntax enable                    "打开语法高亮syntax on" 撤销"""""""""""""""""""""""""""""""""""""""""set undolevels=1000              "How many undosset undoreload=10000             "number of lines to save for undoif v:version >= 730    set undofile                 "keep a persistent backup file    set undodir=~/bak/vimundo/endif" 状态栏"""""""""""""""""""""""""""""""""""""""""set ruler                        "显示当前的行号列号set showcmd                      "在状态栏显示正在输入的命令set showmodeset statusline=%<%f\ %h%m%r%=%k[%{(&fenc==\"\")?&enc:&fenc}%{(&bomb?\",BOM\":\"\")}]\ %-14.(%l,%c%V%)\ %Pset laststatus=2                 "命令行(在状态行下)的高度,默认为1,这里是2" 相对绝对行号""""""""""""""""""""""""""""""""""""""""""autocmd FocusLost * :set norelativenumber numberautocmd FocusGained * :set relativenumberautocmd InsertEnter * :set norelativenumber numberautocmd InsertLeave * :set relativenumber"set cursorline                  "突出显示当前行,可用Ctrl+k切换是否显示"set cursorcolumn                "突出显示当前列,可用Ctrl+k切换是否显示"set backup                       "备份" 退出插入模式时自动保存"autocmd InsertLeave * :w!<ESC>"""""""""""""""""""""""""""""""""""""""""" 自定义快捷键"""""""""""""""""""""""""""""""""""""""""" 前导符号"""""""""""""""""""""""""""""""""""""""""let mapleader = ,let g:mapleader = ," 常用快捷键"""""""""""""""""""""""""""""""""""""""""" 到行首行尾noremap H ^noremap L $" 到光标所在行第一个非空字符"map 0 ^" 从光标处复制到行尾,不包括行尾结束符map Y y$" t/T增加空行nmap t o<ESC>nmap T O<ESC>" 恢复撤销nnoremap U <C-r>" 保存map <leader>w :w!<cr>" 保存并退出当前窗口map <leader>q :wq!<CR>" 保存并挂起map <leader>z :w!<cr><C-z>" 全选map <C-a> ggVG" 相对/绝对行号转换noremap <C-n> :call NumberToggle()<cr>cnoremap <C-n> :call NumberToggle()<cr>:" 突出显示当前行/列开关map <leader>k :call CusorCulLineToggle()<cr>" 打开/关闭全部折叠map <leader>o zRmap <leader>c zM" 连续按jf退出插入/命令行/可视模式inoremap jk <ESC>lcnoremap jk <ESC>lvnoremap jf <ESC>l" 选中状态下 Ctrl+c 复制vmap <C-c> "+y" 按;直接进入命令行模式nnoremap ; :" 将光标所在行上移或下移一行,^[是按ctrl+v出来的,[k是按Alt+k出来的."nmap <S-k> :m-2<cr>"nmap <S-j> :m+1<cr>"vmap <S-k> :m-2<cr>"vmap <S-j> :m+1<cr>"nmap k :m-2<cr>"nmap j :m+1<cr>"vmap k :m-2<cr>"vmap j :m+1<cr>nmap <S-j> yypnmap <S-k> yyp" 搜索查找快捷键"""""""""""""""""""""""""""""""""""""""""" 替换,匹配模式采用very magicmap \ :%s/\v" 查找,匹配模式采用very magicnnoremap / /\vvnoremap / /\v" 去掉查找后的高亮显示noremap <silent><leader>/ :nohls<CR>" 搜索的内容总是在屏幕中心显示nnoremap <silent> n nzznnoremap <silent> N Nzznnoremap <silent> * *zznnoremap <silent> # #zznnoremap <silent> g* g*zz" 普通模式(Nomal Mode)下快捷键"""""""""""""""""""""""""""""""""""""""""" 快速编辑重vimrcnmap <silent> <leader>ev :e $MYVIMRC<CR>nmap <silent> <leader>sv :so $MYVIMRC<CR>" 快速滚屏nnoremap <C-e> 2<C-e>nnoremap <C-y> 2<C-y>" 命令行模式(Command Line Mode)下快捷键"""""""""""""""""""""""""""""""""""""""""cnoremap <C-j> <t_kd>cnoremap <C-k> <t_ku>cnoremap <C-a> <Home>cnoremap <C-e> <End>" 功能键"""""""""""""""""""""""""""""""""""""""""" F6语法高亮快捷键nnoremap <F6> :exec exists(syntax_on) ? syn off : syn on<CR>" F7标签导航"nnoremap <silent> <F7> :TlistToggle<CR>nnoremap <leader>m :TlistToggle<CR>" F8标签导航"nmap <F8> :TagbarToggle<CR>" 多窗口标签快捷键"""""""""""""""""""""""""""""""""""""""""" 在多个窗口间切换map <C-j> <C-W>jmap <C-k> <C-W>kmap <C-h> <C-W>hmap <C-l> <C-W>l" Disbale paste mode when leaving insert modemap <leader>tn :tabnew<cr>map <leader>to :tabonly<cr>map <leader>tc :tabclose<cr>map <leader>tm :tabmove<cr>" Opens a new tab with the current buffer‘s path" Super useful when editing files in the same directorymap <leader>te :tabedit <C-r>=expand("%:p:h")<cr>/" 杂项"""""""""""""""""""""""""""""""""""""""""" Disbale paste mode when leaving insert modeautocmd InsertLeave * set nopaste" w!! to sudo & write a filecmap w!! w !sudo tee >/dev/null %" Swap implementations of ` and ‘ jump to markers" By default, ‘ jumps to the marked line, ` jumps to the marked line and" column, so swap themnnoremap  `nnoremap ` " Automatically reload vimrc when it‘s savedautocmd BufWritePost .vimrc so ~/.vimrc" ; can repeat fx/tx. so do not map itnnoremap <leader>v V`}"""""""""""""""""""""""""""""""""""""""""" 主题颜色显示"""""""""""""""""""""""""""""""""""""""""" Set extra options when running in GUI modeif has("gui_running")    set guifont=Monaco:h14    set guioptions-=T    set guioptions+=e    set guioptions-=r    set guioptions-=L    set guitablabel=%M\ %t    set showtabline=1    set linespace=2    set noimd    set t_Co=256endif" 修改主题和颜色展示" colorscheme solarizedset background=darkset t_Co=256" colorscheme molokai" colorscheme desert" 设置标记一列的背景颜色和数字一行颜色一致hi! link SignColumn   LineNrhi! link ShowMarksHLl DiffAddhi! link ShowMarksHLu DiffChange" 防止错误整行标红导致看不清highlight clear SpellBadhighlight SpellBad term=standout ctermfg=1 term=underline cterm=underlinehighlight clear SpellCaphighlight SpellCap term=underline cterm=underlinehighlight clear SpellRarehighlight SpellRare term=underline cterm=underlinehighlight clear SpellLocalhighlight SpellLocal term=underline cterm=underline" settings for kien/rainbow_parentheses.vimautocmd VimEnter * RainbowParenthesesToggleautocmd Syntax * RainbowParenthesesLoadRoundautocmd Syntax * RainbowParenthesesLoadSquareautocmd Syntax * RainbowParenthesesLoadBraces"""""""""""""""""""""""""""""""""""""""""" 其它杂项配置"""""""""""""""""""""""""""""""""""""""""autocmd! bufwritepost _vimrc source %     "vimrc文件修改之后自动加载。 windows。autocmd! bufwritepost .vimrc source %     "vimrc文件修改之后自动加载。 linux。set completeopt=longest,menu              "自动补全配置,让Vim的补全菜单行为与一般IDE一致(参考VimTip1228)" 离开插入模式后自动关闭预览窗口autocmd InsertLeave * if pumvisible() == 0|pclose|endif" 回车即选中当前项inoremap <expr> <CR>       pumvisible() ? "\<C-y>" : "\<CR>"" 增强模式中的命令行自动完成操作set wildmenu" Ignore compiled files" set wildignore=*.o,*~,*.pyc,*.class" Python 文件的一般设置,比如不要tab等autocmd FileType python set tabstop=4 shiftwidth=4 expandtab ai" 如果不起作用,确定.viminfo是否可写if has("autocmd")  au BufReadPost * if line("‘\"") > 1 && line("‘\"") <= line("$") | exe "normal! g‘\"" | endifendif" 删除多余空格func! DeleteTrailingWS()  exe "normal mz"  %s/\s\+$//ge  exe "normal `z"endfuncautocmd BufWrite *.py :call DeleteTrailingWS()"""""""""""""""""""""""""""""""""""""""""" 插件管理配置开始"""""""""""""""""""""""""""""""""""""""""" package dependent:  ctags" python dependent:  pep8, pyflakefiletype offset rtp+=~/.vim/bundle/vundle/call vundle#rc()Bundle gmarik/vundle" vim plugin bundle control, command model" :BundleInstall     install" :BundleInstall!    update" :BundleClean       remove plugin not in list" 插件:目录导航等"""""""""""""""""""""""""""""""""""""""""Bundle scrooloose/nerdtreemap <leader>n :NERDTreeToggle<CR>let NERDTreeHighlightCursorline=1let NERDTreeIgnore=[ \.pyc$, \.pyo$, \.obj$, \.o$, \.so$, \.egg$, ^\.git$, ^\.svn$, ^\.hg$ ]let g:netrw_home=~/" close vim if the only window left open is a NERDTreeautocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | end" for minibufferexplBundle fholgado/minibufexpl.vimlet g:miniBufExplMapWindowNavVim = 1let g:miniBufExplMapWindowNavArrows = 1let g:miniBufExplMapCTabSwitchBufs = 1let g:miniBufExplModSelTarget = 1let g:miniBufExplForceSyntaxEnable = 1let g:miniBufExplorerMoreThanOne=2let g:miniBufExplCycleArround=1" 默认方向键左右可以切换buffernnoremap <TAB> :MBEbn<CR>noremap <leader>bn :MBEbn<CR>noremap <leader>bp :MBEbp<CR>noremap <leader>bd :MBEbd<CR>" 插件:标签导航等"""""""""""""""""""""""""""""""""""""""""Bundle majutsushi/tagbarlet g:tagbar_autofocus = 1Bundle vim-scripts/taglist.vimset tags=tags;/let Tlist_Ctags_Cmd="/usr/bin/ctags"let Tlist_Auto_Highlight_Tag = 1let Tlist_Auto_Open = 0let Tlist_Auto_Update = 1let Tlist_Close_On_Select = 0let Tlist_Compact_Format = 0let Tlist_Display_Prototype = 0let Tlist_Display_Tag_Scope = 1let Tlist_Enable_Fold_Column = 0let Tlist_Exit_OnlyWindow = 1let Tlist_File_Fold_Auto_Close = 0let Tlist_GainFocus_On_ToggleOpen = 1let Tlist_Hightlight_Tag_On_BufEnter = 1let Tlist_Inc_Winwidth = 0let Tlist_Max_Submenu_Items = 1let Tlist_Max_Tag_Length = 30let Tlist_Process_File_Always = 0let Tlist_Show_Menu = 0let Tlist_Show_One_File = 1let Tlist_Sort_Type = "order"let Tlist_Use_Horiz_Window = 0let Tlist_Use_Right_Window = 0let Tlist_WinWidth = 25" 插件:文件搜索"""""""""""""""""""""""""""""""""""""""""Bundle kien/ctrlp.vimlet g:ctrlp_map = <leader>plet g:ctrlp_cmd = CtrlPmap <leader>f :CtrlPMRU<CR>" set wildignore+=*/tmp/*,*.so,*.swp,*.zip     " MacOSX/Linux"let g:ctrlp_custom_ignore = {    \ dir:  \v[\/]\.(git|hg|svn|rvm)$,    \ file: \v\.(exe|so|dll|zip|tar|tar.gz)$,    \ }" \ ‘link‘: ‘SOME_BAD_SYMBOLIC_LINKS‘,let g:ctrlp_working_path_mode=0let g:ctrlp_match_window_bottom=1let g:ctrlp_max_height=15let g:ctrlp_match_window_reversed=0let g:ctrlp_mruf_max=500let g:ctrlp_follow_symlinks=1" 插件:状态栏美观"""""""""""""""""""""""""""""""""""""""""Bundle Lokaltog/vim-powerline" if want to use fancy,need to add font patch -> git clone git://gist.github.com/1630581.git ~/.fonts/ttf-dejavu-powerline"let g:Powerline_symbols = ‘fancy‘"let g:Powerline_symbols = ‘unicode‘" 插件:括号显示增强"""""""""""""""""""""""""""""""""""""""""Bundle kien/rainbow_parentheses.vimlet g:rbpt_colorpairs = [    \ [brown,       RoyalBlue3],    \ [Darkblue,    SeaGreen3],    \ [darkgray,    DarkOrchid3],    \ [darkgreen,   firebrick3],    \ [darkcyan,    RoyalBlue3],    \ [darkred,     SeaGreen3],    \ [darkmagenta, DarkOrchid3],    \ [brown,       firebrick3],    \ [gray,        RoyalBlue3],    \ [black,       SeaGreen3],    \ [darkmagenta, DarkOrchid3],    \ [Darkblue,    firebrick3],    \ [darkgreen,   RoyalBlue3],    \ [darkcyan,    SeaGreen3],    \ [darkred,     DarkOrchid3],    \ [red,         firebrick3],    \ ]let g:rbpt_max = 40let g:rbpt_loadcmd_toggle = 0" 插件:将每行无效的空格标红(,空格按键去掉末尾空格)"""""""""""""""""""""""""""""""""""""""""Bundle bronson/vim-trailing-whitespacemap <leader><space> :FixWhitespace<cr>" 插件:主题solarizedBundle altercation/vim-colors-solarized" let g:solarized_termcolors=256let g:solarized_termtrans=1let g:solarized_contrast="normal"let g:solarized_visibility="normal"" 插件:主题molokaiBundle tomasr/molokai" let g:molokai_original = 1" 插件:快速移动"""""""""""""""""""""""""""""""""""""""""" 更高效的移动 ,, + w/fxBundle Lokaltog/vim-easymotionBundle vim-scripts/matchit.zip" 插件:迄今为止用到的最好的自动VIM自动补全插件"""""""""""""""""""""""""""""""""""""""""" Bundle ‘Valloric/YouCompleteMe‘" youcompleteme  默认tab  s-tab 和自动补全冲突" let g:ycm_key_list_select_completion=[‘<C-n>‘]" let g:ycm_key_list_select_completion = [‘<Down>‘]" let g:ycm_key_list_previous_completion=[‘<C-p>‘]" let g:ycm_key_list_previous_completion = [‘<Up>‘]" 在注释输入中也能补全" let g:ycm_complete_in_comments = 1" 在字符串输入中也能补全" let g:ycm_complete_in_strings = 1" 注释和字符串中的文字也会被收入补全" let g:ycm_collect_identifiers_from_comments_and_strings = 0" 插件:快速插入代码片段"""""""""""""""""""""""""""""""""""""""""Bundle SirVer/ultisnipslet g:UltiSnipsExpandTrigger = "<tab>"let g:UltiSnipsJumpForwardTrigger = "<tab>"" 定义存放代码片段的文件夹 .vim/snippets下,使用自定义和默认的,将会的到全局,有冲突的会提示let g:UltiSnipsSnippetDirectories=["snippets", "bundle/ultisnips/UltiSnips"]" 插件:快速加/减注释(选中后,按,cc加上注释,按,cu解开注释)"""""""""""""""""""""""""""""""""""""""""Bundle scrooloose/nerdcommenter" 插件:用双引号/单引号包裹字符串"""""""""""""""""""""""""""""""""""""""""" cs" ‘" Hello world!" -> Hello world!" ds"" " Hello world!" -> Hello world!" ysiw"" Hello -> " Hello"Bundle tpope/vim-surroundBundle tpope/vim-repeat" 插件:自动补全单引号,双引号等"""""""""""""""""""""""""""""""""""""""""Bundle Raimondi/delimitMate" for python docstring " ,优化输入autocmd FileType python let b:delimitMate_nesting_quotes = ["]" 自动补全html/xml标签Bundle docunext/closetag.vimlet g:closetag_html_style=1" 插件:代码格式化"""""""""""""""""""""""""""""""""""""""""Bundle godlygeek/tabularnmap <Leader>a= :Tabularize /=<CR>vmap <Leader>a= :Tabularize /=<CR>nmap <Leader>a: :Tabularize /:\zs<CR>vmap <Leader>a: :Tabularize /:\zs<CR>" for visual selectionBundle terryma/vim-expand-regionmap = <Plug>(expand_region_expand)map - <Plug>(expand_region_shrink)" 插件:多光标批量操作"""""""""""""""""""""""""""""""""""""""""" Bundle ‘terryma/vim-multiple-cursors‘" let g:multi_cursor_use_default_mapping=0" Default mapping" let g:multi_cursor_next_key=‘<C-m>‘" let g:multi_cursor_prev_key=‘<C-p>‘" let g:multi_cursor_skip_key=‘<C-x>‘" let g:multi_cursor_quit_key=‘<ESC>‘" 插件:语法检查"""""""""""""""""""""""""""""""""""""""""" 编辑时自动语法检查标红, vim-flake8目前还不支持,所以多装一个" 使用pyflakes,速度比pylint快Bundle scrooloose/syntasticlet g:syntastic_error_symbol=>>let g:syntastic_warning_symbol=>let g:syntastic_check_on_open=1let g:syntastic_enable_highlighting = 0let g:syntastic_python_checkers=[pyflakes]highlight SyntasticErrorSign guifg=white guibg=black" python fly check, 弥补syntastic只能打开和保存才检查语法的不足Bundle kevinw/pyflakes-vimlet g:pyflakes_use_quickfix = 0" 插件:具体语言语法高亮"""""""""""""""""""""""""""""""""""""""""" for python.vim syntax highlightBundle hdima/python-syntaxlet python_highlight_all = 1" for golangBundle jnwhiteh/vim-golangBundle Blackrush/vim-gocode" for markdownBundle plasticboy/vim-markdownlet g:vim_markdown_folding_disabled=1" for javascriptBundle "pangloss/vim-javascript"let g:html_indent_inctags = "html,body,head,tbody"let g:html_indent_script1 = "inc"let g:html_indent_style1 = "inc"" for jqueryBundle nono/jquery.vim" for jinja2 highlightBundle Glench/Vim-Jinja2-Syntax" for nginx conf file highlight.   need to confirm it worksBundle thiderman/nginx-vim-syntax" 插件:杂项"""""""""""""""""""""""""""""""""""""""""" task listBundle vim-scripts/TaskList.vimmap <leader>td <Plug>TaskList" for git 尚未用起来Bundle tpope/vim-fugitive" 可以查看/回到某个历史状态Bundle sjl/gundo.vimnnoremap <leader>h :GundoToggle<CR>" end turn onfiletype plugin indent on"""""""""""""""""""""""""""""""""""""""""" 插件管理配置结束""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 自定义的函数"""""""""""""""""""""""""""""""""""""""""" 相对绝对行号转换function! NumberToggle()  if(&relativenumber == 1)    set norelativenumber number  else    set relativenumber  endifendfunc" 突出显示当前行列转换function! CusorCulLineToggle()  if(&cursorcolumn == 1)    set nocursorcolumn    set nocursorline  else    set cursorcolumn    set cursorline  endifendfuncfunction! GoToFileEnd()    normal Gendfunc""定义函数SetTitle,自动插入文件头autocmd BufNewFile *.py,*.cpp,*.c,*.sh,*.java exec ":call SetTitle()"function! SetTitle()    "如果文件类型为.sh文件    if &filetype == sh        call setline(1,"\#!/bin/bash")        call append(line("."), "\#############################################")        call append(line(".")+1, "\# Copyright(c) Tencent, all rights reserved")        call append(line(".")+2, "\# @file        : ".expand("%"))        call append(line(".")+3, "\# @author      : lucasysfeng")        call append(line(".")+4, "\# @revision    : ".strftime("%Y-%m-%-d %H:%M:%S"))        call append(line(".")+5, "\# @brief       :")        call append(line(".")+6, "\#############################################")    elseif &filetype == cpp || &filetype == c        call setline(1,"/****************************************************")        call append(line("."), "\# Copyright(c) Tencent, all rights reserved")        call append(line(".")+1, "\# @file        : ".expand("%"))        call append(line(".")+2, "\# @author      : lucasysfeng")        call append(line(".")+3, "\# @revision    : ".strftime("%Y-%m-%-d %H:%M:%S"))        call append(line(".")+4, "\# @brief       :")        call append(line(".")+5, "****************************************************/")        call append(line(".")+6, "")        call append(line(".")+7, "#include <iostream>")        call append(line(".")+8, "#include <string>")        call append(line(".")+9, "")        call append(line(".")+10, "using namespace std;")        call append(line(".")+11, "")        call append(line(".")+12, "int main()")        call append(line(".")+13, "{")        call append(line(".")+14, "")        call append(line(".")+15, "    return 0;")        call append(line(".")+16,"}")    elseif &filetype == python        call setline(1,"\#!/usr/bin/env python")        call append(line("."), "\# -*- coding: utf-8 -*-")        call append(line(".")+1, "\#############################################")        call append(line(".")+2, "\# Copyright(c) , all rights reserved")        call append(line(".")+3, "\# @file        : ".expand("%"))        call append(line(".")+4, "\# @author      : lucasysfeng")        call append(line(".")+5, "\# @revision    : ".strftime("%Y-%m-%-d %H:%M:%S"))        call append(line(".")+6, "\# @brief       :")        call append(line(".")+7, "\#############################################")    endif    "新建文件后,自动定位到文件末尾    "autocmd BufNewFile * exec ":call GoToFileEnd()"    call GoToFileEnd()endfunc" Doxygen注释快捷键nnoremap <leader>g :Dox<CR>" DoxygenToolkit.vim" Brief: Usefull tools for Doxygen (comment, author, license)." Version: 0.2.13" Date: 2010/10/16" Author: Mathias Lorente"" TODO: add automatically (option controlled) in/in out flags to function"       parameters" TODO: (Python) Check default paramareters defined as list/dictionnary/tuple"" Note: Correct insertion position and ‘xxx_post‘ parameters."      - Insert position is correct when g:DoxygenToolkit_compactOneLineDoc = "yes""        and let g:DoxygenToolkit_commentType = "C++" are set."      - When you define:"              g:DoxygenToolkit_briefTag_pre = "@brief ""              g:DoxygenToolkit_briefTag_post = "<++>""              g:DoxygenToolkit_briefTag_funcName = "yes""        Documentation generated with these parameters is something like:"           /// @brief foo <++>"        You can configure similarly parameters to get something like:"           /// @brief foo <++>"           /// @param bar <++>"           /// @param baz <++>"" Note: Position the cursor at the right position for one line documentation."" Note: Remove trailing blank characters where they are not needed."" Note: ‘extern‘ keyword added in list of values to ignore for return type."" Note: Correct bugs related to templates and add support for throw statement"       (many thanks to Dennis Lubert):"   - Template parameter of different type from class and typename are"     recognized."   - Indentation mistake while detecting template."   - New option are available: g:DoxygenToolkit_throwTag_pre and"     g:DoxygenToolkit_throwTag_post"" Note: Add support for documentation of template parameters."       Thanks to Dennis (plasmahh) and its suggestions."   - New option are available: g:DoxygenToolkit_templateParamTag_pre"     and g:DoxygenToolkit_templateParamTag_post"" Note: Solve almost all compatibility problem with c/c++ IDE"" Note: Bug correction and improve compatibility with c/c++ IDE"   - Documentation of function with struct parameters are now allowed."   - Comments are written in two steps to avoid conflicts with c/c++ IDE."" Note: Bug correction (thanks to Jhon Do)"   - DoxygenToolkit_briefTag_funcName and other xxx_xxName parameters"     should work properly now."" Note: Bug correction (thanks to Anders Bo Rasmussen)"   - C++: now functions like  void foo(type &bar); are correctly documented."          The parameter‘s name is bar (and no more &bar)."" Note: Added @version tag into the DocBlock generated by DoxygenAuthorFunc()"       (thanks to Dave Walter)."       The version string can be defines into your .vimrc file with"       g:DoxygenToolkit_versionString or it will be asked the first time the"       function is called (same behavior as @author tag). Example:"                 /// \file foo.cpp"                 /// \brief"                 /// \author Dave Walter"                 /// \version 1.0"                 /// \date 2009-03-26"" Note: Comments are now allowed in function declaration. Example:"   - C/C++:   void func( int foo, // first param"                         int bar  /* second param */ );""   - Python:  def func( foo,  # first param"                        bar ) # second param"" Note: Bug correction (many thanks to Alexey Radkov)"   - C/C++: following function/method are now correctly documented:"      - operator(),"      - constructor with initialization parameter(s),"      - pure virtual method,"      - const method."   - Python:"      - Single line function are now correctly documented."" Note: The main function has been rewritten (I hope it is cleaner)."   - There is now support for function pointer as parameter (C/C++)."   - You can configure the script to get one line documentation (for"     attribute instance for example, you need to set"     g:DoxygenToolkit_compactOneLineDoc to "yes").""   - NEW: Support Python scripts:"      - Function/method are not scanned, so by default they are considered"        as if they always return something (modify this behavior by defining"        g:DoxygenToolkit_python_autoFunctionReturn to "no")"      - self parameter is automatically ignored when scanning function"        parameters (you can change this behavior by defining"        g:DoxygenToolkit_python_autoRemoveSelfParam to "no")"" Note: Number of lines scanned is now configurable. Default value is still 10"     lines. (Thanks to Spencer Collyer for this improvement)."" Note: Bug correction : function that returns null pointer are correctly"     documented (Thanks to Ronald WAHL for his report and patch)."" Note: Remove header and footer from doxygen documentation"   - Generated documentation with block header/footer activated (see"     parameters g:DoxygenToolkit_blockHeader and"     g:DoxygenToolkit_blockFooter) do not integrate header and footer"     anymore."     Thanks to Justin RANDALL for this."     Now comments are as following:"     /* --- My Header --- */             // --- My Header ---"     /**                                 /// @brief ..."      *  @brief ...                or    // --- My Footer ---"      */"     /* -- My Footer --- */"" Note: Changes to customize cinoptions"   - New option available for cinoptions : g:DoxygenToolkit_cinoptions"     (default value is still c1C1)"     Thanks to Arnaud GODET for this. Now comment can have the following"     look:"     /**                      /**"     *       and not only     *"     */                       */" Note: Changes for linux kernel comment style"   - New option are available for brief tag and parameter tag ! Now there is"     a pre and a post tag for each of these tag."   - You can define ‘let g:DoxygenToolkit_briefTag_funcName = "yes"‘ to add"     the name of commented function between pre-brief tag and post-brief tag."   - With these new features you can get something like:"     /**"      * @brief MyFunction -"      *"      * @param foo:"      * @param bar:"      */" Note: Changes suggested by Soh Kok Hong:"   - Fixed indentation in comments"     ( no more /**               /**"                 *       but      *"                 */               */     )" Note: Changes made by Jason Mills:"   - Fixed \n bug which resulted in comments being screwed up"   - Added use of doxygen /// comments." Note: Changes made by Mathias Lorente on 05/25/04"   - Fixed filename bug when including doxygen author comment whereas file"     has not been open directly on commamd line."   - Now /// or /** doxygen comments are correctly integrated (except for"     license)." Note: Changes made by Mathias Lorente on 08/02/04"   - Now include only filename in author comment (no more folder...)"   - Fixed errors with function with no indentation.""" Currently five purposes have been defined :"" Generates a doxygen license comment.  The tag text is configurable."" Generates a doxygen author skeleton.  The tag text is configurable."" Generates a doxygen comment skeleton for a C, C++ or Python function or class," including @brief, @param (for each named argument), and @return.  The tag" text as well as a comment block header and footer are configurable." (Consequently, you can have \brief, etc. if you wish, with little effort.)"" Ignore code fragment placed in a block defined by #ifdef ... #endif (C/C++).  The" block name must be given to the function.  All of the corresponding blocks" in all the file will be treated and placed in a new block DOX_SKIP_BLOCK (or" any other name that you have configured).  Then you have to update" PREDEFINED value in your doxygen configuration file with correct block name." You also have to set ENABLE_PREPROCESSING to YES."" Generate a doxygen group (begining and ending). The tag text is" configurable."" Use:" - Type of comments (C/C++: /// or /** ... */, Python: ## and # ) :"   In vim, default C++ comments are : /** ... */. But if you prefer to use ///"   Doxygen comments just add ‘let g:DoxygenToolkit_commentType = "C++""   (without quotes) in your .vimrc file"" - License :"   In vim, place the cursor on the line that will follow doxygen license"   comment.  Then, execute the command :DoxLic.  This will generate license"   comment and leave the cursor on the line just after."" - Author :"   In vim, place the cursor on the line that will follow doxygen author"   comment.  Then, execute the command :DoxAuthor.  This will generate the"   skeleton and leave the cursor just after @author tag if no variable"   define it, or just after the skeleton."" - Function / class comment :"   In vim, place the cursor on the line of the function header (or returned"   value of the function) or the class.  Then execute the command :Dox.  This"   will generate the skeleton and leave the cursor after the @brief tag."" - Ignore code fragment :"   In vim, if you want to ignore all code fragment placed in a block such as :"     #ifdef DEBUG"     ..."     #endif"   You only have to execute the command :DoxUndoc(DEBUG) !"" - Group :"   In vim, execute the command :DoxBlock to insert a doxygen block on the"   following line."" Limitations:" - Assumes that the function name (and the following opening parenthesis) is"   at least on the third line after current cursor position." - Not able to update a comment block after it‘s been written." - Blocks delimiters (header and footer) are only included for function"   comment." - Assumes that cindent is used." - Comments in function parameters (such as void foo(int bar /* ... */, baz))"   are not yet supported.""" Example:" Given:" int"   foo(char mychar,"       int myint,"       double* myarray,"       int mask = DEFAULT)" { //..." }"" Issuing the :Dox command with the cursor on the function declaration would" generate"" /**"  * @brief"  *"  * @param mychar"  * @param myint"  * @param myarray"  * @param mask"  *"  * @return"  */""" To customize the output of the script, see the g:DoxygenToolkit_*" variables in the script‘s source.  These variables can be set in your" .vimrc."" For example, my .vimrc contains:" let g:DoxygenToolkit_briefTag_pre="@Synopsis  "" let g:DoxygenToolkit_paramTag_pre="@Param "" let g:DoxygenToolkit_returnTag="@Returns   "" let g:DoxygenToolkit_blockHeader="--------------------------------------------------------------------------"" let g:DoxygenToolkit_blockFooter="----------------------------------------------------------------------------"" let g:DoxygenToolkit_authorName="Mathias Lorente"" let g:DoxygenToolkit_licenseTag="My own license"   <-- Does not end with" "\<enter>"" Verify if already loaded"if exists("loaded_DoxygenToolkit")" echo ‘DoxygenToolkit Already Loaded.‘" finish"endiflet loaded_DoxygenToolkit = 1"echo ‘Loading DoxygenToolkit...‘let s:licenseTag = "Copyright (C) \<enter>\<enter>"let s:licenseTag = s:licenseTag . "This program is free software; you can redistribute it and/or\<enter>"let s:licenseTag = s:licenseTag . "modify it under the terms of the GNU General Public License\<enter>"let s:licenseTag = s:licenseTag . "as published by the Free Software Foundation; either version 2\<enter>"let s:licenseTag = s:licenseTag . "of the License, or (at your option) any later version.\<enter>\<enter>"let s:licenseTag = s:licenseTag . "This program is distributed in the hope that it will be useful,\<enter>"let s:licenseTag = s:licenseTag . "but WITHOUT ANY WARRANTY; without even the implied warranty of\<enter>"let s:licenseTag = s:licenseTag . "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\<enter>"let s:licenseTag = s:licenseTag . "GNU General Public License for more details.\<enter>\<enter>"let s:licenseTag = s:licenseTag . "You should have received a copy of the GNU General Public License\<enter>"let s:licenseTag = s:licenseTag . "along with this program; if not, write to the Free Software\<enter>"let s:licenseTag = s:licenseTag . "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\<enter>"" Common standard constantsif !exists("g:DoxygenToolkit_briefTag_pre")  let g:DoxygenToolkit_briefTag_pre = "@brief "endifif !exists("g:DoxygenToolkit_briefTag_post")  let g:DoxygenToolkit_briefTag_post = ""endifif !exists("g:DoxygenToolkit_templateParamTag_pre")  let g:DoxygenToolkit_templateParamTag_pre = "@tparam "endifif !exists("g:DoxygenToolkit_templateParamTag_post")  let g:DoxygenToolkit_templateParamTag_post = ""endifif !exists("g:DoxygenToolkit_paramTag_pre")  let g:DoxygenToolkit_paramTag_pre = "@param "endifif !exists("g:DoxygenToolkit_paramTag_post")  let g:DoxygenToolkit_paramTag_post = ""endifif !exists("g:DoxygenToolkit_returnTag")  let g:DoxygenToolkit_returnTag = "@return"endifif !exists("g:DoxygenToolkit_throwTag_pre")  let g:DoxygenToolkit_throwTag_pre = "@throw " " @exception is also validendifif !exists("g:DoxygenToolkit_throwTag_post")  let g:DoxygenToolkit_throwTag_post = ""endifif !exists("g:DoxygenToolkit_blockHeader")  let g:DoxygenToolkit_blockHeader = ""endifif !exists("g:DoxygenToolkit_blockFooter")  let g:DoxygenToolkit_blockFooter = ""endifif !exists("g:DoxygenToolkit_licenseTag")  let g:DoxygenToolkit_licenseTag = s:licenseTagendifif !exists("g:DoxygenToolkit_fileTag")  let g:DoxygenToolkit_fileTag = "@file "endifif !exists("g:DoxygenToolkit_authorTag")  let g:DoxygenToolkit_authorTag = "@author "endifif !exists("g:DoxygenToolkit_dateTag")  let g:DoxygenToolkit_dateTag = "@date "endifif !exists("g:DoxygenToolkit_versionTag")  let g:DoxygenToolkit_versionTag = "@version "endifif !exists("g:DoxygenToolkit_undocTag")  let g:DoxygenToolkit_undocTag = "DOX_SKIP_BLOCK"endifif !exists("g:DoxygenToolkit_blockTag")  let g:DoxygenToolkit_blockTag = "@name "endifif !exists("g:DoxygenToolkit_classTag")  let g:DoxygenToolkit_classTag = "@class "endifif !exists("g:DoxygenToolkit_cinoptions")    let g:DoxygenToolkit_cinoptions = "c1C1"endifif !exists("g:DoxygenToolkit_startCommentTag ")  let g:DoxygenToolkit_startCommentTag = "/** "  let g:DoxygenToolkit_startCommentBlock = "/* "endifif !exists("g:DoxygenToolkit_interCommentTag ")  let g:DoxygenToolkit_interCommentTag = "* "endifif !exists("g:DoxygenToolkit_interCommentBlock ")  let g:DoxygenToolkit_interCommentBlock = "* "endifif !exists("g:DoxygenToolkit_endCommentTag ")  let g:DoxygenToolkit_endCommentTag = "*/"  let g:DoxygenToolkit_endCommentBlock = "*/"endifif exists("g:DoxygenToolkit_commentType")  if ( g:DoxygenToolkit_commentType == "C++" )    let g:DoxygenToolkit_startCommentTag = "/// "    let g:DoxygenToolkit_interCommentTag = "/// "    let g:DoxygenToolkit_endCommentTag = ""    let g:DoxygenToolkit_startCommentBlock = "// "    let g:DoxygenToolkit_interCommentBlock = "// "    let g:DoxygenToolkit_endCommentBlock = ""  else    let g:DoxygenToolkit_commentType = "C"  endifelse  let g:DoxygenToolkit_commentType = "C"endif" Compact documentation" /**"  * \brief foo      --->    /** \brief foo */"  */if !exists("g:DoxygenToolkit_compactOneLineDoc")  let g:DoxygenToolkit_compactOneLineDoc = "no"endif" /**"  * \brief foo             /**"  *                         * \brief foo"  * \param bar      --->    * \param bar"  *                         * \return"  * \return                 */"  */if !exists("g:DoxygenToolkit_compactDoc")  let g:DoxygenToolkit_compactDoc = "no"endif" Necessary ‘\<‘ and ‘\>‘ will be added to each item of the list.let s:ignoreForReturn = [template, explicit, inline, static, virtual, void\([[:blank:]]*\*\)\@!, const, volatile, struct, extern]if !exists("g:DoxygenToolkit_ignoreForReturn")  let g:DoxygenToolkit_ignoreForReturn = s:ignoreForReturn[:]else  let g:DoxygenToolkit_ignoreForReturn += s:ignoreForReturnendifunlet s:ignoreForReturn" Maximum number of lines to check for function parametersif !exists("g:DoxygenToolkit_maxFunctionProtoLines")  let g:DoxygenToolkit_maxFunctionProtoLines = 10endif" Add name of function/class/struct... after pre brief tag if you wantif !exists("g:DoxygenToolkit_briefTag_className")  let g:DoxygenToolkit_briefTag_className = "no"endifif !exists("g:DoxygenToolkit_briefTag_structName")  let g:DoxygenToolkit_briefTag_structName = "no"endifif !exists("g:DoxygenToolkit_briefTag_enumName")  let g:DoxygenToolkit_briefTag_enumName = "no"endifif !exists("g:DoxygenToolkit_briefTag_namespaceName")  let g:DoxygenToolkit_briefTag_namespaceName = "no"endifif !exists("g:DoxygenToolkit_briefTag_funcName")  let g:DoxygenToolkit_briefTag_funcName = "no"endif" Keep empty line (if any) between comment and function/class/...if !exists("g:DoxygenToolkit_keepEmptyLineAfterComment")  let g:DoxygenToolkit_keepEmptyLineAfterComment = "no"endif" PYTHON specific"""""""""""""""""" Remove automatically self parameter from function to avoid its documantationif !exists("g:DoxygenToolkit_python_autoRemoveSelfParam")  let g:DoxygenToolkit_python_autoRemoveSelfParam = "yes"endif" Consider functions as if they always return something (default: yes)if !exists("g:DoxygenToolkit_python_autoFunctionReturn")  let g:DoxygenToolkit_python_autoFunctionReturn = "yes"endif""""""""""""""""""""""""""" Doxygen license comment""""""""""""""""""""""""""function! <SID>DoxygenLicenseFunc()  call s:InitializeParameters()  " Test authorName variable  if !exists("g:DoxygenToolkit_authorName")    let g:DoxygenToolkit_authorName = input("Enter name of the author (generally yours...) : ")  endif  mark d  let l:date = strftime("%Y")  exec "normal O".strpart( s:startCommentBlock, 0, 1 )  exec "normal A".strpart( s:startCommentBlock, 1 ).substitute( g:DoxygenToolkit_licenseTag, "\<enter>", "\<enter>".s:interCommentBlock, "g" )  if( s:endCommentBlock != "" )    exec "normal o".s:endCommentBlock  endif  if( g:DoxygenToolkit_licenseTag == s:licenseTag )    exec "normal %jA".l:date." - ".g:DoxygenToolkit_authorName  endif  exec "normal `d"  call s:RestoreParameters()endfunction""""""""""""""""""""""""""" Doxygen author comment""""""""""""""""""""""""""function! <SID>DoxygenAuthorFunc()  call s:InitializeParameters()  " Test authorName variable  if !exists("g:DoxygenToolkit_authorName")    let g:DoxygenToolkit_authorName = input("Enter name of the author (generally yours...) : ")  endif  " Test versionString variable  if !exists("g:DoxygenToolkit_versionString")    let g:DoxygenToolkit_versionString = input("Enter version string : ")  endif  " Get file name  let l:fileName = expand(%:t)  " Begin to write skeleton  let l:insertionMode = s:StartDocumentationBlock()  exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_fileTag.l:fileName  exec "normal o".s:interCommentTag.g:DoxygenToolkit_briefTag_pre  mark d  exec "normal o".s:interCommentTag.g:DoxygenToolkit_authorTag.g:DoxygenToolkit_authorName  exec "normal o".s:interCommentTag.g:DoxygenToolkit_versionTag.g:DoxygenToolkit_versionString  let l:date = strftime("%Y-%m-%d")  exec "normal o".s:interCommentTag.g:DoxygenToolkit_dateTag.l:date  if ( g:DoxygenToolkit_endCommentTag != "" )    exec "normal o".s:endCommentTag  endif  " Move the cursor to the rigth position  exec "normal `d"  call s:RestoreParameters()  startinsert!endfunction""""""""""""""""""""""""""" Doxygen undocument function" C/C++ only!""""""""""""""""""""""""""function! <SID>DoxygenUndocumentFunc(blockTag)  call s:InitializeParameters()  let l:search = "#ifdef " . a:blockTag  " Save cursor position and go to the begining of the file  mark d  exec "normal gg"  while ( search(l:search, W) != 0 )    exec "normal O#ifndef " . g:DoxygenToolkit_undocTag    exec "normal j^%"    if ( g:DoxygenToolkit_endCommentTag == "" )      exec "normal o#endif // " . g:DoxygenToolkit_undocTag    else      exec "normal o#endif /* " . g:DoxygenToolkit_undocTag . " */"    endif  endwhile  exec "normal `d"  call s:RestoreParameters()endfunction""""""""""""""""""""""""""" DoxygenBlockFunc""""""""""""""""""""""""""function! <SID>DoxygenBlockFunc()  call s:InitializeParameters()  let l:insertionMode = s:StartDocumentationBlock()  exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_blockTag  mark d  exec "normal o".s:interCommentTag."@{ ".s:endCommentTag  exec "normal o".strpart( s:startCommentTag, 0, 1 )  exec "normal A".strpart( s:startCommentTag, 1 )." @} ".s:endCommentTag  exec "normal `d"  call s:RestoreParameters()  startinsert!endfunction"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Main comment function for class, attribute, function..."""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! <SID>DoxygenCommentFunc()  " Initialize default templates.  " Assure compatibility with Python for classes (cf. endDocPattern).  let l:emptyLinePattern = ^[[:blank:]]*$  let l:someNamePattern  = [_[:alpha:]][_[:alnum:]]*  if( s:CheckFileType() == "cpp" )    let l:someNameWithNamespacePattern  = l:someNamePattern.\%(::.l:someNamePattern.\)*    let l:endDocPattern    = ;\|{\|\%([^:]\zs:\ze\%([^:]\|$\)\)    let l:commentPattern   = \%(/*\)\|\%(//\)\‘    let l:templateParameterPattern = "<[^<>]*>"    let l:throwPattern = .*\<throw\>[[:blank:]]*(\([^()]*\)).* "available only for ‘cpp‘ type    let l:classPattern     = \<class\>[[:blank:]]\+\zs.l:someNameWithNamespacePattern.\ze.*\%(.l:endDocPattern.\)    let l:structPattern    = \<struct\>[[:blank:]]\+\zs.l:someNameWithNamespacePattern.\ze[^(),]*\%(.l:endDocPattern.\)    let l:enumPattern      = \<enum\>\%(\%([[:blank:]]\+\zs.l:someNamePattern.\ze[[:blank:]]*\)\|\%(\zs\ze[[:blank:]]*\)\)\%(.l:endDocPattern.\)    let l:namespacePattern = \<namespace\>[[:blank:]]\+\zs.l:someNamePattern.\ze[[:blank:]]*\%(.l:endDocPattern.\)    let l:types = { "class": l:classPattern, "struct": l:structPattern, "enum": l:enumPattern, "namespace": l:namespacePattern }  else    let l:commentPattern   = #\|^[[:blank:]]*"""    let l:classPattern     = \<class\>[[:blank:]]\+\zs.l:someNamePattern.\ze.*:    let l:functionPattern  = \<def\>[[:blank:]]\+\zs.l:someNamePattern.\ze.*:    let l:endDocPattern    = \%(\<class\>\|\<def\>[^:]*\)\@<!$    let l:types = { "class": l:classPattern, "function": l:functionPattern }  endif  let l:lineBuffer       = getline( line( "." ) )  let l:count            = 1  let l:endDocFound      = 0  let l:doc = { "type": "", "name": "None", "params": [], "returns": "" , "templates": [], "throws": [] }  " Mark current line for future use  mark d  " Look for function/method/... to document  " We look only on the first three lines!  while( match( l:lineBuffer, l:emptyLinePattern ) != -1 && l:count < 4 )    exec "normal j"    let l:lineBuffer = l:lineBuffer. .getline( line( "." ) )    let l:count = l:count + 1  endwhile  " Error message when the buffer is still empty.  if( match( l:lineBuffer, l:emptyLinePattern ) != -1 )    call s:WarnMsg( "Nothing to document here!" )    exec "normal `d"    return  endif  " Remove unwanted lines (ie: jump to the first significant line)  if( g:DoxygenToolkit_keepEmptyLineAfterComment == "no" )    " This erase previous mark    mark d  endif  " Look for the end of the function/class/... to document  " TODO does not work when function/class/... is commented out!  let l:readError = "Cannot reach end of function/class/... declaration!"  let l:count = 0  let l:throwCompleted = 0  let l:endReadPattern = l:endDocPattern  while( l:endDocFound == 0 && l:count < g:DoxygenToolkit_maxFunctionProtoLines )    let l:lineBuffer = s:RemoveComments( l:lineBuffer )    " Valid only for cpp. For Python it must be ‘class ...:‘ or ‘def ...:‘ or    " ‘... EOL‘.    if( match( l:lineBuffer, l:endReadPattern ) != -1 )      " Look for throw statement at the end      if( s:CheckFileType() == "cpp" && l:throwCompleted == 0 )        " throw statement can have already been read or can be on next line        if( match( l:lineBuffer. .getline( line ( "." ) + 1 ), .*\<throw\>.* ) != -1 )          let l:endReadPattern = l:throwPattern          let l:throwCompleted = 1          let l:readError = "Cannot reach end of throw statement"        else          let l:endDocFound = 1        endif      else        let l:endDocFound = 1      endif      continue    endif    exec "normal j"    let l:lineBuffer = l:lineBuffer. .getline( line( "." ))    let l:count = l:count + 1  endwhile  " Error message when the end of the function(/...) has not been found  if( l:endDocFound == 0 )    if( match( l:lineBuffer, l:emptyLinePattern ) != -1 )      " Fall here when only comments have been found.      call s:WarnMsg( "Nothing to document here!" )    else      call s:WarnMsg( l:readError )    endif    exec "normal `d"    return  endif  " Trim the buffer  let l:lineBuffer = substitute( l:lineBuffer, "^[[:blank:]]*\|[[:blank:]]*$", "", "g" )  " Check whether it is a template definition  call s:ParseFunctionTemplateParameters( l:lineBuffer, l:doc )  " Remove any template parameter.  if( s:CheckFileType() == "cpp" )    while( match( l:lineBuffer, l:templateParameterPattern ) != -1 )      let l:lineBuffer = substitute( l:lineBuffer, l:templateParameterPattern, "", "g" )    endwhile  endif  " Look for the type  for key in keys( l:types )    "call s:WarnMsg( "[DEBUG] buffer:_".l:lineBuffer."_, test:_".l:types[key] )    let l:name = matchstr( l:lineBuffer, l:types[key] )    if( l:name != "" )      let l:doc.type = key      let l:doc.name = l:name      " Python only. Functions are detected differently for C/C++.      if( key == "function" )        "call s:WarnMsg( "HERE !!!".l:lineBuffer )        call s:ParseFunctionParameters( l:lineBuffer, l:doc )      endif      break    endif  endfor  if( l:doc.type == "" )    " Should be a function/method (cpp only) or an attribute.    " (cpp only) Can also be an unnamed enum/namespace... (or something else ?)    if( s:CheckFileType() == "cpp" )      if( match( l:lineBuffer, ( ) == -1 )        if( match( l:lineBuffer, \<enum\> ) != -1 )          let l:doc.type = enum        elseif( match( l:lineBuffer, \<namespace\> ) != -1 )          let l:doc.type = namespace        else          " TODO here we get a class attribute of something like that.          "      We probably just need a \brief statement...          let l:doc.type = attribute          " TODO Retrieve the name of the attribute.          "      Do we really need it? I‘m not sure for the moment.        endif      else        let l:doc.type = function        call s:ParseFunctionParameters( l:lineBuffer, l:doc )        if( l:throwCompleted == 1 )          call s:ParseThrowParameters( l:lineBuffer, l:doc, l:throwPattern )        endif      endif    " This is an attribute for Python    else      let l:doc.type = attribute    endif  endif  " Remove the function/class/... name when it is not necessary  if( ( l:doc.type == "class" && g:DoxygenToolkit_briefTag_className != "yes" ) || ( l:doc.type == "struct" && g:DoxygenToolkit_briefTag_structName != "yes" ) || ( l:doc.type == "enum" && g:DoxygenToolkit_briefTag_enumName != "yes" ) || ( l:doc.type == "namespace" && g:DoxygenToolkit_briefTag_namespaceName != "yes" ) || ( l:doc.type == "function" && g:DoxygenToolkit_briefTag_funcName != "yes" ) )    let l:doc.name = "None"  " Remove namespace from the name of the class/function...  elseif( s:CheckFileType() == "cpp" )    let l:doc.name = substitute( l:doc.name, \%(.l:someNamePattern.::\), ‘‘, g )  endif  " Below, write what we have found  """""""""""""""""""""""""""""""""  call s:InitializeParameters()  if( s:CheckFileType() == "python" && l:doc.type == "function" && g:DoxygenToolkit_python_autoFunctionReturn == "yes" )    let l:doc.returns = "yes"  endif  " Header  exec "normal `d"  if( g:DoxygenToolkit_blockHeader != "" )    exec "normal O".strpart( s:startCommentBlock, 0, 1 )    exec "normal A".strpart( s:startCommentBlock, 1 ).g:DoxygenToolkit_blockHeader.s:endCommentBlock    exec "normal `d"  endif  " Brief  if( g:DoxygenToolkit_compactOneLineDoc =~ "yes" && l:doc.returns != "yes" && len( l:doc.params ) == 0 )    let s:compactOneLineDoc = "yes"    exec "normal O".strpart( s:startCommentTag, 0, 1 )    exec "normal A".strpart( s:startCommentTag, 1 ).g:DoxygenToolkit_briefTag_pre  else    let s:compactOneLineDoc = "no"    let l:insertionMode = s:StartDocumentationBlock()    exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_briefTag_pre  endif  if( l:doc.name != "None" )    exec "normal A".l:doc.name." "  endif  exec "normal A".g:DoxygenToolkit_briefTag_post  " Mark the line where the cursor will be positionned.  mark d  " Arguments/parameters  if( g:DoxygenToolkit_compactDoc =~ "yes" )    let s:insertEmptyLine = 0  else    let s:insertEmptyLine = 1  endif  for param in l:doc.templates    if( s:insertEmptyLine == 1 )      exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )      let s:insertEmptyLine = 0    endif    exec "normal o".s:interCommentTag.g:DoxygenToolkit_templateParamTag_pre.param.g:DoxygenToolkit_templateParamTag_post  endfor  for param in l:doc.params    if( s:insertEmptyLine == 1 )      exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )      let s:insertEmptyLine = 0    endif    exec "normal o".s:interCommentTag.g:DoxygenToolkit_paramTag_pre.param.g:DoxygenToolkit_paramTag_post  endfor  " Returned value  if( l:doc.returns == "yes" )    if( g:DoxygenToolkit_compactDoc != "yes" )      exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )    endif    exec "normal o".s:interCommentTag.g:DoxygenToolkit_returnTag  endif  " Exception (throw) values (cpp only)  if( len( l:doc.throws ) > 0 )    if( g:DoxygenToolkit_compactDoc =~ "yes" )      let s:insertEmptyLine = 0    else      let s:insertEmptyLine = 1    endif    for param in l:doc.throws      if( s:insertEmptyLine == 1 )        exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )        let s:insertEmptyLine = 0      endif      exec "normal o".s:interCommentTag.g:DoxygenToolkit_throwTag_pre.param.g:DoxygenToolkit_throwTag_post    endfor  endif  " End (if any) of documentation block.  if( s:endCommentTag != "" )    if( s:compactOneLineDoc =~ "yes" )      let s:execCommand = "A"      exec "normal A "      exec "normal $md"    else      let s:execCommand = "o"    endif    exec "normal ".s:execCommand.s:endCommentTag  endif  " Footer  if ( g:DoxygenToolkit_blockFooter != "" )    exec "normal o".strpart( s:startCommentBlock, 0, 1 )    exec "normal A".strpart( s:startCommentBlock, 1 ).g:DoxygenToolkit_blockFooter.s:endCommentBlock  endif  exec "normal `d"  call s:RestoreParameters()  if( s:compactOneLineDoc =~ "yes" && s:endCommentTag != "" )    startinsert  else    startinsert!  endif  " DEBUG purpose only  "call s:WarnMsg( "Found a ".l:doc.type." named ".l:doc.name." (env: ".s:CheckFileType().")." )  "if( l:doc.type == "function" )  "  let l:funcReturn = "returns something."  "  if( l:doc.returns == "" )  "    let l:funcReturn = "doesnt return anything."  "  endif  "  call s:WarnMsg( " - which ".l:funcReturn )  "  call s:WarnMsg( " - which has following parameter(s):" )  "  for param in l:doc.params  "    call s:WarnMsg( "   - ".param )  "  endfor  "endifendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Write the beginning of the documentation block:" - C and Python format: insert ‘/**‘ and ‘##‘ respectively then a linefeed," - C++ insert ‘///‘ and continue on the same line"" This function return the insertion mode which should be used for the next" call to ‘normal‘.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:StartDocumentationBlock()  " For C++ documentation format we do not need first empty line  if( s:startCommentTag != s:interCommentTag )    "exec "normal O".s:startCommentTag    exec "normal O".strpart( s:startCommentTag, 0, 1 )    exec "normal A".substitute( strpart( s:startCommentTag, 1 ), "[[:blank:]]*$", "", "" )    let l:insertionMode = "o"  else    let l:insertionMode = "O"  endif  return l:insertionModeendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Remove comments from the given buffer." - Remove everything after ‘//‘ or ‘#‘." - Remove everything between ‘/*‘ and ‘*/‘ or keep ‘/*‘ if ‘*/‘ is not present.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:RemoveComments( lineBuffer )  if( s:CheckFileType() == "cpp" )    " Remove C++ (//) comment.    let l:lineBuffer = substitute( a:lineBuffer, [[:blank:]]*\/\/.*$, ‘‘, ‘‘)    " Remove partial C (/* ...) comment: /* foo bar   -->   /*    " ‘/*‘ is preserved until corresponding ‘*/‘ is found. Other part of the    " comment is discarded to prevent the case where it contains characters    " corresponding to the endDoc string.    let l:lineBuffer = substitute( l:lineBuffer, \%(\/\*\zs.*\ze\)\&\%(\%(\/\*.*\*\/\)\@!\), ‘‘, ‘‘)    " Remove C (/* ... */) comment.    let l:lineBuffer = substitute( l:lineBuffer, \/\*.\{-}\*\/, ‘‘, g)  else    let l:lineBuffer = substitute( a:lineBuffer, [[:blank:]]*#.*$, ‘‘, ‘‘)  endif  return l:lineBufferendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Retrieve file type." - Default type is still ‘cpp‘.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:CheckFileType()  if( &filetype == "python" )    let l:fileType       = "python"  else    let l:fileType       = "cpp"  endif  return l:fileTypeendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Parse the buffer and set the doc parameter." - Functions which return pointer to function are not supported.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:ParseFunctionParameters( lineBuffer, doc )  "call s:WarnMsg( ‘IN__‘.a:lineBuffer )  let l:paramPosition = matchend( a:lineBuffer, operator[[:blank:]]*([[:blank:]]*) )  if ( l:paramPosition == -1 )    let l:paramPosition = stridx( a:lineBuffer, ( )  else    let l:paramPosition = stridx( a:lineBuffer, (, l:paramPosition )  endif  " (cpp only) First deal with function name and returned value.  " Function name has already been retrieved for Python and we need to parse  " all the function definition to know whether a value is returned or not.  if( s:CheckFileType() == "cpp" )    let l:functionBuffer = strpart( a:lineBuffer, 0, l:paramPosition )    " Remove unnecessary elements    for ignored in g:DoxygenToolkit_ignoreForReturn      let l:functionBuffer = substitute( l:functionBuffer, \<.ignored.\>, ‘‘, g )    endfor    let l:functionReturnAndName = split( l:functionBuffer, [[:blank:]*] )    if( len( l:functionReturnAndName ) > 1 )      let a:doc.returns = yes    endif    let a:doc.name = l:functionReturnAndName[-1]  endif  " Work on parameters.  let l:parametersBuffer = strpart( a:lineBuffer, l:paramPosition + 1 )  " Remove trailing closing bracket and everything that follows and trim.  if( s:CheckFileType() == "cpp" )    let l:parametersBuffer = substitute( l:parametersBuffer, )[^)]*\%(;\|{\|\%([^:]:\%([^:]\|$\)\)\|\%(\<throw\>\)\).*, ‘‘, ‘‘ )  else    let l:parametersBuffer = substitute( l:parametersBuffer, )[^)]*:.*, ‘‘, ‘‘ )  endif  let l:parametersBuffer = substitute( l:parametersBuffer, ^[[:blank:]]*\|[[:blank:]]*$, ‘‘, ‘‘ )  " Remove default parameter values (if any).  let l:index = stridx( l:parametersBuffer, = )  let l:startIndex = l:index  while( l:index != -1 )    " Look for the next colon...    let l:colonIndex = stridx( l:parametersBuffer, ,, l:startIndex )    if( l:colonIndex == -1 )      let l:colonIndex = strlen( l:parametersBuffer )    endif    let l:paramBuffer = strpart( l:parametersBuffer, l:index, l:colonIndex - l:index )    if( s:CountBrackets( l:paramBuffer ) == 0 )      " Everything in [l:index, l:colonIndex[ can be removed.      let l:parametersBuffer = substitute( l:parametersBuffer, l:paramBuffer, ‘‘, ‘‘ )      let l:index = stridx( l:parametersBuffer, = )      let l:startIndex = l:index    else      " Parameter initialization contains brakets and colons...      let l:startIndex = l:colonIndex + 1    endif  endwhile  "call s:WarnMsg( "[DEBUG]: ".l:parametersBuffer )  " Now, work on each parameter.  let l:params = []  let l:index = stridx( l:parametersBuffer, , )  while( l:index != -1 )    let l:paramBuffer = strpart( l:parametersBuffer, 0, l:index )    if( s:CountBrackets( l:paramBuffer ) == 0 )      let l:params = add( l:params, s:ParseParameter( l:paramBuffer ) )      let l:parametersBuffer = strpart( l:parametersBuffer, l:index + 1 )      let l:index = stridx( l:parametersBuffer, , )    else      let l:index = stridx( l:parametersBuffer, ,, l:index + 1 )    endif  endwhile  if( strlen( l:parametersBuffer ) != 0 )    let l:params = add( l:params, s:ParseParameter( l:parametersBuffer ) )  endif  if( s:CheckFileType() == "cpp" )    call filter( l:params, v:val !~ "void" )  else    if( g:DoxygenToolkit_python_autoRemoveSelfParam == "yes" )      call filter( l:params, v:val !~ "self" )    endif  endif  for param in l:params    call add( a:doc.params, param )    "call s:WarnMsg( ‘[DEBUG]:OUT_‘.param )  endforendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Parse given parameter and return its name." It is easy to do unless you use function‘s pointers...""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:ParseParameter( param )  let l:paramName = "Unknown"  let l:firstIndex = stridx( a:param, ( )  if( l:firstIndex == -1 )    let l:paramName =  split( a:param, [[:blank:]*&] )[-1]  else    if( l:firstIndex != 0 )      let l:startIndex = 0    else      let l:startIndex = stridx( a:param, ) )      if( l:startIndex == -1 ) " Argggg...        let l:paramName =  a:param      else        let l:startIndex += 1        while( s:CountBrackets( strpart( a:param, 0, l:startIndex ) ) != 0 )          let l:startIndex = stridx( a:param, ), l:startIndex + 1 ) + 1          if( l:startIndex == -1) " Argggg...            let l:paramName =  a:param          endif        endwhile      endif    endif    if( l:startIndex != -1 )      let l:startIndex = stridx( a:param, (, l:startIndex ) + 1      let l:endIndex = stridx( a:param, ), l:startIndex + 1 )      let l:param = strpart( a:param, l:startIndex, l:endIndex - l:startIndex )      let l:paramName =  substitute( l:param, ^[[:blank:]*]*\|[[:blank:]*]*$, ‘‘, ‘‘ )    else      " Something really wrong has happened.      let l:paramName =  a:param    endif  endif  return l:paramNameendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Extract template parameter name for function/class/method""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:ParseFunctionTemplateParameters( lineBuffer, doc )  if( match( a:lineBuffer, ^[[:blank:]]*template ) == 0 )    let l:firstIndex = stridx( a:lineBuffer, < )    if( l:firstIndex != -1 )      let l:lastIndex = stridx( a:lineBuffer, >, l:firstIndex + 1 )      if( l:lastIndex != -1 )        " Keep only template parameters        let l:parameters = strpart( a:lineBuffer, l:firstIndex + 1, l:lastIndex - l:firstIndex - 1)        " Split on separator (,)        let l:params = split( l:parameters, \, )        for param in l:params          " Extract template parameter name          let l:paramName = split( split( param, = )[0], [[:blank:]] )[-1]          call add( a:doc.templates, l:paramName )        endfor      endif    endif  endifendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Extract throw parameter name""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:ParseThrowParameters( lineBuffer, doc, throwPattern )  let l:throwParams = substitute( a:lineBuffer, a:throwPattern, \1, "" )  for param in split( l:throwParams, "," )    call add( a:doc.throws, substitute( param, [[:blank:]], ‘‘, "" ) )  endforendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Define start/end documentation format and backup generic parameters.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:InitializeParameters()  if( s:CheckFileType() == "cpp" )    let s:startCommentTag   = g:DoxygenToolkit_startCommentTag    let s:interCommentTag   = g:DoxygenToolkit_interCommentTag    let s:endCommentTag     = g:DoxygenToolkit_endCommentTag    let s:startCommentBlock = g:DoxygenToolkit_startCommentBlock    let s:interCommentBlock = g:DoxygenToolkit_interCommentBlock    let s:endCommentBlock   = g:DoxygenToolkit_endCommentBlock  else    let s:startCommentTag   = "## "    let s:interCommentTag   = "# "    let s:endCommentTag     = ""    let s:startCommentBlock = "# "    let s:interCommentBlock = "# "    let s:endCommentBlock   = ""  endif  " Backup standard comment expension and indentation  let s:commentsBackup = &comments  let &comments        = ""  let s:cinoptionsBackup = &cinoptions  let &cinoptions        = g:DoxygenToolkit_cinoptions  " Compatibility with c/c++ IDE plugin  let s:timeoutlenBackup = &timeoutlen  let &timeoutlen = 0endfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Restore previously backuped parameters.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:RestoreParameters()  " Restore standard comment expension and indentation  let &comments = s:commentsBackup  let &cinoptions = s:cinoptionsBackup  " Compatibility with c/c++ IDE plugin  let &timeoutlen = s:timeoutlenBackupendfunction""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Count opened/closed brackets in the given buffer." Each opened bracket increase the counter by 1." Each closed bracket decrease the counter by 1.""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""function! s:CountBrackets( buffer )  let l:count =  len( split( a:buffer, (, 1 ) )  let l:count -= len( split( a:buffer, ), 1 ) )  return l:countendfunction"""""""""""""""""""""""""""""""""""" Simple warning message function"""""""""""""""""""""""""""""""""""function! s:WarnMsg( msg )  echohl WarningMsg  echo a:msg  echohl None  returnendfunction""""""""""""""""""""""""""" Shortcuts...""""""""""""""""""""""""""command! -nargs=0 Dox :call <SID>DoxygenCommentFunc()command! -nargs=0 DoxLic :call <SID>DoxygenLicenseFunc()command! -nargs=0 DoxAuthor :call <SID>DoxygenAuthorFunc()command! -nargs=1 DoxUndoc :call <SID>DoxygenUndocumentFunc(<q-args>)command! -nargs=0 DoxBlock :call <SID>DoxygenBlockFunc()