Skip navigation.

crocodile's blog

a python lover

Posts tagged with "vim"

vim中文手册

vim常用技巧
所以我初步设想分三大部分来写
(1)vim基础
(2)vim tips的翻译和解释
(3)vimrc
由于水平所限,有错误和可笑之处,恳请批评。

这里就附带说一下vim基础了
很简单的概括一下:

1.程序
Unix: vim
Win : gvim

2.工作方式
normal mode普通模式
insert mode插入模式
visual mode可视模式
visual-line mode
visual-block mode
command-line mode命令行模式
search mode搜索模式

模式切换:记住Esc总可以返回 普通模式
normal = i => insert
normal = v => visual
normal = Shift-V => visual-line
normal = Ctrl-V => visual-block
normal = : => command-line
normal = / => search

3.光标移动
开始,会用方向键和PgUp,PgDn就可以用了
vim 和 perl 一样,你掌握一个子集,就可以很好的使用了

4.最后,说一下两个概念<cword>和<cWORD>
<cword>称为狭义字,它指一个单词,其中不包含空白和特殊字符
<cWORD>称为广义字,它所指的单词可以包含一些特殊字符
具体有那些字符可以看help
通常,它们会和你想的一样:)

因为第二部分经常用到这个概念,所以在此说一下

----------------------------------------
# 基础
----------------------------------------
* # g* g# : 寻找光标处的狭义单词(<cword>) (前向/后向)
% : 括号配对寻找 {}[]()
matchit.vim : 使得 % 能够配对标记 <script> <?php 等等
<C-N><C-P> : 插入模式下的单词自动完成
<C-X><C-L> : 行自动完成(超级有用)
/<C-R><C-W> : 把狭义单词 <cword> 写到 搜索命令 行
/<C-R><C-A> : 把广义单词 <cWORD> 写到 搜索命令 行
:set ignorecase : 搜索时忽略大小写
:syntax on : 在 Perl,HTML,PHP 等中进行语法着色
:h regexp<C-D> : 按下 control-D 键即可得到包含有 regexp 的帮助主题的列表
: (使用TAB可以实现帮助的自动补齐)
----------------------------------------
# 使更新 _vimrc 更容易
:nmap ,s :source $VIM/_vimrc
# 译释:nmap 是绑定一个在normal模式下的快捷键
:nmap ,v :e $VIM/_vimrc
# 译释:在normal模式下,先后按下 ,s 两个键执行_vimrc,而 ,v 则是编辑_vimrc

----------------------------------------
# visual 模式 (例子是:轻松添加其他的 HTML Tags)
:vmap sb "zdi<C-R>z<ESC> : 在visual模式下选中的文字前后分别加上
# 译释:vmap 是绑定一个在visual模式下的快捷键

# 译释:原理:在visual模式下,"zd 把一个选中的区域命名为z 然后删除,
# i 进入插入模式,输入,<C-R>z 撤销刚才的删除,然后再写入
# 最后<ESC>返回normal模式

# 译释:"z 命令创建一个选中的区域为register,并把它命名为z

# 译释:更令人开心的有:在visual模式下选中几行,然后输入 2> ,
# 则选中的行会全部缩进两个tab
# 555,偶一开始还是用 :xx,xx s/^/\t\t/,好傻啊!

:vmap st "zdi<?= <C-R>z ?><ESC> : 在visual模式下选中的文字前后分别加上<?= 和 ?>
----------------------------------------
# 文件浏览
:Ex : 开启目录浏览器,注意首字母E是大写的
:Sex : 在一个分割的窗口中开启目录浏览器
:ls : 显示当前buffer的情况
:cd .. : 进入父目录
:args : 显示目前打开的文件
:lcd %:p:h : 更改到当前文件所在的目录
# 译释:lcd是紧紧改变当前窗口的工作路径,% 是代表当前文件的文件名,
# 加上 :p扩展成全名(就是带了路径),加上 :h析取出路径

:autocmd BufEnter * lcd %:p:h : 自动更改到当前文件所在的目录
# 译释:autocmd指定一个自动命令,BufEnter指定一个事件,* 指定事件的对象,
# lcd %:p:h 指定一个动作
# hehe,好像和写记叙文差不多
----------------------------------------
# 缓冲区(buffer)浏览器 (第三方的一个最流行的脚本)
# 需要下载 bufexplorer.vim ,http://www.vim.org/script.php?script_id=42 上就有
\be : 在缓冲区浏览器中打开缓冲区列表
\bs : 以分割窗口的形式打开缓冲区浏览器
----------------------------------------
# 大小写转换
guu : 行小写
gUU : 行大写
g~~ : 行翻转(当然指大小写啦)
# 译释: g 是大小写转换命令(greate),u/U/~是三种转换形式(小写/大写/翻转),
# 最后一个重复则表示该转换是对于一行而言的


guw : 字大写(狭义字) 译注:建议对比iw
gUw : 字小写(狭义字)
g~w : 字翻转(狭义字)
# 译释:最后一个w 表示该转换是对于一个字而言的,由于是在normal模式下,
# 所以这个w 表示一个狭义字<cword>

vEU : 字大写(广义字)
vE~ : 字翻转(广义字)
# 译释:vE 这个指令组合会进入visual模式,然后选择一个广义字<CWORD>

ggguG : 把整个文章全部小写(ft!bt!)
gf : 取当前光标处的广义字作为文件名,然后试图打开它!
# 译释:为什么是广义字呢?因为这样可以方便的取到路径啊,像/var/www/html/index.htm

ga : 显示光标处字符的ascii,hex,oct,...晕菜的一堆转换
ggVGg? : 用rot13编码整个文件(晕!)
# 译释:gg到文件首行首字符,V进入Visual-Line模式,G到文件末行首字符,
# 这样就选中了整篇文章,然后g?就是用rot13编码整个文件啦
#
# 【关于rot13——谁让英文是偶数个字母啊】
# ROT13 是一种简单的编码,它把字母分成前后两组,每组13个,编码和解码
# 的算法相同,仅仅交换字母的这两个部分,即:[a..m] --> [n..z] 和 [n..z]
# --> [a..m] 。 ROT13 用简易的手段使得信件不能直接被识别和阅
# 读,也不会被搜索匹配程序用通常的方法直接找到。经常用于 USENET 中发表一
# 些攻击性或令人不快的言论或有简单保密需要的文章。
# 由于 ROT13 是自逆算法,所以,解码和编码是同一个过程。

<C-A>,<C-X> : 增加,减少 光标处的狭义字所表示的数字
:(,仅仅是分割了这两个命令,不是命令的一部分)
: Win32的用户可能需要重新定义一下Ctrl-A,呵呵
# 译注:good guy, 令人不得不想到perl的数字串

