2009年3月28日星期六

肚包肉

在美丽的枣林前街上,临近牛街的路北,牛街西里一栋居民楼底层,有一家小小的餐厅,叫“雅伊斋清真食品”店。这里,潜藏着号称北京独此一家的清真熟食品种——“肚包肉”。

“肚包肉”这名字,相当容易顾名思义——就是外面一层羊肚,里面密密实实地裹压着羊肉和羊杂,成品是那么一坨子,吃的时候,切成薄片,口感略略有些筋道。

好吃。

来自洛阳的店家说,家里自己做着吃了几十年,在朋友的建议下在京尝试商业化。

有空的时候去尝尝……




2009年3月26日星期四

SQL Server 2008导出数据到Access Excel2007的简单方法

SQL2008提供了强大的SSIS功能,但是操作起来比较复杂,而且避免不了需要数据驱动的问题
本文给出一种简单方法,可以简化操作过程。

SQL2008支持Office2007的数据格式,但是需要安装驱动,要么就要安装Office2007,这个动作从成本角度来说,是费时费钱的,(安装和正版Office授权)。
微软提供了访问驱动包
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7554f536-8c28-4598-9b72-ef94e038c891

http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463960fdcdb/AccessDatabaseEngine.exe

安装了该包以后,从SQL2008导出到Office2007的操作就很容易了。

在SSMS的数据库节点上选中导出数据,指定office格式即可。

2009年3月21日星期六

Internet Explorer 8 的键盘快捷键

Internet Explorer 8 的键盘快捷键

可以使用 Internet Explorer 快捷键快速执行许多不同任务,或在不使用鼠标的情况下正常操作。

查看和浏览网页
下表描述了用于查看和浏览网页的快捷方式。


操作
按键名称

显示帮助
F1

在全屏幕和常规浏览器窗口之间进行切换
F11

在网页、地址栏或收藏夹栏中的项目中向前移动
Tab

在网页、地址栏或收藏夹栏中的项目中向后移动
Shift+Tab

开始插入光标浏览
F7

进入您的主页
Alt+Home

转到下一页
Alt+向右键

返回前一页
Alt+向左键或 Backspace

显示某个链接的快捷菜单
Shift+F10

向前移动边框和浏览器元素(仅在禁用选项卡式浏览时有效)
Ctrl+Tab 或 F6

在边框之间向后移动(仅在禁用选项卡式浏览时有效)
Ctrl+Shift+Tab

向文档起始处滚动
向上键

向文档结尾处滚动
向下键

以较大跨度向文档起始处翻页
Page Up

以较大跨度向文档结尾处翻页
Page Down

移动到文档的开头
Home

移动到文档的结尾
End

在网页中查找
Ctrl+F

刷新当前网页
F5

即使 Web 上的页面与本机存储的网页时间戳相同,仍然 刷新当前网页
Ctrl+F5

停止下载网页
Esc

打开新网站或页面
Ctrl+O

打开新窗口
Ctrl+N

打开一个新的 InPrivate 浏览窗口
Ctrl+Alt+P

复制选项卡(在一个新选项卡中打开当前选项卡)
Ctrl+K

关闭当前窗口(如果仅打开了一个选项卡)
Ctrl+W

保存当前页
Ctrl+S

打印当前页或当前框架
Ctrl+P

激活选定的链接
Enter

打开收藏夹
Ctrl+I

打开历史记录
Ctrl+H

打开源
Ctrl+J

打开“页面”菜单
Alt+P

打开“工具”菜单
ALT+T

打开“帮助”菜单
ALT+H


使用选项卡
下表描述了使用选项卡时所使用的快捷方式。

操作
按键名称

在后台打开新选项卡中的链接
Ctrl+单击

在前台打开新选项卡中的链接
Ctrl+Shift+单击

在前台打开新选项卡
Ctrl+T

切换选项卡
Ctrl+Tab 或 Ctrl+Shift+Tab

关闭当前选项卡(或当前窗口,如果禁用了选项卡式浏览)
Ctrl+W

在前台从地址栏中打开新选项卡
Alt+Enter

切换到特定的选项卡号
CTRL+n(其中,n 是 1 到 8 之间的数字)

切换到上一个选项卡
Ctrl+9

关闭其他选项卡
Ctrl+Alt+F4

切换快速选项卡(缩略图视图)开关状态
Ctrl+Q


使用缩放功能
下表描述了用于缩放功能的快捷方式


操作
按键名称

放大 (+ 10%)
Ctrl+加号

缩小 (- 10%)
Ctrl+减号

缩放到 100%
Ctrl+0


使用搜索
下表描述了用于搜索功能的快捷方式


操作
按键名称

转到搜索框
Ctrl+E

在新选项卡中打开搜索查询
Alt+Enter

打开搜索提供程序菜单
CTRL+向下键


使用打印预览
下表描述了用于预览和打印网页的快捷方式。


操作
按键名称

设置打印选项并打印页面
Alt+P

更改纸张、页眉和页脚、方向和页面的页边距
Alt+U

显示要打印的第一页
Alt+Home

显示要打印的上一页
Alt+向左键

键入希望显示的页面的页码
Alt+A

显示要打印的下一页
Alt+向右键

显示要打印的最后一页
Alt+End

指定要如何打印边框(只有在打印使用边框的网页时 此选项才可用)
Alt+F

关闭打印预览
Alt+C


使用地址栏
下表描述了在地址栏上使用的快捷方式。


操作
按键名称

选择地址栏中的文本
Alt+D

显示已键入的地址的列表
F4

在地址栏中时,将光标向左移动到地址中的下一个逻辑断点(句点或 正斜杠)
Ctrl+向左箭头

在地址栏中时,将光标向右移动到地址中的下一个逻辑断点(句点或 正斜杠)
Ctrl+向右箭头

在地址栏中将“www.”添加到所键入文本的前面,将“.com”添加到所键入文本的 后面
Ctrl+Enter

在“自动完成”匹配项的列表中向前移动
向上键

在“自动完成”匹配项的列表中向后移动
向下键


打开 Internet Explorer 工具栏菜单
下表描述了用于打开 Internet Explorer 工具栏和命令栏菜单的快捷方式。


操作
按键名称

打开主页菜单
Alt+M

打开“打印”菜单
Alt+R

打开 RSS 菜单
Alt+J

打开“工具”菜单
Alt+O

打开“安全”菜单
Alt+S

打开“帮助”菜单
Alt+L


使用源、历史记录和收藏夹
下表描述了使用源、历史记录和收藏夹时所描述的快捷方式。


操作
按键名称

将当前网页添加到收藏夹中(或在源预览中订阅源)
Ctrl+D

删除浏览历史记录
Ctrl+Shift+Del

打开 InPrivate 浏览窗口
Ctrl+Shift+P

打开“整理收藏夹”对话框
Ctrl+B

在“整理收藏夹”对话框的收藏夹列表中向上移动所选项目
Alt+向上键

在“整理收藏夹”对话框的收藏夹列表中向下移动所选项目
Alt+向下键

打开“收藏中心”并显示收藏夹
Alt+C

打开“收藏中心”并显示历史记录
Ctrl+H

打开“收藏中心”并显示源
Ctrl+J

打开与插接“收藏中心”并显示源
Ctrl+Shift+J

打开“添加到收藏夹”菜单(或在源预览中订阅源)
Alt+Z

在菜单栏打开“收藏夹”菜单
Alt+A

显示所有源(当在源视图中时)
Alt+I

将源标记为可读(当在源视图中时)
Alt+M

将光标放到源视图的“搜索”框内
Alt+S


编辑
下表描述了在编辑网页时使用的快捷方式


操作
按键名称

删除所选项目并将其复制到剪贴板中
Ctrl+X

将所选项目复制到剪贴板
Ctrl+C

将剪贴板中的内容插入到所选位置
Ctrl+V

选中当前网页中的所有项目
Ctrl+A

打开 Internet Explorer Developer Tool
F12


使用信息栏
下表描述了使用信息栏时所使用的快捷方式。


操作
按键名称

将焦点移到信息栏
Alt+N

单击信息栏
空格键

Internet Explorer的前世今生

Internet Explorer最初是从早期一款商业性的专利网页浏览器Spyglass Mosaic衍生出来的产品。在1996年,微软透过给予季度费用和部分收入从Spyglass中取得了Spyglass Mosaic的授权。虽然Spyglass Mosaic的名字与NCSA Mosaic(首款应用得最广泛的网页浏览器)甚为相似,但Spyglass Mosaic则相对地较不出名以及使用了NCSA Mosaic少量的源代码。

Internet Explorer 3.0及之前版本

1995年8月,Internet Explorer第一个版本发布,但其最初几个版本并不受到广泛的使用,直到3.0版本的发行则开始改写了这个局面。3.0版本于1996年8月13日发布,是首个脱离Spyglass源代码发展的版本(但仍使用Spyglass的“技术”,所以程序的文件记录仍保留了Spyglass的版权资讯),它亦是首个支持CSS技术的主流浏览器。它引进了ActiveX控件、Java Applet、内联网页多媒体以及因特网内容选择平台系统对内容元数据的支持。对比于当时它的主要竞争对手Netscape Navigator,这些改进算是十分具代表性的。3.0版本亦捆绑了Internet Mail and News(为Outlook Express的前身)、NetMeeting及Windows Address Book,它亦缺省在Windows 95 OSR 2中。3.0版本被认为是Internet Explorer首个最受到欢迎的版本,但在发行后的数个月后亦被黑客发现了数个安全性和隐私漏洞。



Internet Explorer 4.0版本

4.0版本于1997年9月发布,它深化了浏览器和操作系统的整合层面,在Windows 95或Windows NT 4上安装4.0版本及选择视窗桌面更新功能可将传统式的Windows Explorer更新成与网页浏览器界面相似的新版Windows Explorer,用户亦可透过Active Desktop将网页浏览功能嵌入于视窗桌面上,可是这样的整合行为亦受到不少的批评(参见United States v. Microsoft案例),这个功能已在后期的版本安装中移除(但预先安装此功能的系统不会受到移除)。4.0版本引进了群组原则,允许公司设定和锁上浏览器的参数设置。Internet Mail and News被Outlook Express取代,Microsoft Chat和经改良的NetMeeting亦被捆绑在IE中。Windows 98 第一版亦包含了这个版本。



Internet Explorer 5.0及5.5版本

Windows 3.2简体中文版上的Internet Explorer 5.0版本于1999年3月18日发布,随后亦被捆绑在Windows 98 Second Edition和Windows 2000中(Windows 2000捆绑了5.01版本)。这个版本亦是另一个具代表性的发布,它引进了双向文字、旁注标记、XML、XSL及将网页储存成MHTML格式的功能。 5.5版本随后在2000年7月中发布,它改善了打印预览的功能、CSS及HTML标准的支持和应用程序编程接口。这个版本被捆绑在Windows Me中。



Internet Explorer 6.0版本

6.0版本于2001年8月27日发布,距Windows XP正式发布日的数星期前发布。这版本包含增强版DHTML、内联网页框架的内容限制和部分支持CSS level 1、DOM level 1和SMIL 2.0。MSXML引擎会更新到3.0版本。其他新的特征包含一个新版本的IEAK、媒体列和Windows Messenger综合版、错误收集、自动化重整图片大小、P3P和一个新的外观,能配合Windows XP的"Luna"界面。于2002年,Gopher的功能被禁用,7.0版本更取消了对Gopher的支持。



Internet Explorer 7.0版本

Windows Vista Beta 1上的Internet Explorer 7.0 Beta 1在2005年2月15日,微软主席比尔·盖茨于旧金山的RSA讨论会中,宣布新版本浏览器将会发布。推出新浏览器的原因是Internet Explorer的市场估有率逐渐被Mozilla Firefox侵蚀。此外,微软宣布7.0版本只可以用于Windows XP SP2和之后的操作系统中,包括Windows Server 2003 SP1和Windows Vista。Internet Explorer的第一个预览版本于2005年7月27日推出,主要用于技术测试。而第一个向大众的测试版本于2006年1月31日推出,版本是Beta 2 preview。最后的公开测试版本于2006年10月18日推出。7.0版本预期可以保护用户于钓鱼式攻击和其他的恶意软件。用户可以完全控制 ActiveX和更佳的保安架构,包括与Windows系统分开,不像以往般紧密融合,从而提高安全性。另外,新版本包括收复了一些程序中的错误,加强对各网际标准的支持,增进支持HTML 4.01/CSS 2,新加入分页浏览,还有一个支持各搜索引擎的搜寻方块,一个Web-feed阅览器,支持国际化域名,和反钓鱼式攻击过滤器。它甚至可以挡掉一些程序类型,例如Flash电影和Java。



2008年2月12日,微软以“安全原因”将通过Windows Server Update Services把所有Windows系统的浏览器强制升级到7.0版本。

Internet Explorer 8.0版本

北京时间2009年3月20日凌晨,微软向公众正式发布了Internet Explorer 8(IE8)浏览器。涉及包括中文简体、繁体等二十多种语言的版本。IE8浏览器中了最新的加速器、网页快讯、可视化搜索以及隐私浏览模式等新颖功能,而且IE8浏览器中还包含一个IE8百宝箱,为你的IE8浏览器提供了丰富的资源,不仅可以利用这些插件增强自己的IE8浏览器,有兴趣和能力的网友还能自己开发IE8插件与全球网民共同分享。

体验IE8

2009年3月20日 微软发布了IE8,当还有很多人还在使用IE6的时候,IE8已经横空出世,从IE6到IE7用了4年,到IE8只用了一年半时间,微软推陈出新的加速度确实让人佩服。

笔者在看到IE8出正式版的第一时间就下载安装到了自己的机器上。对宣传中的种种优点,开始了逐一体验,下面就为大家一一展开。当然,仅限于最终用户角度。

智能地址栏
智能地址栏让用户可以更方便地找到所需的网站。它可以高效地把历史记录、收藏夹中的标题同用户输入地址栏的内容进行匹配,而不会出现重复的情况。
当匹配到已经输入的地址之后,区别于传统IE显示地址的做法,IE8里显示的是以前访问过的对应地址的页面标题和地址,定位要打开的网址更准确了。
在地址栏上的内容也有些变化,会对域名高亮显示,或者说弱化其他信息。比如http://cityeremite.blogspot.com/,显示的blogspot.com是黑色的,而其他内容就是灰色。

标签显示
多了个收藏夹栏,非常类似国产某些浏览器,就是把收藏夹里的链接显示在这里,好像一行菜单一样,这样访问更直接了。
标签支持分组,即从一个页面打开的链接都会显示相同的颜色,顺序大概是绿色、蓝色、黄色、紫色……
菜单内容也比IE7丰富了很多,支持对标签组的操作,对选项卡也提供重新打开关闭了的选项卡功能,这个对不小心关闭的选项卡特别有帮助;选项卡仍然不支持鼠标双击操作,即不支持空白处双击为新键卡,选项卡上双击为关闭卡。
快捷键对新增加的功能也有全面支持,保留常用的Ctrl-T为新建卡,Ctrl-W为关闭当前选项卡之外,还增加了重新打开选项卡的Ctrl-Shift-T,并且这些快捷键不同于原来标注在顶行菜单的做法,而是标注在了选项卡的右键菜单上,这样对于推广这些快捷键的使用是非常有意义的。

增强的“页面内查找”:改进了人们在网页中搜索文本的方式。
页面内查找:按Ctrl+F或者在编辑菜单或即时搜索对话框中选择,即可开启页面内查找功能。工具条显示在用户的选项卡下面,因此不会阻碍页面上的任何文本。
结果数:强化的页面内查找功能会显示搜索词在页面中出现的次数。
结果高亮显示:强化的页面内查找功能让用户可以迅速找到搜索项目,因为搜索文本出现的所有地方都会高亮显示。

可视化搜索
基本就是原来中搜的划词搜索,在页面上选中一些内容,旁边就会浮现出搜索的按钮,省却了拷贝粘贴的动作,直接可以搜索了,确实方便一些。

加速器
乍看以为是在性能上有新技术,其实指的是方便性,支持多种IE小工具。
以前是通过软件实现的功能,现在是通过页面来的。比如我们安装FlashGet,在ie的右键菜单上增加了用Flashget下载的项目,而IE8的加速器是可以接入其他在线服务,比如翻译、地图查找、购物信息、天气等等。把互联网能提供的功能更容易的整合在了一起。


网页快讯
对那些喜欢上网看新闻的人来说更方便了,可以把我们几乎每天都要去关注的一些网站的栏目汇集到一起,比如:新闻追踪、体育赛况、购物竞拍、电视剧、邮件……
使用方法跟加速器定制差不多,在收藏夹栏上有网页快讯库按钮,打开后可以选择加载到你本机的网页快讯。
IE8会在你网络连通的状态下,自动更新你订阅的内容,这些都会增加后台进程的资源消耗。


稳定性问题
在之前的IE版本中,常有不慎打开了导致浏览器崩溃的页面,不管是IE7的选项卡还是之前版本的单独窗口,都会一起关闭。
这是源于早期版本的浏览窗口是基于线程的,从任务管理器里可以看到只有一个iexplore.exe,而从IE8开始,浏览窗口是基于进程的了,有一个统一的总进程管理。
通过Processor Explorer工具查看时,总进程是直接调用iexplore.exe打开的,而其他进程是后面跟参数调用的。
当你第一次打开IE的时候(之前系统里没有启动IE),这个进程就是总进程,以后增加的选项卡,都会增加进程,从任务管理器里看到的ie进程数量和选项卡数量不是完全匹配的,而且跟同时浏览的网站数量没有直接关系,所以,这块的算法不是很清楚。
不管怎样,当我们再碰到让浏览器崩溃的页面时,受影响的也仅有出错的选项卡,不会导致全部关闭了。

IE8还有其他新增功能,可以参考IE8的官方页面的介绍
http://www.microsoft.com/china/windows/internet-explorer/default.aspx

