|
二、VI/VIM基础知识
很多人应该都知道VI是个有模式的编辑器:编辑模式和命令模式,按ESC回到命令模式,用i或者a进入编辑模式,由于区分了模式,导致VI的命令非常简洁,而无模式编辑器比如Emacs,所有的命令都需要加上控制键Ctrl或Alt,所以有个笑话说Emacser们最希望计算机备一个脚踏板,这样就可以用脚踩Ctrl和Alt键了(编辑器圣战——在VI和Emacs之间有很多口水战,自然也引出非常多的幽默),这里罗嗦一句VI vs. Emacs: VI继承了ed的理念,另外也有历史原因,VI追求的是快捷——启动程序迅速,编辑文本高效,功能专注,而Emacs追求的是功能的丰富强大以及集成带来的方便,在Emacs里头可以发邮件,上新闻组,听mp3,浏览网页,玩游戏,几乎可以login->emacs->logout了:-),VI和Emacs都是程序员的编辑器,相比而言,Emacs更是提供了一种程序员的生活氛围。
闲话少说,这篇文档也不是一份VI/VIM教程,所以这一节只会简单的提及VI/VIM的基础知识。VIM引入了更多的模式,在VIM里头:help mode可以看到VIM的所有模式,主要有如下几种:
- Normal mode即通常所谓的命令模式,在此模式使用a、i、A、I、o、O等进入Insert mode
- Insert mode即通常所谓的编辑模式,在此模式使用ESC进入Normal mode或者Ctrl-o临时进入Normal mode。
- Command-line mode命令行模式,在Normal mode下按冒号进入,按ESC取消执行命令或者回车执行命令,然后回到Normal mode。(Visual Studio.Net也添加了命令行脚本功能,幸甚)
- Visual mode即选择模式(注意跟用鼠标选择不同),用v,V,C-v或C-q进入
- Select mode鼠标选择
- Replace mode在Normal mode下按R进入,按ESC返回Normal mode,相当于Windows下命令行中按Insert键进入的覆盖模式
从VI/VIM中退出: 按ESC确认返回到Normal mode,然后
- :wq保存并退出
- :q!不保存并退出
- :x退出,如果文件更改则保存
- ZZ退出,如果文件更改则保存(按住Shift,再按两次z)
VI的命令是非常具有美感的,下面是几个例子:
- i在光标前插入I在行首插入
- a在光标后插入A在行末插入
- o在下一行插入O在上一行插入
- x删除当前字符X删除前一个字符
类似的还有b,B,ge,gE,w,W,e,E,f,F,t,T,这些命令都可以用:help cmdname查到帮助。
- dd删除一行yy拷贝一行
- h j k l 左下上右移动光标
- Ctrl-w h,Ctrl-w j,Ctrl-w k,Ctrl-w l 切换到左下上右窗口
类似ed,VI/VIM的命令大多都可以带一个数字前缀或者一个数字范围,比如:
- 5dd从当前行开始删除5行
- 5yy从当前行开始拷贝5行
- 1,3d删除1至3行
- 1,3y拷贝1至3行(.代表当前行,$代表最后一行)
d<motion>,y<motion>,c<motion>,v<motion>分别代表删除/拷贝/修改/选择<motion>
命令指定的范围,比如 int main(void) { ......; }
将光标放在{处,然后输入v%就可以把大括号中内容选定,然后按=就可以按照C语言格式缩排(:help =可以看到=命令的描述),%命令的作用是跳到匹配处,比如括号之间,C的宏指令#if #else #endif之间。
int some_ugly_modifier and some_ugly_name (void) 如果光标放在第一个s上,想删除到“(”为止,则输入dt(就可以了,t(的作用是跳到下一个 "("前。
dG可以从当前位置一直删除到文件末尾,因为G的作用是跳到文件最后一行。
VIM的命令可以非常快捷的做到一些复杂的编辑操作,下面是几个示例:
(a)
将“(1), ...., (2), ....,(100)”替换成“(2), ...., (3), ...., (101)”。
在文本中一处处找到并修改是很累的,在VIM下一条命令就可以搞定:
:%s/(\(\d+\))/\="(".(submatch(1)+1).")"/g
命令解释如下:
- % 全文(“%”是“1,$”范围的缩写)
- s 替换
- / 搜索字符串开始
- ( 左括号
- \) 开始记录匹配
- \d+ 一个或多个数字
- \) 结束记录匹配
- ) 右括号
- / 搜索字符串结束
- \= 把后面的表达式计算出来作为替换字符串
- "(" 左括号
- . 字符串连接运算符
- (submatch(1) + 1) 把第一个匹配的结果加一作为一个整体返回
- .")" 添上右括号
- /g 替换字符串结束,g表示替换每一行的所有匹配结果。
(b)
这个问题是笔者曾经碰到的,有一个log系统对于输出行长度有限制,因此在输出很长的log时需要断行,在断行时以单行的“-$-”标记,现在的需求是把这些行连起来,在VIM中也可以很方便的做到(edyfox at newsmth指点):
:%s/\n-\$-\n//g
命令的含义就是把“换行-$-换行”替换成空,另一个办法是:
:g/-\$-/norm ddkJx
命令g/-\$-/的含义就是找到所有的断行标记,然后norm表示在找到的每一个行上执行后面的命令,dd删除这个断行标记,k移动到上一行,J合并当前行和下一行,由于J合并后会留一个空格(只对于英文情况下),所以x来删除这个空格。
(c)在Fortran代码
integer, dimension(:, :), allocatable :: & short_var, & A_very_long_name_var, & other
中,想把每行的&符号定位到固定的一列,比如第78列,手动对齐也是很麻烦的,这个问题可以用VIM的Align插件(http://www.vim.org/scripts/script.php?script_id=294)解决,另外利用宏也可以:
- :set ve=all使得光标可以定位到屏幕任何位置(缺省下VIM的光标只能放在行内的字符上)
- gg 到文件第一行
- /\s\+&\s*$ 找以&结尾的行,&前至少一个空白字符,后0或多个空白字符
- qa 记录宏到寄存器a
- D 删除到行尾
- 78| 定位到第78列
- i&<ESC> 插入&并返回到命令模式
- n 查找下一个&
- q 停止记录宏
- 10000@a 执行一万遍寄存器a中保存的命令
- :set ve="" 恢复ve缺省值
(d)连续插入72个等号
按ESC进入Normal mode,输入72i=再按ESC即可。
(e)在多行开始插入//
移动光标到需要注释掉的第一行开头,然后按Ctrl-v(如果使用了VIM的mswin.vim,则Ctrl-v表示粘贴,这时需要用Ctrl-q代替)进入Visual blockwise模式,这个模式是Visual mode的一种,相当于UltraEdit中的块选择。 然后按j选择上所有需要注释行的行首(看起来效果是选择了第一列),输入I//再按ESC就可以在每一行开头插入//了。
Reference:
- http://newsmth.orgVIM board
- http://edyfox.codecarver.org/html/index.htmledyfox的个人主页
这些例子也许初看起来有点吓人,可是在很多时候VIM这些强大的命令能省不少力,VIM不愧是为“编辑”这个功能费尽心思。
上一页 [1] [2] [3] [4] [5] [6] [7] [8] 下一页 |