<C-R>=5*5 : 插入25 (这是一个迷你计算器耶!)
----------------------------------------
# 好玩的东东
:h 42 : 也可以访问 http://www.google.com/search?q=42
: 第一个结果就是 News. Douglas Adams 1952 - 2001.
: Floor 42 extends its deepest sympathies to
: the family, friends, and fans of Douglas Adams.
:h holy-grail
:h!
----------------------------------------
# 标记和移动
'. : 跳到最后修改的那一行 (超级有用)(ft,怎么又是这个评价)
`. : 不仅跳到最后修改的那一行,还要定位到修改点
<C-O> : 依次沿着你的跳转记录向回跳 (从最近的一次开始)
<C-I> : 依次沿着你的跳转记录向前跳
:ju(mps) : 列出你跳转的足迹
:help jump-motions
:history : 列出历史命令记录
:his c : 命令行命令历史
:his s : 搜索命令历史
q/ : 搜索命令历史的窗口
q: : 命令行命令历史的窗口
:<C-F> : 历史命令记录的窗口
----------------------------------------
# 缩写和键盘映射(原文中文件举例都用了c:/aaa/x,偶全给他改成/path/file了,哼唧)
:map <f7> :'a,'bw! /path/file
# 译释:map是映射一个normal模式下的键
# 这里是把F7键映射成把标记a到标记b中间的内容另存为一个文件/path/file
# 标记(mark)的方法:把光标移动到需要标记的地方,输入m,然后输入标记名,例如a
# 引用标记的方法:'a ,即:单引号加标记名

:map <f8> :r /path/file
# 译释:把F8键映射成在当前位置插入文件/path/file的内容
:map <f11> :.w! /path/file2<CR>
# 译释:.(点号)表示当前行
# 所以F11就是把当前行存为/path/file2
# 最后的<CR>表示一个回车
:map <f12> :r /path/file2<CR>
:ab php : 列出php表示的缩写
# 译释:定义一个缩写使用::iab hm hmisty
# 一个有趣的现象是,它列出的会是php和它的前子串开头的缩写
# 例如,有这么几个缩写:
# h => hmisty1 , hm => hmisty2 , hmi => hmisty3, m => hmisty4
# 那么使用 :ab hm会显示这么几个缩写:hm 和 h
# 而不是你想象中的 hm 和 hmi

:map , : 列出以逗号开始的键盘映射
# 译释:一般而言,我们称这些逗号开始的组合键为“逗号命令”
# 不过hmisty更喜欢用;构成“分号命令”
# 而且不是用map,而是用imap
# 因为偶懒么,懒得按<Esc>,所以直接在insert模式下就执行命令了
# 为什么用分号呢?因为我最常用它写程序啊
# perl/C/C++/object pascal/java,都是用分号结束一个语句
# 我们一般很少在分号后面连续写其他字符
# 所以用“分号+其他键”就很少会在输入的时候造成冲突

# 在键盘映射中常用的表示
<CR> : 回车
<ESC> : Esc
<LEADER> : 转义符号 \
<BAR> : 管道符号 |
----------------------------------------
# 列出寄存器(Registers)
:reg : 显示所有当前的registers
"1p : "表示引用register,1表示一个名字叫做1的register,
: p就是粘贴(paste)命令
# 译释:"也用来定义register
# 先输入 ",表示定义register
# 然后输入名字,如0~9,a~z
# 然后执行删除或复制命令,如dd或y,
# 或者是visual模式下的d(删除选中的部分)或y(复制选中的部分)
# 则被删除或复制的部分就被存入了这个命名的register
#
# 观察:一个特殊的register, "" ,里面存储了一个匿名的删除/复制
# 在你执行dd或y的时候,被作用的部分被存到了""中
# 这些和perl是多么像啊
----------------------------------------
# Useful trick
"ayy@a : 把当前行作为一个Vim命令来执行
# 译释:"ayy 是定义当前行到register a,然后@a是执行register a中存储的指令
# yy: 复制一行
# 10yy: 复制从此向下的10行

yy@" : 用上面所提到的那个匿名register
----------------------------------------
# 从其他程序获取输出 (需要外部程序)
:r!ls.exe : 读取ls的输出到当前位置
!!date : 读取date的输出 (但是会替换当前行的内容)
# 译释:其实你输入了!!后,vim就自动转换到 :.! 等待你继续输入

# 使用外部程序sort进行排序(sort是Unix标准命令,ls,date也是)
:%!sort -u : 使用sort程序排序整个文件(用结果重写文件)
# 译释:%表示整个文件的所有行
# !sort表示执行外部命令sort
# -u是sort的参数,man sort看看,这个参数的意义是合并相同的行
# u就是unique,如果两行内容相同,则结果中只保留一行的说

:'a,'b!sort -u : 对mark a 到mark b中间的内容进行排序
!1} sort -u : 排序当前段落 (只能在normal模式下使用!!)
# 译释:!表示使用filter,1}表示filter的对象是从当前行开始向后数一段
# 段落指到空行处结束,不包括空行
# 其实你一旦输入 !1},vim就自动计算当前段落应该到那一行(eg.+5),然后生成
# :.,.+5! 等待之后输入sort -u,回车,完成操作
# .表示当前行,.+5当然就是当前行向后数5行
----------------------------------------
# 多文档操作 (基础)
# 译注:用 :ls! 可以显示出当前所有的buffer
:bn : 跳转到下一个buffer

:bp : 跳转到上一个buffer
:wn : 存盘当前文件并跳转到下一个(又是“超级……”,ft!)
:wp : 存盘当前文件并跳转到上一个
:bd : 把这个文件从buffer列表中做掉
:bun : 卸掉buffer (关闭这个buffer的窗口但是不把它从列表中做掉)
:badd file.c : 把文件file.c添加到buffer列表
:b 3 : 跳到第3个buffer
:b main : 跳到一个名字中包含main的buffer,例如main.c
: (ultra,这个怎么翻译?:()
:sav php.html : 把当前文件存为php.html并打开php.html
:sav! %<.bak : 换一个后缀保存
:e! : 返回到修改之前的文件(修改之后没有存盘)
:w /path/% : 把文件存到一个地儿
:e # : 编辑标记为#的buffer(这个buffer必须含有一个可编辑的文件)
: 用ls命令就能看到哪一个buffer有#
: %a表示当前正在编辑的buffer
: u 表示不能编辑或者已经被做掉的buffer

:e #3 : 编辑编号为3的buffer(这个buffer必须含有一个可编辑的文件)
:rew : 回到第一个可编辑的文件
:brew : 回到第一个buffer
:sp fred.txt : 在一个水平分割的窗口中打开文件fred.txt
# 译注:vs fred.txt可以实现垂直分割
:sball : 把当前所有含有可编辑文件的buffer显示到一个分割窗口中
: (偶该考虑把super翻译成 高级指令 了,ft)

:map <F5> :ls<CR>:e # : 在normal模式下按F5键,则会显示所有含有一个
: 可编辑文件的buffer,然后提示你输入buffer的序号,
: 输入后回车,则编辑这个buffer
# 译注:这是一个键盘绑定

:set hidden : 允许不保存buffer而切换buffer (w/o=without)
----------------------------------------
# 在分割窗口中快速切换
:map <C-J> <C-W>j<C-W>_
# 译注:原文此处有误,前面应该加上冒号
# 这是一个键盘绑定,把Ctrl-J定义成切换到下一个窗口并最大化
:map <C-K> <C-W>k<C-W>_
----------------------------------------
# 命令录制 (最佳技巧,ft)
qq #录制到q
... #输入一系列复杂的指令
q #再次按q停止录制
@q #执行q中存储的指令
@@ #重复执行
# 编辑register/录制
"ap #把register a中的内容贴到当前位置
... #现在你可以修改它了
"add#删除之,重新存入register a
@a #执行register a中的指令
----------------------------------------
# _vimrc基础
:set incsearch : 实时匹配你输入的内容
:set wildignore=*.o,*.obj,*.bak,*.exe : tab键的自动完成现在会忽略这些
:set shiftwidth=4 : 现在自动缩进将是4个字符
# 译注:一个tab位通常是8个字符
# 所以,我们还要设定 :set tabstop=4,这样,所有的缩进都是4字符了
# emacs默认就是4字符缩进吧?
:set vb t_vb=". : 沉默方式(不要叫beep!)
----------------------------------------
# 加载windows iexplorer来浏览(我想这只有在windows下用gvim才能用到)
:nmap ,f :update<CR>:silent !start c:\progra~1\intern~1\iexplore.exe file://%:p
# 译释:nmap是做一个normal模式下的键盘绑定
# 这里绑定了一个逗号命令 ,f
# :update是写这个文件,与:w不同,它只有当文件被修改了的时候才写
# :silent别让弹出窗口报告执行结果
# !...后面就是执行windows命令了。呵呵,去问bill gates什么意思吧。
# 不过偶用gvim 6.1试过了,好用!

:nmap ,i :update<CR>: !start c:\progra~1\intern~1\iexplore.exe <cWORD><CR>
----------------------------------------
# 用VIM编辑ftp文件
:cmap ,r :Nread ftp://209.51.134.122/public_html/index.html
:cmap ,w :Nwrite ftp://209.51.134.122/public_html/index.html
# 译注:原文丢失了开头的冒号
# cmap是命令(command)模式绑定

gvim ftp://209.51.134.122/public_html/index.html
# 这一句就是开始编辑一个ftp远端的文件,ft
----------------------------------------
# 附加到一个register (就是用大写的register名字啦!)
"a5yy #复制5行到a中
10j #下移10行
"A5yy #再添加5行到a中
----------------------------------------
[I : 显示光标处的狭义字可以匹配的行(高级指令)
# 译注:# 可以全文查找与光标处的狭义字相匹配的字,
# 这在查找函数原型和实现,或者变量使用的时候很有用
----------------------------------------
# 常规缩进
:'a,'b>>
# 译释:把mark a到mark b之间的内容进行两次缩进

# 在visual模式下缩进 (无限可重复)
:vnoremap < <gv
# 译释::vnoremap 重定义了visual模式下 < 符号的含义
# 把它定义成 <gv
# 即:先<向外缩进,然后gv重新选择上一次选择了的区域
# 这样在visual模式下就可以实现连续按<而连续缩进了
:vnoremap > >gv
# 同里,内缩
----------------------------------------
# 查找(译注:建议先学习正则表达式)
# 译注:查找命令不用进入:命令模式,直接按/就可以了
# 如果没有修饰,可以不要右边的/
# 和smth bbs差不多啦,呵呵
/joe/e : 光标停留在匹配单词最后一个字母处
/joe/e+1 : 光标停留在匹配单词最后一个字母的下一个字母处
/joe/s : 光标停留在匹配单词第一个字母处
/^joe.*fred.*bill/ : ft,标准正则表达式
/^[A-J]\+/ : 找一个以A~J中一个字母重复两次或以上开头的行
/forum\(\_.\)*pent : 多行匹配
/fred\_s*joe/i : 中间可以有任何空白,包括换行符\n
# 译注:这个和perl不太一样的哦
/fred\|joe : 匹配FRED或JOE
/\<fred\>/i : 匹配fred,fred必须是一个独立的单词,而不是子串
# 译注:这和perl也不太一样,perl是用\b做单词定界符的
/\<\d\d\d\d\> : 匹配4个数字
\<\d\{4}\> : 也是匹配4个数字
# 在visual模式下查找
:vmap g/ y/<C-R>"<CR> : 匹配选中的高亮文字
# 译释:vmap是在visual模式下的键盘映射
# 映射了g/这个命令组合
# y 把选中的高亮文字写入匿名register "
# / 打开搜索模式
# <C-R> 准备粘贴register
# " 粘贴了""中的内容
# <CR> 回车,执行

:vmap <silent> g/ y/<C-R>=escape(@", '\\/.*$^~[]')<CR><CR> : with spec chars
# 译释:@#$&^*@#%&*#$@!

# 跨行匹配,\_ 表示允许匹配换行符,或者说,允许匹配新行
# 译注:小心,和perl不一样
/ : 匹配多行注释
/fred\_s*joe/i : 似乎上面有了,ft
/bugs\(\_.\)*bunny : 中间可以有无数东西
:h \_ : 看看关于 \_ 的帮助

# 查找当前光标位置所在子例程/函数(subroutine/function)的声明
:nmap gx yiw/^\(sub\<bar>function\)\s\+<C-R>"<CR>
# 译释:nmap 做一个normal模式下的键盘绑定
# y 进入复制状态,后面需要一个motion
# 接着就用 iw 指出了这个motion,是inner word
# inner word也是狭义字<cword>,但是和 w 不同
# w 是从光标位置开始向后看
# 而inner word总是把光标移到第一个字母,从而总能得到一个完整的狭义字
# 试一试 gUw 和 gUiw 就知道区别了,呵呵。

# 在多个文档中搜索
:bufdo /searchstr
:argdo /searchstr
----------------------------------------
# 替换
# 译注:替换命令需要先进入:命令模式

:%s/fred/joe/igc : 一个常见的替换命令,修饰符igc和perl中一样意思

:%s/\r//g : 删除DOS方式的回车^M
:%s= *$== : 删除行尾空白
:'a,'bg/fred/s/dick/joe/igc : 非常有用!(ft,又来了!)
# 译释:'a,'b指定一个范围:mark a ~ mark b
# g//用一个正则表达式指出了进行操作的行必须可以被fred匹配
# 看后面,g//是一个全局显示命令
# s/dick/joe/igc则对于这些满足条件的行进行替换

# 列复制
# 译注:@#%&^#*^%#$!
:%s= [^ ]\+$=&&= : 复制最后一列
:%s= \f\+$=&&= : 一样的功能
:%s= \S\+$=&& : ft,还是一样
# 反向引用,或称记忆
:s/\(.*\):\(.*\)/\2 : \1/ : 颠倒用:分割的两个字段
:%s/^\(.*\)\n\1/\1$/ : 删除重复行
# 非贪婪匹配,\{-}
:%s/^.\{-}pdf/new.pdf/ : 只是删除第一个pdf
# 跨越可能的多行
:%s/// : 又是删除多行注释(咦?为什么要说“又”呢?)
:help /\{-} : 看看关于 非贪婪数量符 的帮助
:s/fred/<c-r>a/g : 替换fred成register a中的内容,呵呵
# 写在一行里的复杂命令
:%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
# 译注:就是用 | 管道啦

# 或者
:%s/suck\|buck/loopy/gc : 或者(或者需要\,ft!,|不是或者)
# ft, \不就是转义了么!这个和perl真是不同了!

# 调用VIM函数
:s/__date__/\=strftime("%c")/ : 插入时间串

# 处理列,替换所有在第三列中的str1
:%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:

# 交换第一列和最后一列 (共4列)
:%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:

# filter all form elements into paste register
# 把所有的form元素(就是html里面的form啦)放到register里?
# ft, 头疼,不解释了
:redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END
:nmap ,z :redir @*<Bar>sil exec 'g@<\(input\<Bar>select\<Bar>textarea\<Bar>/\=fo
----------------------------------------
# 全局(global)显示命令,就是用 :g+正则表达式
# 译释: :g/{pattern}/{cmd} 就是全局找到匹配的行
# 然后对这些行执行命令{cmd}
:g/\<fred\>/ : 显示所有能够为单词fred所匹配的行
:g/<pattern>/z#.5 : 显示内容,还有行号,呵呵
:g/<pattern>/z#.5|echo "==========" : 漂亮的显示,ft!

# 全局命令 (其他)
:g/^\s*$/d : 删除所有空行
:g!/^dd/d : 删除不含字串'dd'的行
:v/^dd/d : 同上
# 译释:v == g!,就是不匹配!
:g/fred/,/joe/d : not line based (very powerfull)
:v/./.,/./-1join : 压缩空行
:g/^$/,/./-j : 压缩空行
:g/<input\|<form/p : 或者 要用\|
:g/^/pu _ : 把文中空行扩增一倍 (pu = put)
: 即:原来两行间有一个空行,现在变成2个
:g/^/m0 : 按行翻转文章 (m = move)
:g/fred/t$ : 拷贝行,从fred到文件末尾(EOF)
:%norm jdd : 隔行删除
# 译释:% 指明是对所有行进行操作
# norm指出后面是normal模式的指令
# j是下移一行,dd是删除行

# incrementing numbers
:.,$g/^\d/exe "norm! \<c-a>" : 增加在BOL(beginning of line)处的数字
# 译注:.,$ 指明命令从当前行执行到最后一行
# 如果没有 .,$ 限定范围,那么g//就会对整个文件进行操作
# exe 是执行后面的命令组合

:.,$g/^\d/exe "norm \<c-p>" : Win32下必须重定义Ctrl-A

# 保存全局命令的结果 (注意必须使用添加模式)
:g/fred/y A : 添加所有为fred所匹配的行到register a
:'a,'b g/^Error/ . w >> errors.txt

# 复制每一行,然后在复制出来的每一行两侧加上一个 print '复制出来的内容'
:g/./yank|put|-1s/'/"/g|s/.*/Print '&'/
----------------------------------------
# 全局命令和替换命令联姻 (强大的编辑能力)
:'a,'bg/fred/s/joe/susan/gic : 可以使用反向引用来匹配
:g/fred/,/joe/s/fred/joe/gic : non-line based (ultra)
----------------------------------------
# 先找fred,然后找joe,然后#$^$%^#$%^@%^%&%^*!
:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
----------------------------------------
# 重定向到register * 和 粘贴register *
:redir @* : 重定向命令的输出结果(最下方命令行上的结果)
: 到register * (ft,* 代表0~1,a~z,..)
:redir END : 结束重定向
# 处理粘贴
"*yy : 上面讲过了,就是复制到register *中
"*p : 然后贴出来
----------------------------------------
:redir >> out.txt : 重定向到一个文件
----------------------------------------
# 重新格式化文本
gq<CR>
gqap (a是motion p是段落(visual模式))
ggVGgq 重新格式化整个文章
----------------------------------------
# 对多个文档实施命令
:argdo %s/foo/bar/ : 对所有:args列表中的文档执行命令
:bufdo %s/foo/bar/
:windo %s/foo/bar/
:argdo exe '%!sort'|w! : 使用外部命令
----------------------------------------
# 命令行的一些好玩的东东
gvim -h : 启动的时候启动帮助(Win32)
vi -h 或 vim -h : 这个是unix下用
ls | gvim - : 编辑一个数据流!
gvim -o file1 file2 : 以分割窗口打开两个文件

# 指出打开之后执行的命令
gvim.exe -c "/main" joe.c : 打开joe.c,然后跳转到'main'

# 对一个文件执行多个命令
vim -c "%s/ABC/DEF/ge | update" file1.c

# 对一组文件执行多个命令
vim -c "argdo %s/ABC/DEF/ge | update" *.c

# 自动编辑文件 (编辑命令序列Ex commands已经包含在convert.vim中了)
vim -s "convert.vim" file.c

# 不要加载.vimrc和任何plugins (启动一个干净的VIM)
gvim -u NONE -U NONE -N
----------------------------------------
# GVIM 不同的地方
gvim -d file1 file2 : vimdiff (比较不同)
dp : 把光标处的不同放到另一个文件
do : 在光标处从另一个文件取得不同
----------------------------------------
# Vim陷阱
# 在vim的正则表达式中, + 和 | 都必须加转义符 \
# 小心,这和perl不一样!
/fred\+/ : 匹配fred或freddy但是不匹配free
----------------------------------------
# \v ,或叫做very magic (通常都是这么叫)可以取消转义符
/codes\(\n\|\s\)*where : 普通的正则表达式
/\vcodes(\n|\s)*where : very magic,| 不用加 \ 了!
----------------------------------------
# 把东西送到命令行/搜索行 (SUPER:偶不再翻译这种叹词了)
<C-R><C-W> : 送一个狭义词
<C-R><C-A> : 送一个广义词
<C-R>- : 送一个小型删除寄存器register
<C-R>[0-9a-z] : 送一个命名寄存器register
<C-R>% : 送文件名过去 (#也行)
----------------------------------------
# 操作寄存器
:let @a=@_ : 清除register a
:let @*=@a : 寄存器赋值
:map <f11> "qyy:let @q=@q."zzz"
# 译注:猜猜这个无聊的绑定是什么意思?
----------------------------------------
# 关于帮助的帮助
:h quickref : 翻到VIM Quick Reference页(有用!)
:h tips : Vim自己的tips
:h visual<C-D><tab> : 得到一个关于visual关键字的帮助列表
: 然后用tab键去选择
:h ctrl<C-D> : 显示所有关于Ctrl的帮助
:h :r : :ex冒号命令
:h CTRL-R : 普通模式命令
:h \r : \r在正则表达式中是什么意思呢?
:h i_CTRL-R : insert模式下的Ctrl-R
:h c_CTRL-R : 命令行(command-line)模式下的Ctrl-R
:h v_CTRL-V : visual模式下的Ctrl-V
:h tutor : VIM 指南
gvim -h : 关于 VIM 命令的帮助
vi/vim -h
<C-S>T : Control Shift T go backwards in help
: 偶不清楚有什么用:(
----------------------------------------
# 选项设置在哪里?
:scriptnames : 列出所有加载的 plugins, _vimrcs
:verbose set history : 显示history的值并指出设置文件的位置
----------------------------------------
# 制作你自己的VIM帮助
:helptags /vim/vim61/doc : 重建 /doc 中所有的 *.txt 帮助文件
:help add-local-help
----------------------------------------
# 用外部程序来运行程序 (例如 perl :)
map <f2> :w<CR>:!perl -c %<CR>
# 译释::w<CR>写文件
# :!perl -c %<CR>用perl来运行当前文件
# 当前文件必须有文件名!
----------------------------------------
# 插入DOS换行符
:%s/nubian/<C-V><C-M>&/g : Ctrl-V是一种转义,它说要解释<C-M>
:%s/nubian/<C-Q><C-M>&/g : 对于Win32应该这样
:%s/nubian/^M&/g : 你看到的^M是一个字符
:%s/nubian/\r&/g : 更好的形式
----------------------------------------
# 把最后一个命令贴到当前位置
i<c-r>:
# 把最后一个搜索指令贴到当前位置
i<c-r>/
# 译释:i是进入insert模式,
# Ctrl-r是开启插入模式下register的引用
# :和/分别引用了两个register的内容
----------------------------------------
# 更多的完成功能
<C-X><C-F> :插入当前目录下的一个文件名到当前位置
# 在insert模式下使用
# 然后用 Ctrl-P/Ctrl-N 翻页
----------------------------------------
# 替换一个visual区域
# 选择一个区域,然后输入 :s/Emacs/Vim/ 等等,vim会自动进入:模式
:'<,'>s/Emacs/Vim/g : 前面的'<,'>是vim自动添加的
----------------------------------------
# 在文件中插入行号(不是显示行号,是插入!)
:g/^/exec "s/^/".strpart(line(".")." ", 0, 4)
----------------------------------------
# 用VIM的方式来编号行

:set number :显示行号
:set nonu :取消显示
:%s/^/\=strpart(line('.')." ",0,&ts)

#从任意行开始编号(需要perl,嘿嘿)
:'a,'b!perl -pne 'BEGIN{$a=223} substr($_,2,0)=$a++'
#似乎有点小问题,你试试看:)

qqmnYP`n^Aq : 记录到q 然后用 @q 重复
#似乎不能工作,你试试看:)

# 递增已存在数字到文件末
:.,$g/^\d/exe "normal! \<c-a>"

# 高级递增,看:
http://vim.sourceforge.net/tip_view.php?tip_id=150
----------------------------------------
# 高级递增 ("真的很有用",ft)
" 把下面几句放到 _vimrc #vimrc脚本用 " 做行注释符
let g:I=0
function! INC(increment)
let g:I =g:I + a:increment
return g:I
endfunction
" 例如从mark a 到mark b 递增,从223开始,步长为5
:let I=223
:'a,'bs/$/\=INC(5)/
" (原文:create a map for INC)
" 但是cab是清楚命令行缩写啊?怎么回事?
cab viminc :let I=223 \| 'a,'bs/$/\=INC(5)/
----------------------------------------
# 加密(小心使用,不要忘了密码)
:X : 然后vim会提示你输入密码
:h :X
----------------------------------------
# 模式行(modeline)
# 第二版新加,感谢tcpip
vim:noai:ts=2:sw=4:readonly: #让文档只读
# 译释:这一行必须以vim:开头,而且只能在文档的前5行或后5行之内
# 后面是需要执行的命令,依次是:
# noai noautoindent
# ts=2 tabstop=2
# sw=4 shiftwidth=4
# readonly readonly

:h modeline #看看关于modeline的帮助先!
----------------------------------------
# Creating your own GUI Toolbar entry
# 对于text模式下的vim没用,不翻了
amenu Modeline.Insert\ a\ VIM\ modeline <Esc><Esc>ggOvim:ff=unix ts=4 ss=4<CR>v
----------------------------------------
# 一个保存当前光标下的狭义字到一个文件的函数
function! SaveWord() "这里用!是强制覆盖以前的定义
normal yiw
exe ':!echo '.@0.' >> word.txt'
endfunction
map ,p :call SaveWord() #使用该函数的一个例子
----------------------------------------
# 删除重复行的函数
function! Del()
if getline(".") == getline(line(".") - 1)
norm dd
endif
endfunction

:g/^/ call Del() #使用该函数的一个例子
----------------------------------------
# 双字节编码 (non alpha-numerics)
:digraphs : 显示编码表
:h dig : 帮助
i<C-K>e' : 输入 é
i<C-V>233 : 输入 é (Unix)
i<C-Q>233 : 输入 é (Win32)
ga : 查看字符的hex值
----------------------------------------
# 文件名自动完成 (例如 main_c.c)
:e main_<tab> : tab 键完成
gf : 打开光标处广义字命名的文件 (normal模式)
main_<C-X><C-F> : 文件名自动完成(insert模式)

----------------------------------------
# Vim复杂使用
# 交换两个单词
:%s/\<\(on\|off\)\>/\=strpart("offon", 3 * ("off" == submatch(0)), 3)/g
----------------------------------------
# 把text文件转换成html文件(oh,ft)
:runtime! syntax/2html.vim : 转换 txt 成 html
:h 2html : 看看帮助
----------------------------------------
# VIM 有一个内部自带的 grep 命令
:grep some_keyword *.c : 得到一个包含some_keyword的c文件名列表
:cn : 去下一个出现的位置
----------------------------------------
# 强制无后缀文件的语法着色方式 .pl
:set syntax=perl
# 取消语法着色
:set syntax off
# 改变色彩主题 (在~vim/vim??/colors中的任何文件)
:colorscheme blue
----------------------------------------
:set noma (non modifiable) : 防止修改
:set ro (Read Only) : 只读保护
----------------------------------------
# Sessions (打开一系列文件)
gvim file1.c file2.c lib/lib.h lib/lib2.h :在"session"中加载一系列文件
:mksession : 生成一个Session文件 (默认是Session.vim)
:q
gvim -S Session.vim : 重新读取一个session,也就读取了所有文件,ft
----------------------------------------
# 标记(tags) (跳转到subroutines/functions)
taglist.vim : 最流行的插件
:Tlist : 显示Tags (functions的列表)
<C-]> : 跳转到光标处的function
: 这个键 Ctrl-] 和vim帮助中是一样的
----------------------------------------
# Just Another Vim Hacker JAVH
# Juat Another Perl Hacker JAPH,嘿嘿
vim -c ":%s/^/WhfgTNabgureRIvzSUnpxre/|:%s/[R-T]/ /Ig|:normal ggVGg?"
# 译释:呵呵,谁来解释一下吧!
# 其实不过是在启动vim的时候执行了一个命令
# 先写入了 Just Another Vim Hacker 的rot13编码
# 然后再解码
----------------------------------------
终于翻完了,呵呵。好累啊!

前言
工欲善其事,必先利其器。一个programmer必然要先有一个好的editor。
vim就是一个十分强大的编辑器。它的强大之处,在于其个性化和可定制。
学习vim,就像学习Linux,学习perl,你发现你可以让它来适应自己,
你发现你只需要学一点点就可以工作了;而当你继续学习下去,你会
惊奇的发现它的“新”功能能够极大的提高你的工作效率;就是这样,
你学习的兴趣将始终超过学习的难度,因此促使你一直钻研下去……
另外一点,你总是可以找到vim,至少是vi,可是你可能不会在你的公司
的Sun机器上找到记事本,也可能不会在AIX上找到emacs——除非你是root,
你可以自己装一个:)
我无意把vim和其他编辑器比较,我只知道Larry Wall用vim。
言归正传,个性化vim最基本也是最重要的就是编写vimrc文件(不要说
你不知道vimrc在哪里,它就在你的home目录下,名字叫做.vimrc)。

1. 注释
写程序之前,第一件事情不是了解语法,而是知道如何写注释。
vimrc脚本的注释是使用引号(")作行注释。

2. 变量
(1) 标量变量
可以是数字或字符串,基本与perl相同。
命名方式为:作用域:变量名,常用的有如下几种:
b:name —— 只对当前buffer有效的变量
w:name —— 只对当前窗口有效的变量
g:name —— 全局变量
v:name —— vim预定义变量
a:name —— 函数的参变量
注意:引用标量变量的时候请包含作用域和冒号

(2) 一类有特殊含义的变量
命名方式:Fun Character(这个词请参看Programming Perl)加上变量名
共有三类:
$NAME —— 环境变量(一般变量名都是大写)
&name —— 选项(vim处理某些事情的时候的默认设置)
@r —— register(寄存器,不是汇编的EAX,EBX,看第2部分vim tips)
常见环境变量例子:$VIMRUNTIME —— vim运行路径
常见选项例子:&ic —— ignorecase
注:使用set命令可以改变选项设置,例如:
:set ignorecase
使用一个set命令可以看到当前所有的选项及其设置。

(3) 变量赋值
:let 变量名=值
注意:最前面的冒号不仅是为了表示这是一个冒号命令,而且是必须的。

释放变量::unlet! 变量名

(4) 运算符(和perl基本一样)
数学运算:+ - * / % .
逻辑运算:== != > >= < <= ?:
正则匹配运算符=~ !~

3. 控制结构
(1) if 条件
语句块
elseif 条件
语句块
else
语句块
endif
注意:条件表达式不需要小括号,语句块不需要大括号

(2) while 条件
语句块
[break/continue]
endwhile

4. 函数:

定义:
function 函数名(参数)
函数体
endfunc

调用:
在脚本语句中使用 call 函数名(参数)
在vim命令中使用 :call 函数名(参数)

注:在函数体中使用参数需要在参数变量名称前加上a:,例如参数名为
keyword,
则函数体中使用a:keyword来引用

注:常用系统函数 参见【附】。

5. 执行命令,键盘绑定,命令行命令和自动命令
(1) 执行命令
exec "命令" —— 用于在vim脚本中执行一系列vim命令
:!外部命令 —— 这是一个vim命令行命令,功能是调用外部程序
(2) 键盘绑定 :help map-overview
vim最大的特点在于可以把所有的操作能够用一个命令字符串表达出来,
因此这带来了编写脚本的最大的便利。键盘绑定就是一个例子,这个功能允许
把一个命令字符串绑定到一个按键/按键组合。

一般格式:映射命令 按键组合 命令组合
例子:nmap c ^i#<Esc>j
解释:映射normal模式下的按键c为:^i#<Esc>j,就是在该行开头加上#号
,然后下移一行

常用映射命令:
map :全模式映射
nmap :normal模式映射
vmap :visual模式映射
imap :insert模式映射

(3) 命令行命令
vim支持在启动的时候使用-c开关执行命令字符串,例如:
$ cat n
#!/bin/sh
vim -c "set filetype=$PERL" -c "s.$.#!/usr/bin/$PERL -w\r\r." -c
":nohlsearch" $1
设置文件类型 写入#!/usr/bin/perl -w
取消匹配加亮
$ n myperlfile
(4) 自动命令
一般格式:autocmd 事件 文件类型 命令
例子:au BufNewFile,BufRead *.pl setf perl
解释:当事件 BufNewFile 和 BufRead 发生在 *.pl 文件上的时候,
执行命令:setf perl

========================================================================
【附】常用系统函数 :help function-list

函数 返回值 解释

(1)字符串操作
char2nr( {expr}) Number {expr}中字符的ASCII值
nr2char( {expr}) String {expr}中ASCII值对应的字符
escape( {string}, {chars}) String 使用'\'对{string}中的字符
{chars}进行转义
strtrans( {expr}) String 把字符串转换成可打印字符串
tolower( {expr}) String 将字符串{expr}小写
toupper( {expr}) String 将字符串{expr}大写
match( {expr}, {pat}[, {start}])
Number {pat}在{expr}中的匹配位置
matchend( {expr}, {pat}[, {start})
Number {pat}在{expr}中的最后匹配位

matchstr( {expr}, {pat}[, {start}])
String {pat}在{expr}中的匹配,成功
返回{pat},失败返回""
stridx( {haystack}, {needle}) Number {needle}在{haystack}中的始
索引位置
strridx( {haystack}, {needle}) Number {needle}在{haystack}中的终
索引位置
strlen( {expr}) Number 字符串{expr}的长度
substitute( {expr}, {pat}, {sub}, {flags})
String 用{sub}替换{expr}中的模式
{pat}
submatch( {nr}) String ":substitute"的特殊匹配
strpart( {src}, {start}[, {len}])
String 子串函数,在{src}中从
{start}开始取出{len}个字符
expand( {expr}) String 扩展{expr}中的字符串
type( {name}) Number 变量{name}的类型

(2)操作当前缓冲区中的文本
byte2line( {byte}) Number 字节数为{byte}的行
line2byte( {lnum}) Number 行号为{lnum}的行的字节数
col( {expr}) Number {expr}的列号:. 光标所在列
$ 末列 "x 标记x所在位置
virtcol( {expr}) Number {expr}的屏幕列号(screen
column)
line( {expr}) Number {expr}的行号
wincol() Number {expr}的窗口列号(screen
column)
winline() Number {expr}的窗口行号(screen
column)
getline( {expr}) Number {expr}的行号
setline( {lnum}, {line}) Number 把{line}写入{lnum}行
append( {lnum}, {string}) Number 在{lnum}行下一行加入
{string}
indent( {lnum}) Number 缩进行{lnum}
cindent( {lnum}) Number C格式缩进行{lnum}
lispindent( {lnum}) Number Lisp格式缩进行{lnum}
nextnonblank( {lnum}) Number 行号 >= {lnum} 的非空白行的
行号
prevnonblank( {lnum}) Number 行号 <= {lnum} 的非空白行的
行号
search( {pattern} [, {flags}]) Number 查找{pattern}
searchpair( {start}, {middle}, {end} [, {flags} [, {skip}]])
Number 查找 始/末对 的另一个末端


(3)系统函数和文件操作
browse( {save}, {title}, {initdir}, {default})
String 启动一个文件请求
glob( {expr}]) String 展开一个fileglob {expr}
globpath( {path}, {expr}) String 对{path}中的所有目录调用
glob({expr})
resolve( {filename}) String 得到符号链接的指向
fnamemodify( {fname}, {mods}) String 更改文件名
executable( {expr}) Number 如果{expr}存在且可执行,则

filereadable( {file}) Number 如果{file}可读,则真
isdirectory( {directory}) Number 如果{directory}存在,则真
getcwd() String 当前工作目录
getfsize( {fname}) Number 文件字节数
getftime( {fname}) Number 文件最终修改时间
localtime() Number 当前时间
strftime( {format}[, {time}]) String 格式化的时间
tempname() String 生成一个临时文件名
delete( {fname}) Number 删除文件{fname}
rename( {from}, {to}) Number 重命名{from}成{to}
system( {expr}) String 执行shell命令{expr}
hostname() String 机器名

(4)缓冲区,窗口,参数列表
argc() Number 参数列表中的文件个数
argidx() Number 参数列表中当前索引值
argv( {nr}) String 参数列表中第{nr}个
bufexists( {var}) Number 如果{var}存在则真
buflisted( {expr}) Number 如果{expr}被列出则真
bufloaded( {expr}) Number 如果{expr}被加载则真
bufname( {expr}) String 缓冲{expr}的名字
bufnr( {expr}) Number 缓冲{expr}的缓冲序号
winnr() Number 当前窗口的窗口序号
bufwinnr( {expr}) Number 指定缓冲的窗口序号
winbufnr( {nr}) Number 指定窗口的缓冲序号
getbufvar( {expr}, {varname}) 得到缓冲{expr}的特殊变量
{varname}的值
setbufvar( {expr}, {varname}, {val}) 设置缓冲{expr}的特殊变量
{varname}的值为{val}
getwinvar( {nr}, {varname}) 得到窗口{nr}的特殊变量
{varname}的值
setwinvar( {nr}, {varname}, {val}) 设置窗口{nr}的特殊变量
{varname}的值为{val}

(5)折叠(Folding)
foldclosed( {lnum}) Number 如果{lnum}行的折叠闭合了,
返回第一行
foldlevel( {lnum}) Number {lnum}行的折叠级数
foldtext( ) String 生成一个闭合折叠的表示

(6)语法加亮
hlexists( {name}) Number 如果命名为{name}的高亮组存
在,则真
hlID( {name}) Number 名字为{name}的高亮组的语法
ID
synID( {line}, {col}, {trans}) Number {line}行{col}列的语法ID
synIDattr( {synID}, {what} [, {mode}])
String 返回语法ID {synID}的{what}
属性
synIDtrans( {synID}) Number 翻译的语法ID {synID}

(7)历史
histadd( {history},{item}) String 向历史中增加一项
histdel( {history} [, {item}]) String 在历史中删除一项
histget( {history} [, {index}]) String 在历史中取出索引{index}的项
histnr( {history}) Number 历史项最大索引

(8)交互
confirm( {msg} [, {choices} [, {default} [, {type}]]])
Number 返回用户选择的项序号
getchar( [expr]) Number 获得一个输入字符
getcharmod( ) Number 修改最后一个输入的字符
input( {prompt} [, {text}]) String 获得用户输入
inputsecret( {prompt} [, {text}]) String 获得用户输入,但是不回显
inputdialog( {prompt} [, {text}]) String 产生一个GUI对话框以获得用
户输入

(9)Vim服务器
serverlist() String 返回一个可用的服务器列表
remote_send( {server}, {string} [, {idvar}])
String 送出key序列

remote_expr( {server}, {string} [, {idvar}])
String 送出表达式
server2client( {serverid}, {string})
Number 送出回复串
remote_peek( {serverid} [, {retvar}])
Number 检查回复串
remote_read( {serverid}) String 读取回复串
foreground( ) Number 把vim窗口带到前台
remote_foreground( {server}) Number 把vim服务器带到前台

(10)变量检查
mode() String 返回当前编辑方式
visualmode() String 返回最后一次visual模式的使

hasmapto( {what} [, {mode}]) Number 如果存在{what}的映射则真
mapcheck( {name}[, {mode}]) String 检查所有被{name}匹配的映射
名称
maparg( {name}[, {mode}]) String 在模式{mode}下的映射{name}
的rhs值
exists( {var}) Number 如果{var}存在则真
has( {feature}) Number 如果特性{feature}被支持则真
cscope_connection( [{num} , {dbpath} [, {prepend}]])
Number 检查是否存在cscope连接
did_filetype( {name}) Number 设置文件类型的自动命令
{name}存在则真
eventhandler( ) Number 如果在一个事件处理中则真
getwinposx() Number vim窗口在GUI模式下的X轴坐标
象素数
getwinposy() Number vim窗口在GUI模式下的Y轴坐标
象素数
winheight( {nr}) Number 窗口{nr}的高度
winwidth( {nr}) Number 窗口{nr}的宽度
libcall( {lib}, {func}, {arg}) String 使用参数{arg}调用在{lib}中
的函数{func}
libcallnr( {lib}, {func}, {arg})
Number 和上一个函数相同,用于返回
整数的函数
写一点vim常用的技巧,
主要是其他讲vim的文章不太讲的。

1. %
%用来匹配块,
如果你的光标在类似([{}])
或者#ifdef #else #endif上
%将把光标跳转到相应的匹配符号上去,
%还可以用来指定命令范围,
如果你想把一个
{
..
...
}的块全部删除。
可以先把光标移到{ 再敲d%
类似的,
如果你想把一个块全部往里缩进一个tab
可以把光标移到 { 敲>%

2. =
=是用来缩进的假设你已经在.vimrc里
设置了你的缩进格式,
你就可以用=来缩进你的代码了
=%就是缩进一个块。

3.正则表达式
正则表达式大家都清楚,
我主要讲个一般人不太用,
但很有用的表达,

例如你想把所有的"..."形式的串替换成'...'的形式
但引号里的内容不变
你就可以用
%s/"\(.*\)"/'\1'/来做
上面这个正则表达式"\(.*\)"里 \用来表示()是元字符
第一个在括号里的被匹配的串就可以被\1来代表, 以后依次是\2 \3。
顺便说一句,我到现在还不
知道怎么限制vim里正则表达匹配的贪婪算法。

------------------------------------

里面说的非贪婪匹配是 \{-},
也就是 %s/"\(.\{-}\)"/'\1'/g
\ 太多了可以用 \v,
%s/\v"(.{-})"/'\1'/g
详细
:h /\{-
:h \v
另外 和 perl 正则表达式的区别在 :h perl-patterns

1.

fx
x 表示任何一个字符。
这是最快的在一行种移动的方法了。然后用
; (分号)
继续移动。

反向移动好像是 t ,但是我记性不好,
总是记不住,于是
0fx
用 0 先回到行首,在 f

2.
任何一个操作命令在加一个移动命令。实现对某个范围的操作。
例如
dfx
表示删除到下一个出现 x 的地方, x 可以使任意字符。
操作命令有 d (cut), y(copy) , p(paste), v (select)
移动命令有 hjkl, f, /, gg, G

3.
任何命令组合都可以先按一些 数字健 表示重复操作。
如:
d123j
删除下面123行。

4. 宏纪录的功能
例如,把文件中所有奇数行和偶数行合并。按如下序列
gg
qq
J
q
100000000@q

5. C-p
在 insert mode 下
写程序的时候,任何超长的变量名字都不成问题。
如果有一个this_is_very_long_variable_name
可以
this<C-P>
90%的可能性自动就把名字补全了。

于是,我写程序的时候,变量的名字其的越来越长,输入越来越快。:)

6. C-x C-p
在写程序 abc.h 的时候
写道 #include "abc.h" 的时候
其实可以
#include "a<C-x><C-p>"

90% 的情况,可以自动补全文件名称。


6.从外部命令输入
:r !ls
可以读取当前目录的文件列表。
如果你对 bash 很熟悉的话,这个功能非常好用
例如
输入
case 1
case 2
....
case 1000:
的方法是
:r !for ((i=0;i<100;i++));do echo "case $i" ; done

7. 利用外部命令处理文字。
我在 ~/.vimrc 中写了一行。
map = ggVG:!indent -nut -st -kr 2>/dev/null<CR>G

我按一个 = ,就可以利用外部命令 indent 美化 我的 c 程序。
我认为,
还可以用外部命令排序
例如
用 v 选定要排序的区域
然后按一个叹号。
:'<,'>!sort

8
我在 ~/.vimrc 中写了
map <Left> :bp<CR>
map <Right> :bn<CR>
map <F4> :bd<CR>

就可以用 左右方向健来切换 buffer
F4 关闭 buffer 了。

9
我在 ~/.vimrc 中写了
runtime ftplugin/man.vim

就可以在把光标停在一个函数上,然后用
\k
查看在线帮助了。

:Man getuid
查看 getuid 函数的手册了。

10.
:make
可以用外部命令 make 编译工程。
:cw
查看出错信息,
:cn
:cp
在出错信息之间跳转。

11.
]] , [[ , [] , ][ 命令可以在函数之间移动。

我先说几个
标记文本
  mchar   用字母char标记当前光标的位置
  `char   移至char所标记处
  'char   移至char标记所在行的开头处
  "     移至当前行上一次所在位置(在光标移动之后)――一个双引号
  ''    移至当前行上第一次所在位置的行的开头处(在光标移动之后)―
―两个单引号
清理掉DOS文本中的^M
可以在:1,$s/^M//g,其中^是用CTRL+v上去的M是回车形成的

----------------

编辑数个文件(利用vi filename(s))进入vi后)
:args         显示编辑名
单中的各个文件名
:n         ?
3;读入编辑名单中的下一个文件
:rew         读入
编辑名单中的第一个文件
:e#          读入
编辑名单内的前一个文件
:e file        读入另一个文件进
vi(此文件可不在编辑名单内),若原文件经修改还没有存档,则   
        应先以: w 存档。

:e! file       强迫读入另一个文
件进入vi,原文件不作存档动作。

----------------

>>
<<

移动整行的命令。类似于delphi的ctrl+shift+I/ctrl+shift+U
在调整大段代码时很方便。
设置在.exrc中
sw=4

----------------

在vim中ctrl-v开始列编辑。
:help 可以看vim的使用手册。很丰富的。

----------------

快速块复制

用m char标识某行(如 mb)
移动到复制的起始行,y'b,就可以复制整块
将整块复制到制定的‘寄存器’ "qy'b
将寄存器中的数据插入到某位置 "qp

在寄存器中保存的块在整个vi过程中有效(包括用e 重新编辑其他文件)

----------------

shift +G 跳到文件尾
?char 从后往前查找字符串
/ char 从前往后查找字符串

----------------

% - 移至匹配的括号
xp - 交换两个字符
y[cursor movement] - 光标移多少复制多少,如yw, y2w, y2l
. - repeat last command
q<reg> - 开始录制宏,存入<register>Register中。
@<reg> - 回放<reg>中的宏

----------------

偶来说几个(vim):
"*p, 把文本拷贝到系统剪贴板, 可以在别的程序窗口中粘贴

计算器^^:
(例):在插入模式下输入 35*45=CTRL_R=35*45回车,结果为35*45=1575
(输入CTRL_R=后光标会跳到底行,应继续输完,你也可以在此输入
任意四则运算)

快速复制上一行(或下一行):
(插入模式下)输完一行后回车,在下面一行按住CTRL_Y不放,直到复制完上一行^^
CTRL_E为复制下一行;

快速插入已输入过的单词:
(例):如果已经在文本中输入过hello, 再次输hello的时候,在输到he的时候
按CTRL_P就可补全hello, CTRL_N为向后搜索。

格式化程序段:
假如你拿到别人的c代码,里面没有代码缩进怎么办?
首先确保你的vim cindent选项打开了(:set cindent) ,
然后在命令模式下按 gg=G 就全部缩进好了。

----------------

保存退出 :x

#vi +10 program.c
直接转到文件第十行

----------------

交换两个字符位置
xp
上下两行调换
ddp
把文件内容反转
:g/^/m0/

----------------

:X
然后系统会提示输入密码
输入密码后存盘退出
下次编辑时请使用
vi -x filename
系统会提示你输入密码

----------------

:set nu 在每行行首加上行号
:set nonu 和上面的相反

----------------

:!command       暂时退出vi并执行shell指
令,执行完毕后再回到vi。
:sh          暂时
退出vi到系统下,结束时按Ctrl + d则回到vi。

vi filename      进入vi并读入指定名称的文件(
新、旧文件均可)。
vi +n filename    进入vi并且由文件的第几行开始。
vi +filename      进入vi并且由文件的最后一行开始。
vi + /word filename  进入vi并且由文件的word这个字开始。
vi filename(s)     进入vi并且将各指定文件列入名单内,第一个
文件先读入。

----------------

vi -r filename 恢复被毁坏的文件

----------------

在查找、替换命令 使用以下正则表达式元字符,功能强大。
也可用在:g/命令中

& 代表最近匹配串
~ 代表最近替换串
. 任一字符
^ 行首 或 表示 非
$ 行末
\< 词首
\> 词尾
* 0次或多次
\( \) 分节指定与其中正则式匹配的部分,在替换时候可以用 \1 \2 \3 ... 引用匹配部

[] 表示选择
- 表示范围 ,例如 [0-9]代表数字,[a-z]代表小写字母 [^0-9a-zA-Z] 代表非数字和大小
写字母
\{m,n\} 前面部分的从 m 次 至 n 次出现,m n 为数值
\{m\} 精确m次出现
\{m,\} 大于等于m次出现

以下举几例子,欢迎大家提出问题来共同探讨。
1.在20列后插入串
:%s/^.\{20\}/&insert something here/g

2.把C++语言里 //注释 修改为 /* */ 格式
:%s/\/\/\(.*\)$/\/\*\1\*\//g

3.在建存储过程的sql文本里,在每个create procedure procname()
前加上drop procedure procname ; [ ]里输入的是一个空格和TAB键。
:%s/^[ ]*[cC][rR][eE][Aa][tT][eE][ ]*[pP][Rr][oO][cC][eE][dD][uU][rR][eE][ ]*
\([^(]*\)/drop procedure \1;Ctrl_VCtrl_Mcreate procedure \1/g


----------------

数字加减, CTRL-A, CTRL-X

----------------

vim里自动缩进一段
把光标移动到某个花括号,
按 =% 缩进整段。
把整段不按格式往外缩一个tab
>%
缩两个
>>%
往里缩
<%

注意%匹配很多东西,
如果你想从
#ifdef
缩到
#endif
也可如此

1. * (super star)
向下查找光标下(或附近)的<word>。向上找用#。g*查找则不限制whole word。

2. C-R (magic insert)
在insert模式下,C-R (register) 插入register里的内容,一个有趣的reg是"=".
假设你想输入123K的具体字节数,不用打开计算器,试试这个“<C-R>=1024*123<CR>”,
“125952”就出来了!
另外在命令行里C-R C-W和C-R C-A是必用的技巧,它们将光标下的<word>和<WORD>
考到命令行里,省了你无数的typing。

3. C-X (auto complete)
在insert模式下,C-X C-P/N/L/F等自动完成前面的词、行、文件名等,是编程时必用的
命令。其中C-P和C-N可以不用C-X。

4. [p & ]p (smart paste)
paste同时自动根据目标行的缩进调整来源行的缩进。在copy代码段的时候非常有用。

5. C-O (fast out, fast in)
在insert模式下,用C-O后可以执行一个normal命令,然后立即返回insert模式,省去了
用ESC的麻烦。

6. [I (fast grep )
[I显示文件中包含光标下<word>的所有行。我常用来浏览某个id在程序中的引用情况。
还有很多相关的命令::h include-search

vi在使用查找中如何忽略大小写

/searchword\c

vi同时编辑多个文件

vi file1 file2
:n 切换到文件2 (n=next)
:e# 或 :N 切换回文件1

也可以在一个窗口下打开多个文件的。
先打开一个文件,vi 文件名,然后在vi的命令输入状态下输入 :sp 另外一个文件的路径及文件名
如此就可以在一个窗口打开多个文件了。
或者用 vi -o file1 file2 file3....用分割屏幕窗口方式同时打开多个文件。
可以使用 ctrl + 两次按 w 或者ctrl w 然后按上下键在上下窗口间切换

my .vimrc

,

set fileencodings=utf-8,cp936,big5,latin1
set encoding=utf-8
set termencoding=cp936
set fileencoding=utf-8

set ts=4 ht=4 sw=4
set background=dark

vim reference

Vi IMproved (VIM) 是 Bram Moolenaar 开发的与 UNIX 下的通用文本编辑器 vi 兼容并且功能更强大的文本编辑器. 文本文件的编辑在计算机使用中简直就像吃饭一样平常, 对于程序员和系统管理员来说更是必不可少. 能编辑文本文件的程序很多, 但能像 VIM 功能那样强大的我想就不多了. 对于写程序来说 VIM 更是最适合不过.

VIM 几乎可以运行在"任何"操作系统之上, 包括我们常用的 DOS, Windows 和 UNIX/Linux. 目前, 大多数的 Linux 分版都带有 VIM, 它的源程序以及其它操作系统的版本也可以很容易地从它的主页上自由下载. 你可以访问 VIM 的主页以获得更多的信息.

尽管 VIM 功能十分强大, 但对于刚接触它的人尤其是用惯 DOS 的 EDIT 的人来说, VIM 并不十分易于掌握, 毕竟它兼容的是 vi 而不是 EDIT. 本文旨在介绍 VIM 中我所了解的用法, 希望有更多的人喜欢 VIM. 应该指出的是, VIM 中有太多的功能和命令, 有许多你并不用的着, 因此没有记得必要, 有些我也不知道, 这要靠你来发现, 关键是多看"help", 多试.

1. vi 的基本用法
vi 的屏幕区域分为两个部分: 最下面一行是命令行, 一般用于提示信息或命令行输入; 除此之外为正文显示区域. 跟 EDIT 不同的是, vi 中存在三种模式: 普通(Normal)模式, 插入(Insert)模式, 可视(Visual)模式.

进入 vi 后缺省即为普通模式. 新手一般初次进入 vi 后就狂敲一串字符, 结果发现 vi 一连串莫名其妙的反应. 其实, 在 vi 的普通模式下, 任何按键包括普通字符都表示某个命令, 并不表示在当前光标处插入字符. 常用的命令有: (注意区分大小写)

: 进入命令行
i 或 a 进入插入模式. 区别是: i 进入插入模式后的光标在当前字符前面, a 进入插入模式后的光标在当前字符后面
v 进入可视模式
h, j, k, l 分别是光标左移, 下移, 上移, 右移 (一般来说你不会用到它来移动光标, 按方向键就可以了)
x 删除一个字符
dd 删除一行
J 删除本行的回车符, 也就是把下一行并入本行末尾
r字符 替换光标所在字符为新字符
p 或 P 在当前位置粘贴剪贴板的内容, p 粘在光标所在字符后面, P 粘在前面
数字G 移动光标到第若干行, 如果直接按 G 则移动到最后一行

在普通模式中, 命令以按键形式输入. 而在命令行中, 命令以字符串形式输入. 下面是常用的命令行:

:q 退出! (更确切的说应该是关闭当前文件)
:w 文件名 存盘. 如果还是保存为当前文件名, 那么文件名不必写
:wq 存盘退出
:n 文件名 打开或新建文件(同时关闭当前文件). 如果不指定文件名或者文件名不存在则是新建文件
:help 帮助! 看完后用 :q 关掉窗口. 可以在 help 后面加某个帮助主题的名称, 如 :help dd 和 :help help

还有一点是, 如果某个命令得到警告(拒绝执行), 则要在命令的命令词后加叹号表示强制执行. 比如你修改过文件, 但又想放弃存盘并退出, 如果输入 :q, vi 会告诉你文件已修改, 这时, 你只能输入 :q! 退出. 又如用 :w! a.txt 表示把当前文件存为 a.txt 而不管 a.txt 是否已经存在.

插入模式就不用多说了, 添加你的新内容吧. 不过, 你也许会发现 BackSpace 健和 Delete 健的运用很受限制, 也不能像 EDIT 那样选择, 复制和粘贴. 这些都是由于这是 vi 的标准, 后面我们将看到 VIM 扩展的功能可以解决这些问题. 记住按 ESC 退出插入模式, 回到普通模式.

可视模式其实跟"可视"没有太大联系, 更确切的应该称为选择模式. vi 里对复制粘贴的问题是这样解决的: 首先在普通模式下移动光标到要选择的文本块开头, 然后按 v 进入可视模式, 再移动光标到要选择的文本块末尾(注意光标所在字符是包含在块中的), 现在你有几种选择: 按 y 复制到剪贴板, 按 x 剪切到剪贴板, 按 d 删除. 当你输入了其中一条命令后, vi 将会回到普通模式, 这时你可以按 p 或 P 粘贴. 在 vi 中复制粘贴需要切换模式, 因此挺麻烦. 后面我们将利用 VIM 扩展的功能解决这个问题.

2. VIM 的定制
VIM 在 vi 的基础上扩展了许多功能和命令, 但是这些功能缺省是关闭的. 为了使用这些功能, 我们需要编写一个 vimrc 文件. 在 DOS/Windows 版本的 VIM 中, 这个文件应放在 VIM 的目录下, 文件名为"_vimrc". 在 UNIX 版本 的 VIM 中, 这个文件一般可以放在用户的个人主目录下, 文件名为".vimrc". VIM 启动时将会把 vimrc 文件中的每一行作为命令行依次执行, 我们可以在该文件中加入若干命令, 使 VIM 启动时自动开启一些有用的功能, 定义一些常用的快捷键等.

你的 VIM 安装目录下很可能已经带有一个缺省的 vimrc 文件, 它在某些方面也许比下面我所介绍的设置要好用, 你可以互相参考.

下面是一个 vimrc 文件的示例: (请注意区分浏览器的换行与实际的换行.)

" 设置 Backspace 和 Delete 的灵活程度, backspace=2 则没有任何限制
set backspace=2
" 设置在哪些模式下使用鼠标功能, mouse=a 表示所有模式
set mouse=a
" 设置路径, 在 f 等命令中涉及此参数
" 对于 Windows95 编程, path 可设为如
" set path=.,"C:\Program Files\Microsoft Visual Studio\vc98\Include",,
" 对于 UNIX 编程, path 可设为如下
set path=.,/usr/include,/usr/include/qt,,
" 打开光标的行列位置显示功能
set ruler
" 设置跳格距离
set tabstop=4
" 设置自动缩进格数
set shiftwidth=4
" 打开自动缩进功能
set smartindent
" 设置哪些键可以行间绕转, 如下设置则 Backspace 和方向键等均可行间绕转
set whichwrap=b,s,h,l,<,>,[,]
" 根据当前文件语法自动变色. VIM 识别上百种文本文件的语法, 如 html, c++, java 等
syntax on
" 以下定义 等键, 解决 vi 复制粘贴的困难
vnoremap y "ryi vnoremap x "rxi
vnoremap d di
imap :if col(".")!=1 exe 'normal "rp'elseexe 'normal "rP'endif`[i
nmap "rP
imap :if col(".")!=1 exe 'normal lv'elseexe 'normal v'endif
nmap v

根据以上定义, 复制粘贴可以这样完成: (在普通或插入模式下)首先移动光标到要选择的文本块开头, 然后按 自动切换到可视模式, 再移动光标到要选择的文本块末尾, 按 y 复制到剪贴板, 按 x 剪切到剪贴板, 按 d 删除. 当你输入了其中一条命令后, vi 自动回到插入模式, 这时你可以按 粘贴. 以上操作无需按 Esc 回到普通模式, 因此比 vi 中方便.

上面所述仅仅是解决复制粘贴问题的方法之一, 是我所习惯的一种方法. 其实, 你还可以尝试以下方法, 它们均无须进行多次模式切换:
1) 插入模式下按 Ctrl+O 再按 v 即可进入可视模式, 或者按 Ctrl+O 再按 P 或 p 即可粘贴. Ctrl+O 的详细用法请见后.
2) 命令 :behave mswin 可以使用 EDIT 风格的按键, 如 Shift+方向键 选择等, 详细情况请看帮助.
3) 肯定还有其它方法. :-)


这里是我常用的 .vimrc (3K) 文件, 你可以参考一下. 如果遇到没有见过的命令或者参数, 可以自己看看"help".

3. VIM 的其它命令
要真正使用 VIM, 光靠 vi 的基本命令当然不行啦, 下面就来介绍更多的命令. 以下的命令, 有些是 VIM 特有的, 有些在 vi 中也存在, 我就不加区分了. 其中, 以":"开头表示该命令在命令行输入, 以"i"开头表示这是插入模式下的命令, 其它则是普通模式下的命令. 表示按 Ctrl+X.

3.1 使用帮助
在 :help 中, 遇到超连接可以按 Ctrl+] 跳转 
在 :help 中, 按 Ctrl+T 往回跳转 

3.2 打开多个文件

:split 文件名 切分出一个新窗口, 打开指定文件. 如果省略文件名, 则仍显示当前文件, 可用于同时观察文件的不同部分.(注意跟 :n 的区别)
f 切分显示光标所指的文件名, VIM 会在 path 中搜索该文件名, 比如常用它打开 #include 语句中的文件
当同时打开几个文件时, 按 在各窗口之间切换
_ 当同时打开几个文件时, 按 _ 使当前窗口最大化
:set scrollbind 设置卷动绑定属性. 所有设置了卷动绑定属性的窗口将一起卷动. 可以用 :set noscrollbind 解除绑定

3.3 撤销和恢复
编辑过程中出现错误在所难免, 不过没有关系, VIM 允许无限次的撤销. 只要你没有关闭文件, 你甚至可以一直撤销下去, 回到几个小时以前刚打开这个文件开始工作时的状态.

u 撤销(Undo)上次所做的修改
恢复(Redo)上次撤销的内容

3.4 字符串搜索替换

/字符串 向下搜索字符串
?字符串 向上搜索字符串
*, # 向下和向上搜索光标所指的词
n 重复上一次搜索
:起始行,结束行s/搜索串/替换串/g 从起始行到结束行, 把所有的搜索串替换为替换串
:set ignorecase 设置忽略字母大小写. 可以用 :set noignorecase 取消忽略字母大小写

例如 /hello 从当前光标位置开始向下搜索 hello, 不带字符串的命令 / 可重复上一次搜索, 相当于 n. 又如 :1,$s/hello/hi/g 把全文中的 hello 改为 hi, 其中 $ 表示最后一行. 另外, 你还可以先进入可视模式选择一段文本, 按 : 并输入 s/hello/hi/g , VIM 将在选中段中进行替换操作.

搜索字符串用的是正规表达式(Regular expression), 其中许多字符都有特殊含义:

\ 取消后面所跟字符的特殊含义. 比如 \[vim\] 匹配字符串"[vim]"
[] 匹配其中之一. 比如 [vim] 匹配字母"v", "i"或者"m", [a-zA-Z] 匹配任意字母
. 匹配任意字符
* 匹配前一字符大于等于零遍. 比如 vi*m 匹配"vm", "vim", "viim"....
\+ 匹配前一字符大于等于一遍. 比如 vi\+m 匹配"vim", "viim", "viiim"....
\= 匹配前一字符零遍或者一遍. 比如 vi\=m 匹配"vm"或者"vim"
^ 匹配行首. 例如 /^hello 查找出现在行首的单词 hello
$ 匹配行末. 例如 /hello$ 查找出现在行末的单词 hello
\(\) 括住某段正规表达式
\数字 重复匹配前面某段括住的表达式. 例如 \(hello\).*\1 匹配一个开始和末尾都是"hello", 中间是任意字符串的字符串

对于替换字符串, 可以用"&"代表整个搜索字符串, 或者用"\数字"代表搜索字符串中的某段括住的表达式.

举一个复杂的例子, 把文中的所有"abc......xyz"字符串替换为"xyz......abc"可以有下列写法:
:%s/abc\(.*\)xyz/xyz\1abc/g
:%s/\(abc\)\(.*\)\(xyz\)/\3\2\1/g
其它关于正规表达式搜索替换的更详细准确的说明请看"help".

3.5 插入补全
在插入模式下, 为了减少重复的击键输入, VIM 提供了若干快捷键, 当你要输入某个上下文曾经输入过的字符串时, 你只要输入开头若干字符, 使用快捷键, VIM 将搜索上下文, 找到匹配字符串, 把剩下的字符补全, 你就不必敲了. 这样, 编程序时你起多长的变量名都没关系了, 而且还可以减少输入错误. 我认为, 插入补全是 VIM 最为突出的一项功能.

i 向上搜索, 补全一个词. 例如, 上文中出现过 filename 这个词, 当你想再输入 filename 时, 只要按 f 即可. 假如 VIM 向上搜索, 找到以 f 开头的第一个匹配不是 filename, 你可以继续按 搜索下一个匹配进行补全. 当然, 如果你想一次 就成功, 你可以多输入几个字符比如 filen 再按 补全
i 向下搜索, 补全一个词
i 补全一行. 比如你写过一行 for (int i=0;i<100;i++), 你想再写一模一样的一行, 只要输入 for 即可. 如果补全出来的不是你想要的那一行, 你可以按 或 选择上一个或下一个匹配行
i 在文件系统中搜索, 补全一个文件名

如果按 或 补全一个词, 在当前文件中没有找到匹配, VIM 将搜索 #include 语句中的文件, 而文件的位置将在 path 中搜索.

3.6 键的定义
在 VIM 中你可以定义一个键, 按了这个键等于按了某一串预定的键. 比如
:map! ddi
表示如果你在插入模式下按 就相当于连续按了 ddi, 这将会使 VIM 退回到普通模式, 删除一行, 再进入插入模式.

map 命令有许多变化形式, 每种变化形式所定义的键只在某些模式下有效, 而在其它模式下无效. 你需要根据情况使用正确的变化形式:

:nmap 键只对普通模式有效
:imap 键只对插入模式有效
:vmap 键只对可视模式有效
:cmap 键只在命令行下有效
:map 键在普通模式和可视模式都有效
:map! 键在插入模式和命令行下都有效

还要注意, 如果你定义 :map d di 这将引起循环定义错误. 这时, 你需要使用 :noremap d di 来定义. 同样, noremap 也有对不同模式的变化形式.

比如, 你想在文件的每一行的倒数第二个字符处插入字符串"abc", 你可以定义
:nmap $hiabcj
在普通模式下按一次 将会: 光标移到行末, 光标左移一格, 进入插入模式, 输入"abc", 退回到普通模式, 光标下移一行. 不停地按 将解决问题. 这是我编程时临时处理多行重复操作的常用手段, 当然, 这是一种笨办法. :-) 而上文写到的对 的定义则是 map 更复杂的用法. 你还可以定义
:map :w:!gcc -o %< -I/usr/include/qt -lqt %
:map :!./%<
实现按 编译当前文件, 按 执行.

在插入补全当中提到的补全一行需要按 , 如果你觉得麻烦, 你可以定义
:inoremap
减少击键次数. 同样, 对 也可以作类似定义.

3.7 其它命令

:!命令行 执行一条外部命令
. 在光标当前位置处重复上一次操作
i后续字符 输入特殊的 ASCII 字符或键. 除了插入模式外, 也适用于命令行. 后续字符可以是键盘上的任意键, 也可以是三位的十进制数字表示字符的 ASCII 码. 具体细节请自己尝试, 或者看"help".
i命令 执行一个普通模式的命令, 执行完毕后回到插入模式
i 跳转到光标所指标识符的定义行. 比如你在编程时遇到一个函数 CreateWindow, 想看它的定义语句, 你就可以在它上面按 i, VIM 将打开新窗口, 把光标移到它定义的地方. 当然, 前提是在当前文件或它的 #include 文件中存在 CreateWindow 的定义. 这也牵涉到 path 的设置. 不过, VIM 找得不一定很准
K 看光标所指标识符的 man 帮助页
i 把上一行对应列的字符抄下来
i 把下一行对应列的字符抄上来(写这一行时我就用了 )
光标所指整数加一
光标所指整数减一
光标返回到以前的位置. 相当于光标移动的"撤销"
:X 对当前文本文件加密

4. VIM 6.0 的一些新特性
2001 年 9 月 26 日发布的 VIM 6.0 增加了一些以往没有的新特性. 下面仅仅是一些简单的介绍, 更详细的描述请自己看"help".

打开目录
在 VIM 6.0 中, n 和 split 等命令不但可以打开普通文件, 还可以打开目录. 一个目录打开以后将列出里面的文件信息, 可以按回车继续打开相应的文件或者子目录, 也可以按 ? 得到其它目录操作(修改文件名, 删除文件等)的帮助.

