您的位置:首页 > 其它

vim 终极配置

2015-06-05 11:54 573 查看
lucasysfeng


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 paste
set 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 title
set novisualbell                 "don't beep
set noerrorbells                 "don't beep
set t_vb=
set tm=500
set mat=2                        "Blink times every second when matching brackets
set showmatch                    "括号配对情况
set hidden                       "A buffer becomes hidden when it is abandoned
set wildmode=list:longest
set ttyfast
set wildignore=*.swp,*.,*.pyc,*.class
set scrolloff=7                  "至少有7行在光标所在行上下
set mouse=a                      "为所有模式启用鼠标
set selection=old
set selectmode=mouse,key
set viminfo^=%                   "Remember info about open buffers on close
set magic                        "正则表达式匹配形式
set backspace=eol,start,indent   "Configure backspace so it acts as it should act
set whichwrap+=<,>,h,l

" 搜索
"""""""""""""""""""""""""""""""""""""""""
set hlsearch                     "高亮search命中的文本。
set ignorecase                   "搜索时忽略大小写
set incsearch                    "随着键入即时搜索
set smartcase                    "有一个或以上大写字母时仍大小写敏感

" 折叠
"""""""""""""""""""""""""""""""""""""""""
set foldenable
set foldmethod=indent
set 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 tabstop
set expandtab                    "将Tab自动转化成空格(需要输入真正的Tab键时,使用Ctrl+V+Tab)
set shiftround                   "Use multiple of shiftwidth when indenting with '<' and '>'

" 编码
"""""""""""""""""""""""""""""""""""""""""
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936,gb18030,chinese,big5,euc-jp,euc-kr,latin1
set fileencoding=utf-8
set helplang=cn
set termencoding=utf-8           "这句只影响普通模式 (非图形界面) 下的Vim
set ffs=unix,dos,mac             "Use Unix as the standard file type
set formatoptions+=m             "如遇Unicode值大于255的文本,不必等到空格再折行。
set formatoptions+=B             "合并两行中文时,不在中间加空格:

" 语法
"""""""""""""""""""""""""""""""""""""""""
syntax enable                    "打开语法高亮
syntax on