在众多新功能的鲜亮外衣之下,内存占用的大幅提升也给老机器用户带来了麻烦,对于加速器、网页快讯等等挂在IE8上的新内容,无一不是侵占资源的帮凶,在大家体验IE8的新特性的同时,需要好好平衡一下方便和速度。否则,越来越慢的上网速度会让你兴致全无。

2009年3月19日星期四

gVim基本操作方法汇总

看着网上的高人发布的关于gvim使用的帖子,不禁手痒,借着试用开源软件FreeMind的机会,将常用的gVim操作方法整理如下,基本可以满足初级菜鸟使用了。

2009年3月18日星期三

高效率编辑器 VIM-操作篇

高效率编辑器 VIM-操作篇,非常适合 VIM 新手
2007-01-27 Toy Posted in Featured, Text Editor, TutorialsRSSTrackback

虽然从很久前就开始用 VIM 了,但一直都是半调吊子,翻来覆去只用自己会的命令。最近为了提高书写代码的效率,还有 coding 时候的乐趣,又重新钻研了一下 VIM,发现了一篇很好的 VIM 入门的文章,原文是英文版的,我觉得非常适合 VIM 使用入门,所以翻译了过来。这里是简单的介绍了 VIM 的操作方式,并没有说为什么要用 VIM,如果你想知道答案可以去 Google,VIM 被誉为编辑器之神。

这篇教程写了在不同工作模式下使用 VIM 的一些基本技巧——即插入模式(insert mode), 命令模式(command mode), 存取文件等。目的是帮助刚刚接触 VIM 的新手更加有效率的使用这个出色的编辑器。

说明:在这篇文章里面, 代表 Ctrl + X——就是按住 Ctrl 键然后再按 X。而且你可以在很多情况下使用 :help command 来获得大部分命令的帮助,这个是 VIM 的内部帮助文件命令。

高效率移动

在插入模式之外

基本上来说,你应该尽可能少的呆在插入模式里面,因为在插入模式里面 VIM 就像一个“哑巴”编辑器一样。很多新手都会一直呆在插入模式里面,因为这样易于使用。但 VIM 的强大之处在于他的命令行模式!你会发现,在你越来越了解 VIM 之后,你就会花越来越少的时间使用插入模式了。

使用 h、j、k、l

使用 VIM 高效率编辑的第一步,就是放弃使用箭头键。使用 VIM,你就不用频繁的在箭头键和字母键之间移来移去了,这会节省你很多时间。当你在命令模式时,你可以用 h、j、k、l 来分别实现左、下、上、右箭头的功能。一开始可能需要适应一下,但一旦习惯这种方式,你就会发现这样操作的高效之处了。

在你编辑你的电子邮件或者其他有段落的文本时,你可能会发现使用方向键和你预期的效果不一样,有时候可能会一次跳过了很多行。这是因为你的段落在 VIM 看来是一个大的长长的行。这时你可以在按 h、j、k 或者 l 之前键入一个 g,这样 VIM 就会按屏幕上面的行如你所愿的移动了。

在当前行里面有效的移动光标

很多编辑器只提供了简单的命令来控制光标的移动(比如左、上、右、下、到行首/尾等)。VIM 则提供了很多强大的命令来满足你控制光标的欲望。当光标从一点移动到另外一点,在这两点之间的文本(包括这两个点)称作被“跨过”,这里的命令也被称作是 motion。(简单说明一下,后面会用到这个重要的概念)

这里是常用到的一些命令(motion):

fx:移动光标到当前行的下一个 x 处。很明显,x 可以是任意一个字母,而且你可以使用 ; 来重复你的上一个 f 命令。
tx:和上面的命令类似,但是是移动到 x 的左边一个位置。(这真的很有用)
Fx:和 fx 类似,不过是往回找。
w:光标往前移动一个词。
b:光标往后移动一个词。
0:移动光标到当前行首。
^:移动光标到当前行的第一个字母位置。
$:移动光标到行尾。
):移动光标到下一个句子。
( :移动光标到上一个句子。

在整个文件里面有效移动光标

VIM 有很多命令,可以用来到达文件里面你想到达的地方。下面是一些在文件里面移动的命令:

Ctrl-F: 向下移动一屏。
Ctrl-B:向上移动一屏。
G:到文件尾
numG:移动光标到指定的行(num)。(比如 10G 就是到第 10 行)
gg:到文件首
H:移动光标到屏幕上面
M:移动光标到屏幕中间
L:移动光标到屏幕下面
*:读取光标处的字符串,并且移动光标到它再次出现的地方。
#:和上面的类似,但是是往反方向寻找。
/text:从当前光标处开始搜索字符串 text,并且到达 text 出现的地方。必须使用回车来开始这个搜索命令。如果想重复上次的搜索的话,按 n。
?text:和上面类似,但是是反方向。
ma:在当前光标的位置标记一个书签,名字为 a。书签名只能是小写字母。你看不见书签的存在,但它确实已经在那里了。
a:到书签 a 处。注意这个不是单引号,它一般位于大部分键盘的 1 的左边。
  • .:到你上次编辑文件的地方。这个命令很有用,而且你不用自己去标记它。

    高效的输入

    使用关键词自动完成

    VIM 有一个非常漂亮的关键词自动完成系统。这表示,你可以输入一个长词的一部分,然后按一下某个键,然后 VIM 就替你完成了这个长词的输入了。举个例子:你有一个变量名为 iAmALongAndAwkwardVarName 在你写的代码的某个地方。也许你不想每回都自己一个一个字母的去输入它。

    使用关键词自动完成功能,你只需要输入开始几个字母(比如 iAmAL),然后按 (按住 Ctrl,再按 N)或者 。如果 VIM 没有给出你想要的词,继续按,直到你满意为止,VIM 会一直循环它找到的匹配的字符串。

    聪明的进入插入模式

    很多新手进入插入模式都只是用 i。这样当然可以进入插入模式,但通常不是那么合适,因为 VIM 提供了很多进入插入模式的命令。下面是最常用的一些:

    i:在当前字符的左边插入
    I:在当前行首插入
    a:在当前字符的右边插入
    A:在当前行尾插入
    o:在当前行下面插入一个新行
    O:在当前行上面插入一个新行
    c{motion}:删除 motion 命令跨过的字符,并且进入插入模式。比如:c$,这将会删除从光标位置到行尾的字符并且进入插入模式。ct!,这会删除从光标位置到下一个叹号(但不包括),然后进入插入模式。被删除的字符被存在了剪贴板里面,并且可以再粘贴出来。
    d{motion}:和上面差不多,但是不进入插入模式。
    有效的移动大段的文本

    使用可视选择(visual selections)和合适的选择模式

    不像最初的 VI,VIM 允许你高亮(选择)一些文本,并且进行操作。这里有三种可视选择模式:

    v:按字符选择。经常使用的模式,所以亲自尝试一下它。
    V:按行选择。这在你想拷贝或者移动很多行的文本的时候特别有用。
    Ctrl-V: 按块选择。非常强大,只在很少的编辑器中才有这样的功能。你可以选择一个矩形块,并且在这个矩形里面的文本会被高亮。

    在选择模式的时候使用上面所述的方向键和命令(motion)。比如,vwww,会高亮光标前面的三个词。Vjj 将会高亮当前行以及下面两行。

    在可视选择模式下剪切和拷贝

    一旦你高亮了选区,你或许想进行一些操作:

    d:剪贴选择的内容到剪贴板。
    y:拷贝选择的内容到剪贴板。
    c:剪贴选择的内容到剪贴板并且进入插入模式。

    在非可视选择模式下剪切和拷贝

    如果你很清楚的知道你想拷贝或者剪切什么,那你根本就不需要进入可视选择模式。这样也会节省时间:

    d{motion}:剪切 motion 命令跨过的字符到剪贴板。比如,dw 会剪切一个词而 dfS 会将从当前光标到下一个 S 之间的字符剪切至剪贴板。
    y{motion}:和上面类似,不过是拷贝。
    c{motion}:和 d{motion} 类似,不过最后进入插入模式。
    dd:剪切当前行。
    yy:拷贝当前行。
    cc:剪切当前行并且进入插入模式。
    D:剪切从光标位置到行尾到剪贴板。
    Y:拷贝当前行。
    C:和 D 类似,最后进入插入模式。
    x:剪切当前字符到剪贴板。
    s:和x类似,不过最后进入插入模式。

    粘贴

    粘贴很简单,按 p。

    使用多重剪贴板

    很多编辑器都只提供了一个剪贴板。VIM 有很多。剪贴板在 VIM 里面被称为寄存器(Registers)。你可以列出当前定义的所有寄存器名和它们的内容,命令为“:reg”。最好使用小写字母来作为寄存器的名称,因为大写的有些被 VIM 占用了。

    使用寄存器的命令为双引号 "。

    比如:我们要拷贝当前行到寄存器 k。你应该按 "kyy。(你也可以使用 V"ky。为什么这样也可以呢?)现在当前行应该已经存在了寄存器 k 里面直到你又拷贝了一些东西进入寄存器 k。现在你可以使用命令 "kp 来粘贴寄存器 k 里面的内容到你想要的位置。

    避免重复

    令人惊奇的 . 命令

    在 VI 里面,输入 . (小数点符号),将会重复你输入的上一个命令。比如,你上个命令为“dw”(删除一个词),VI 将会接着再删除一个词。

    使用数字

    使用数字也是 VIM 强大的而且很节省时间的重要特性之一。在很多 VIM 的命令之前都可以使用一个数字,这个数字将会告诉 VIM 这个命令需要执行几次。比如:

    3j 将会把光标向下移动三行。
    10dd 将会删除十行。
    y3" 将会拷贝从当前光标到第三个出现的引号之间的内容到剪贴板。

    数字是扩展 motion 命令作用域非常有效的方法。

    记录宏

    有时候,你会发现你自己在文章的每段或者每行都重复相同的一系列动作。VIM 允许你记录一个宏来完成你的特殊需要。

    qregister:记录宏到寄存器 register,这里 register 是任意的你的寄存器的名字。比如 qa,将会记录并且把宏存在寄存器 a 里面。
    q:结束宏的记录。
    @register:使用存在寄存器 register 的宏。比如 @a,将会使用存在寄存器 a 里面的宏。

    必须要记住的是,宏只记录了你的系列按键并且重复执行它们。它们不是魔法。因为在 VIM 里面完成目的的方法有很多,所以有时候你要小心选择命令来记录你的宏。因为它们会在所有你要执行它的地方执行。

    用 VIM 写代码

    VIM 是一个用来写代码的绝好编辑器,因为它有一些特性是专门为程序员而设计的。这里是一些常用的:

    ]p:和 p 的功能差不多,但是它会自动调整被粘贴的文本的缩进去适应当前代码的位置。试一下!
    %:匹配花括号、方括号、括号等。在一个括号的上面,然后按 %,鼠标就会出现在匹配的另外一半括号处。
    >>:缩进所有选择的代码
    <<:和上面类似,但是反缩进
    gd:到达光标所在处函数或者变量的定义处。
    K:在 Man 里面查找光标当前所在处的词。


    http://linuxtoy.org/archives/efficient-editing-with-vim.html
  • 2009年3月17日星期二

    gvim学习实践

    前几天从善用佳软上学到了不少gvim的使用方法,实际摸索中遇到了几个问题,经过尝试,基本都可以从帮助里面找到答案,这里就不作说明了。
    今天又遇到一共稀奇古怪的问题,我想匹配以"ABC "开头到行尾的文本行(不含引号),按模糊匹配*的方式都无法成功。
    最终尝试出了一个方法:
    :/ABC .*$
    这样就可以匹配到了,不知道这是不是bug?

    匹配空行
    /^$
    直接使用行开始符和结束符

    当文档里有空字符空行时使用下面的
    /^\s*$
    \s表示空格
    *表示重复多次

    删除所有空行的命令
    :g/^\s*$/d
    g 代表 globe,最后的d是删除行的命令,这里还可以跟其他命令。

    03/24/2009
    今天终于搞明白了之前设置了那么多次启动配置文件不生效的原因了
    每次打开gvim文件菜单上的打开文件时,目录总是C:\Documents and Settings\Administrator
    一直想设置成为一个新的目录,但是总不成功,今天才知道,原来这个目录就是gvim传说中的$HOME目录!

    既然这是HOME,那配置文件就设置在这里就OK了?于是创建了一个Windows里的_vimrc文件,试着写入
    colo evening #设置配色方案为黑白
    新开一个gvim文件,哇塞,居然生效了!!!

    于是把收集的gvim文档的设置选项简单实验了几个,什么set ruler ,incsearch等,都OK

    借助这个方法,终于实现了把gvim启动目录重定向的目的,虽然是偏方,但也能用:
    在_vimrc文件里写入一行:
    lcd d:\mywork\doc
    这样就实现了将启动目录指向d:\mywork\doc了。

    还发现了一个很强的功能:Ex
    通过这个命令,可以打开一个类似Dos命令dir的功能,把当前目录的列表显示出来,还支持按不同形式排序显示以及简单的目录操作:向上一级,删除,更名,执行。
    这个执行命令比较神奇,基本相当于windows里的鼠标双击了,只要把光标移动到所在的行,x执行,跟双击到这个文件上没有什么区别

    03/26/2009
    发现了段很有用的命令:没有完全理解,暂且记录下来作为工具使用。

    :g/^/exec "s/^/".strpart(line(".")." ", 0, 4) 在行首插入行号


    03/27/2009
    前几天遇到一个问题,把某个目录下的一组dll文件注册到系统里。
    如果每个dll使用regsvr32命令单独注册比较麻烦,于是想通过脚本实现:
    首先,使用了gvim的lcd命令更换编辑目录到dll所在的目录
    然后使用r!dir *.dll命令将所有dll目录引入gvim
    下面的问题就来了,怎么把格式比较规范的列表文件替换成用regsrv32开头的呢??
    文件格式如下:

    2005-04-05 20:00 69,584 AVICAP.DLL
    2005-04-05 20:00 109,456 AVIFILE.DLL
    2005-04-05 20:00 32,848 COMMDLG.DLL
    2005-04-05 20:00 9,936 LZEXPAND.DLL
    2005-04-05 20:00 68,768 MMSYSTEM.DLL
    2005-04-05 20:00 126,912 MSVIDEO.DLL
    2005-04-05 20:00 82,535 OLECLI.DLL
    2005-04-05 20:00 24,064 OLESVR.DLL
    2005-04-05 20:00 5,120 SHELL.DLL
    2005-04-05 20:00 19,216 TAPI.DLL
    2005-04-05 20:00 9,008 VER.DLL

    今天终于解决了,当然是个很土的办法
    :%s/^\A\{34}\d/regsvr32 /gc

    思路就是借助列表是开头35个字符对齐的特点展开
    ^表示行首
    \A 表非英文字母,即 [^a-zA-Z]
    \d 表示数字
    \{34}表示前面的字符重复34次

    2009年3月15日星期日

    vim&gvim技巧大全(3)

    vim&gvim技巧大全(3)
    li3 发表于 2006-2-27 14:25:00
    http://blog.21ic.org/user1/313/archives/2006/9670.html
    0
    推荐启动vi的时候自动加载.尤其是源命令(so),缩写(ab)和宏定义都可以用.在.exrc中不
    允许有空行.以"开头的一行vi将把它当成注释.

    7.1 - .exrc文件的样本
    以下的.exrc文件是一个实际的例子, 我自己的. 因此,它就没有有些人想象的那样设置
    很多的选项.即便如此,它还是给出一些基本的概念,而且它也相当易懂.

    首先,记住你无须在命令前面加:号,因为它是缺省就添加了的.

    "译注--以下是.exrc文件中的内容,为真实起见,而且事实上也相当浅显,
    "我没有翻译其中的注
    " set wordwrap 9 characters from the right
    set wm=9
    " show matching parenthesis. When },), or ] is hit, show the opening
    " {,(, or [ that matches it.
    set sm
    " set the shell to be /usr/local/bin/tcsh
    set sh=/usr/local/bin/tcsh
    " a few abbreviations
    " this makes -l automatically become -Larry, and zidlle to be my
    " name and email address.
    ab zidlle E. Larry Lidz - ellidz@midway.uchicago.edu
    ab -l -Larry
    " uppercase V will run ispell -x (-x tells it not to save backups) on current
    " file
    map V :w
    " K will center the line... (this doesn't work on SunOS -- ??)
    map K :s/^[ ]*//
    " v will reformat the current paragraph
    map v {0!}fmt
    " q runs a program to lock my terminal
    map q :!lock2
    " Splits a line in two at current cursor location, puts a > at the
    "beginning of the line - useful for Usenet/email
    map g may0O`ay$:s/./ /g

    8.0 - vi的bug
    我很想说vi中没有bug,但很不幸,它不是这样的. 这些bug都是初始版本vi中的,
    它其他的一些变种就不一定有. 例如 _宏有时就运行的有问题,某个宏允许我们只敲
    一个键就可以执行好几个不同的命令.

    开放模式 open mode
    开始模式是说vi启动的时候不能确定你的终端类型,或者它肯定你的是一个硬的或
    电子管的终端

    正规表达式 regular expressions (RegEx)
    正规表达式,通常缩写为"RegEx",是一些关键字的集合,它允许用户在查找的时候有更大的
    控制力度. RegEx是在UNIX下面用的,但是在很多程序中也用到了它.

    sed
    流-行式的编辑器.它没有界面,所有命令都是通过命令行的形式给出的.

    vi
    就是这个FAQ讨论的编辑器

    9.0 - 术语表
    如果有人提议说某个术语他不明白,我们将更新这个术语表.如果你有什么建议,
    请一定要告诉我.

    命令模式 command mode

    命令模式是说我们在此模式下面可以向vi发命令(包括光标移动,编辑命令等等)

    ed
    UNIX里面一个非可视化的编辑器


    escape键. 键盘上标记为escape(ESC)的一个键.有时候^[可以起到相同的作用.
    如果没有escape键,你可以试试Meta键
    ex
    UNIX下的一个编辑器.所有vi中的:命令都是送给它处理的

    插入模式 insert mode
    插入模式是指我们可以在此模式下面键入文本.

    宏 macro
    宏是一些键的组合起来的快捷方式.例如,某个宏允许我们只敲一个键就可以执行
    好几个不同的命令.

    开放模式 open mode
    开始模式是说vi启动的时候不能确定你的终端类型,或者它肯定你的是一个硬的或
    电子管的终端

    正规表达式 regular expressions (RegEx)
    正规表达式,通常缩写为"RegEx",是一些关键字的集合,它允许用户在查找的时候有更大的
    控制力度. RegEx是在UNIX下面用的,但是在很多程序中也用到了它.

    sed
    流-行式的编辑器.它没有界面,所有命令都是通过命令行的形式给出的.

    vi
    就是这个FAQ讨论的编辑器

    --
    昨夜银河送落花,潺潺落谁家?
    冰心素月,两相映无暇。

    寒烟淡笼蒹葭,风吹别怨过天涯。
    双星黯处,山瞑隐清笳。
    規則表示式的運用

    在本系列文章一開始就說明了學 vi(m) 可以順便學規則表示式(regular expression,以下簡稱 regexp),那為什麼到現在才來講呢?因為 regexp 說簡單也算不很難,但您要深入去使用的話,有時會馬上看不出一個複雜的 regexp 在說些什麼的,就曾有人形容 regexp 為「有字天書」!而且在 vi(m) 整體都還沒一個概念就加入 regexp 的話,那後面的單元恐怕就沒人看了!而 regexp 各家有各家的 extensions,這也是大家視為畏途的原因之一,不過總是大同小異,只需注意一下就可以了。目前先不必管別家怎麼說,就讓 vim 暫時先成為我們的「標準」,以後碰到其它程式的 regexp 應該就可以觸類旁通。以下我們盡量由實例去瞭解。當然,小小的一篇文章是沒有辦法詳盡介紹,只能撿重點來說明了。如有疑問,可 :h pattern 或在 Un*x 系統中可 man 7 regex,甚至 man ed,man sed,man grep,man awk,man perlre 裡面也是會說些 regexp,但要注意和 vim 差異的地方!其中 perl 的 regexp 應該是最完整的了,如果您的系統沒有 perl 那應該是「稀有動物」了!:-) ㄟㄟㄟ!vim 只是一個編輯器,可不是獨立的程式語言!

    基本的匹配

    * 指前所綁住的字元或字元集合,出現 0 次或 0 次以上。
    \+ 和 * 作用相同,但不包括出現 0 次。
    \= 指前所綁住的字元恰好出現 0 或 1 次。
    \| 這是多選,就是 or 的意思,被 \| 隔開的 pattern,任一個符
    合的話就算符合。

    \+, \=, \| 會加上一個 \,是因原字元在 vi(m) 就具有特殊意義,在一般的 regexp 中是 +,?,| 就可以了,只是提醒您一下,以免搞混了!
    記住 * \+ 是不可數的!用辭不是是精確,只是幫助您記憶啦!
    在 elvis 及 ed 中是使用 \? 來匹配出現 0 或 1 次,而不是 \=,這裡要非常小心!
    [實例] dg*
    指 * 前所綁住的字元 g 出現 0 次或 0 次以上。也就是說 d(出現 0 次),dg,dgggg,dgggggggg 都是符合這個 pattern。如果您下尋找指令 /dg*,那符合這個 pattern 的字串都會被找出來。如果用在代換就要非常小心了,像 extended 中的 d 也是會被置換掉的。例如您下 :%s/dg*/test/g 的話,那 extended 這個字會換成 extentestetest。

    shell 中使用的通用字元為 pattern matching notation 和 regexp 不同的。dg* 在 shell 中是解為以 dg 開頭的任意字串,這就不包括 d 在內了,也就是說在 shell 中,* 是代表任一字元或字串。
    [實例] dg\+
    dg, dgg, dgggggg 皆符合,但 d 則不符合。如果是 dg\= 的話,就只有 d、dg 這兩個符合了。

    [實例] :%s/The\|All/test/g
    全文中只要是 The 或 All 都會被替換成 test。注意,如果文中有 There 也是會被替換成 testre!要如何避免這種情形呢?下面會另述及限定使用法。

    [實例] /123-\=4567
    這樣會找出,123-4567 及 1234567。當然 123-456789 也是會被找出來。

    [...] 字元集合,表示中括號中所有字元中的其中一個。
    [^..] 這是上述 [...] 的補集,表非中括號內字元的其中一個。
    . 除換行字元外的任一單一字元。指本身,非指前所綁之字元。
    就好像 shell 中的 ? 一樣。如果要指定真正的英文句點,要
    用 \ 來 escape,就是說 \. 這時的 . 是代表真正句點,而不
    是 regexp 中的特殊意義。其他如 \* 亦同。

    [實例]

    [Aa]
    A 或 a 其中的一個。
    [12345]
    12345 其中的一個數目字。可用 [1-5] 來表示。連續性的數目字或字元可用 - 來隔開,寫出頭尾來代表就可以了。[0-9] 就表 0 到 9 的數目字,[a-d] 就代表 abcd 四個英文字母

    [實例] W[0-9]*\.cc
    這個例子是說以 W 開頭,後接 0-9 其中一個或多個數目字或不接什麼,然後是一個句點,最後是 cc。所以 W.cc,W1.cc,W2.cc,W345.cc,W8976543287.cc 皆符合。如果要表示 W 及 .cc 間夾一個以上的數目字,要寫成 W[0-9][0-9]*\.cc。

    [實例] .*
    這代表任意字元或字串,或什麼都沒有,腦筋急轉彎,對照前面的定義想一下。當然這是不包括換行字元的。

    [實例]
    [^M] 表除 M 以外的任意字元。
    [^Tt] 表 T 及 t 以外的任意字元。
    [^0-9] 表非數目字之字元。
    [^a-zA-Z] 表非英文字母之字元。

    注意,^ 要在中括號內,且在最開頭的地方,否則另有含意。
    ^ 匹配行首,指其後綁住的字串,出現在行首才符合。
    $ 匹配行尾,指其前綁住的字串,出現在行尾才符合。含換行字元。

    不是在行首的 ^ 指的是 ^ 這個字元。不是在行尾的 $ 是指 $ 本身這個字元。
    [實例] /^What
    這樣只有在行首的 What 才會被找出來。注意! Whatever, What's 也是會被找出來。如果是 /What$ 則是在行尾的 What 才會被找出來。

    [實例] ^$
    這是什麼東東?行首也是行尾的行。ㄚ,就是空白行嘛!當然也不能說這個行是沒有什麼東東啦!空白行至少也是會有個換行字元。在後面會詳述如何消除全文的空白行。

    \(...\) 記憶 pattern,可由 \1, \2...\9 來叫出。

    [實例] :%s/\([a-z]\)\1/test/g
    這樣 aa, bb, cc, dd, ..., zz 都會被 test 替換掉。這和 :%s/[a-z][a-z]/test/g 是不一樣的意思,後者會把 aa, ab, ac... ba, bb, bc...zz 都換成 test。也就是說 \(...\) 由 \1 叫出時會有對稱性的配對出現。

    [實例] :%s/\(.\)\(.\)r\2\1/test/g
    會將中間為 r,前有二個任一字元,後有兩個具對稱性的字元所組成的字串替換成 test。\2 是呼叫第二組 \(.\),而 \1 是呼叫第一組 \(.\)。例如:12r21,cfrfc,7grg7 等都會被替換成 test。

    \< 匹配字(word)首。所謂 word 包括文數字及底線。
    \> 匹配字尾。這就是前所提及的限定用法,被 \<,或 \> 括住的
    pattern 就會被限制住,使 regexp 不能再向右(左)擴充解釋。

    ed 及 perl 中可以 \b 來表示這兩個符號,perl 中只支援 \b,ed 則 \b 及 \<, \>皆支援。但在 perl 可多加個 ? 來限制 regexp 的擴充解譯。
    功能上而言,這是和 ^ $ 一樣的定位樣式(anchor pattern)指所綁住的字串必須是單字邊界(word boundary),前或後或前後除了空白字元及標點符號外不可再有其它字元。
    在 vim 中 \b 是表示 即 backspace 鍵。
    [實例] :%s/\/test/g
    這樣只有 abbbc 才會被替換成 test。如果沒有這樣限定,:%s/abbbc/test/g,那 deabbbcly 中的 "abbbc" 亦會被替換成 test。所以前面 :%s/The\|All/test/g 可換成 :%s/\\|\/test/g 這樣一來,There 就不會被替換成 testre 了!

    [實例] :%s/\《abbbc/test/g
    這樣的話,只要是以 abbbc 為首的字(word),其中的 abbbc 的部份都會被 test 所替換。注意!是指字首,而不是指行首。所以 abbbc,abbbcerd,abbbckijuds 都符合。

    \{n,m} 指前所綁住的字元或字元集合最少出現 n 次,最多出現 m 次。

    這在一般的 regexp 表示成 \{n,m\}。vim 及 elvis 兩種表示法皆支援。perl 則直接使用 {}。以下會舉四種不同的例子,請大家發揮一下想像力。:-)
    [實例] \{最小值,最大值}
    如 [0-9]\{3,4} 匹配至少三位數,但不可多於四位數的數目字。如:
    123
    12
    1
    123456
    1234567
    12345678
    1234
    12345

    如果下 :%s/[0-9]\{3,4}/test/g 的話,那 1,12 這兩組不會被替換,因為不滿 3 位數。而 12345,則會換成 test5。123456,則會換成 test56。12345678,則會換成 testtest。1234567 也是會換成 testtest。123,1234 這兩組則會被替換成 test。您可以親自操作一次就知道怎麼一回事了。操作時最後加 gc 來 confirm,這樣您會更瞭解實際替換的內容。ㄟ,別忘了 u 可以回複您的編輯動作。

    [實例] \{數目字}
    xy\{20} 表示 x 後接 20 個 y。
    e[x-z]\{4} 表示 e 後接有四個字元,是 x,y,z 的其中一個的
      組合。如:exxxx, exyyz, ezzyz, exyzz 皆符合。

    [實例] \{最小值,}
    xy\{2,} 表 x 後接至少二個的 y。相當於 xyyy* 或 xyy\+ 。

    [實例] \{,最大值}
    xy\{,4} 表 x 後接至多四個或更少的 y (可能沒有)。
    因此 x, xy, xyy ,xyyy, xyyyy 皆符合。

    中介字元(metacharacter, or character classes)

    主要是簡化 regexp 的書寫。

    \s 表空白字元,即

    不含換行字元,這是編輯器的特性使然。在 perl 的 \s 是包含換行字元的。而且 vim 及 elvis 皆不支援 \n 這種換行中介字元。
    \S 表非空白字元。
    \d 表數目字(digits),即 [0-9]。
    \D 表非數目字,即 [^0-9]。
    \w 表一般字元(word character),包括底線。即 [0-9a-zA-Z_]。
    \W 表非一般字元,即 [^0-9a-zA-Z_]。
    \a 表英文字母(alphabetic character),即 [a-zA-Z]。
    \A 表非英文字母,即 [^a-zA-Z]。
    \l 表小寫字母(lowercase character),即 [a-z]。
    \L 表非小寫字母,即 [^a-z]。
    \u 表大寫字母(uppercase),即 [A-Z]。
    \U 表非大寫字母,即 [^A-Z]。

    原始 vi 不支援此種中介字元。
    使用中介字元的比對速度將會比使用字元集合 [] 的快。

    全域性的指令

    :[range]g/pattern/[cmd]

    cmd 是 ed 可用的指令,預設是 p(print),您可查一下 man ed,就可以知道有什麼指令可用。這個小節裡主要是說明 d(delete) 的功能。因為是要說明如何消除空白行。需注意的是,d 是行刪除指令,凡含 pattern 的整行都會被刪掉,而且 range 不指定的話,預設是全篇文章,因為 g 就是代表 globe。
    在 vim 的 help 檔裡說的是 ex 指令,但 ex 實際上是和 vim 連結的,因此這裡特別指出 ed。但 ed 的指令少數可能會和 vim 的 ex 不同,這是因為 ed 和 vim 並非同步在發展,作者也非同一人。
    :g/^$/d

    這樣就會刪除全文的空白行。前面已提過 ^$ 代表的是空白行。但這裡有個問題,如果空白行裡包含了其它空白字元(即 Space 或 Tab)的話。表面看起來是和一般空白行一模一樣,但卻暗藏玄機,用上面的方法就無法刪除這種空白行了!怎麼辦?來!看招!
    :g/^[]*$/d

    在 vim 或 elvis 裡您可以如此照打,也就是 代表空白字元, 代表按 Tab 鍵的結果。在原始 vi 則不行,得自行按出特殊字元出來,就是 Ctrl-v Space 及 Ctrl-v Tab。或採更簡單的打法:
    :g/^\s*$/d

    還記得中介中元嗎?好用吧!少打了不少字。:-) 意思就是刪除含 0 或 1 個以上空白字元的行。
    有些書中寫成 :%s/^$//g 可以刪除空白行,這是錯誤的,因為 :s 這個指令只更動一行裡的內容物,但不會做刪除一行的動作。

    & 替代變數

    代表置換時合於 patern 的字元或字串。

    [實例] :%s/\u\d\d\d\d\d\d\d\d\d\>/ID:&/g
    這樣全文中的身份證字號前就會加上 ID: 字樣,也就是說 T123456789 會被換成 ID:T123456789。還記得嗎? \d 就是 [0-9],\u 代表大寫的英文字母。加個 \> 是防止 T12345678999 也被換掉。當然前面再加個 \< 更保險。ID: 字樣您用中文也行!
    另一個好用的例子是電話號碼前加上 TeL:,就請您自行練習了!

    [實例] 將檔案 3 至 7 行的資料向右移 2 個空白

    :3,7s/.*/ &/

    但這樣連空白行也是會插入空白字元,較高明的做法是:
    :3,7s/.\+/ &/

    這樣空白行就不會去動它了!想通了 .* 及 .\+ 的意思了嗎?往前翻一下 . * \+ 的定義。

    [實例] 將檔案 3 至 7 行的資料向左移 2 個空白

    :3,7s/^ //

    就是刪去行首的二個空白啦!

    [實例] 將全文的 Edward 這個單字,前後加上中括號

    :%s/\/[&]/g

    [實例] 將全文的 Edward 這個單字,改成大寫的。

    :%s/\/\U&/g

    ㄟ!\U 不是代表非大寫字母嗎?喔!您搞錯位置了。\U 在 pattern 的位置的時候是指非大寫字母的樣式,即 [^A-Z],但如果是在置換字串位置的時候是指將其後的字串通通改成大寫。與其相對的是 \L,會將其後的字串改為小寫。詳細請 :h sub-replace-special。
    [實例] 將全文每行最後加上
    這個 HTML tag。

    :%s/.*/&
    /g

    怎麼樣,是否已感覺到 regexp 威力無窮了呢?還是您已經快睡著了呢?:-) 不過也請您想想,如果是在沒有 regexp 功能的編輯器裡,範例中的一些動作您會怎麼做呢?一個一個去改?

    greedy 陷阱

    regexp 會有貪心的傾向,什麼意思呢?就是說在同一行內,如果有多個符合 pattern 的情形,會找最長的那一個。

    注意!greedy 的特性是針對會反覆比對的 regexp 而言,例如:*, \=, \+, \{} 等。前面所舉的 .* 的例子,由於 greedy 的關係,在整篇文章中做替換時,會被當成是每一行整行,因為 regexp 會去找每一行最長符合的那一個。
    [實例] This is a test. Test for regexp.
    如果您下 :%s/[Tt].*t/program/g 原意是想把所有的 Test 或 test 換成 program 的,結果由於 regexp 的貪心,整個 "This is a test. Test" 會換成 program。結果原文就變成了 program for regexp. 因此在全文替換時要非常小心,避免使用彈性太大的 regexp。像此例,只要下 :%s/\<[Tt]est\>/program/g 就可以了!

    最後提醒您,這可不是 regexp 的全部,礙於篇幅及在下功力的問題,當然是沒辦法全面詳盡的向各位做介紹,在下只是將各位領進門,修行就得看各位了!如果還想更深入的研究 regexp,可參考: Mastering Regular Expressions(O'Reilly & Associates) 一書。

    David Rayner (zzapper) 15 Years of Vi + 4 years of Vim and still learning 27Dec05 : Last Update
    Tips Sign-Up __BEGIN__
    ------------------------------------------------------------------------------
    " searching
    /joe/e : cursor set to End of match
    /joe/e+1 : cursor set to End of match plus 1
    /joe/s-2 : cursor set to Start of match minus 2
    /^joe.*fred.*bill/ : normal
    /^[A-J]\+/ : search for lines beginning with one or more A-J
    /begin\_.*end : search over possible multiple lines
    /fred\_s*joe/i : any whitespace including newline
    /fred\|joe : Search for FRED OR JOE
    /.*fred\&.*joe : Search for FRED AND JOE in any ORDER!
    /\/i : search for fred but not alfred or frederick
    /\<\d\d\d\d\> : Search for exactly 4 digit numbers
    /\D\d\d\d\d\D : Search for exactly 4 digit numbers
    /\<\d\{4}\> : same thing
    /\([^0-9]\|^\)%.*% : Search for absence of a digit or beginning of line
    " finding empty lines
    /^\n\{3} : find 3 empty lines
    " using rexexp memory in a search
    /\(fred\).*\(joe\).*\2.*\1
    " Repeating the Regexp (rather than what the Regexp finds)
    /^\([^,]*,\)\{8}
    " visual searching
    :vmap // y/" : search for visually highlighted text
    :vmap // y/=escape(@", '\\/.*$^~[]') : with spec chars
    " \zs and \ze regex delimiters :h /\zs
    /<\zs[^>]*\ze> : search for tag contents, ignoring chevrons
    " zero-width :h /\@=
    /<\@<=[^>]*>\@= : search for tag contents, ignoring chevrons
    /<\@<=\_[^>]*>\@= : search for tags across possible multiple lines
    " searching over multiple lines \_ means including newline
    / : search for multiple line comments
    /fred\_s*joe/i : any whitespace including newline
    /bugs\(\_.\)*bunny : bugs followed by bunny anywhere in file
    :h \_ : help
    " search for declaration of subroutine/function under cursor
    :nmap gx yiw/^\(sub\function\)\s\+"
    " multiple file search
    :bufdo /searchstr/ : use :rewind to recommence search
    " multiple file search better but cheating
    :bufdo %s/searchstr/&/gic : say n and then a to stop
    " How to search for a URL without backslashing
    ?http://www.vim.org/ : search BACKWARDS!!! clever huh!
    " Specify what you are NOT searching for (vowels)
    /\c\v([^aeiou]&\a){4} : search for 4 consecutive consonants
    ----------------------------------------
    #substitution
    :%s/fred/joe/igc : general substitute command
    :%s/\r//g : Delete DOS returns ^M
    " Is your Text File jumbled onto one line? use following
    :%s/\r/\r/g : Turn DOS returns ^M into real returns
    :%s= *$== : delete end of line blanks
    :%s= \+$== : Same thing
    :%s#\s*\r\?$## : Clean both trailing spaces AND DOS returns
    :%s#\s*\r*$## : same thing
    " deleting empty lines
    :%s/^\n\{3}// : delete blocks of 3 empty lines
    :%s/^\n\+/\r/ : compressing empty lines
    %s#<[^>]\+>##g : delete html tags, leave text
    " IF YOU ONLY WANT TO KNOW ONE THING
    :'a,'bg/fred/s/dick/joe/igc : VERY USEFUL
    " duplicating columns
    :%s= [^ ]\+$=&&= : duplicate end column
    :%s= \f\+$=&&= : same thing
    :%s= \S\+$=&& : usually the same
    " memory
    :s/\(.*\):\(.*\)/\2 : \1/ : reverse fields separated by :
    :%s/^\(.*\)\n\1$/\1/ : delete duplicate lines
    " non-greedy matching \{-}
    :%s/^.\{-}pdf/new.pdf/ : delete to 1st pdf only
    " use of optional atom \?
    :%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc : lowercase with optional leading characters
    " over possibly many lines
    :%s/// : delete possibly multi-line comments
    :help /\{-} : help non-greedy
    " substitute using a register
    :s/fred/a/g : sub "fred" with contents of register "a"
    :s/fred/\=@a/g : better alternative as register not displayed
    " multiple commands on one line
    :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
    :%s/a/but/gie|:update|:next : then use @: to repeat
    " ORing
    :%s/suck\|buck/loopy/gc : ORing (must break pipe)
    " Calling a VIM function
    :s/__date__/\=strftime("%c")/ : insert datestring
    " Working with Columns sub any str1 in col3
    :%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
    " Swapping first & last column (4 columns)
    :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:
    " filter all form elements into paste register
    :redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END
    :nmap ,z :redir @*sil exec 'g@<\(input\select\textarea\/\=form\)\>@p'redir END
    " decrement numbers by 3
    :%s/\d\+/\=(submatch(0)-3)/
    " increment numbers by 6 on certain lines only
    :g/loc\|function/s/\d/\=submatch(0)+6/
    " better
    :%s#txtdev\zs\d#\=submatch(0)+1#g
    :h /\zs
    " increment only numbers gg\d\d by 6 (another way)
    :%s/\(gg\)\@<=\d\+/\=submatch(0)+6/
    :h zero-width
    " rename a string with an incrementing number
    :let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # convert yy to 10,11,12 etc
    " as above but more precise
    :let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # convert xxyy to xx11,xx12,xx13
    " find replacement text, put in memory, then use \zs to simplify substitute
    :%s/"\([^.]\+\).*\zsxx/\1/
    " Pull word under cursor into LHS of a substitute
    :nmap z :%s#\<=expand("")\>#
    " Pull Visually Highlighted text into LHS of a substitute
    :vmap z :%s/\<*\>/
    ----------------------------------------
    " all following performing similar task, substitute within substitution
    " Multiple single character substitution in a portion of line only
    :%s,\(all/.*\)\@<=/,_,g : replace all / with _ AFTER "all/"
    " Same thing
    :s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')#
    " Substitute by splitting line, then re-joining
    :s#all/#&^M#|s#/#_#g|-j!
    " Substitute inside substitute
    :%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/
    ----------------------------------------
    " global command display
    :g/gladiolli/# : display with line numbers (YOU WANT THIS!)
    :g/fred.*joe.*dick/ : display all lines fred,joe & dick
    :g/\/ : display all lines fred but not freddy
    :g/^\s*$/d : delete all blank lines
    :g!/^dd/d : delete lines not containing string
    :v/^dd/d : delete lines not containing string
    :g/fred/,/joe/d : not line based (very powerfull)
    :g/-------/.-10,.d : Delete string & 10 previous lines
    :g/{/ ,/}/- s/\n\+/\r/g : Delete empty lines but only between {...}
    :v/\S/d : Delete empty lines (both types)
    :v/./,/./-j : compress empty lines
    :g/^$/,/./-j : compress empty lines
    :g/《input\|《form/p : ORing
    :g/^/put_ : double space file (pu = put)
    :g/^/m0 : Reverse file (m = move)
    :'a,'b/^/m'b : Reverse a section a to b
    :g/^/t. : duplicate every line
    :g/fred/t$ : copy lines matching fred to EOF
    :g/stage/t'a : copy lines matching stage to marker a
    :g/\(^I[^^I]*\)\{80}/d : delete all lines containing at least 80 tabs
    " perform a substitute on every other line
    :g/^/ if line('.')%2|s/^/zz /
    " match all lines containing "somestr" between markers a & b
    " copy after line containing "otherstr"
    :'a,'bg/somestr/co/otherstr/ : co(py) or mo(ve)
    " as above but also do a substitution
    :'a,'bg/str1/s/str1/&&&/|mo/str2/
    :%norm jdd : delete every other line
    " incrementing numbers (type as 5 characters)
    :.,$g/^\d/exe "norm! \": increment numbers
    :'a,'bg/\d\+/norm! ^A : increment numbers
    " storing glob results (note must use APPEND) you need to empty reg a first with qaq.
    "save results to a register/paste buffer
    :g/fred/y A : append all lines fred to register a
    :g/fred/y A | :let @*=@a : put into paste buffer
    :let @a=''|g/Barratt/y A |:let @*=@a
    :'a,'b g/^Error/ . w >> errors.txt
    " duplicate every line in a file wrap a print '' around each duplicate
    :g/./yank|put|-1s/'/"/g|s/.*/Print '&'/
    " replace string with contents of a file, -d deletes the "mark"
    :g/^MARK$/r tmp.ex | -d
    " display prettily
    :g//z#.5 : display with context
    :g//z#.5|echo "==========" : display beautifully
    " Combining g// with normal mode commands
    :g/|/norm 2f|r* : replace 2nd | with a star
    "send output of previous global command to a new window
    :nmap :redir @a:g//:redir END:new:put! a
    ----------------------------------------
    " Global combined with substitute (power editing)
    :'a,'bg/fred/s/joe/susan/gic : can use memory to extend matching
    :g/fred/,/joe/s/fred/joe/gic : non-line based (ultra)
    ----------------------------------------
    " Find fred before beginning search for joe
    :/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
    ----------------------------------------
    " create a new file for each line of file eg 1.txt,2.txt,3,txt etc
    :g/^/exe ".w ".line(".").".txt"
    ----------------------------------------
    " Absolutely essential
    ----------------------------------------
    * # g* g# : find word under cursor () (forwards/backwards)
    % : match brackets {}[]()
    . : repeat last modification
    @: : repeat last : command (then @@)
    matchit.vim : % now matches tags 《script> : word completion in insert mode
    : Line complete SUPER USEFUL
    / : Pull onto search/command line
    / : Pull onto search/command line
    :set ignorecase : you nearly always want this
    :syntax on : colour syntax in Perl,HTML,PHP etc
    :h regexp : type control-D and get a list all help topics containing
    regexp (plus use TAB to Step thru list)
    ----------------------------------------
    " MAKE IT EASY TO UPDATE/RELOAD _vimrc
    :nmap ,s :source $VIM/_vimrc
    :nmap ,v :e $VIM/_vimrc
    ----------------------------------------
    #VISUAL MODE (easy to add other HTML Tags)
    :vmap sb "zdiz : wrap around VISUALLY selected Text
    :vmap st "zdiz ?> : wrap around VISUALLY selected Text
    ----------------------------------------
    " Exploring
    :Exp(lore) : file explorer note capital Ex
    :Sex(plore) : file explorer in split window
    :ls : list of buffers
    :cd .. : move to parent directory
    :args : list of files
    :lcd %:p:h : change to directory of current file
    :autocmd BufEnter * lcd %:p:h : change to directory of current file automatically (put in _vimrc)
    ----------------------------------------
    " Buffer Explorer (Top Ten Vim Script)
    " needs bufexplorer.vim http://www.vim.org/script.php?script_id=42
    \be : buffer explorer list of buffers
    \bs : buffer explorer (split window)
    ----------------------------------------
    " Changing Case
    guu : lowercase line
    gUU : uppercase line
    Vu : lowercase line
    VU : uppercase line
    g~~ : flip case line
    vEU : Upper Case Word
    vE~ : Flip Case Word
    ggguG : lowercase entire file
    " Titlise Visually Selected Text (map for .vimrc)
    vmap ,c :s/\<\(.\)\(\k*\)\>/\u\1\L\2/g
    " Uppercase first letter of sentences
    :%s/[.!?]\_s\+\a/\U&\E/g
    ----------------------------------------
    gf : open file name under cursor (SUPER)
    :nnoremap gF :view : open file under cursor, create if necessary
    ga : display hex,ascii value of char under cursor
    ggVGg? : rot13 whole file
    ggg?G : rot13 whole file (quicker for large file)
    :8 | normal VGg? : rot13 from line 8
    :normal 10GVGg? : rot13 from line 8
    , : increment,decrement number under cursor
    win32 users must remap CNTRL-A
    =5*5 : insert 25 into text (mini-calculator)
    ----------------------------------------
    " Makes all other tips superfluous
    :h 42 : also http://www.google.com/search?q=42
    :h holy-grail
    :h!
    ----------------------------------------
    " Markers & moving about
    '. : jump to last modification line (SUPER)
    `. : jump to exact spot in last modification line
    g; : cycle thru recent changes (oldest first) (new in vim6.3)
    g, : reverse direction (new in vim6.3)
    :changes
    :h changelist : help for above
    : retrace your movements in file (starting from most recent)
    : retrace your movements in file (reverse direction)
    :ju(mps) : list of your movements
    :help jump-motions
    :history : list of all your commands
    :his c : commandline history
    :his s : search history
    q/ : Search history Window (puts you in full edit mode)
    q: : commandline history Window (puts you in full edit mode)
    : : history Window
    ----------------------------------------
    " Abbreviations & maps
    :map :'a,'bw! c:/aaa/x
    :map :r c:/aaa/x
    :map :.w! c:/aaa/xr
    :map :r c:/aaa/xr
    :ab php : list of abbreviations beginning php
    :map , : list of maps beginning ,
    " allow use of F10 for mapping (win32)
    set wak=no : :h winaltkeys
    " For use in Maps
    : carriage Return for maps
    : Escape
    : normally \
    : | pipe
    : backspace
    : No hanging shell window
    #display RGB colour under the cursor eg #445588
    :nmap c :hi Normal guibg=#=expand("")
    ----------------------------------------
    " Simple PHP debugging display all variables yanked into register a
    iab phpdb exit("
    Debug a ");
    ----------------------------------------
    " Using a register as a map (preload registers in .vimrc)
    :let @m=":'a,'bs/"
    :let @s=":%!sort -u"
    ----------------------------------------
    " List your Registers
    :reg : display contents of all registers
    :reg a : display content of individual registers

    vim&gvim技巧大全(2)

    vim&gvim技巧大全(2)
    li3 发表于 2006-2-27 14:25:00
    http://blog.21ic.org/user1/313/archives/2006/9669.html
    0
    推荐Bei.Liu 210324650708001 1965/07/08 male
    -----------------------------------------------

    ⑿:g/female/.m$
    将所有的女员工记录移至文件尾。

    Fei.Zhang 430759701022003 1970/10/22 male
    Yu.Guan 342869680413001 1968/04/13 male
    Bei.Liu 210324650708001 1965/07/08 male
    -----------------------------------------------
    Chan.Diao 651302801225012 1980/12/25 female
    Shi.Xi 120638780214006 1978/02/14 female

    笔者目前正在为某外资公司从事大型机(IBM S/390)的软件开发,一切工作都在TSO环境中进行。为了对编写的程序进行测试,必须准备测试数据。有过大型机开发经验的人会知道,通过TSO,输入字符型数据还可以,如果要输入16进制数据,操作起来很麻烦。因为16进制数是纵向排列的,输入时既不方便,又很容易错位。怎么解决呢?我尝试了几种办法,实际证明,用VIM最方便。

    例六、下列数据 1234567890ABCDEF ,将其变成 13579ACE 24680BDF 的形式,这样,数据就可以很方便的粘贴到TSO环境中了。

    下面给出宏命令脚本change_d.vim

    "----------------------------------------------------
    "Macro Function : Convert Char Arrange Direction
    "
    " Sample : 40 50 60 ==> 4 5 6
    " 0 0 0
    " Date : 2001/12/01
    " Author : Yan Shi
    "----------------------------------------------------
    :s/.*/&^M/
    :1
    :map = malx+$p-`al=

    说明如下:

    ⑴ :s/.*/&^M/ 在数据行下方添加一空行。
    ⑵ :1 回到文件的首行的首字符。
    ⑶ :map = malx+$p-`al= 将一大串VIM命令映像给字符=

    ① ma 将首字符标记为a
    ② l 光标右移一个字符
    ③ x 删除光标处字符
    ④ + 移至下一行
    ⑤ $ 到行尾
    ⑥ p 将删除的字符粘贴
    ⑦ - 回至上一行
    ⑧ `a 返回到标记字符处
    ⑨ l 光标右移一个字符
    ⑩ = 递归调用,重复以上步骤,直到将该行所有的数据处理完。

    上面的这几个实例,展示了VIM强大的文本处理功能,但这远不能覆盖其全貌。VIM的命令很多,而且使用灵活,需要狠下一番气力才能熟练掌握。笔者年龄尚小,经验还很欠缺,希望本文能够起到抛砖引玉的作用。由于时间的原因,上述实例仅在DOS和WINDOWS环境下测试,没有在其他系统下进行进一步的测试,希望各位同行、前辈不吝赐教,谢谢!

    ※ VIM 意为 VI Improved ,与VI99%向下兼容。而且,VIM提供了许多VI不具备的功能,内置了诸多函数,因此,建议有经验的VI用户对VIM有所了解,您会发现,转向VIM 是明智之举。欲查询有关VIM的资料,请参考 http://www.vim.org

    注:本文使用 VIM 6.0 版本

    作者简介
    闫石,工程师。您可以通过电子邮件:iloveibm@163.com 或者 yan-shi@sino-com.com 和他联系。

    附录A:一个用vi作表单的在线教程
    http://www-900.ibm.com/developerWorks/cn/cnedu.nsf/linux-onlinecourse-bytitle/9F896668D7EB5CA948256A710030E157?OpenDocument

    附录B:vi 命令常见问题解答
    http://www.linuxsir.com/bbs/showthread.php?s=&threadid=23957
    附录C:命令行下在线教程:
    运行vimtutor即可学习!

    vi 命令常见问题解答

    作者:译者Elale

    [vi-faq中文版]

    0.0 - 引言 -- 我怎样用这个FAQ

    这个文档分为了几个部分.首先,第0节和第1节介绍了什么是vi;第2节则收录了很多新
    学者的问题,一些对vi没有很多经验的人也经常问这些问题.这里面包括诸如“命令模式
    和插入模式之间的区别”,以及“我怎样拷贝和粘贴”之类的问题.第3节是面向vi的中级
    用户的,它从问题“我如何查找和替换”开始,逐步深入,直到对vi里面的宏(Macro)的
    用法讨论为止.第3节还包括了一个vi的快速参考,有一个规范的vi命令列表.再下面,
    是一个有关“:set”命令的列表,包含了所有能定vi环境的变量,这些变量也可以在
    .exrc文件中定义.

    我们已经在一个运行SunOS和UCB版本vi的机器上验证了快速参考.除了SunOS带的vi外,
    每个命令都可以在系统V和UCB版本vi运行,但是我个人并没有验证这一点.

    除非我们在文档中指明,缺省我们假定你处在命令模式下.

    我们还尝试保留尽可能多的术语,因为在原始的vi文档中使用了这些术语,尽管我可能
    忘了它的本来含义.

    0.1 - 索引

    第一个文件:

    0.0 - 引言 -- 我怎样用这个FAQ?
    0.1 - 索引
    0.2 - 我可以散发这个FAQ吗?
    0.3 - 你能为这个FAQ做什么?

    1.0 - 什么是vi?
    1.1 - 关于vi有什么重大的交易? 为什么大家都用它? 更进一步说,为什么我要用它?
    1.2 - 噢! 这听起来不错! 有没有理由不用vi?
    1.3 - vi能在多少不同的操作系统下面运行?
    1.4 - 好吧, 你说服了我. 我决定开始使用vi. 我该从哪儿开始?
    1.5 - vi有其他一些可用的变种吗?

    2.0 - vi入门
    2.1 - 有什么游戏帮助我们学习vi吗?
    2.2 - 命令模式和插入模式有什么区别?
    2.3 - 等等,我的键盘没有键,我该怎么办?
    2.4 - 那些~s是什么东西?
    2.5 - 我无法习惯用 hjkl, 你有什么建议吗?
    2.6 - 我如何才能不存盘就退出?
    2.7 - 我怎样插入一个文件?
    2.8 - 我怎样查找文本?
    2.9 - 我怎样搜索一个控制序列?
    2.10 - 我怎样重新格式化文本?
    2.11 - 我怎样复制文本?
    2.12 - 啊! 我刚才敲了一个dG,然后我的论文就没有了! 我该怎么办?
    (或者,我刚才犯了个错误,我该怎么办?)
    2.13 - 我正在写我的论文,被告知我必须将每一节都放在不同的文件,我该怎么办?
    2.14 - 所有的:命令都是怎样处理的?

    3.0 - 怎样查找和替换?
    3.1 - 我怎样在vi中运行一个程序?
    3.2 - 啊! 我正在写我的论文, 系统崩溃了! 怎么办?
    3.3 - 有没有使vi对程序员更友好的窍门?
    3.4 - 宏 -- 我怎样写宏?
    3.5 - 我怎样将一个功能键定义成一个宏?
    3.6 - 有没有办法缩写文本?
    3.7 - 我怎样在当前文档中做拼写检查?
    3.8 - 我手头有一个硬拷贝的终端, 我还能用vi吗?
    3.9 - 好了,是不是处在开放模式下的原因呀?! 但是我现在没有用硬拷贝终端,
    它还是在开放模式呀?

    第二个文件:

    4.0 - vi档案的在线帮助在哪?
    5.0 - 好玩的vi诀窍,无聊的宏
    5.1 - 好玩的vi诀窍
    5.2 - 好玩的宏
    6.0 - 依字母顺序的vi快速参考
    6.1 - 命令模式的输入选项(:命令)
    6.2 - 设置选项(set)
    7.0 - 建立 .exrc文件
    7.1 - .exrc文件的样本
    8.0 - vi的漏洞
    9.0 - 术语表
    10.0 - 关于vi的参考书目

    0.2 - 我可以散发这个FAQ吗?

    可以!只要你没有对它做任何修改,或者用它来赚钱.

    0.3 - 你能为这个FAQ做什么?
    首先, 把你发现的错误告诉我. 如果你有什么建议我们也很欢迎. 你认为还不清楚的
    地方告诉我们,我们同样欢迎. 还有, 使用vi! (Spread the word) 我很抱歉我无法将
    所有对这FAQ有贡献的人都列出来, 因为许许多多的人都给过我建议和帮助,如果我将
    他们都列出来的话,那么恐怕这张贡献者的清单将和这个文档本身一样长了.

    1.0 - 什么是vi?
    vi是个可视化的编辑器(vi就意味着可视化--VIsual). 那么,什么是可视化的编辑器呢?
    (相对于非可视化的编辑器来说)?可视化的编辑器就是可以让你在编辑文本的时候看到
    它们.今天,这听起来似乎非常普通,反之,非可视化的编辑器似乎很奇怪. 非可视化的
    编辑器的例子可以举出不少:如ed, sed和edlin(直到相当近的一段时间内,它是DOS自带
    的最后一个编辑器) 等.vi是威廉.侨伊写的,作为BSD UNIX的一部分. 后来AT&T也开始
    用vi, 于是标准UNIX也开始用vi了.

    1.1 - 关于vi有什么重大的交易吗? 为什么大家都用它? 更进一步说,为什么我要用?
    vi是UNIX下面的缺省编辑器, 因此几乎近来所有的UNIX都捆绑了vi(近来是指1984年左右).
    这意味着无论何时你跨平台使用某种UNIX,你都知道在你指尖下面有一个强力的编辑器.
    为什么不是别的呢? vi是个强大的编辑器.同样,一旦你了解了vi,你就能很快的编辑你的
    文件,因为它非常能节省你的敲键次数. 由于它在插入和命令两种情况下使用不同的模式,
    它比大多数的不基于这种模式的编辑器要快. 而且,vi非常小(我机器上面的版本只有
    200K).还有,vi几乎能做任何事,只要你知道如何使它做你想做的事.

    1.2 - 噢! 这听起来不错! 有没有理由不用vi?
    有. 有一个非常好的理: vi稍微有些难学, 如果你开始学的话,vi又慢又让人痛苦,
    当然,一旦你学会了, vi就快多了. 但是学习的过程很慢. 有人曾经问我, 如果vi是个
    比较易学的编辑器, 它是否直观(intuitive)呢? 我一般这样回答:"是的,我们有些人是
    这样认为.但是大多数人认为我们疯了."

    1.3 - vi能在多少不同的操作系统下面运行?
    UNIX. 就是它. 尽管如此,还是有很多vi的变种运行在不同的操作系统上. 我就在以下
    一些操作系统上用过vi: UNIX, DOS, OS/2, MAC SYSTEM 7.(后面有一个有关细节的列表)

    1.4 - 好吧, 你说服了我. 我决定开始使用vi. 我该从哪儿开始?
    好吧, 狡猾的家伙. 关于vi有很多很好的书:大多数讲UNIX的书至少有一章给了vi,而且
    有不少是专门讲vi的书.我没有什么偏爱. 所以你最好是问问你们那儿的vi高手们他们
    是从哪儿学来的. 还有,到处试. 用vi打开一个不重要的文档(你的论文不象是个学vi的
    好实验品),然后再到处. 我无法想象有人学习vi却不花相当多的时间去到处试试. 记住:
    如果你有些地方不明白了, 只要敲两次键,你就又回到命令模式下了. 我要提到的
    一点是,我想在这里提比较合适,就是如果要成为系统管理员或者其他对UNIX配置
    做什么修改的话,最好是学学ed或者ex,因为有些版本的UNIX没有把vi放在根分区里面,
    这样你就可能无计可施了. ed是个不错的选择.

    1.5 - vi有其他一些可用的变种吗?
    只能列出一部分:STvi (STevie), elvis, vile, vim, 和nvi, xvi.
    elvis适用于:Amiga, DOS, OS/2, Unix, VMS, Atari.
    STevie适用于: Atari ST, DOS, Unix, Mac System 7.
    Mac System 7可以在很多info-mac的镜象站点获取,在/info-mac/text下.
    (例如ftp.hawaii.edu)
    nvi是将和BSD 4.4捆绑在一起的vi.
    vim适用于: Amiga, DOS, Mac System 7, Unix.
    Amiga, DOS,和源码可以在以下站点换取:ftp.fu-berlin.de /misc/editors/vim
    Mac System 7可以在很多info-mac的镜象站点获取,在/info-mac/text下.
    (例如ftp.hawaii.edu)
    vile适用于: DOS, OS/2, Unix, VMS.
    xvi适用于: DOS, Unix.
    vi的变种之间很有很多差异.很多都改进了vi,大多数都可以使用在这个文档
    种列出的命令,但是有一些不同的地方.更进一步的细节,你可以参考这些变
    附带的相应的文档.

    2.0 - vi入门
    对vi的初学者来说,有些基本的提示.第一,任何时候,手头都要有一份命令摘要.
    我们将在后面给出一个快速参考/命令摘要. 第二, 找一本vi方面的比较好的书.
    这个文档不是学vi的最佳途径(最起码现在还不是),我不敢保证这个文档能教会一个
    对vi一无所知的人, 而很多书已经做到了这一点. 但是,我们这里还是给出了不少
    提示. 对选择书籍来说,有一个标准的原则:买之前一定要仔细阅读. 要了解这本书
    对你是否有意义.确信它能在你练习vi的时候有用. 和其他的书做个比较 -- 不管怎样,
    vi可能让你感到非常莫名其妙, 而且你要确信这么一点:是书让你糊,而不是
    你低估了学vi的难度.
    还有, 找一些诸如"学vi"(vilearn),"vi向导"(vitutor)之类的软件来帮助你掌握
    vi的基本知识.

    2.1 - 有什么游戏帮助我们学习vi吗?
    这似乎很无聊, 但是事实上UNIX系统里面有不少游戏可以帮助你学习使用vi.这些帮助
    主要是一些基本知识. 虽然我还不知道有哪个游戏可以帮你学习vi的所有命令, 但我
    确实知道有一些可以帮助你学习使用 hjkl来移动光标. NetHack,一个类Rogue的游戏,
    就对这非常有帮助. 而且它是一个很大的游戏,能玩很长一段时间. 我没有贬低其他游戏
    的意思,这些游戏是: rogue, moria, omega, worm, snake.)

    2.2 - 命令模式和插入模式有什么区别?
    vi将命令模式和插入模式区分开来,这经常被认为是vi的一个大问题,但往往这也被认为是
    vi的优势所在. 理解其中的区别是掌握vi的关键.vi启动时,开始处于命令模式;在这种模式
    下,我们可以在文件中到处移动,改变文本的某个特定区域, 剪切, 复制和粘贴文本,还有更
    多. 插入模式是指用户可以真正插入文本.换句话说,命令模式是用来在文件中移动,而插入
    模式是用来在文件中键入文本. 有些命令,例如: a, i, c, C, O, o和其他一些可以从命令
    模式切换到插入模式. 键或者^C(CRTL+C)可以脱离插入模式而返回到命令模.
    你要适应这种差别. 它使得vi区别于其他的编辑器. 它也使你能在你的手不离开标准
    键盘做很多事情.

    2.3 - 等等,我的键盘没有键,我该怎么办?
    试试敲 ^[(CTRL+[). 如果你的键盘有一个《Meta》键,再试试它.如果还不行,再试试^3.

    2.4 - 那些~s是什么东西?
    它们仅仅是用来让你知道你的文档末尾在哪儿.实际上它们并不在你的文档里面,所以
    你用不着担心它们.

    2.5 - 我无法习惯用 hjkl, 你有什么建议吗?
    首先,如果你的终端设置正确而且你连接的也没有问题的话,你可以使用箭头键.但是,
    如果你认为你要经常使用vi,那么最好是习惯使用 hjkl,因为它们敲起来更. 而且,
    有时候连接出问题了,使得ESC序列都可能丢失了.(这样你可能就无法使用箭头键了--译注)

    2.6 - 我如何才能不存盘就退出?
    :q!可以做到这一点. 如果vi看起来冻住了,确信你没有错敲了个 ^S. 敲^Q可以解开^S.

    2.7 - 我怎样插入一个文件?
    :r <文件名>
    例如,要插入文件/etc/motd, 可以敲 :r /etc/motd.
    这将把文件插入到光标处.如果你在r前面指定了一个数字,那么这条命令将把文件插入
    到那个位置.

    2.8 - 我怎样查找文本?
    /<文本>将向前查找, ?<文本>将向后查找. ??或者//将重复上次查找. 在UNIX下,这已经
    是个可爱的标准用法了. 而且, 在vi中, n将查找文本下一次的出现位置. N重复上次查找,
    不过逆转了查找的方向. 在查找中可以使用规范.

    2.9 - 我怎样搜索一个控制序列?
    /^V^<序列>
    ^V会告诉vi照字面理解下一个字符,不要把它看作是一条命令.

    2.10 - 我怎样重新格式化文本?
    如果你的计算机有一个名叫fmt的程序, 你要做的仅仅是在命令模式下面敲!}fmt(记住,
    不要在前面加. 这可以重新格式化你的文件,从光标所在的位置一直到当前段落的结尾.
    如果你的机器里面没有fmt这个程序, 你就得去找个类似的软件了(我记得在公共域里面
    有不少这样的程序,但是我对此了解不多)

    2.11 - 我怎样复制文本?
    这有点复杂.把这节拿出来,多看几遍;还有,一定要多做实验.
    "<字母>yy可以把一行文本拷贝到寄存器中(这里的寄存器是vi的术语,指可以存放剪切和
    拷贝下来的东西的地方), <字母>里面的字母必须是a到z之间的一个. "<字母>dd可以把
    一行剪切下来放到寄存器里面. 你可以在yy或者dd前面用数字指明要拷贝或者剪切的
    行数.如果<字母>中的字母是大写的话,意味着把文本插入到寄存器中已有的文本之前.
    "<字母>p把文本插入到光标之后,"<字母>P把文本插入到光标之前.如果寄存器中含有某
    一行的开头或结尾,这一行将会被放到另一合适的行. Y是yy的快捷方式. 还有, y$, yH,
    yM,等等,都是可以用的.d命令也是一样的.如果要快速的剪切和粘贴, 你就无须指定寄存器
    了.如果这样的话,你就不能往寄存器里面添加文本了.而且只要有一个删除命令的话,
    寄存器中的东西就没有了(包括x命令). 举例来说,如果要移动上一段的话,你可以把光标
    移到段落的开头,敲"a13dd,再把光标移到你想要放文本的地方,敲"ap,就可以把那段文本
    放到光标所在的行后面. 现在,大概你想要剪切和粘贴文本到不是行末尾的区域去.我们
    来看如何做到这一点:我们可以使用 m<字母> 命令来标记一个区域,这个字母可以和
    剪切/粘贴寄存器的字母相,因为它们是保存在内存中的不同位置. 然后,
    敲"<寄存器>`<字母>[yy或者dd], 这里的寄存器就是要保存文本的那个寄存器,<字母>
    是用来标记的,yy和dd是你的操作.

    2.12 - 啊! 我刚才敲了一个dG,然后我的论文就没有了! 我该怎么办?
    (或者,我刚才犯了个错误,我该怎么办?)
    u可以撤消你刚才的操作.U可以撤消你对当前行的修改(当然,一行对于一篇论文来说当然
    很不够了). :e!可以不保存修改而重新把你的文件调进来. 还有,你删除的文本都保存在从
    0到9编号的寄存器里.所以,"p就可以把上第n次的删除文本粘贴出来.你可以按如下的
    方法迅速地查看所有删除的文. 先试一个,不对的话,敲u,再试下一个.(为加速这个过程,
    这时vi中的.命令和通常的用法不一样了.它不是重复上次操作,而是试下一个寄存器,这样
    你要做的无非就是: "1p u . u .,直到你撤消了你想撤消的删除操作)

    2.13 - 我正在写我的论文,被告知我必须将每一节都放在不同的文件里,我该怎么办?
    :[m],[n]w <文件名>可以将从第m行到第n行之间的文本保存到<文件名>所指定的文件中.
    这种行序号方法几乎在所有的:命令下都可以使用. 如果你用命令:[m],[n] w >><文件名>,
    这些文本将添加到文件的后面.

    2.14 - 所有的:命令都是怎样处理的?
    :后面的命令都是从ex编辑器里面过来的. 这就给vi加入了很多灵活性,也使vi功能更强
    大. 例如, 有很多的方法可以用来查找和替换,它们有很多的类似地方(事实上,它们在
    某种意义上说都是一样的)

    3.0 - 怎样查找和替换?
    有很多方. 最简单的是:
    :s/old/new/g, 但是,这仅对当前行起作用..., 所以,我们用
    :%s/old/new/g, 更一般的,我们还可以用
    :[范围]s/old/new/[cg],这里,[范围]是任意的行范围,包括行号,$(文件末尾),.(当前行),
    %(当前文件),或者两个行号之间加个破折号(或者可以这样: .,+5,这表示下面5行).
    [cgi]是c,g,i中间的一个或者什么也没有.c告诉vi每次替换的时候要给提示,g是说对
    所有一行中出现的地方都做替换.i则是指在查找时不区分大小写.如果最后一个斜杠(/)
    后面没有东西的话,那么vi只替换在行中第一次匹配的地方. 我比较喜欢这样做:
    :g/foobar/s/bar/baz/g, 这个命令首先搜寻foobar,然后把它变成foobaz. 它没有改变
    jailbars, 而其他的一些命令可能会改变jailbars. 这是我的方法,但是可能比较难记.
    当然,你还可以在查找的的时候使用正规式,以及在替换文本的时候使用其他一些命令.如果
    你在正规式里用\(和\)来剥离一个序列的话,你会发现你可以做很多好玩的事情. 例如:
    :g/\(foo\)\(bar\)/s/\2/\1baz/g 将foobar替换成foobaz
    还有一些特殊的序列:
    & 所有查找时匹配到的东西
    \[1-9] 1到9号用\(和\)括起来的东西
    \u 下一个字符将被变成大写.
    \U 以后的字符都变成大写,直到遇到\e或\E
    \l 下一个字符将被变成小.
    \L 以后的字符都变成大写,直到遇到\e或\E
    \[Ee] 更改大小写的选择区域的终点

    3.1 - 我怎样在vi中运行一个程序?
    :!命令 可以在vi中运行程序. :sh会启动一个交互式的外壳(SHELL).在这个外壳
    里面, 如果你愿意,你还可以再次运行vi. 当你在编辑Makefiles和配置文件来编译
    某个程序的时候,这可能比较有用. 这比:e优越之处在于它无须保存文件,而且如果
    你退出外壳的时候,vi还回到原来的地方.(当然,我还是建议你先保存一下文件)

    3.2 - 啊! 我正在写我的论文, 系统崩溃了! 怎么办?
    不要怕! 你会收到一封电子邮件,里面就是你的论文.敲入vi -r <文件名>
    (这个文件名就是系统崩溃时你正在编辑的文件)你就可以恢复出你的论文来.只敲
    vi -r将把所有可能恢复的文件都列出来.

    3.3 - 有没有使vi对程序员更友好的窍门?
    :set ai可以让vi自动对齐.
    :set sw=#,#是移动的宽度(shiftwidth),或者说TAB键的宽度(tabwidth);你可以
    用<<或者>>命令来左移或右移某一行. 还有, 你可以使用 <%或>%来将{,(或[等符号
    括起来的文本都左移或右移;这时候,你必须把光标放在这些符号({,(或[)上面.
    :set sm会在你敲},]或)显示出对应匹配的{,[或(来.
    :set lisp会对lisp编程有些帮助. ()被移到s表达式(s-expressions)外面,如果
    原子(atoms)没有停止则{}将被移走.

    3.4 - 宏 -- 我怎样写宏?
    :map , 其中最多10个字符,最多100个字符. 以后,如果
    你敲了,vi就会用来取代它.所有的宏都是在命令模式下开始的,但是可以
    在你想在的模式下终止. 记住,在你想用的控制字符前面加上^V.
    :unmap 将删除这个宏. :map! 使得插入到文档
    中去.

    3.5 - 我怎样将一个功能键定义成一个宏?
    如果是#n,n是0-9之间的一个数,那么这个宏就映射成某一个功能键了.(你
    可以试一下F1-F10之间的键--译者)

    3.6 - 有没有办法缩写文本?
    当然了. 这可是vi呀,它能做任何事情!
    :ab email ellidz@midway.uchicago.edu 可以在你敲完email后,把那个没有缩写
    的文本插入到文件中. :una email取消缩写.

    3.7 - 我怎样在当前文档中做拼写检查?
    这儿有一个宏可以做到这一点. 这些应该放在你的.exrc文件中(后面我们将对.exrc
    进一步讨论). 它是一个相当简单的宏. 它仅仅是调用ispell来处理当前文件.当然,你
    的系统里面一定得有ispell这个程序. 使用它的时候,只需要敲个V键就行了(因为vi并
    没有用V,所以V是一个比较合适的键)

    map V :w^M:!ispell % ^M:e!^M^M
    第二个^M使你在拼写检查完之后无须敲回车就可以到vi中.
    (译注, 在我的系统里,没有ispell,只有spell,我用它替换了ispell,工作的不错;还有,
    ^M不是两个字符,而是一个字符,通过^V^M敲进去的;另外,我个人认为第二个^M还是不要
    的好,因为直接回到vi后你就无法看到拼写检查的结果了)

    3.8 - 我手头有一个硬拷贝的终端, 我还能用vi吗?
    好了,好了. 我并认为有人会真的问这个问题.这个问题太偏了,我们大可不必理
    它.(而且,它回答了一个非常普通的问题)
    vi启动的时候处于一种特殊的模式下面,叫做"开放模式"; 在这种状态下,事情或多或少
    的有些不同. 删除的字符在你面前显示成一\',vi会认为你的终端窗口只有一行. ^r
    可以把当前行重新输出. z则把当前行周围的窗口重画一遍.

    3.9 - 好了,是不是处在开放模式下的原因呀?! 但是我现在没有用硬拷贝终端,它还是在
    开放模式呀?
    这儿的问题就是vi没有认出你用的终端的类型. 于是它假定你有的是个最烂的终端,
    所以它决定依然处在开放模式下.这似乎没什么用处.因为没有多少人喜欢开放模式,但是
    开放模式还是需要知道你的终端的一些最起码的信息的. 现在,我们来看如何解决这个
    问题.我们有可能把它分成几种特殊的情形,但是,一般情况下, 这并没有用处. 如果你
    直到你的终端的类, 你可以在UNIX提示符下面设置终端类型(在CSH及其变种下面,使用
    命令setenv TERM <终端类型>;在SH及其变种下面,使用命令TERM=<终端类型>;
    export TERM) 最好你能把上面的命令写在.profile文件或者.cshrc文件里面,这样你
    一登录它就自动地给你设置好了.(当然,你应该知道如何使用ed,或者你能在UNIX提示符
    下面设置好终端类型以便能使用vi, 这样你才有可能去编辑这些文件).如果你确实不
    知道你地终端类型,试一试vt100.现在大多数地终端或者终端仿真器都能仿真vt100.
    如果这还不能生效的话,你只好去找个高手来帮你了.

    4.0 - vi档案的在线帮助在哪儿?
    有一个vi的FAQ,其中列出了vi档案的所有在线文件. 同时它还列出了这些文档
    的镜象站点. 最主要的一个地址是alf.uib.no,但是这些文档在很多很多地地方
    都保存着. vi-archive faq把它们都给列出来了.你在下载这些文件之前一定要
    核对一下这个FAQ.因为很有可能有一个站点比去挪威的站点更近更快些.
    一个镜象站点是cs.uwp.edu/pub/vi, 另一个是monu6.cc.monash.edu.au/pub/Vi,
    这些站点上有很多有关vi的文件,还有一些vi的变种版本;当然,UCB版本的vi是
    肯定有的, 还有许多的宏.

    5.0 - 好玩的vi诀窍,好玩的宏
    这一节主要讲述一些无聊的诀窍和一些无聊的.事实上,任何vi的诀窍和宏我们
    都欢迎,只要它们不是过分冗长. 如果有人向我建议而我也认为确实值得加的话,
    我会考虑加进去的.

    5.1 - 好玩的vi诀窍
    xp 删除光标下的字符,再把粘贴到后面去.换句话说,它交换了当前两个字符
    的位置. ddp 和xp类似,不过是交换两行的位置.
    uu 撤消和重复上次所做的修改.(这可以使你不改变什么东西就可以到你上次所
    做的修改处)

    5.2 - 好玩的宏
    和垂直上方的字符交换位置
    map * kxjphxkP

    折行
    map g $80|F r
    (译注,我对这条宏表示疑问!)

    改变大多数单词的大小写
    map v ywmno:s/./\~/g
    (译注,这条好象也不大对!)

    在当前的单词周围加上`和'
    map *` i`'
    在当前的单词周围加上'和'
    map *' i''
    在当前的单词周围加上"和"
    map *" i""
    (这几条也太无聊了吧--译注)
    在当前的单词周围加上``和``
    map! `` `'
    (咦,好象又有问题?--译注)

    从光标处把当前行分开,在下一行开头加上一个>号(例如,引用USENET).如果加上了单词的折行
    功能那么最后一个单词可能被折在第一行.
    map g may0O`ay$:s/./ /g
    (不对吧--译注)

    插入一个字符
    map g i$^[r

    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命令)
    保存之后退出
    :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) 显示所有的制
    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 可以保存到任意一个文件去

    (译注--这些选项在各种vi版本中都基本上大同小异,以SunOS带的vi为例,它没有这里列
    出来的open选项, scroll的参数值也不同,还多出来一些选项,如flash,modelines,
    novice,tagstack等等)

    7.0 - 建立 .exrc文件
    所有命令输入模式下的命令(即 :命令)都可以在.exrc文件中使用,在.exrc中的命令在

    vim&gvim技巧大全(1)

    vim&gvim技巧大全(1)
    li3 发表于 2006-2-27 14:25:00
    http://blog.21ic.org/user1/313/archives/2006/9667.html
    0
    推荐d0 表示删除从当前光标到光标所在行首的内容.
    y$ 表示拷贝从当前光标到光标所在行尾的内容.
    d$ 表示删除从当前光标到光标所在行尾的内容.
    yfa 表示拷贝从当前光标到光标后面的第一个a字符之间的内容.
    dfa 表示删除从当前光标到光标后面的第一个a字符之间的内容.

    特殊地:
    yy 表示拷贝光标所在行.
    dd 表示删除光标所在行.
    D 表示删除从当前光标到光标所在行尾的内容.

    关于拷贝, 删除和粘贴的复杂用法与寄存器有关, 可以自行查询.

    4. 数字与命令
    在 vi 中数字与命令结合往往表示重复进行此命令, 若在扩展模式的开头出现则表示行
    号定位. 如:

    5fx 表示查找光标后第 5 个 x 字符.

    5w(e) 移动光标到下五个单词.

    5yy 表示拷贝光标以下 5 行.
    5dd 表示删除光标以下 5 行.

    y2fa 表示拷贝从当前光标到光标后面的第二个a字符之间的内容.

    :12,24y 表示拷贝第12行到第24行之间的内容.
    :12,y 表示拷贝第12行到光标所在行之间的内容.
    :,24y 表示拷贝光标所在行到第24行之间的内容. 删除类似.

    5. 快速输入字符
    在 vi 中, 不要求你输入每一个字符, 可以有很多种方法快速输入一些字符.
    使用 linux/unix 的同学一定有一个经验, 在命令行下输入命令时敲入头几个字符再按
    TAB 系统就会自动将剩下的字符补齐, 假如有多个匹配则会打印出来. 这就是著名的命令
    补齐(其实windows中也有文件名补齐功能). vi 中有许多的字符串补齐命令, 非常方便.

    c-p(c-n) 在编辑模式中, 输入几个字符后再输入此命令则 vi 开始向上(下)搜
    索开头与其匹配的单词并补齐, 不断输入此命令则循环查找. 此命令
    会在所有在这个 vim 程序中打开的文件中进行匹配.

    c-x-l 在编辑模式中, 此命令快速补齐整行内容, 但是仅在本窗口中出现的
    文档中进行匹配.

    c-x-f 在编辑模式中, 这个命令表示补齐文件名. 如输入:
    /usr/local/tom 后再输入此命令则它会自动匹配出:
    /usr/local/tomcat/

    abbr 即缩写. 这是一个宏操作, 可以在编辑模式中用一个缩写代替另一个
    字符串. 比如编写java文件的常常输入 System.out.println, 这很
    是麻烦, 所以应该用缩写来减少敲字. 可以这么做:
    :abbr sprt System.out.println
    以后在输入sprt后再输入其他非字母符号, 它就会自动扩展为System.
    out.println

    6. 替换
    替换是 vi 的强项, 因为可以用正规表达式来匹配字符串.以下提供几个例子.

    :s/aa/bb/g 将光标所在行出现的所有包含 aa 的字符串中的 aa 替换为 bb
    :s/\/bb/g 将光标所在行出现的所有 aa 替换为 bb, 仅替换 aa 这个单词
    :%s/aa/bb/g 将文档中出现的所有包含 aa 的字符串中的 aa 替换为 bb
    :12,23s/aa/bb/g 将从12行到23行中出现的所有包含 aa 的字符串中的 aa 替换为 bb
    :12,23s/^/#/ 将从12行到23行的行首加入 # 字符
    :%s= *$== 将所有行尾多余的空格删除
    :g/^s*$/d 将所有不包含字符(空格也不包含)的空行删除.

    7. 多文件编辑
    在一个 vim 程序中打开很多文件进行编辑是挺方便的.

    :sp(:vsp) 文件名 vim 将分割出一个横(纵)向窗口, 并在该窗口中打开新文件.
    从 vim6.0 开始, 文件名可以是一个目录的名称, 这样, vim 会
    把该目录打开并显示文件列表, 在文件名上按回车则在本窗口打
    开该文件, 若输入 O 则在新窗口中打开该文件, 输入 ? 可以看
    到帮助信息.

    :e 文件名 vim 将在原窗口中打开新的文件, 若旧文件编辑过, 会要求保存.

    c-w-w vim 分割了好几个窗口怎么办? 输入此命令可以将光标循环定位
    到各个窗口之中.

    :ls 此命令查看本 vim 程序已经打开了多少个文件, 在屏幕的最下方
    会显示出如下数据:
    1 %a "usevim.html" 行 162
    2 # "xxxxxx.html" 行 0

    其中:
    1 表示打开的文件序号, 这个序号很有用处.
    %a 表示文件代号, % 表示当前编辑的文件,
    # 表示上次编辑的文件
    "usevim.html" 表示文件名.
    行 162 表示光标位置.

    :b 序号(代号) 此命令将指定序号(代号)的文件在本窗口打开, 其中的序号(代号)
    就是用 :ls 命令看到的.

    :set diff 此命令用于比较两个文件, 可以用
    :vsp filename
    命令打开另一个文件, 然后在每个文件窗口中输入此命令,就能看
    到效果了.

    8. 宏替换
    vi 不仅可以用 abbr 来替换文字, 也可以进行命令的宏定义. 有些命令输起来很费劲,
    因此我把它们定义到 - 上, 这样就很方便了.这些配置可以预先写到 ~/.vimrc
    (windows 下为 $VIM/_vimrc) 中, 写进去的时候不用写前面的冒号.

    :nmap :nohls 取消被搜索字串的高亮
    :nmap w 命令模式下转移光标到不同窗口
    :imap 输入模式下运行
    :nmap :%s= *$== 删除所有行尾多余的空格.
    :imap 同上

    :java 中: (注, 这里为什么说 java 中, 因为以下定义对其他文件格式不起作用, 下文
    会说到如何实现这一点)
    :nmap :comp javac:mak -d . %
    此命令用 javac 编译 java 文件, 它会自动将光标定位到出错点. 不过这需要定
    义一个 javac.vim 文件在 $VIM/compiler 下, 在 javac.vim 里面只有两行字:
    setlocal makeprg=javac
    setlocal errorformat=%A%f:%l:\ %m,%-Z%p^,%-C%.%#

    :nmap :comp ant:mak
    此命令用 ant 编译 java 文件, 它会自动将光标定位到出错点. 一般来说, 安装
    vim 后已经有了compiler/ant.vim文件, 因此这个命令可以直接使用. 但是需要
    在当前目录下有 build.xml 文件, 当然还必须安装 ant 才行.

    :nmap :cl 此命令用于查看所有的编译错误.
    :imap

    :nmap :cc 此命令用于查看当前的编译错误.
    :imap

    :nmap :cn 此命令用于跳到下一个出错位置.
    :imap

    :nmap :cp 此命令用于跳到上一个出错位置.
    :imap

    :nmap :JavaBrowser
    此命令用于在窗口左部分割出一个新窗口, 里面的内容是 java 的资源树, 包括
    本文件中出现的类, 类的成员变量及成员方法, 就好像 JCreator 表现的那样.
    在这个窗口中输入 ? 会看到帮助. 嘿嘿, 很好用, 不过需要 ctags 支持.
    :imap

    9. TAB
    TAB 就是制表符, 单独拿出来做一节是因为这个东西确实很有用.

    << 输入此命令则光标所在行向左移动一个 tab.
    >> 输入此命令则光标所在行向右移动一个 tab.
    5>> 输入此命令则光标后 5 行向右移动一个 tab.
    :12,24> 此命令将12行到14行的数据都向右移动一个 tab.
    :12,24>> 此命令将12行到14行的数据都向右移动两个 tab.

    那么如何定义 tab 的大小呢? 有人愿意使用 8 个空格位, 有人用4个, 有的用2个.
    有的人希望 tab 完全用空格代替, 也有的人希望 tab 就是 tab. 没关系, vim 能
    帮助你.以下的设置一般也都先写入配置文件中, 免得老敲.

    :set shiftwidth=4 设置自动缩进 4 个空格, 当然要设自动缩进先.
    :set sts=4 即设置 softtabstop 为 4. 输入 tab 后就跳了 4 格.
    :set tabstop=4 实际的 tab 即为 4 个空格, 而不是缺省的 8 个.
    :set expandtab 在输入 tab 后, vim 用恰当的空格来填充这个 tab.

    10. autocmd
    这个命令十分的强大, 可以用这个命令实现对不同的文件格式应用不同的配置; 可以
    在新建文件时自动添加上版权声明等等. 这些命令一般定义在 ~/.vimrc 这样的配置文件
    里面. 由于他很强大, 所以我不能给出很具体的说明, 只能举几个例子, 详细的请看帮助.

    :autocmd! 删除所有之前的自动命令.
    autocmd FileType java source ~/.vim/files/java.vim
    autocmd FileType java source ~/.vim/files/jcommenter.vim
    以上两条命令让我在打开 java 文件时才应用后面提到的两个配置文件.
    autocmd BufNewFile *.java 0r ~/.vim/files/skeletons/java.skel
    以上这条命令让我在新建 java 文件时自动加入 java.skel 文件的内容.
    autocmd BufNewFile *.java normal gnp
    以上这条命令让我在新建 java 文件时自动运行 gnp 命令, 这个命令进行一些特殊化
    处理, 比如将新 java 文件中的 __date__ 替换成今天的日期什么的.

    11. 常用脚本
    在 vim.sf.net 你可以发现很多脚本(script), 这些脚本常常有让你意想不到的作用.
    我常用的有:

    jcommenter.vim 自动加入 javadoc 风格的注释.
    JBrowser.vim 类资源浏览. C, C++ 等可以用 Tlist

    还有许多有用的, 比如 checkstyle.vim 可以检验你的编程风格, jad.vim 可以直接
    反编译 .class 文件等等.

    12. 常用配置
    在~/.vimrc 配置文件中你常常需要一些个性化配置. 比如上面写的一些宏定义, 一些
    autocmd 定义等等. 比如:

    set suffixes=.bak,~,.o,.h,.info,.swp,.aux,.bbl,.blg,.dvi,.lof,.log,.lot,.ps,.toc
    这样在vim中打开文件时, 按 tab 键补齐文件名时它会忽略上述文件.

    set nu 显示行号
    set ai 设置自动缩进
    map Y y$ 让 Y 和 D 一样, 要不然 Y 的本意和 yy 一样.

    13. 其他
    还有许多有意思的命令, 记录在这里免得忘记.

    . 重复上次编辑命令.
    :g/^/exec "s/^/".strpart(line(".")." ", 0, 4) 在行首插入行号
    :runtime! syntax/2html.vim 转换 txt 成 html, 会按照你的
    颜色配置来转

    VI高级命令集锦及VIM应用实例
    作者: 转自:http://linux-down.kmip.net/ 本文已被阅读:5 次
    *****************************************************************************

    本文由正泰linux http://linux-down.kmip.net 搜集,整理,如需转载,请注明出处!
    本站有大量的linux电子教程,软件,技术文档,欢迎大家访问!站长阿泰qq:253222170

    ******************************************************************************

    VI高级命令集锦及VIM应用实例

    javalee 写到:

    1.交换两个字符位置
    xp
    2.上下两行调换
    ddp
    3.把文件内容反转
    :g/^/m0/ (未通过)
    4.上下两行合并
    J
    5.删除所有行
    dG
    6.从当前位置删除到行尾
    d$
    7.从当前位置复制到行尾
    y$ 如果要粘贴到其他地方 p 就可以了

    由于vi 是建立在 EX 上的 所以 当键入 : 时就来到了 EX 命令状态
    8.
    :ab string strings
    例如 ":ab usa United States of America" ,
    当你在文见里插入 usa 时
    United States of America 就蹦出来了
    9.
    :map keys new_seq
    定义你当前 键盘命令
    10.
    :set [all]
    vi or ex 的编辑状态
    如 显示每行 :set nu
    11.
    在命令状态下,nyy表示拷贝从光标行起的下n行内容,p表示paste,可刚复制的内容粘贴在光标处的
    下面。

    12.
    单个字符替换用r,覆盖多个字符用R,用多个字符替换一个字符用s,整行替换用S

    13.

    :%s/old_word/new_word/g
    这个指令是于在整个文件中替换特定字符串

    14.光标控制

    k:上移 nk 上移n行
    j:下移 nj 下移n行

    将光标移到第n行,按下 mk
    将光标移到第m行,按下 "ay'k
    即将第n到m的行存到a寄存器,以此类推,b,c........寄存器等

    这样就可以将你常用的需要复用的内容粘贴到不同的寄存器中以备用

    想粘贴到某处,直接将光标移到某地,按下 'ap 即可,以此类推,b,c........寄存器等

    在当前屏幕中
    H 跳到第一行
    M 跳到中间一行
    L 跳到最后一行

    15.
    表8-2 删除命令
    删除命令操作
    d l 删除当前字符(与x命令功能相同)
    d 0 删除到某一行的开始位置
    d ^ 删除到某一行的第一个字符位置(不包括空格或TA B字符)
    d w 删除到某个单词的结尾位置
    d 3 w 删除到第三个单词的结尾位置
    d b 删除到某个单词的开始位置
    d W 删除到某个以空格作为分隔符的单词的结尾位置
    d B 删除到某个以空格作为分隔符的单词的开始位置
    d 7 B 删除到前面7个以空格作为分隔符的单词的开始位置
    d) 删除到某个语句的结尾位置
    d 4) 删除到第四个语句的结尾位置
    d( 删除到某个语句的开始位置
    d } 删除到某个段落的结尾位置
    d { 删除到某个段落的开始位置
    d 7 { 删除到当前段落起始位置之前的第7个段落位置
    d d 删除当前行
    d /t e x t 删除从文本中出现" t e x t"中所指定字样的位置,一直向前直到下一个该字样所出现的
    位置(但不包括该字样)之间的内容
    d fc 删除从文本中出现字符"c"的位置,一直向前直到下一个该字符所出现的位置(包括
    该字符)之间的内容
    d tc 删除当前行直到下一个字符" c"所出现位置之间的内容
    D 删除到某一行的结尾
    d $ 删除到某一行的结尾
    5 d d 删除从当前行所开始的5行内容
    d L 删除直到屏幕上最后一行的内容
    d H 删除直到屏幕上第一行的内容
    d G 删除直到工作缓存区结尾的内容
    d 1 G 删除直到工作缓存区开始的内容

    修改命令操作
    c l 更改当前字符
    c w 修改到某个单词的结尾位置
    c 3 w 修改到第三个单词的结尾位置
    c b 修改到某个单词的开始位置
    c W 修改到某个以空格作为分隔符的单词的结尾位置
    c B 修改到某个以空格作为分隔符的单词的开始位置
    c 7 B 修改到前面7个以空格作为分隔符的单词的开始位置
    c 0 修改到某行的结尾位置
    c) 修改到某个语句的结尾位置
    c 4) 修改到第四个语句的结尾位置
    c( 修改到某个语句的开始位置
    c } 修改到某个段落的结尾位置
    c { 修改到某个段落的开始位置
    c 7 { 修改到当前段落起始位置之前的第7个段落位置
    c tc 修改当前行直到下一个字符c所出现位置之间的内容
    C 修改到某一行的结尾
    c c 修改当前行
    5 c c 修改从当前行所开始的5行内容

    .重复上一次修改!

    表8-4 替换命令
    替换命令操作
    G的开头处
    " 移至当前行上一次所在位置(在光标移动之后)――一个双引号
    '' 移至当前行上第一次所在位置的行的开头处(在光标移动之后)――两个单引号

    19.
    同时vi多个文件时,CTRL-SHIFT-6回到上一个文件,在本次vi的文件和上次vi的文件之间切换。
    但是我发现一个BUG:在用CTRL-SHIFT-6切换到上一个文件后,用:args查看多文件vi状态时,
    屏幕底部仍然显示目前vi的是刚才的文件。
    (在HP-UX,Solaris,AIX上通过)

    也可以使用:
    :e#
    进行切换

    20.
    sco 下VI 要在文本前同样的字符加用
    %s/^/要加的内容/g 要在文本后同样的字符加
    %s/$/要加的内容/g

    21.
    如何去掉文本中的 ^M 硬回车?不必用binary传回去再ascii传回来的方式,用shell或者unix语句实现。

    cat filename |tr -d '\015' >newfile
    不同的unix系统还存在一些其他不同的命令,如:doscp
    sed 也可以实现这个功能.

    dos2unix filename filename2
    反之
    unix2dos filename filename2

    在vi 中用:$s/^M//g
    ^是crtl-V crtl-M

    22.如何在"unix命令行"下将一个文件的某字符串用另一个串换掉

    sed 's/string1/string2/gp' file1 > file2

    23.将/etc/hosts下所有的地址都ping 2次

    1 #/usr/bin/sh
    2 #grad /etc/hosts and ping each address
    3 cat /etc/hosts|grep -v '^#' | while read LINE
    4 do
    5 ADDR=`awk '{print $1}'`
    6 for MACHINE in $ADDR
    7 do
    8 ping $MACHINE -n 2
    9 done
    10 done

    24

    到前一个函数[[ ,到下一个函数]] ,括号配对% ,交叉参考Ctrl_] (事先用ctags做索引),回来用e# ` 编辑一个函数:vi -t 函数名 ,编辑加密文本vi -X

    25
    在插入模式下ctrl+p,自动补齐剩余单词,以赖规则:tags,以有的单词等等

    *****************************************************************************

    本文由正泰linux http://linux-down.kmip.net 搜集,整理,如需转载,请注明出处!
    本站有大量的linux电子教程,软件,技术文档,欢迎大家访问!站长阿泰qq:253222170

    ******************************************************************************

    当今世界,文本编辑器种类繁多,大有"乱花渐欲迷人眼"之势。中国有句古语:手巧不如家什妙,作为IT业的专业人士,选择一款优秀的编辑软件至关重要。笔者认为:LINUX下的VIM※以其强大的功能和无穷的魅力将使您终生受益。

    作者:闫石 (iloveibm@163.com)
    来自:http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip15/index.shtml

    由于被广泛移植,无论是PC机的DOS和WINDOWS,还是RISC/6000的AIX,乃至于IBM的大型机S/390,都能见到VIM的身影。然而,对于初学者,VIM的用户界面与使用方法非常不符合常规,甚至认为它比较混乱,无所适从。事实上,VIM编辑器是专门为经验丰富的用户设计的,它的界面和使用方法提供了更快的速度和更强的功能。对于熟知它的用户,VIM的许多特性节省了时间和击键次数,并可以完成一些其他编辑器无法完成的功能。

    学习的最好方法是实践,唯有如此,才能真正掌握其中的精髓。文中列举的实例,都是笔者在实际工作中遇到的,具有一定的代表性,请大家在阅读的过程中仔细体会。

    好了,现在让我们共同畅游神奇的VIM的世界!

    例一、两个常用的指令序列

    xp 左右交换光标处两字符的位置。
    ddp 上下交换光标处两行的位置。

    例二、重复输入同一字符

    有时,我们可能想多次输入同一字符,VIM的插入功能可以很好的完成这项工作

    命令 80i=^ESC 一次可以输入80个字符= ,当然,80a=^ESC 也可以完成上述功能。

    请注意:此处的^ESC表示键盘左上方上的ESC键。

    例三、将两个文本数据文件按行逐条合并,并给出标尺

    数据文件1内容如下:
    1-----
    2-----
    3-----

    数据文件2内容如下:
    1=====
    2=====
    3=====

    要求的结果如下:
    |--------1---------2---------3---------4---------5
    1-----
    1=====
    |--------1---------2---------3---------4---------5
    2-----
    2=====
    |--------1---------2---------3---------4---------5
    3-----
    3=====

    也许您会说,这还不简单,无非是反复拷贝、粘贴,任何一款文本编辑器都能完成上述功能。可是,如果这两个文件都很大,每个文件都成千上万行,恐怕简单的拷贝、粘贴就难以胜任了。因此,我们所关心的,是找到一种行之有效的方法,把枯燥乏味的工作留给计算机,我们只需发布指令。为达到此目的,请按以下步骤执行:

    ㈠、将两文件合并,结果如下
    1-----
    2-----
    3-----
    1=====
    2=====
    3=====

    ㈡、在两文件头尾相接的地方插入标志行,用以区分两个文件,本文采用的是一整行!字符
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    1=====
    2=====
    3=====

    ㈢、在标志行的下方输入标尺
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    ㈣、执行宏命令脚本merge_2r.vim,即在VIM编辑器中按如下键 :so merge_2r.vim 回车

    ㈤、按下键盘上的=键,执行的结果如下
    |--------1---------2---------3---------4---------5
    1-----
    1=====
    |--------1---------2---------3---------4---------5
    2-----
    2=====
    |--------1---------2---------3---------4---------5
    3-----
    3=====
    |--------1---------2---------3---------4---------5
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5

    ㈥、将最后三行删除,即可得到我们需要的结果
    |--------1---------2---------3---------4---------5
    1-----
    1=====
    |--------1---------2---------3---------4---------5
    2-----
    2=====
    |--------1---------2---------3---------4---------5
    3-----
    3=====

    怎么样,简单吗?请大家自己实际尝试一下。下面,我来详细讲解宏命令脚本merge_2r.vim 。

    该脚本内容如下:

    "--------------------------------------------------------------------
    "Macro Function : Merge File1 And File2,Have Ruler in every record
    " Date : 2001/12/01
    " Author : Yan Shi
    "--------------------------------------------------------------------
    "1-----
    "2----- } Sample File1
    "3-----
    "!!!!!!!!!!!!!!!!!!!!!!!! Flag Row
    "|--------1---------2---------3---------4---------5 Ruler
    "1=====
    "2===== } Sample File2
    "3=====
    "--------------------------------------------------------------------
    :1
    :map = ma/!!!!!^M+:.co 'a-1^M/!!!!!^M2+:.m'a^M+=

    前14行每行都以"开始,表明该行是注释行,实际并不执行,只是方便读者阅读,只有最后两行才是真正的代码行。请注意:本例中的^M表示键盘上的回车键,并非^和M两个字符。为了讲述清楚,我把命令行分解开,逐一说明。

    首先将第一行置为当前行,然后执行map命令,将一大串VIM指令映像给字符=。这一大串VIM指令共分9步执行:

    ma 将数据文件一的第一行标记为a
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    /!!!!!^M 找到标志行,置为当前行
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    + 光标下移一行,即把标尺行置为当前行
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    :.co 'a-1^M 把标尺行复制到标记行(数据文件一的第一行)的上方
    |--------1---------2---------3---------4---------5
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    /!!!!!^M 再次找到标志行,置为当前行
    |--------1---------2---------3---------4---------5
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    2+ 光标下移2行,即数据文件二的第一行置为当前行
    |--------1---------2---------3---------4---------5
    1-----
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    1=====
    2=====
    3=====

    :.m'a^M 把数据文件二的第一行移至标记行的下方
    |--------1---------2---------3---------4---------5
    1-----
    1=====
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    2=====
    3=====

    + 光标下移一行,即数据文件一的第二行置为当前行
    |--------1---------2---------3---------4---------5
    1-----
    1=====
    2-----
    3-----
    !!!!!!!!!!!!!!!!!!!!!!!!
    |--------1---------2---------3---------4---------5
    2=====
    3=====

    = 这一步很关键,是典型的递归调用,重复完成以上步骤

    例四、在文件中置入行号

    工作中,我们有时希望把行号置入文件中,而VIM提供的功能 :set nu 只能显示行号,不能编辑或将其置入文件当中,下面的宏命令脚本row_num.vim可以完成此项功能。

    "------------------------------------------
    "Macro Function : Source File Add Row_Num
    " Date : 2001/12/01
    " Author : Yan Shi
    "------------------------------------------
    :%s/^/^I/
    :$
    :let end=line(".")
    :1
    "------------------------------------------
    :let num=1
    :while num<=end
    :let line=getline(".")
    :let temp=substitute(line,$,num,"")
    :call setline(".",temp)
    :+
    :let num=num+1
    :endwhile
    "------------------------------------------

    请注意:本例中的^I表示键盘上的TAB键,并非^和I两个字符。下面,我针对该宏命令脚本逐一讲解。

    :%s/^/^I/ 每一行的行首添加一个TAB字符
    :$ 到文件的末行
    :let end=line(".") 末行的行号 ==〉变量 END,函数line的功能是取得指定行的行号,此处参数"."表示当前行
    :1 到文件的首行
    "------------------------------------------
    :let num=1 1 ==〉计数器
    :while num<=end
    :let line=getline(".") 取当前行的内容 ==〉变量 LINE
    :let line=substitute(line,$,num,"") 在变量 LINE 的前面置入行号
    :call setline(".",line) 将变量 LINE 的内容写回当前行
    :+ 下移一行
    :let num=num+1 计数器加一
    :endwhile 循环执行,直到文件结束
    "------------------------------------------

    有关正则表达式的使用

    UNIX/LINUX下的很多工具之所以强大、灵活,关键是因为有了正则文法和元字符,这也是VIM乃至UNIX/LINUX系统的精华所在。正因为使用灵活,因此掌握起来比较吃力,如果不是真正理解,实际运用中会出现千奇百怪的错误。因此,有必要对这部分知识多花些气力。下面结合具体实例讲解。

    例五、有一文件,包含某外企的中国员工的资料,首先是姓名,然后是两个空格,其次是15位身份证号码。

    zhang.fei 430759701022003
    diao.chan 651302801225012
    guan.yu 342869680413001
    xi.shi 120638780214006
    liu.bei 210324650708001

    现在,有以下问题需要解决:

    按照外国人的习惯,应该是名在前,姓在后。因此,文件中的姓名字段需要修改。
    姓与名的首字母应该大写。
    根据身份证号码,还可以判断出生年月日,将其作为一个新字段添加。
    根据身份证号码,可以判断出性别。若为男性,添加male,若为女性,添加female 。
    将男女员工分开,男员工在前,女员工在后。
    将各字段数据左对齐

    最终结果如下:

    Fei.Zhang 430759701022003 1970/10/22 male
    Yu.Guan 342869680413001 1968/04/13 male
    Bei.Liu 210324650708001 1965/07/08 male
    -----------------------------------------------
    Chan.Diao 651302801225012 1980/12/25 female
    Shi.Xi 120638780214006 1978/02/14 female

    为了完成上述功能,只需执行脚本employee.vim ,使用方法为 :so employee.vim 回车即可。

    脚本内容如下:

    :%s/ / /
    :%s/\(............\)\( *\)/\1/
    :%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/
    :%s/$/ xxxxxx/
    :%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/
    :%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3
    :%s/$/ xxxxxx/
    :%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /
    :%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/
    :$
    :s/.*/&^M-----------------------------------------------
    :g/female/.m$

    在这个脚本中,使用了大量的正则表达式,这里仅对涉及到的正则表达式做一简要介绍。有关正则表达式的内容相当多,本文不可能占用大量篇幅叙述,请大家谅解。

    % 地址范围符号,代表文件中的所有行,作用等同于地址范围 1,$
    . 与任意单字符(换行符除外)匹配,例如 y.s 可以匹配 yas y.s 或 y s 等等。
    * 与前一字符的0次或多次出现匹配,例如 y*s 可以匹配 yys yyyyys 或 s 等等。
    $ 与行尾匹配。
    & 代表模式匹配中出现的字符串,例如 s/abc/&def 是把当前行的abc替换成abcdef 。
    [] 匹配[]中出现的字符,例如[abc]匹配字符 a,b 或 c ,[a-zA-Z]匹配所有的英文字符。
    \( \) \(和\)之间出现的内容可以由\num来替代。
    \1\2\3 替代\(和\)之间出现的内容。
    \u 将后续字符串的首字母大写。
    \{num} 与前一字符的num次出现匹配。

    现在,我们对脚本逐条讲解,希望能帮助大家理解正则文法。

    ⑴:%s/ / /
    将文件中每行出现的2个空格替换为10个空格。

    zhang.fei 430759701022003
    diao.chan 651302801225012
    guan.yu 342869680413001
    xi.shi 120638780214006
    liu.bei 210324650708001

    ⑵:%s/\(............\)\( *\)/\1/
    保留行首的12个字符,将其余的空格删除,这样,前两个字段就对齐了。

    zhang.fei 430759701022003
    diao.chan 651302801225012
    guan.yu 342869680413001
    xi.shi 120638780214006
    liu.bei 210324650708001

    ⑶:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/
    将文件中每行出现的雇员姓名互换,并将首字母大写。

    Fei.Zhang 430759701022003
    Chan.Diao 651302801225012
    Yu.Guan 342869680413001
    Shi.Xi 120638780214006
    Bei.Liu 210324650708001

    ⑷:%s/$/ xxxxxx/
    在每一行的行尾添加2个空格和6个x

    Fei.Zhang 430759701022003 xxxxxx
    Chan.Diao 651302801225012 xxxxxx
    Yu.Guan 342869680413001 xxxxxx
    Shi.Xi 120638780214006 xxxxxx
    Bei.Liu 210324650708001 xxxxxx

    ⑸:%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/
    将xxxxxx替换成出生年月日。

    Fei.Zhang 430759701022003 701022
    Chan.Diao 651302801225012 801225
    Yu.Guan 342869680413001 680413
    Shi.Xi 120638780214006 780214
    Bei.Liu 210324650708001 650708

    ⑹:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3
    将年月日用/字符分隔,并在年前添加19。

    Fei.Zhang 430759701022003 1970/10/22
    Chan.Diao 651302801225012 1980/12/25
    Yu.Guan 342869680413001 1968/04/13
    Shi.Xi 120638780214006 1978/02/14
    Bei.Liu 210324650708001 1965/07/08

    ⑺:%s/$/ xxxxxx/
    在每一行的行尾添加2个空格和6个x

    Fei.Zhang 430759701022003 1970/10/22 xxxxxx
    Chan.Diao 651302801225012 1980/12/25 xxxxxx
    Yu.Guan 342869680413001 1968/04/13 xxxxxx
    Shi.Xi 120638780214006 1978/02/14 xxxxxx
    Bei.Liu 210324650708001 1965/07/08 xxxxxx

    ⑻:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /
    身份证号码末位是奇数的,将xxxxxx替换成male

    Fei.Zhang 430759701022003 1970/10/22 male
    Chan.Diao 651302801225012 1980/12/25 xxxxxx
    Yu.Guan 342869680413001 1968/04/13 male
    Shi.Xi 120638780214006 1978/02/14 xxxxxx
    Bei.Liu 210324650708001 1965/07/08 male

    ⑼:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/
    身份证号码末位是偶数的,将xxxxxx替换成female

    Fei.Zhang 430759701022003 1970/10/22 male
    Chan.Diao 651302801225012 1980/12/25 female
    Yu.Guan 342869680413001 1968/04/13 male
    Shi.Xi 120638780214006 1978/02/14 female
    Bei.Liu 210324650708001 1965/07/08 male

    ⑽:$ 到文件的最后一行

    ⑾:s/.*/&^M-----------------------------------------------
    在文件的最末行插入一行 "-" 字符。

    Fei.Zhang 430759701022003 1970/10/22 male
    Chan.Diao 651302801225012 1980/12/25 female

    vim&gvim技巧大全(0)

    第二部分:vim tips的翻译
    很多东东都对于深入认识vim有很大帮助:)

    来源:http://www.rayninfo.co.uk/vimtips.html
    原作者:d.j.rayner (zzapper)
    翻译:hmisty (lqy99@mails.tsinghua.edu.cn)
    2003-3-23
    http://blog.21ic.org/user1/313/archives/2006/9666.html
    # 最佳vim技巧
    ----------------------------------------
    # 信息来源
    ----------------------------------------
    www.vim.org : 官方站点
    comp.editors : 新闻组
    http://www.newriders.com/books/opl/ebooks/0735710015.html : Vim书籍
    http://vimdoc.sourceforge.net/cgi-bin/vim2html2.pl : 关于vim的可查询文档
    http://vimdoc.sourceforge.net/vimfaq.html : VIM FAQ
    ----------------------------------------
    # 基础
    ----------------------------------------
    * # g* g# : 寻找光标处的狭义单词() (前向/后向)
    % : 括号配对寻找 {}[]()
    matchit.vim : 使得 % 能够配对标记 《script》 : 插入模式下的单词自动完成
    : 行自动完成(超级有用)
    / : 把狭义单词 写到 搜索命令 行
    / : 把广义单词 写到 搜索命令 行
    :set ignorecase : 搜索时忽略大小写
    :syntax on : 在 Perl,HTML,PHP 等中进行语法着色
    :h regexp : 按下 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 "zdiz :在visual模式下选中的文字前后分别加上
    # 译释:vmap 是绑定一个在visual模式下的快捷键

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

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

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

    :vmap st "zdiz ?> :在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 表示一个狭义字

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

    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 是自逆算法,所以,解码和编码是同一个过程。

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

    =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,怎么又是这个评价)
    `. : 不仅跳到最后修改的那一行,还要定位到修改点
    : 依次沿着你的跳转记录向回跳 (从最近的一次开始)
    : 依次沿着你的跳转记录向前跳
    :ju(mps) : 列出你跳转的足迹
    :help jump-motions
    :history : 列出历史命令记录
    :his c : 命令行命令历史
    :his s : 搜索命令历史
    q/ : 搜索命令历史的窗口
    q: : 命令行命令历史的窗口
    : : 历史命令记录的窗口
    ----------------------------------------
    # 缩写和键盘映射(原文中文件举例都用了c:/aaa/x,偶全给他改成/path/file了,哼唧)
    :map :'a,'bw! /path/file
    # 译释:map是映射一个normal模式下的键
    # 这里是把F7键映射成把标记a到标记b中间的内容另存为一个文件/path/file
    # 标记(mark)的方法:把光标移动到需要标记的地方,输入m,然后输入标记名,例如a

    # 引用标记的方法:'a ,即:单引号加标记名

    :map :r /path/file # 译释:把F8键映射成在当前位置插入文件/path/file的内容
    :map :.w! /path/file2
    # 译释:.(点号)表示当前行
    # 所以F11就是把当前行存为/path/file2
    # 最后的表示一个回车
    :map :r /path/file2
    :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
    # 因为偶懒么,懒得按,所以直接在insert模式下就执行命令了
    # 为什么用分号呢?因为我最常用它写程序啊
    # perl/C/C++/object pascal/java,都是用分号结束一个语句
    # 我们一般很少在分号后面连续写其他字符
    # 所以用“分号+其他键”就很少会在输入的时候造成冲突

    # 在键盘映射中常用的表示
    : 回车
    : Esc
    : 转义符号 \
    : 管道符号 |
    ----------------------------------------
    # 列出寄存器(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 :ls:e # : 在normal模式下按F5键,则会显示所有含有一个

    : 可编辑文件的buffer,然后提示你输入buffer的序号,
    : 输入后回车,则编辑这个buffer
    # 译注:这是一个键盘绑定

    :set hidden : 允许不保存buffer而切换buffer (w/o=without)
    ----------------------------------------
    # 在分割窗口中快速切换
    :map j_
    # 译注:原文此处有误,前面应该加上冒号
    # 这是一个键盘绑定,把Ctrl-J定义成切换到下一个窗口并最大化
    :map k_
    ----------------------------------------
    # 命令录制 (最佳技巧,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: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: !start c:\progra~1\intern~1\iexplore.exe
    ----------------------------------------
    # 用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
    /\/i : 匹配fred,fred必须是一个独立的单词,而不是子串
    # 译注:这和perl也不太一样,perl是用\b做单词定界符的
    /\<\d\d\d\d\> : 匹配4个数字
    \<\d\{4}\> : 也是匹配4个数字
    # 在visual模式下查找
    :vmap g/ y/" : 匹配选中的高亮文字
    # 译释:vmap是在visual模式下的键盘映射
    # 映射了g/这个命令组合
    # y 把选中的高亮文字写入匿名register "
    # / 打开搜索模式
    # 准备粘贴register
    # " 粘贴了""中的内容
    # 回车,执行

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

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

    # 查找当前光标位置所在子例程/函数(subroutine/function)的声明
    :nmap gx yiw/^\(sub\function\)\s\+"
    # 译释:nmap 做一个normal模式下的键盘绑定
    # y 进入复制状态,后面需要一个motion
    # 接着就用 iw 指出了这个motion,是inner word
    # inner word也是狭义字,但是和 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/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 @*sil exec 'g@<\(input\select\textarea\/\=fo
    # 上面这一行不能完全显示,最好Copy Article下去看

    ----------------------------------------
    # 全局(global)显示命令,就是用 :g+正则表达式
    # 译释: :g/{pattern}/{cmd} 就是全局找到匹配的行
    # 然后对这些行执行命令{cmd}
    :g/\/ : 显示所有能够为单词fred所匹配的行
    :g//z#.5 : 显示内容,还有行号,呵呵
    :g//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! \" : 增加在BOL(beginning of line)处的数字
    # 译注:.,$ 指明命令从当前行执行到最后一行
    # 如果没有 .,$ 限定范围,那么g//就会对整个文件进行操作
    # exe 是执行后面的命令组合

    :.,$g/^\d/exe "norm \" : 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
    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:偶不再翻译这种叹词了)
    : 送一个狭义词
    : 送一个广义词
    - : 送一个小型删除寄存器register
    [0-9a-z] : 送一个命名寄存器register
    % : 送文件名过去 (#也行)
    ----------------------------------------
    # 操作寄存器
    :let @a=@_ : 清除register a
    :let @*=@a : 寄存器赋值
    :map "qyy:let @q=@q."zzz"
    # 译注:猜猜这个无聊的绑定是什么意思?
    ----------------------------------------
    # 关于帮助的帮助
    :h quickref : 翻到VIM Quick Reference页(有用!)
    :h tips : Vim自己的tips
    :h visual : 得到一个关于visual关键字的帮助列表 : 然后用tab键去选择
    :h ctrl : 显示所有关于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
    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 :w:!perl -c %
    # 译释::w写文件
    # :!perl -c %用perl来运行当前文件
    # 当前文件必须有文件名!
    ----------------------------------------
    # 插入DOS换行符
    :%s/nubian/&/g : Ctrl-V是一种转义,它说要解释
    :%s/nubian/&/g : 对于Win32应该这样
    :%s/nubian/^M&/g : 你看到的^M是一个字符
    :%s/nubian/\r&/g : 更好的形式
    ----------------------------------------
    # 把最后一个命令贴到当前位置
    i:
    # 把最后一个搜索指令贴到当前位置
    i/
    # 译释:i是进入insert模式,
    # Ctrl-r是开启插入模式下register的引用
    # :和/分别引用了两个register的内容
    ----------------------------------------
    # 更多的完成功能
    :插入当前目录下的一个文件名到当前位置
    # 在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! \"

    # 高级递增,看:
    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 (make a file readonly etc) must be in first/last 5 lines
    # 不会用,不翻了
    // vim:noai:ts=2:sw=4:readonly:
    :h modeline
    ----------------------------------------
    # Creating your own GUI Toolbar entry
    # 对于text模式下的vim没用,不翻了
    amenu Modeline.Insert\ a\ VIM\ modeline ggOvim:ff=unix ts=4 ss=4v
    ----------------------------------------
    # 一个保存当前光标下的狭义字到一个文件的函数
    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 : 帮助
    ie' : 输入 é
    i233 : 输入 é (Unix)
    i233 : 输入 é (Win32)
    ga : 查看字符的hex值
    ----------------------------------------
    # 文件名自动完成 (例如 main_c.c)
    :e main_ : tab 键完成
    gf : 打开光标处广义字命名的文件 (normal模式)
    main_ : 文件名自动完成(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的列表)
    : 跳转到光标处的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编码
    # 然后再解码
    ----------------------------------------
    终于翻完了,呵呵。好累啊!
    __END__

    --
    hmisty, hey misty!
    H misty
    Haow Much I'm Special To You
    vi 剪贴操作补充(一)

    强烈建议大家先看看 doc/change.txt 里关于寄存器部分的内容,
    只是简单提及一下,英文不太好的朋友请找 vim 的中文文档。
    我要介绍的超强武器是 ctrl-r,在 insert mode
    和 command mode 均可使用,功能就是插入寄存器相关内容。
    大家可以试试先 copy 或 delete 一些文本,然后在
    normal mode 或 command mode 输入 ctrl-r ",看到了吗,
    你粘贴了寄存器"的内容。

    寄存器的主要有以下几种:
    a. The unnamed register ""
    "d", "c", "s", "x" 和 "y" 等涉及删除或拷贝的命令
    都会将内容存放于此(有例外)。

    b. 10 numbered registers "0 to "9
    0 为最近拷贝的内容,1-9 为最近删除的内容。
    指定 named register 时不会存放于此。

    c. The small delete register "-
    删除不多于一行的内容会存在于此。

    d. 26 named registers "a to "z or "A to "Z
    小写与大写的区别是,小写是覆盖方式,大写是添加方式。

    e. four read-only registers ":, "., "% and "#
    ". 存放上次插入的文本
    有什么用?呵,例如,你输入了一段文本,在另一个地方也
    要有相同的内容,你输完后,一般要选择并复制一下吧?
    而用这个,直接移到需要插入的地方,i. 即可。
    "% 是当前编辑文件全名
    呵,vim 中,% 就是代表当前编辑文件名的变量,好记吧?
    不过,一般直接用 % 就行,例如":!cat %",vim 会自动
    扩展。
    "# 是alternate file 名称 (这个我不知道)
    ": 上次执行的命令
    记起来比较容易,冒号就是命令行提示符嘛。这个有些什么用呢?
    在测试配置文件时十分有用,先在命令行输入命令,调试好后,
    在 insert mode 里按Ctrl-R : 就可将该命令插到文件中。

    f. the expression register "=
    呵,表达式寄存器,可以输入一个表达式,并插入结果。

    g. The selection and drop registers "*, "+ and "~
    跟 gui 即 X/Windows 剪贴板有关的变量。
    在 X 中,鼠标中键与系统剪贴板不一样,至于区别,大家自己
    试验一下,这里给个提示,在命令行下输入 reg 可以列出所有
    寄存器的内容。
    h. The black hole register "_
    黑洞

    i. Last search pattern register "/
    上次搜索的内容。例如,我要搜索一个单词 linuxforum,但我
    比较懒,先输入 /linux,发现出现很多个 linux,多次按 n 无果,
    难道要重新输入 /linuxforum ? 不用,只需要 //forum 即可。
    呵,聪明的你一定想到了,用命令行历史也可以调来,按 ctrl-p 或 ctrl-n
    即可上下翻阅。这样也可以嘛,也比较快捷,但要查找 forumlinux 呢?
    用 ctrl-r 的话只需 /forum/ 。

    vim 使用技巧
    作者: camry.wu

    我是 vim 粉丝, 用了许久, 有一些自己的感受, 又到处挖到一些别人的技巧. 感觉对 vim
    粉丝比较有用, 就把它记在这儿. 希望借此文套出大家自己的巧活, 就正应了抛砖引玉的古
    话了.

    先稍为介绍一下 vim. vi 是 unix/linux 下极为普遍的一种文本编辑器, 大部分机器上都
    有. vi 有各种变种, 在不同的机器上常用不同的变种软件. 其中 vim 比较好用也用得比较
    广泛. vim 是 Vi IMproved 的缩写, 表示更好的 vi. 我个人觉得它是非常好的编辑器(为
    了避免 Emacs 粉丝挑眼, 就不说最好了). 没用过的也建议试试看, 当然 vim 对编写文本
    文件很方便好用, 比如编写程序, html文档等等, 却不能用来编写 word 文档.

    关于 vim 的安装, 基本使用方法等网络上能搜出许多, 就不在这里罗嗦了, 要是对 vim 有
    兴趣, 那就看看这里(中文文档): http://vcd.cosoft.org.cn/pwiki/index.php

    本文就说些其中比较有用, 比较常用的命令, 若能熟练运用这些命令, 那么会发现编辑文件
    很舒服.

    说明:
    以下的例子中 xxx 表示在命令模式下输入 xxx 并回车
    以下的例子中 :xxx 表示在扩展模式下输入 xxx 并回车
    小括号中的命令表示相关命令.
    在编辑模式或可视模式下输入的命令会另外注明.

    1. 查找

    /xxx(?xxx) 表示在整篇文档中搜索匹配xxx的字符串, / 表示向下查找, ? 表示
    向上查找.其中xxx可以是正规表达式,关于正规式就不多说了.
    一般来说是区分大小写的, 要想不区分大小写, 那得先输入
    :set ignorecase
    查找到以后, 再输入 n 查找下一个匹配处, 输入 N 反方向查找.

    *(#) 当光标停留在某个单词上时, 输入这条命令表示查找与该单词匹配的
    下(上)一个单词. 同样, 再输入 n 查找下一个匹配处, 输入 N 反方
    向查找.

    g*(g#) 此命令与上条命令相似, 只不过它不完全匹配光标所在处的单词, 而
    是匹配包含该单词的所有字符串.

    gd 本命令查找与光标所在单词相匹配的单词, 并将光标停留在文档的非
    注释段中第一次出现这个单词的地方.

    % 本命令查找与光标所在处相匹配的反括号, 包括 () [] {}

    f(F)x 本命令表示在光标所在行进行查找, 查找光标右(左)方第一个x字符.
    找到后:
    输入 ; 表示继续往下找
    输入 , 表示反方向查找

    2. 快速移动光标
    在 vi 中, 移动光标和编辑是两件事, 正因为区分开来, 所以可以很方便的进行光标定
    位和编辑. 因此能更快一点移动光标是很有用的.

    w(e) 移动光标到下一个单词.
    b 移动光标到上一个单词.

    0 移动光标到本行最开头.
    ^ 移动光标到本行最开头的字符处.
    $ 移动光标到本行结尾处.

    H 移动光标到屏幕的首行.
    M 移动光标到屏幕的中间一行.
    L 移动光标到屏幕的尾行.
    gg 移动光标到文档首行.
    G 移动光标到文档尾行.
    c-f (即 ctrl 键与 f 键一同按下) 本命令即 page down.
    c-b (即 ctrl 键与 b 键一同按下, 后同) 本命令即 page up.

    '' 此命令相当有用, 它移动光标到上一个标记处, 比如用 gd, * 等查
    找到某个单词后, 再输入此命令则回到上次停留的位置.

    '. 此命令相当好使, 它移动光标到上一次的修改行.

    `. 此命令相当强大, 它移动光标到上一次的修改点.

    3. 拷贝, 删除与粘贴
    在 vi 中 y 表示拷贝, d 表示删除, p 表示粘贴. 其中拷贝与删除是与光标移动命令
    结合的, 看几个例子就能够明白了.

    yw 表示拷贝从当前光标到光标所在单词结尾的内容.
    dw 表示删除从当前光标到光标所在单词结尾的内容.
    y0 表示拷贝从当前光标到光标所在行首的内容.