折叠
当一个文本太长而你又对其中很长一大段内容不关心的话, 可以把你不关心的那些行折叠起来, 让它们从你的视线中消失. 被折叠的行将以一行显示代替, 例如:
+--217 行: 2. VIM 的定制---------------------
折叠可以有多种方式控制, 可以通过设置 foldmethod 选项的值来改变. 缺省情况下 foldmethod=manual 为手工折叠. 下面介绍几个使用折叠的最简单的命令:

vzf 手工创建折叠. 在可视模式下选择一段文本, 然后按 zf 可以手工创建一个折叠
方向键左或右 打开折叠. 普通或插入模式下, 在折叠行上横向移动光标将打开被折叠的行
zc 关闭折叠


垂直切分窗口

:vsplit 文件名 垂直切分窗口. 跟 :split 命令相似, 但新窗口与原窗口左右并列.


更多的正规表达式
VIM 6.0 比以前增加了许多新的正规表达式, 其中我认为最有用的是换行匹配符 \n. 以前的版本中, 正规表达式只能在同一行上匹配. 现在, 只要显式地给出 \n , 正规表达式可以跨多行.

diff 模式
专门用于比较编辑两个或多个内容相近的文件的模式. 一般来说, 比如你要比较编辑 A 跟 B 两个文件, 你可以这样: 先打开文件 A, 然后 vsplit 打开文件 B, 对文件 A 和 B 都输入命令 :diffthis. 这时 VIM 将非常清晰的对比显示出两个文件的不同之处, 编辑起来十分方便.

仔细一看, 这个 diff 模式动用了 VIM 许许多多的特性, 包括垂直切割, 滚动绑定, 折叠和语法变色等等. 好高级啊!

我所熟悉的 VIM 的功能已经介绍得差不多, 剩下的要靠你自己来学习了. 其实, VIM 的功能还有很多很多. 还是那句话, 多看"help", 多试. VIM 的帮助还是挺容易看的, 相信你看了以后会有更多的惊喜. 如果你有什么心得或者新发现, 欢迎跟我讨论. 最后, 向大家推荐一个去处: vim online. 那有一些 VIM 的脚本和插件, 还有不少有用的技巧提示.


6.0 - 依字母顺序的vi快速参考
... 是指有些东西需要在命令之前或之后指明.这通常是说光标的移动键
(h,j,k,l,w,b等等)或者是指行号.
# (这里#代表一个数字) 执行n次后面的命令...
: 进入ex模式
) 下一句
( 上一句
} 下一段
{ 上一段
]] 下一节
[[ 上一节
0 行的开头
$ 行的末尾
^ 行的第一个非空白字符
+ 下一行的开头
- 上一行的开头
(空格) 下一个字符
(回车) 下一行
/ 向前搜索
? 向后搜索
% 查找当前小(中,大)括号的匹配字符
, 逆向重复上一个f,F,t或T操作
; 重复上一个f,F,t或T操作
. 重复上一个操作
` 转到标记处
转到标记所在行的开头
`` 查找前回到上一个做标记的地方
\ 查找前回到上一个做标记所在行的开头
~ 切换字符的大小写
" 保存到寄存器中
!! 重复上一次SHELL命令
! 把后面的文本送给命令, 取代输出(例如, !}fmt把当前的段落
送给命令fmt处理,然后用fmt返回的东西替换输出.)
>> 右移当前段落一个移动宽度(shiftwidth)
<< 左移当前段落一个移动宽度(shiftwidth)
>% 从当前到匹配小(中,大)括号之间的文本右移
<% 从当前到匹配小(中,大)括号之间的文本左移
(似乎漏了一个符号|, 移动到某一列----译注)
a 在当前位置之后添加
A 在当前行的末尾添加
^a 没有使用
b 上一个单词的开头
B 上一个单词的开头,忽略标点符号
^b 上移一屏
c 覆盖...
C 覆盖到行末尾
^c 终止插入模式,在命令模式没有用
d 删除...
D 删除到行末尾
^d 下移半屏,如果在插入模式下则移到上一个移动宽度(ShiftTab)处
e 单词的末尾
E 单词的末尾,忽略标点符号
^e 屏幕下卷一行
f 查找...
F 向后查找...
^f 下移一屏
g 未用
G ...跳至[缺省是到文件末尾]
^g 显示状态栏
h 左移
H 屏幕上的第一行
^h 在插入模式下是退格,命令模式下是左移
i 在当前的位置前面插入
I 在本行的第一个非空白字符前面插入
^i 插入模式下是制表键,命令模式下未用
j 下移
J 把下一行合并到本行
^j 命令模式下是下移,插入模式下是建一个新行
k 上移
K 未用
^k 未用
l 右移
L 屏幕中的最后一行
^l 重绘屏幕
m 把当前位置标记到寄存器中
M 屏幕的中间行
^m 回车
n 重复上次查找
N 逆向重复上次查找
^n 命令模式下是下移
o 在当前行的下面建一个新行
O 在当前行的上面建一个新行
^o 未用
p 在当前行的下面粘贴
(译注--应为在当前位置的后面粘贴)
P 在当前行的上面粘贴
(译注--应为在当前位置的前面粘贴)
^p 命令模式下是上移
q 未用
Q 退出并且启动ex
^q 未用
r 覆盖当前的字符
R 在插入模式下一直覆盖字符
^r 在命令模式下面重绘屏幕
s 替换
S 替换整行
t 到...
T 向后到...
^t 移到下一个移动宽度(shifttab)处
u 撤消上一次操作
U 撤消对本行的所有修改
^u 上移半屏
v 未用
V 未用
^v 未用
w 下一个单词的开头
W 下一个单词的开头,忽略标点符号
^w 命令模式下未用,在插入模式下是到上一个单词的开头处
x 删除当前字符
X 删除前一个字符
^x 未用
y 复制...
Y 复制整行
^y 屏幕上卷一行
z 重新配置当前行周围的屏幕
ZZ 保存之后退出
^z 未用
(译注--在命令模式下,^z执行了UNIX暂停操作



6.1 - 命令模式的输入选项(:命令)
(注: 这不是一个规范的列表,, 我只是列出了一些最重要的命令)
:r <文件> 把<文件>读入到当前文档
:r !<命令> 把<命令>的输出插入到当前文本中
:nr <文件> 把<文件>插入到第n行
:!<命令> 运行<命令>,然后返回
:sh 转到SHELL
:so <文件> 读取<文件>,再执行文件里面的命令
(译注--文件中的命令应该都是一些ex命令)
:x 保存之后退出
:wq 保存之后退出
:l1,l2w <文件>把第l1和第l2行之间的文本写到<文件>中去,如果没有指定<文件>,
vi就假定是当前文件,如果没有指定l1,l2,就假定是整个文件(就成了:w)
:w >> <文件> 添加到<文件>末尾. 也可以使用行号
:w! 覆盖当前文件
:q 退出
:q! 不存盘就退出
:e <文件> 不离开vi编辑<文件>
:e! 重新编辑当前文件,忽略所有的修改
:n 编辑下一个文件
:e +n <文件> 从第n行开始编辑<文件>,如果超过了末尾,就从末尾开始编辑
:e# 编辑替换文件(如果使用了命令:e<文件>,替换文件就指的是原始文件)
:args 显示所有要编辑的文件
:rew 重新回到第一个编辑的文档
:map m n 创建一个宏(使 m 做 n)
:map! m n 创建一个插入模式的宏(使 m 做 n)
:unmap m 删除宏m
:unmap! m 删除插入模式的宏m
:ab <1> <2> 缩写,敲<1>的时候用<2>取代
:unab <1> 取消缩写<1>
:set <选项> 设置<选项>...

6.2 - 设置选项(set)
可以使用括号中的缩写形式. 语法:
:set <选项> <参数> (如果需要参数的话)
也可以在一行中指定多个选项
:set <选项>? 显示出当前这个选项的参数值
:set all 则显示所有的选项值
对那些无须参数的选项来说,使用:set no<选项>就可以把它给关了


选项: 缺省值: 含义:
autoindent (ai) noai 使新行自动缩进,和上(下)行的位置对齐
autoprint (ap) ap 每条命令之后都显示出修改之处
autowrite (aw) noaw 在:n,:!命令之前都自动保存文件
beautify (bf) nobf 在输入的时候忽略所有的控制字符
(除了制表键(tab),换行(newline),进纸(formfeed))
directory= (dir=) /tmp 存放缓冲区的目录名
edcompatible noedcompatible 在替换的时候使用类ed的用法
errorbells (eb) errorbells 出错的时候响铃
exrc (ex) noexrc 允许在主目录(home)外面之外放.exrc文件
hardtabs= (ht=) 8 设置硬制表的边界
ignore case (ic) noic 正规式里忽略大小写
lisp nolisp 打开lisp模式
list nolist 显示所有的制表键和行的结尾
magic magic 可以使用更多的正规表达式
mesg mesg 允许向终端发送消息
number (nu) nonumber 显示行号
open open 允许开放和可视化
optimize (opt) optimize 优化吞吐量,打印时不发回车
paragraphs= (para=) IPLPPPQPPLIbp 设置{ & }的分界符
prompt prompt 命令模式下的输入给出:的提示符
readonly (ro) noro 除非用!号否则不准保存文件
redraw noredraw 当编辑的时候重绘屏幕
remap remap 允许宏指向其他的宏
report= 5 如果影响的行数>这个数的话就报告
scroll 1/2 window 下卷屏幕时滚动屏幕的数目,
同样这也是z命令输出的行数(z 输出2倍滚屏的大小)
sections= SHNHH HU 定义节的末尾(当使用命令[[ 和 ]] 时)
shell= (sh=) /bin/sh 缺省的SHELL,如果设置了环境变量SHELL的话,就使用变量
shiftwidth= (sw=) 8 当使用移动(shift)命令时移动的字符数
showmatch (sm) nosm 显示{, }, (, ), [, 或者 ] 的匹配情况
showmode noshowmode 显示你处在什么模式下面
slowopen (slow) 插入之后不要立刻更新显示
tabstop= (ts=) 8 设置制表停止位(tabstop)的长度
taglength= (tl=) 0 重要标记的字符个数(0表示所有的字符)
tags= tag, /usr/lib/tags 定义包含标记的文件路径
term= 设置终端类型
terse noterse 显示简短的错误信息
timeout (to) timeout 一秒钟后键盘映射超时
ttytype= 设置终端类型
warn warn 显示"No write since last change"信息
window= (w=) 可视模式下窗口的行数
wrapmargin= (wm=) 0 右边距,大于0的话最右边的单词将折行,留出n个空白位置
wrapscan (ws) ws 查找到文件尾后再重头开始
writeany (wa) nowa 可以保存到任意一个文件去
December 2009
S M T W T F S
November 2009January 2010
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31