" 撤销
"""""""""""""""""""""""""""""""""""""""""
set undolevels=1000              "How many undos
set undoreload=10000             "number of lines to save for undo
if v:version >= 730
set undofile                 "keep a persistent backup file
set undodir=~/bak/vimundo/
endif

" 状态栏
"""""""""""""""""""""""""""""""""""""""""
set ruler                        "显示当前的行号列号
set showcmd                      "在状态栏显示正在输入的命令
set showmode
set statusline=%<%f\ %h%m%r%=%k[%{(&fenc==\"\")?&enc:&fenc}%{(&bomb?\",BOM\":\"\")}]\ %-14.(%l,%c%V%)\ %P
set laststatus=2                 "命令行(在状态行下)的高度,默认为1,这里是2

" 相对绝对行号
"""""""""""""""""""""""""""""""""""""""""
"autocmd FocusLost * :set norelativenumber number
autocmd FocusGained * :set relativenumber
autocmd InsertEnter * :set norelativenumber number
autocmd 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 zR
map <leader>c zM

" 连续按jf退出插入/命令行/可视模式
inoremap jk <ESC>l
cnoremap jk <ESC>l
vnoremap 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> yyp
nmap <S-k> yyp

" 搜索查找快捷键
"""""""""""""""""""""""""""""""""""""""""
" 替换,匹配模式采用very magic
map \ :%s/\v

" 查找,匹配模式采用very magic
nnoremap / /\v
vnoremap / /\v

" 去掉查找后的高亮显示
noremap <silent><leader>/ :nohls<CR>

" 搜索的内容总是在屏幕中心显示
nnoremap <silent> n nzz
nnoremap <silent> N Nzz
nnoremap <silent> * *zz
nnoremap <silent> # #zz
nnoremap <silent> g* g*zz

" 普通模式(Nomal Mode)下快捷键
"""""""""""""""""""""""""""""""""""""""""
" 快速编辑重vimrc
nmap <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>j
map <C-k> <C-W>k
map <C-h> <C-W>h
map <C-l> <C-W>l

" Disbale paste mode when leaving insert mode
map <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 directory
map <leader>te :tabedit <C-r>=expand("%:p:h")<cr>/

" 杂项
"""""""""""""""""""""""""""""""""""""""""
" Disbale paste mode when leaving insert mode
autocmd InsertLeave * set nopaste

" w!! to sudo & write a file
cmap 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 them
nnoremap ' `
nnoremap ` '

" Automatically reload vimrc when it's saved
autocmd BufWritePost .vimrc so ~/.vimrc

" ; can repeat fx/tx. so do not map it
nnoremap <leader>v V`}

"""""""""""""""""""""""""""""""""""""""""
" 主题颜色显示
"""""""""""""""""""""""""""""""""""""""""
" Set extra options when running in GUI mode
if 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=256
endif

" 修改主题和颜色展示
" colorscheme solarized
set background=dark
set t_Co=256
" colorscheme molokai
" colorscheme desert

" 设置标记一列的背景颜色和数字一行颜色一致
hi! link SignColumn   LineNr
hi! link ShowMarksHLl DiffAdd
hi! link ShowMarksHLu DiffChange

" 防止错误整行标红导致看不清
highlight clear SpellBad
highlight SpellBad term=standout ctermfg=1 term=underline cterm=underline
highlight clear SpellCap
highlight SpellCap term=underline cterm=underline
highlight clear SpellRare
highlight SpellRare term=underline cterm=underline
highlight clear SpellLocal
highlight SpellLocal term=underline cterm=underline

" settings for kien/rainbow_parentheses.vim
autocmd VimEnter * RainbowParenthesesToggle
autocmd Syntax * RainbowParenthesesLoadRound
autocmd Syntax * RainbowParenthesesLoadSquare
autocmd 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'\"" | endif
endif

" 删除多余空格
func! DeleteTrailingWS()
exe "normal mz"
%s/\s\+$//ge
exe "normal `z"
endfunc
autocmd BufWrite *.py :call DeleteTrailingWS()

"""""""""""""""""""""""""""""""""""""""""
" 插件管理配置开始
"""""""""""""""""""""""""""""""""""""""""
" package dependent:  ctags
" python dependent:  pep8, pyflake

filetype off
set 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=1
let NERDTreeIgnore=[ '\.pyc$', '\.pyo$', '\.obj$', '\.o$', '\.so$', '\.egg$', '^\.git$', '^\.svn$', '^\.hg$' ]
let g:netrw_home='~/'

" close vim if the only window left open is a NERDTree
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | end

" for minibufferexpl
Bundle 'fholgado/minibufexpl.vim'
let g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1
let g:miniBufExplForceSyntaxEnable = 1
let g:miniBufExplorerMoreThanOne=2
let g:miniBufExplCycleArround=1

" 默认方向键左右可以切换buffer
nnoremap <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 = 1
Bundle 'vim-scripts/taglist.vim'
set tags=tags;/
let Tlist_Ctags_Cmd="/usr/bin/ctags"
let Tlist_Auto_Highlight_Tag = 1
let Tlist_Auto_Open = 0
let Tlist_Auto_Update = 1
let Tlist_Close_On_Select = 0
let Tlist_Compact_Format = 0
let Tlist_Display_Prototype = 0
let Tlist_Display_Tag_Scope = 1
let Tlist_Enable_Fold_Column = 0
let Tlist_Exit_OnlyWindow = 1
let Tlist_File_Fold_Auto_Close = 0
let Tlist_GainFocus_On_ToggleOpen = 1
let Tlist_Hightlight_Tag_On_BufEnter = 1
let Tlist_Inc_Winwidth = 0
let Tlist_Max_Submenu_Items = 1
let Tlist_Max_Tag_Length = 30
let Tlist_Process_File_Always = 0
let Tlist_Show_Menu = 0
let Tlist_Show_One_File = 1
let Tlist_Sort_Type = "order"
let Tlist_Use_Horiz_Window = 0
let Tlist_Use_Right_Window = 0
let 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=0
let g:ctrlp_match_window_bottom=1
let g:ctrlp_max_height=15
let g:ctrlp_match_window_reversed=0
let g:ctrlp_mruf_max=500
let 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 = 40
let g:rbpt_loadcmd_toggle = 0

" 插件:将每行无效的空格标红(,空格按键去掉末尾空格)
"""""""""""""""""""""""""""""""""""""""""
Bundle 'bronson/vim-trailing-whitespace'
map <leader><space> :FixWhitespace<cr>

" 插件:主题solarized
Bundle 'altercation/vim-colors-solarized'
" let g:solarized_termcolors=256
let g:solarized_termtrans=1
let g:solarized_contrast="normal"
let g:solarized_visibility="normal"

" 插件:主题molokai
Bundle 'tomasr/molokai'
" let g:molokai_original = 1

" 插件:快速移动
"""""""""""""""""""""""""""""""""""""""""
" 更高效的移动 ,, + w/fx
Bundle '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 selection
Bundle '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=1
let g:syntastic_enable_highlighting = 0
let 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 highlight
Bundle 'hdima/python-syntax'
let python_highlight_all = 1

" for golang
Bundle 'jnwhiteh/vim-golang'
Bundle 'Blackrush/vim-gocode'

" for markdown
Bundle 'plasticboy/vim-markdown'
let g:vim_markdown_folding_disabled=1

" for javascript
Bundle "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 jquery
Bundle 'nono/jquery.vim'

" for jinja2 highlight
Bundle 'Glench/Vim-Jinja2-Syntax'

" for nginx conf file highlight.   need to confirm it works
Bundle 'thiderman/nginx-vim-syntax'

" 插件:杂项
"""""""""""""""""""""""""""""""""""""""""
" task list
Bundle '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 on
filetype plugin indent on
"""""""""""""""""""""""""""""""""""""""""
" 插件管理配置结束
"""""""""""""""""""""""""""""""""""""""""

"""""""""""""""""""""""""""""""""""""""""
" 自定义的函数
"""""""""""""""""""""""""""""""""""""""""
" 相对绝对行号转换
function! NumberToggle()
if(&relativenumber == 1)
set norelativenumber number
else
set relativenumber
endif
endfunc

" 突出显示当前行列转换
function! CusorCulLineToggle()
if(&cursorcolumn == 1)
set nocursorcolumn
set nocursorline
else
set cursorcolumn
set cursorline
endif
endfunc

function! GoToFileEnd()
normal G
endfunc
""定义函数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
"endif
let 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 constants
if !exists("g:DoxygenToolkit_briefTag_pre")
let g:DoxygenToolkit_briefTag_pre = "@brief "
endif
if !exists("g:DoxygenToolkit_briefTag_post")
let g:DoxygenToolkit_briefTag_post = ""
endif
if !exists("g:DoxygenToolkit_templateParamTag_pre")
let g:DoxygenToolkit_templateParamTag_pre = "@tparam "
endif
if !exists("g:DoxygenToolkit_templateParamTag_post")
let g:DoxygenToolkit_templateParamTag_post = ""
endif
if !exists("g:DoxygenToolkit_paramTag_pre")
let g:DoxygenToolkit_paramTag_pre = "@param "
endif
if !exists("g:DoxygenToolkit_paramTag_post")
let g:DoxygenToolkit_paramTag_post = ""
endif
if !exists("g:DoxygenToolkit_returnTag")
let g:DoxygenToolkit_returnTag = "@return"
endif
if !exists("g:DoxygenToolkit_throwTag_pre")
let g:DoxygenToolkit_throwTag_pre = "@throw " " @exception is also valid
endif
if !exists("g:DoxygenToolkit_throwTag_post")
let g:DoxygenToolkit_throwTag_post = ""
endif
if !exists("g:DoxygenToolkit_blockHeader")
let g:DoxygenToolkit_blockHeader = ""
endif
if !exists("g:DoxygenToolkit_blockFooter")
let g:DoxygenToolkit_blockFooter = ""
endif
if !exists("g:DoxygenToolkit_licenseTag")
let g:DoxygenToolkit_licenseTag = s:licenseTag
endif
if !exists("g:DoxygenToolkit_fileTag")
let g:DoxygenToolkit_fileTag = "@file "
endif
if !exists("g:DoxygenToolkit_authorTag")
let g:DoxygenToolkit_authorTag = "@author "
endif
if !exists("g:DoxygenToolkit_dateTag")
let g:DoxygenToolkit_dateTag = "@date "
endif
if !exists("g:DoxygenToolkit_versionTag")
let g:DoxygenToolkit_versionTag = "@version "
endif
if !exists("g:DoxygenToolkit_undocTag")
let g:DoxygenToolkit_undocTag = "DOX_SKIP_BLOCK"
endif
if !exists("g:DoxygenToolkit_blockTag")
let g:DoxygenToolkit_blockTag = "@name "
endif
if !exists("g:DoxygenToolkit_classTag")
let g:DoxygenToolkit_classTag = "@class "
endif

if !exists("g:DoxygenToolkit_cinoptions")
let g:DoxygenToolkit_cinoptions = "c1C1"
endif
if !exists("g:DoxygenToolkit_startCommentTag ")
let g:DoxygenToolkit_startCommentTag = "/** "
let g:DoxygenToolkit_startCommentBlock = "/* "
endif
if !exists("g:DoxygenToolkit_interCommentTag ")
let g:DoxygenToolkit_interCommentTag = "* "
endif
if !exists("g:DoxygenToolkit_interCommentBlock ")
let g:DoxygenToolkit_interCommentBlock = "* "
endif
if !exists("g:DoxygenToolkit_endCommentTag ")
let g:DoxygenToolkit_endCommentTag = "*/"
let g:DoxygenToolkit_endCommentBlock = "*/"
endif
if 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"
endif
else
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:ignoreForReturn
endif
unlet s:ignoreForReturn

" Maximum number of lines to check for function parameters
if !exists("g:DoxygenToolkit_maxFunctionProtoLines")
let g:DoxygenToolkit_maxFunctionProtoLines = 10
endif

" Add name of function/class/struct... after pre brief tag if you want
if !exists("g:DoxygenToolkit_briefTag_className")
let g:DoxygenToolkit_briefTag_className = "no"
endif
if !exists("g:DoxygenToolkit_briefTag_structName")
let g:DoxygenToolkit_briefTag_structName = "no"
endif
if !exists("g:DoxygenToolkit_briefTag_enumName")
let g:DoxygenToolkit_briefTag_enumName = "no"
endif
if !exists("g:DoxygenToolkit_briefTag_namespaceName")
let g:DoxygenToolkit_briefTag_namespaceName = "no"
endif
if !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 documantation
if !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
"endif

endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:insertionMode
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:lineBuffer
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:fileType
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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 )
endfor
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:paramName
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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
endif
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:]]', '', "" ) )
endfor
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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 = 0
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:timeoutlenBackup
endfunction

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 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:count
endfunction

"""""""""""""""""""""""""""""""""""
" Simple warning message function
"""""""""""""""""""""""""""""""""""
function! s:WarnMsg( msg )
echohl WarningMsg
echo a:msg
echohl None
return
endfunction

""""""""""""""""""""""""""
" 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()


分类: 软件使用vi

绿色通道: 好文要顶 关注我 收藏该文与我联系





lucasysfeng

关注 - 4

粉丝 - 9

+加关注

0

0

(请您对文章做出评价)

« 上一篇:爬虫--用cookie访问任意网页

» 下一篇:python--中文比较

posted on 2014-06-13 22:58 lucasysfeng 阅读(246) 评论(0) 编辑 收藏

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库

【推荐】融云即时通讯云-专注为 App 开发者提供IM云服务

【推荐】如何让你的程序拥有象Excel一样强大的数据编辑功能

【活动】RDS邀您6.5折体验PostgreSQL

{"uid":1,"hostPeerName":"http://www.cnblogs.com","initialGeometry":"{\"windowCoords_t\":23,\"windowCoords_r\":1917,\"windowCoords_b\":953,\"windowCoords_l\":0,\"frameCoords_t\":34621.78125,\"frameCoords_r\":360,\"frameCoords_b\":34871.78125,\"frameCoords_l\":60,\"styleZIndex\":\"auto\",\"allowedExpansion_t\":0,\"allowedExpansion_r\":0,\"allowedExpansion_b\":0,\"allowedExpansion_l\":0,\"xInView\":0,\"yInView\":0}","permissions":"{\"expandByOverlay\":true,\"expandByPush\":false,\"readCookie\":false,\"writeCookie\":false}","metadata":"{\"shared\":{\"sf_ver\":\"1-0-2\",\"ck_on\":1,\"flash_ver\":\"17.0.0\"}}","reportCreativeGeometry":false}" scrolling="no" marginwidth="0" marginheight="0" width="300" height="250" data-is-safeframe="true" style="border-width: 0px; vertical-align: bottom;">

最新IT新闻:

· 马云改主意了?阿里数据只开放给合作伙伴

· 徐小平:“辨人秘方”有科学依据 曾一个项目亏了800万

· SQL Server 2016:内存列存储索引

· 如何提升你的能力?给年轻程序员的几条建议

· 一个月后卖掉Apple Watch:价值正在大幅缩水

» 更多新闻...

最新知识库文章:

· 那些令人喷饭的代码注释:仅以此代码献给...

· 给代码多留一些空间

· 领域驱动设计系列(2)浅析VO、DTO、DO、PO的概念、区别和用处

· 新手学习编程的最佳方式是什么?

· 领域驱动设计系列(1)通过现实例子显示领域驱动设计的威力

» 更多知识库文章...

历史上的今天:

2013-06-13 Effective C++总结

Powered by:

博客园

Copyright © lucasysfeng

<2015年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011


导航

博客园
首页
新随笔

管理


统计

随笔 - 489
文章 - 0
评论 - 14
引用 - 0


搜索


最新随笔

1. gdb--多线程
2. ubuntu14.04 源
3. gdb--带参数
4. angularjs---select使用---默认值及联动
5. protobuf--嵌套repeated get set
6. protobuf--repeated get set
7. protobuf---messge嵌套get set
8. proto变量风格
9. gdb--指定源文件路径
10. gdb--调试过程中输入


随笔分类(501)

linux环境编程(50)
linux命令(20)
linux命令高级(3)
protobuf(5)
web--css(1)
web步步为营(11)
编译原理(1)
操作系统(10)
调试(11)
读书笔记(9)
多线程多进程(4)
服务器架设(9)
开发Android(12)
开发QT(3)
开发Vtun源码分析(26)
求职笔试sizeof(6)
求职笔试算法(35)
求职笔试题目(8)
求职华为机试(11)
求职面试问答(37)
求职面试源码(5)
软件测试(1)
软件使用chrome(1)
软件使用eclipse(10)
软件使用svn(1)
软件使用vi(13)
设计模式(4)
书籍Effective C++(13)
书籍STL源码剖析(4)
协议HTTP(5)
协议TCP/IP(14)
语言C(25)
语言C++(45)
语言c++标准库(1)
语言c++高级(1)
语言HTML(4)
语言Java
语言JSON
语言Matlab(11)
语言MySql(21)
语言PHP(8)
语言python(14)
语言python网页爬虫(2)
语言sed和awk(1)
语言shell(22)
正则表达式(3)


随笔档案(489)

2015年4月 (2)
2015年3月 (1)
2015年1月 (6)
2014年12月 (4)
2014年11月 (15)
2014年10月 (11)
2014年9月 (1)
2014年7月 (2)
2014年6月 (12)
2014年5月 (12)
2014年4月 (1)
2014年3月 (8)
2014年2月 (4)
2014年1月 (26)
2013年11月 (8)
2013年10月 (5)
2013年9月 (5)
2013年8月 (7)
2013年7月 (23)
2013年6月 (51)
2013年5月 (43)
2013年4月 (20)
2013年3月 (15)
2013年2月 (1)
2013年1月 (14)
2012年12月 (52)
2012年11月 (27)
2012年10月 (40)
2012年9月 (73)


文章分类

笔试面试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: