零点坐标's profile零点岁月PhotosBlogLists Tools Help

Blog


    January 22

    vi常见问题

    发信人: thinelephant (严重消化不良), 信区: VIM
    标  题: [faq]常见问题 欢迎指正或补充
    发信站: BBS 水木清华站 (Tue Jun 22 19:44:37 2004), 站内

    本文将根据版上的提问不断修改、补充,力图回答大多数的常见问题。欢迎大家指正或
    补充(补充解答的内容,或者补充没有列出的问题)。

    注:以下问题以及解答均由版上的文章归纳整理而来,部分内容为原文引用。

    (请搜索“(编号)”快速定位到问题答案部分。)

    (1) 为什么别人的方法在我这里行不通?
    (2) 如何找到上次编辑的文件?
    (3) 如何复制粘贴?
    (4) 如何在多个文件中进行替换?
    (5) 如何把fold一次全部打开?
    (6) 如何选择或者复制光标所在的单词?
    (7) 如何计数搜索的字符串?
    (8) 如何去掉高亮搜索?
    (9) 如何解决linux下gvim中文菜单乱码的问题?
    (10) 如何对所编辑的文件语法高亮显示?
    (11) 如何快速插入多行数字0-99?

    ==============================================================================
    (1) 为什么别人的方法在我这里行不通?

    估计这是最难回答的一个问题了。:-)
    不过首先应该确定你的VIM版本是否足够新,功能是否完整。使用 :version 命令查看你
    的VIM版本以及功能。一个常见的情况,如果你用的是RedHat系统,请确定安装了
    vim-enhance的rpm包,否则将是不完整的VIM。

    (2) 如何找到上次编辑的文件?

    Ctrl+O (按两次)

    (3) 如何复制粘贴?

    方法一:先ma标记当前位置为a,移动到新的位置,再y`a或者y'a复制从标记位置a到
    当前位置的内容。`和'的区别:`以字符为单位,'以行为单位。这个方法应该是所有vi
    都适用的。(如果不对请指正。)
    方法二:按v或V或Ctrl+V进入visual模式,移动光标选择一段内容,按y。三者的区别:
    v以字符为单位,V以行为单位,Ctrl+V是块选择。这个方法只在VIM下适用。

    (4) 如何在多个文件中进行替换?

    一般可以用sed或者vim来做。比如要对当前目录下的*.c文件进行替换:
    方法一:
    for i in *.c; do
      sed -i -e 's/oldvalue/newvalue/g' $i
    done
    方法二:
    vim *.c
    :argdo %s/oldvalue/newvalue/g

    (5) 如何把fold一次全部打开?

    zR 或者 :set foldlevel=999

    (6) 如何选择或者复制光标所在的单词?

    在VIM中用iw或者aw表示一个单词,两者稍有区别。
    选择光标所在的单词:viw (v进入visual模式,然后iw)
    复制光标所在的单词:yiw

    (7) 如何计数搜索的字符串?

    如果需要统计缓冲中一个模式(pattern)出现的频率,需要把 'report' 置为0,然后
    用替换命令把模式替换成它自己。Vim 报告的已替换的数目就是模式出现的次数。例:
            :set report=0
            :%s/./&/g               characters
            :%s/\i\+/&/g            words
            :%s/^                   lines
            :%s/the/&/g             "the" anywhere
            :%s/\<the\>/&/g         "the" as a word
    你可能希望复位 'hlsearch' 或者使用 ":nohlsearch"。

    (8) 如何去掉高亮搜索?

    方法一::nohlsearch
    方法二:/awertgvcxz (查找一个肯定不存在的字符串)
    设置了高亮搜索(:set hlsearch)以后,可以通过 :set nohlsearch 永久地关闭高亮
    显示,也可以通过 :nohlsearch 暂时关闭高亮显示,下次搜索时将自动恢复高亮。

    (9) 如何解决linux下gvim中文菜单乱码问题?

    以vim6.3为例
    source /usr/local/vim/share/vim/vim63/delmenu.vim
    source /usr/local/vim/share/vim/vim63/menu.vim

    光source一个menu.vim或者啥也不source都是乱码
    另外,也有网友报告说没有遇到此类问题

    (10) 如何对所编辑的文件语法高亮显示?

    需要解释的是,VI有很多变种,它本身并没有这种功能,提供这种功能
    往往是其各种衍生版本,比如说vim。下面就vim中如何语法高亮简单解释一下。

    首先,确定一下你所用的操作系统,如果是windows,那么默认的配置文件
    就可以工作了。如果还不行,可以用鼠标从syntax菜单下选择一下适合你的
    文件类型(新版本的gvim默认把文件类型选择关闭了,需要点开,然后按照
    开头字母选择类型)
    如果是linux,那么确认一下是否是redhat。如果是redhat,那么需要安装
    vim-enhanced的rpm包。这些都做了以后,可以用:syntax on来打开语法高亮。
    必要时可以用:set filetype=...来设定你的文件类型。
    如果使用图形界面,比如gvim,那么syntax on和set filetype的操作可以
    用鼠标在菜单中选择,同windows下。
    如果是在控制台中使用vim,还应当确定你的终端设置支持颜色。

    (11) 如何快速插入多行数字0-99?

    在命令行中输入以下代码,或者先把代码保存到一个外部文件,然后source这个文件:
    let i = 0
    while i < 100
      put = i
      let i = i + 1
      endw
    如果位数不足需要在前面补零,可以用Ctrl-V块选择,然后I插入0。

    ※ 修改:·thinelephant 于 Jun 30 11:03:43 修改本文·[FROM: 211.100.11.*]
    ※ 来源:·BBS 水木清华站 smth.org·[FROM: 211.100.11.*]

    vi 命令常见问题解答

    发信人: noclouds (景天云飞), 信区: VIM
    标  题: [FAQ] vi 命令常见问题解答 (zz)
    发信站: BBS 水木清华站 (Sat May 22 17:07:45 2004), 站内

    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 - 等等,我的键盘没有<Esc>键,我该怎么办? 
    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却不花相当多的时间去到处试试. 记住:
    如果你有些地方不明白了, 只要敲两次<Esc>键,你就又回到命令模式下了. 我要提到的
    一点是,我想在这里提比较合适,就是如果要成为系统管理员或者其他对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和其他一些可以从命令
    模式切换到插入模式. <Esc>键或者^C(CRTL+C)可以脱离插入模式而返回到命令模. 
    你要适应这种差别. 它使得vi区别于其他的编辑器. 它也使你能在你的手不离开标准 
    键盘做很多事情. 

    2.3 - 等等,我的键盘没有<Esc>键,我该怎么办? 
    试试敲 ^[(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编号的寄存器里.所以,"<n>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 <lhs> <rhs>, 其中<lhs>最多10个字符,<rhs>最多100个字符. 以后,如果 
    你敲了<lhs>,vi就会用<rhs>来取代它.所有的宏都是在命令模式下开始的,但是可以 
    在你想在的模式下终止. 记住,在你想用的控制字符前面加上^V. 
    :unmap <lhs>将删除这个宏. :map!<lhs> <rhs> 使得<lhs>将<rhs>插入到文档 
    中去. 

    3.5 - 我怎样将一个功能键定义成一个宏? 
    如果<lhs>是#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中的命令在
    启动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里面一个非可视化的编辑器 

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

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

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

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

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

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

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

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

    寒烟淡笼蒹葭,风吹别怨过天涯。
    双星黯处,山瞑隐清笳。


    ※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.38.91.*]