首页 > 代码库 > 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/nerdtree‘map <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.vim‘let 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/tagbar‘let g:tagbar_autofocus = 1Bundle ‘vim-scripts/taglist.vim‘set 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.vim‘let g:ctrlp_map = ‘<leader>p‘let g:ctrlp_cmd = ‘CtrlP‘map <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.vim‘let 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-whitespace‘map <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-easymotion‘Bundle ‘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/ultisnips‘let 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-surround‘Bundle ‘tpope/vim-repeat‘" 插件:自动补全单引号,双引号等"""""""""""""""""""""""""""""""""""""""""Bundle ‘Raimondi/delimitMate‘" for python docstring " ,优化输入autocmd FileType python let b:delimitMate_nesting_quotes = [‘"‘]" 自动补全html/xml标签Bundle ‘docunext/closetag.vim‘let g:closetag_html_style=1" 插件:代码格式化"""""""""""""""""""""""""""""""""""""""""Bundle ‘godlygeek/tabular‘nmap <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-region‘map = <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/syntastic‘let 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-vim‘let g:pyflakes_use_quickfix = 0" 插件:具体语言语法高亮"""""""""""""""""""""""""""""""""""""""""" for python.vim syntax highlightBundle ‘hdima/python-syntax‘let python_highlight_all = 1" for golangBundle ‘jnwhiteh/vim-golang‘Bundle ‘Blackrush/vim-gocode‘" for markdownBundle ‘plasticboy/vim-markdown‘let 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.vim‘map <leader>td <Plug>TaskList" for git 尚未用起来Bundle ‘tpope/vim-fugitive‘" 可以查看/回到某个历史状态Bundle ‘sjl/gundo.vim‘nnoremap <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 = "doesn‘t 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()
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。