我的轻度定制 vim

vim的学习曲线又陡又长,但它的功能和可定制性实在太强大,一个熟练的用户加上一个高 度定制化的vim能够达到很高的效率,在加上熟练地运用vim的各种高级功能是很酷的一件 事,于是我决定近期内不再尝试其它的编辑器,逐步地打造适合自己的vim。下面记录的, 都是我自己觉得很有用的,或者是容易忘记的,这篇文章的内容也会是逐步丰富的。

技巧们:

快捷键

  • gd跳到变量声明的地方
  • <Ctrl> + ]跳到定义的地方,需要ctags事先生成tag文件
  • <Ctrl> + o返回之前的位置
  • 5 + <Ctrl> + ^跳到第5号buffer
  • <Ctrl> + PgUp/PgDn在tab间跳
  • :ls列出buffer
  • <Ctrl> + g显示当前编辑文件中当前光标所在行位置以及文件状态信息
  • :r FILENAME向当前文件中插入另外的文件的内容
  • :1,10 w outfile Saves lines 1 to 10 in outfile
  • :1,10 w >> outfile Appends lines 1 to 10 to outfile
  • :r infile Insert the content of infile
  • :23r infile Insert the content of infile under line 23
  • J把两行连起来
  • f/F单字符查找命令,”fx” 命令向前查找本行中的字符 x。”F” 命令则用于向左查找
  • tx命令与fx相似,但它只把光标移动到目标字符的前一个字符上。
  • H,M,L分别代表移到当前视野的Home, Middle, Last处
  • :qall全部退出
  • :wqall全部保存退出
  • 20|move cursor to column 20.
  • [[Jump to function start
  • [{Jump to block start
  • :%s/ *$//g Delete all white spaces
  • :g/string/d 删除所有包含string的行
  • Ctrl+a Increment number under the cursor
  • Ctrl+x Decrement number under cursor
  • uU,在选中之后,”U”和”u”分别把选中的部分大写或小写
  • 对文本进行简单排序:用shift v选中多行文本,输入 : !sort
  • 在 Vim 中统计文本行数和当前光标的位置,可以使用 ctrl + g,统计字节数,可以使用 g + ctrl + g

vim中的替换:

%表示全文匹配:

  • s/old/new/g当前行中所有old替换成new
  • :%s/old/new/表示将全文中old替换成new,但每行只替换第一个单词
  • :%s/old/new/g表示将全文中所有出现过的old替换成new (所有都替换)
  • %s/old/new/gc全文替换, 替换前询问

d表示删除:

  • g/china/d
  • :g/string/d 删除所有包含string的行
  • :v/string/d 删除所有不包含string的行

我的vimrc如下:

" 我的轻度定制VIM
" JH Gao <gaopenghigh@gmail.com>

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 全局设置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set nocompatible      " 不与vi的兼容
set autoread          " 文件修改之后自动载入
set showcmd           " 状态栏显示命令
set showmatch         " 展示匹配
set linebreak         " 整词换行
set smartcase         " 搜索时不区分大小写,除非只有搜索关键字中出现一个大字母
set incsearch         " 输入字符串就显示匹配点
set autowrite         " 自动把内容写回文件
runtime! debian.vim   " 运行时环境
let g:mapleader = ',' " mapleader键设置,通过mapleader键可以完成更多的快捷键

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 显示和格式
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

syntax on
set background=dark
set hlsearch          " 搜索高亮
set nu                " 显示行号
set title             " 在终端的title bar上显示信息
set laststatus=2      " 总是显示状态栏
set ruler             " 显示标尺
set tabstop=4         " Tab宽度
set shiftwidth=4      " 自动缩进的宽度
set expandtab         " 输入:re可以把tab替换为空格
set autoindent        " 自动缩进
set smartindent       " 基于autoindent的一些改进
set wrap              " Wrap lines

" 配色方案
colorscheme molokai
let g:molokai_original = 1
let g:rehash256 = 1

" Python 的关键字设置
let python_highlight_all = 1
au FileType python syn keyword pythonDecorator True None False self

" 删除末尾的空格
func! DeleteTrailingWS()
  exe "normal mz"
  %s/\s\+$//ge
  exe "normal `z"
endfunc
autocmd BufWrite *.py,*.t2t,*.sh,*.md,*.markdown :call DeleteTrailingWS()


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 在tabs和windows之间移动
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 按<F2>在新tab中编辑文件, 注意下一行末尾是有个空格的:)
nnoremap <F2> :tabedit

" 按 ,<Tab> 和 ,` 移动到下一个/上一个tab
set switchbuf=usetab
nnoremap <leader><Tab> :sbnext<CR>
nnoremap <leader>` :sbprevious<CR>

" 按 ,1 ,2 ,3等跳到相应的tab
map <leader>1 1gt
map <leader>2 2gt
map <leader>3 3gt
map <leader>4 4gt
map <leader>5 5gt
map <leader>6 6gt
map <leader>7 7gt
map <leader>8 8gt
map <leader>9 9gt

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 插件设置
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 用vundle来管理插件
filetype off " required!
set rtp+=~/.vim/vundle.git/
call vundle#rc()

" 安装的插件
Bundle 'gmarik/vundle'
Bundle 'genutils'
Bundle 'taglist.vim'
Bundle 'TaskList.vim'
Bundle 'django.vim'
Bundle 'jQuery'
Bundle 'a-new-txt2tags-syntax'
Bundle 'python.vim'
Bundle 'Syntastic'
Bundle 'L9'
Bundle 'FuzzyFinder'
Bundle 'vim-powerline'
Bundle 'c.vim'
Bundle 'Pydiction'
Bundle 'ctrlp.vim'
Bundle 'Tabular'
Bundle 'The-NERD-Commenter'

filetype plugin indent on

" 插件Syntastic
" 可以设置使用什么来做语法检查
" 对于python默认使用pyflask进行检查,也可以通过如下的设置使用pylint进行检查
" let g:syntastic_python_checker = 'pylint'
" let g:syntastic_python_checker_args = '--rcfile /etc/pylint.conf -d C0301'
" let g:syntastic_quiet_warnings=1

" 插件Pydiction
" 编辑python文件时可以通过Tab进行自动补全
let g:pydiction_location = '~/.vim/bundle/Pydiction/complete-dict'

" 插件Tabular
" 自动对齐=,:等两边的内容
map <leader>= :Tabularize /=<CR>:Tabularize /:<CR>

" 插件NERDTree(这个插件没法用vundle安装)
let NERDTreeShowBookmarks = 1
" 按F3打开或关闭文件导航窗口
map <silent> <F3> :NERDTreeToggle<cr>

" 插件FuzzyFinder,快速查找文件、类和函数等
map <leader>f :FufTaggedFile<CR>
map <leader>F :FufFile<CR>
map <leader>g :FufTag<CR>
map <leader>b :FufBuffer<CR>

" 插件CtrlP
" 这是一个更好用的文件查找插件,按F5开启查找模式
map <F5> :CtrlP<CR>

" 对于txt2tags文件,要设置对filetype
au BufNewFile,BufRead *.t2t set ft=txt2tags

" ctags 和 taglist
" 按下F4重新生成tag文件,并更新taglist
map <F4> :!/usr/bin/ctags-exuberant -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR><CR>
            \:TlistUpdate<CR>
set tags=tags
set tags+=./tags                    " 添加当前目录的tags文件查询
let Tlist_Ctags_Cmd = '/usr/bin/ctags-exuberant'
let Tlist_Show_One_File = 1         " 不同时显示多个文件的tag,只显示当前文件的
let Tlist_Exit_OnlyWindow = 1       " 如果taglist窗口是最后一个窗口,则退出vim
let Tlist_Show_One_File=0           " 让taglist可以同时展示多个文件的函数列表
let Tlist_File_Fold_Auto_Close=1    " 非当前文件,函数列表折叠隐藏
let Tlist_Use_Right_Window = 1      " 在右侧窗口中显示taglist窗口
let Tlist_Process_File_Always = 1   " taglist始终解析文件中的tag,
"                                     不管taglist窗口有没有打开
" 用 F9 来打开/关闭taglist页面
map <silent> <F9> :TlistToggle<cr>

" 插件python.vim
" 对python代码快速操作, 快捷键:
"   ]t      -- Jump to beginning of block
"   ]e      -- Jump to end of block
"   ]v      -- Select (Visual Line Mode) block
"   ]<      -- Shift block to left
"   ]>      -- Shift block to right
"   ]#      -- Comment selection
"   ]u      -- Uncomment selection
"   ]c      -- Select current/previous class
"   ]d      -- Select current/previous function
"   ]<up>   -- Jump to previous line with the same/lower indentation
"   ]<down> -- Jump to next line with the same/lower indentation

" 插件TaskList.vim
" 显示标注了TODO的信息
" 默认快捷键<leader>t打开TODO的list window

" 插件powerline
" 增强型的状态栏插件
"set guifont=PowerlineSymbols\ for\ Powerline
set t_Co=256
let g:Powerline_symbols = 'unicode'


"""""""""""""""""""""""""""""""""""""""""""""
" => 自定义功能
"""""""""""""""""""""""""""""""""""""""""""""

" 自动运行这个文件(python, bash, lua, perl)
" 写python或shell时经常需要做单元测试, 按下<F12>就用相应的解释器运行这个文件
map <F10> :call AutoRun(input('argv : '))<cr>

func AutoRun(par)
    let par = a:par
    exec "w"
    if &filetype == 'sh'
        let cmd = "!bash % ".par
    elseif &filetype == 'python'
        let cmd = "!python % ".par
    elseif &filetype == 'ruby'
        let cmd = "!ruby % ".par
    elseif &filetype == 'perl'
        let cmd = "!perl % ".par
    elseif &filetype == 'lua'
        let cmd = "!lua % ".par
    " chromium-browser 中安装了Markdown Preview扩展的话,可以直接打开
    " markdown文件预览
    elseif &filetype == 'markdown'
        let cmd = "!/usr/bin/chromium-browser % ".par
    endif
    exec cmd
endfunc


" 自动添加一些常用信息

autocmd BufNewFile *.sh,*.pl,*.py exec ":call SetTitle()"

func SetTitle()
    if &filetype == 'sh'
        call setline(1, "\#!/bin/sh")
        call append(line("."), "\#****************************************************************#")
        call append(line(".")+1, "\# ScriptName: ".expand("%") )
        call append(line(".")+2, "\# Author: gaopenghigh<gaopenghigh@gmail.com>")
        call append(line(".")+3, "\# Create Date: ".strftime("%F %R"))
        call append(line(".")+4, "\# Function: " )
        call append(line(".")+5, "\#***************************************************************#")
        call append(line(".")+6, "")
        :8
    elseif &filetype == 'perl'
        call setline(1, "\#!/usr/bin/perl")
        call append(line("."), "\#****************************************************************#")
        call append(line(".")+1, "\# ScriptName: ".expand("%") )
        call append(line(".")+2, "\# Author: gaopenghigh<gaopenghigh@gmail.com>")
        call append(line(".")+3, "\# Create Date: ".strftime("%F %R"))
        call append(line(".")+4, "\# Function: ")
        call append(line(".")+5, "\#***************************************************************#")
        call append(line(".")+6, "")
        :8
    elseif &filetype == 'ruby'
        call setline(1, "\#!/usr/bin/ruby")
        call append(line("."), "\#****************************************************************#")
        call append(line(".")+1, "\# ScriptName: ".expand("%") )
        call append(line(".")+2, "\# Author: gaopenghigh<gaopenghigh@gmail.com>")
        call append(line(".")+3, "\# Create Date: ".strftime("%F %R"))
        call append(line(".")+4, "\# Function: ")
        call append(line(".")+5, "\#***************************************************************#")
        call append(line(".")+6, "")
        :8
    elseif &filetype == 'python'
        call setline(1, "\#!/usr/bin/python")
        call append(line("."), "\# -*- coding: utf-8 -*-")
        call append(line(".")+1, "\#****************************************************************#")
        call append(line(".")+2, "\# ScriptName: ".expand("%") )
        call append(line(".")+3, "\# Author: gaopenghigh<gaopenghigh@gmail.com>")
        call append(line(".")+4, "\# Create Date: ".strftime("%F %R"))
        call append(line(".")+5, "\# Function: ")
        call append(line(".")+6, "\#***************************************************************#")
        call append(line(".")+7, "")
        :8
    endif
endfunc

" 列数为80的地方高
" 由于有可能会和插件冲突,所以这一部分放在最后亮显示
if exists('+colorcolumn')
    set colorcolumn=80
else
    au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>80v.\+', -1)
endif
hi ColorColumn guibg=#2d2d2d ctermbg=246