当前位置:Linux教程 - Linux - 大家来学 VIM

大家来学 VIM



        
      本文作者: edt1023

    前言
      鉴于仍有许多人还没找到顺手的编辑器,而许多想学 vi 的人又觉得无从下手,因此在此提出一些个人的心得,希望能对这些朋友有点帮助。或许也减少一点 FAQ 吧!

    真要深入的话,大多数的前辈都认为 vi 比 emacs(xemcas) 还难学。但谁又真的需要熟悉编辑器的所有功能呢?你大可以边用边学啊!需要用到的先学,其它的就放一边,只要能善用一些常用到的功能,又何必要那么深入呢?而且您在使用当中经常会发现一些新功能,这又会马上让您给赚到了。

    文章是自由格式,会分成好几次来 post,不常写文章,各位就将就著看吧!但如有人认为这系列文章还有点看头,您要拿去放,悉听尊便,但不能是商业用途,而且也请告知一下,这样道德上比较完整。您不告知我,也不会去告您啦!只是起毛子有点不好而已。:-)

    何处抓 VIM(elvis) ?


      http://www.vim.org/
      找个自己中意的 mirro 站抓。或许也顺便抓 Win32 的可执行档回来在 windows 系统中使用。别忘了 runtime 档也要抓,否则会无法找到需要的档案来执行。
      http://www.fh-wedel.de/elvis/index.html 以及ftp://ftp.pdx.edu/pub/elvis 也可试试 elvis。
      CLE 的使用者也可以到:ftp://linux.tmtc.edu.tw/pub/CLE/i386/RedHat/RPMS抓最新版来安装,省时省力,而且还把必要的中文设定都弄好。目前最新的版本,VIM 是 5.6,elvis 是 2.1-4。
      编译安装
      只讲重点,避免罗嗦!

    VIM


      configure 时加上:
       --enable-multibyte
       --enable-xim 如果您使用 xcin2.3 的话,就不必了
       --enable-fontset
       --enable-gui=gtk
      
      gtk+ 最好是 1.2.3 以上的版本,1.2.1 也是将就可以啦!大家都用 gtk+ 了,您不会想编 Athena 或 Motif(lesstif)吧!而且后两个版本的 GUI 就没有漂亮的 icon 了(但有的人就是讨厌这些无用的 icon)。

    ~/.vimrc 加入:
       set fileencoding=taiwan
       set guifontset=英文字型,中文字型
      
      设了 guifontset 就不能设 guifont 否则会优先使用 guifont,这样就找不到中文字型了!console 下或 xterm下的话,就看您用什么字型就显示什么字型,和 guifontset 无关。
      英文字型要用固定字,建议使用危卵的 Andale Mono 这个字型,包您满意,可去危卵抓,免费的。我个人是使用 180 的 Andale 字,配上 220 的中文字,绝配(1024x768)!哦!不要告诉我,您的 X server 还不能支援 TTF。


      使用 xcin2.3 的话还是得配合 XA+CV 主要是输入的问题。使用 xcin2.5 的话就不必 XA+CV 了,但您得另外设 xim, 请进入 VIM 后 :help xim。很抱歉您可能得自己试看看了,我并没有亲自试过。

    locale 要设成 zh_TW.Big5,意思就是您的系统的 i18n 支援不能太差,我是使用 gvim-chinese shell script 来呼叫 gvim。
       #!/bin/sh
       # gvim-chinese
       export LC_ALL=zh_TW.Big5
       gvim "$@"
      


      elvis
      elvis 没什么好说的,反正是靠 XA+CV 来显示及输入中文。至于其他外观调整,就请 man elvis。


      勤前教育
      VIM 的模式可有六种,为免初学的人搞混,仍依一般的分类分成三种:

    Normal mode(common mode,以下简称 c-mode):
      您一进入 VIM 就是处于 c-mode,只能下按键指令,不能输入文字。这些指令可能是游标移动的指令,也可能是编辑指令或寻找替换指令。
      Insert mode(i-mode):
      按 i 就会进入 i-mode,此时才可以键入文字,写您的文章,按 Esc 又会回到 c-mode。
      Ed mode(common-line mode,e-mode):
      按冒号:(别忘了 Shift 键)就会进入 e-mode,左下角会有一个冒号:出现可下 ed 指令。也是按 Esc 回 c-mode。反正正常状态都是处于 c-mode,这样才不会把您辛苦打字的文章给随便搞乱掉。
      ed 是一个很古老的行编辑器,就好像 DOS 下的 edline 一样,vi,sed 这些编辑器都是从 ed 衍化而来的。有兴趣可 man ed 学看看有些时候会只有 ed 可以用(当机救助的时候)。

    其它的模式就碰到时再说明了!
      基本教练:step by step


      由命令列来开档:
      vim test.txt 或 gvim test,txt 或 gvim-chinese test.txt 如果您的系统 vi 是 vim 的连结档话,就可以直接用 vi test.txt。以下就直接用 vim 代表 vi,gvim,因操作是一样的。

    先进入 vim 后再开档:
      进入 vim 后,使用冒号命令 :e test.txt,就可以编辑 test.txt 这个档。1. 及 2. 这两个开档法,如果 test.txt 不存在的话,就会开一个以 test.txt 为名的新档案。
      如果 gvim,可由 icon(gtk 版本才有)或功能表来叫出 file browser 来选看看您要编辑哪一个档,但如果您是初学的话不建议您这么做,vi 就是以按键快速闻名,这是她的优点,您还是学起来吧,不然没有 GUI 的时候会很不习惯的。


      进入 vim 后,按 i 进入 i-mode,就可以编写您的文件了。在 vim 游标的移动可以由方向键来移动。Backspace 键可消去前一个字元,中文的话是一个中文字。Del 键可删除游标所在处的字元(中文字)。
      原始 vi 是不能在 i-mode 随意移动游标的,得进入 c-mode 才能移动,因此就常常要按 Esc 来变换模式。vim 及 elvis 都打破了这个规矩。


      如果您写好您的文件,就可以按 Esc 回到 c-mode,然后 :w 就会存档(注意,是冒号命令),但还不会离开 vim,要离开可按 :q,就可以了!也可以合起来用,:wq,就样就会存档后离开。怎么样,也不会很难吧!只不过操作方式和别的编辑器不一样罢了,这样岂不是很有个性。:-)
      尽量记住按键的意义,才不必死背,如 e 是 edit(编辑), w 是 write(写入),q 是 quit(停止、离开)。

    好了,这是就编辑的整个过程。下回开始是详述各部份的功能,把 vim 解剖开来讲,您可以马上现学现卖。由于 vi(m) 的操作方式很有个性,因此,用了一次就会记住有这么一个功能,想忘也忘不了,但有时按键难免会忘记,但有这一种功能大概是忘不了的,查了几次指令就可以记得住了。

    游标的移动
      本节所述皆是在 common-mode(c-mode,在 vim 又名 normal-mode)下的移动,原始的 vi 只能在 c-mode 移动,在 insert-mode 只做文字的输入,而不做游标的移动。当然 vim 及 elvis 的方向键是不论在那一种 mode 皆可移动自如。

    基本的游标移动


      h 左,或 Backspace 或方向键
      j 下,或 Enter 或 +(要 Shift 键),或方向键

    k 上,或 方向键或 -(不必 Shift 键)
      l 右,或 Space 或方向键
      Ctrl-f 即 PageDown 翻页。
      Crtl-b 即 PageUp 翻页。

    使用 hjkl 键的移动是为了使手不必离开打字区(键盘中央的部位),
      以加快打字的速度,如果各位不习惯,那就使用方向键吧!

    Backspace 及 Space 的移动方式是到了行首或行尾时会折行,
      但方向键或 hl 键的移动则在行首或行尾时您继续按也不会折行。
      转折换行的功能是 vim 的扩充功能,elvis 无此功能。

    jk 及使用方向键的上下移动游标会尽量保持在同一栏位。
      使用 Enter,+,- 的上下移动,游标会移至上(下)一行的
      第一个非空白字元处。

    好像有点复杂,各位就暂时使用方向键来移动就简单明白了!
      等您爱上了 vim 后再来讲究吧。
      

    进阶的游标移动


      0 是数目字 0 而不是英文字母 o。或是 Hmoe 键,移至行首,(含空白字元)。
      ^ 移至第一个非空白字元,注意,要 Shift 键。
      $ 移至行尾,或 End 键。要 Shift 键。

    以上两个按键是源自规则表示式(regular expression),
      在 regexp 中 ^ 是匹配行首,$ 是匹配行尾。
      

    G 移至档尾(最后一行的第一个非空白字元处)
      gg □至档首(第一行之第一个非空白字元处)

    gg 是 vim 的扩充功能,在 elvis 或原始 vi 中可用 1G 来
      移至档首(是数字 1 不是英文字 l)。

    G 之原意是 goto,指移至指定数目之行首,如不指定数目,
      则预设是最后一行。
      

    w 移至次一个字(word)字首。当然是指英文单字。
      W 同上,但会忽略一些标点符号。
      e 移至前一个字字尾。
      E 同上,但会忽略一些标点符号。
      b 移至前一个字字首。
      B 同上,但会忽略一些标点符号。
      H 移至萤幕顶第一个非空白字元。
      M 移至萤幕中间第一个非空白字元。
      L 移至萤幕底第一个非空白字元。

    这和 PageDown,PageUp 不一样,内文内容并未动,
      只是游标在动而已。
      

    n| 移至第 n 个字元(栏)处。注意,要用 Shift 键。n 是从头起算的。
      :n 移至第 n 行行首。或 nG。
      特殊的移动


      ) 移至下一个句子(sentence)首。
      ( 移至上一个句子(sentence)首。
      } 移至下一个段落(paragraph)首。
      { 移至上一个段落(paragraph)首。

    sentence 是以 . ! ? 为区格。paragraph 是以空白行为区格。
      

    % 这是匹配 {},[],() 用的,例如您的游标现在在 { 上只要按 %,就会跑到相匹配的 } 上。写程式时满好用的。
      另还有一些 vim 的特殊按键,但这得留待最后才来讲述,否则各位恐怕会头昏眼花了。


      基本编辑指令
      这个单元就开始进入主题了。下编辑指令都是在 commond-mode (c-mode),就是您一进入 vim 时的模式,只能下指令,不能键入文字。如果印象模糊,请瞄一下第一个单元的内容。这个单元说的是基本的指令,有些比较特殊的编辑指令,因为太有个性了,所以会独立成一个单元来说明。

    进入 i-mode 的指令


      i 在游标所在字元前开始输入文字(insert)。
      a 在游标所在字元后开始输入文字(append)。
      o 在游标所在行下开一新行来输入文字(open)。
      I 在行首开始输入文字。
       此之行首指第一个非空白字元处,要从真正的第一个字元处开始输人文字,
      可使用 0i 或 gI(vim)。
      

    A 在行尾开始输入文字。
       这个好用,您不必管游标在此行的什么地方,
      只要按 A 就会在行尾等著您输入文字。
      

    O 在游标所在行上开一新行来输入文字。
      J 将下一行整行接至本行(Joint)。
       并无相对的 split 功能,可在 i-mode 下按 Enter 来达成
      

    ,当然如果您熟 macro 的话,可自行定义。
       使用 J 时,预设会消去本行的 EOL,且上下行接缝间会留下一个空白字元,
      这符合英文习惯,却对中文会造成困扰,欲不留空白字元,
      可使用 gJ(大写 J)指令,但这是 vim 的扩充功能,elvis 不适用。

    请您随便找一个档案来试看看,光看文字说明太抽象了。
      

    删除指令


      x 删除游标所在处之字元。在 vim 及 elvis 亦可用 Del 键。
      X 删除游标前之字元。不可使用 Spaceback 键。
       vim 可以正确使用以上两个指令于中文,会删去一个中文字 elvis 则不行,
      一个中文字要删两次,即使用 xx。
      

    dd 删除一整行(delete line)。
      dw 删除一个字(delete word)。不能适用于中文。
      dG 删至档尾。
      d1G 删至档首。或 dgg(只能用于 vim)。
      D 删至行尾,或 d$(含游标所在处字元)。
      d0 删至行首,或 d^(不含游标所在处字元)。
       请回忆一下 $ 及 ^ 所代表的意义,您就可以理解 d$ 及 d^ 的动作,
      这就是 vi(m) 可爱之处。
      

    取代及还原


      r 取代游标所在处之字元。vi(m) 很有个性的,您在 c-mode 按了 r 她就会停在那里等主人键入所要替代的字元,希望您这个当主人的,不要傻呼呼的也楞在那里,赶快键入您的新字元吧!:-)
       vim 中可用于中文字,也就是可以替换一个中文字,elvis 则不行。
      当然您的 vim 是要设在 taiwan 的才行。怎么样!有没有看过如此
      有个性的取代方式?ㄚ!r 就是 replace 啦!
      

    R 取代字元至按 Esc 为止。
      cc 取代整行内容。或大写 S 亦可。
      cw 替换一个英文字(word),中文不适用。(change)
      ~ 游标所在处之大小写互换。当然不能用于中文。别忘了 Shift!
      C 取代至行尾,即游标所在处以后的字都会被替换。或 c$。
      c0 取代至行首,或 c^。
      s 替换一个字元为您所输入的字串。和 R 不同,R 是覆盖式的取代,s 则是插入式的取代,您可亲自实验看看。ㄟ!是小写的 s。
      u 这个太重要了,就是 undo,传统的 vi 仅支援一次 undo,vim 及 elvis 就不只了,vim 是没有限制的。
      U 在游标没离开本行之前,回复所有编辑动作。
      Crtl+r 这个也是很重要,就是 redo 键。
      加上数目字
      喔!骚到 vi(m) 的痒处了,这是 vi(m) 一个非常骚包的功能,只此一家别无分号(当然同源的 ed,sed 等不在此限)。就是您可以在大部份的指令前加上数目字,代表要处理几次的意思。以下用实例来说明比较清楚。

    5dd 删除游标所在处(含)起算以下五行内容。妙吧!
      3r 按了 3r 后,您键入一个英文字,则三个字元皆会被您所键入的英文取代。很抱歉,这不能用于中文。
      5J 将五行合并成一行。
      3x 删除三个字元。抱歉,不能用于中文。
      5i A 然后按 Ecs,插入五个 A。中文也可以!
      2i system Esc 插入 systemsystem。中文也可以!
      5G 游标移至第五行,是从档首开始起算。
      5l 移至右第五个字元处,当然 j 是可以用方向键取代的。所有移动指令(参考第二单元)都可以加上数目字来控制,中文也通喔!elvis 当然是不能用于中文。
      其它的指令和数目字结合,就留待各位去发掘吧!最重要的是请您亲自操作看看,使用 vi(m) 常常要动动脑筋,会有更妙的操作方式。
      简单重排功能


      >> 整行向右移一个 shiftwidth(预设是 8 个字元,可重设)。
      << 整行向左移一个 shiftwidth(预设是 8 个字元,可重设)。
       :set shiftwidth? 可得知目前的设定值。:set shiftwidth=4
      可马上重设为 4 个字元。shiftwidth 可简写成 sw。ㄟ,别忘了 Shift 键!
      

    :ce(nter) 本行文字置中。注意是冒号命令!
      :ri(ght) 本行文字靠右。
      :le(ft) 本行文字靠左。
       所谓置中、靠左右,是参考 textwidth(tw) 的设定。
      如果 tw 没有设定,预设是 80,就是以 80 个字元为总宽度为标准来置放。
      当然您也可以如 sw 一样马上重设。
      

    gqip 整段重排。中文会出槌!:-(
      gqq 本行重排。
       重排的依据也是 textwidth。这里的重排是指您键入文字时没有按 Enter 键,
      就一直在 keyin,这样会形成一个很长的一行(虽然萤幕上会替您做假性折行),
      重排后,则会在每一行最后加入 EOL。gq 重排功能是 vim 才有的功能。


      复制(yank)
      yank 是什么意思?有疑问的请查一下字典吧!就好像是中医治疗中的「拔罐」的意思啦(是不是叫「拔罐」?知道的朋友指正一下吧)!反正在 vi(m) 中,她就是复制 copy 的意思。这在 vi(m) 的思考逻辑里,就是「拔」yank 起来,「放」put 上去。其实复制的指令就是 y 一个而已,为什么要独立成一个单元来说明呢?因为 vi(m) 复制、贴上的功能实在太独特了,再配合前面介绍的数目字,及 vi(m) 内部的缓冲区来使用的话,您会发现,原来 vi(m) 肚子里还暗藏著秘密武器。

    指令说明


      yy 复制游标所在行整行。或大写一个 Y。
      2yy 或 y2y 复制两行。ㄟ,请举一反三好不好!:-)
      y^ 复制至行首,或 y0。不含游标所在处字元。
      y$ 复制至行尾。含游标所在处字元。
      yw 复制一个 word。
      y2w 复制两个字。
      yG 复制至档尾。
      y1G 复制至档首。
      p 小写 p 代表贴至游标后(下)。
      P 大写 P 代表贴至游标前(上)。
       整行的复制,按 p 或 P 时是插入式的贴在下(上)一行。
      非整行的复制则是贴在游标所在处之后(前)。
      

    "ayy 将本行文字复制到 a 缓冲区
       a 可为 26 个英文字母中的一个,如果是小写的话,原先的
      内容会被清掉,如果是大写的话是 append 的作用,会把内
      容附加到原先内容之后。

    " 是 Enter 键隔壁的那一个同上符号(ditto marks)。
      

    "ap 将 a 缓冲区的内容贴上。
       缓冲区的术语在 vim 称为 registers,vim 扩充了相当多的
      功能,有兴趣深入的朋友请 :h registers。您用 d、c、s、
      x、y 等指令改变或删除的内容都是放在 registers 中的。
      例如:您用 dd 删除的一行,也是可以使用 p 来贴上的。只
      要是在缓冲区的内容都可以使用 p 来贴上,不是一定要 y 起
      来的内容才能用 p。因此您认为 p 是 paste 也可以,认为是
      put 可能较正确。
      

    5"ayy 复制五行内容至 a 缓冲区。
      5"Ayy 再复制五行附在 a 内容之后,现在 a 中有十行内容了!
       ㄟ!不要我一直用 a 您就认为只有 a 可以用喔。26 个英文
      字母都可以的,交叉运用下,您会发觉 vi(m) 肚量不小。

    问题来了!忘记谁是谁的时候怎么办? :reg(冒号命令)就
      会列出所有 registers 的代号及内容。您现在就试著按看看
      咦!怎么还有数目字、特殊符号的缓冲区,原来您刚刚删除
      (复制)的内容就预设放在 " 这个缓冲区,然后依序是
      0,1,2,...9。也就是说您按 p 不加什么的话,是取出 " 缓
      冲区的内容的。% 指的是目前编辑的档案,# 指的是前一次
      编辑的档案。还有其它的呀!因为没什么重要,就请
      :h registers 吧!registers 有个 "s" 结尾,不要搞错了,
      而且 Tab 的补全键 vim 也支援的,也就是说您键入 :h regi
      再按 Tab 键,vim 就会帮您补全,按了 Tab 后发现不是您要
      的,那就继续按,总会出现您要的。:-)

    Tab 补全的功能,elvis 也有,但叫出 registers 列表的命令
      则没有,您得自行记忆在您的脑袋瓜子里。而且 elvis 的补全
      能力并没 vim 强。
      

    天大的指令
      . 这是什么?ㄚ,是英文句点啦!没错,就是英文句点。什么意思?重复前次的编辑动作。这个指令太高明了,只要是编辑动作(移动游标不算,冒号命令也不算)都可以按英文句点来重复,要重复几次都可以。

    例如:您按了 yy,然后按 p 就会复制、贴上一整行,如果要重复这个动作的话,就可以按 . ,也可以把游标移到其它地方后再按。其它 dd,dw,r,cw 等编辑指令都可以这样来重复。如果您要重复做某些编辑动作时,千万千万一定要想到有这么一个英文句点重复指令。ㄚ,拜托啦!您一定要常用这个指令。

    疑难杂症


      那 mouse 中键的剪贴功能还有吗?当然还有,不管在 console 或 X terminal 中都照用不误。当然在 windows 下的话就不能用了,可以用 Shift-Insert 来代替。Ctrl-v 在 vim 中另有作用,在 windows 下就不必去麻烦它了。
      ㄟ,我从 netscape 用 mouse copy 东东过来的时候,常常都搞得天下大乱耶!要设成 :set paste,预设是 map 至 F9 键的,您要 copy 之前先按一下 F9,copy 完后再按一次 F9 来回复。这是 vim 的扩充功能,elvis 没有。那在 elvis 怎么办?只好 :set noai 了。在 GUI 的版本应不会有这种情形。
       set 的功能先不必去理它,往后会有一个单元专门讨论。
      

    朋友!您睡著了吗?不要被吓到了,您只要开个档案,亲自操作一下就能心领神会。那用 mouse 不是更方便吗?不见得,yyp 来复制贴上一整行比较快,还是用 mouse 来拉比较快?您可以试看看。


      寻找/替换
      搜寻、替换的功能几乎是每个编辑器必备的功能,那在 vi(m) 中有没有特殊的地方呢?当然有,您忘了,vi(m) 是个性十足的编辑器。最特殊的地方是和规则表示式(regular expression,简称 regexp) 结合在一起。简单的说她是一种 pattern 的表示法,在执行动作,如寻找或替换,就会依据这个 pattern 去找,所有符合 pattern 的地方就会执行您所下的动作。在这个单元里不讨论 regexp,会另立一个单元来探讨,以免搞得头昏脑胀。目前就暂不使用 regexp,您要找什么就直接键入什么就对了。

    寻找


      / 在 c-mode 的情形下,按 / 就会在左下角出现一个 /,然后键入您要寻找的字串,按个 Enter 就会开始找。
      ? 和 / 相同,只是 / 是向前(下)找,? 则是向后(上)找。
      n 继续寻找。
      N 继续寻找(反向)。
      更方便的寻找操作(vim 才有)


      * 寻找游标所在处之 word(要完全符合)。
      # 同上,但 * 是向前(下)找,# 则是向后(上)找。
      g* 同 * ,但部份符合即可。
      g# 同 # ,但部份符合即可。
       n,N 之继续寻找键仍适用。
      

    替换(substitute)
      :[range]s/pattern/string/[c,e,g,i]

    range 指的是范围,1,7 指从第一行至第七行,1,$ 指从第一行至最后一行,也就是整篇文章,也可以 % 代表。
       还记得吗? % 是目前编辑的文章,# 是前一次编辑的文章。
      


      pattern 就是要被替换掉的字串,可以用 regexp 来表示。

    string 将 pattern 由 string 所取代。

    c confirm,每次替换前会询问。

    e 不显示 error。

    g globe,不询问,整行替换。

    i ignore 不分大小写。
       g 大概都是要加的,否则只会替换每一行的第一个符合字串。
      可以合起来用,如 cgi,表示不分大小写,整行替换,替换前
      要询问是否替换。
      
      [实例] :%s/Edwin/Edward/g
      这样整编文章的 Edwin 就会替换成 Edward。

    更进阶的寻找、替换的例子在说明 regexp 的时候还会再详述。目前只知道最基本的用法就可以了!其实光这样就非常好用了。:-)

    书签功能
      这又是 vi(m) 的一个秘密武器,简单的说,您可以在文章中的某处做个记号(marks),然后跑到其它地方去编辑,在呼叫这个 mark 时又会回到原处。妙吧!

    mx x 代表 26 个小写英文字母,这样游标所在处就会被 mark。
      `x 回到书签原设定位置。
       ` 是 backward quote,就是 Tab 键上面那一个。
      

    x 回到书签设定行行首。
       是 forward quote,是 Enter 键隔壁那一个。
      

    vim 对于书签的扩充功能


      小写字母 只作用于单一档案内。
      大写字母 可作用于编辑中之各档案间。
      数目字 可作用于前次编辑的十个档案。
       数目字的用法比较特殊,0 是回到前一次编辑档案中离开
      前的最后位置,1 则是回到前二次编辑档案的最后位置,
      依此类推。您不必使用 m 来标示,vim 会自动记忆。
      很玄吧!其实这是 viminfo 的功能,您要认真追究的话,
      请 :h viminfo-file-marks。viminfo 关掉,就没这个功能了!

    所谓前次指的是前次启动的 vim。
      

    :marks 得知目前所有书签的列表。


    叫档、存档、紧急回复
      ㄟ,是不是在灌水呀!怎么开个档也成一个单元?那您就错了,在 vi(m) 里叫档的花样可多了,而且又可以多档编辑,各编辑中的档案还可以互通讯息,这里面学问可大著呢!vim 就更骚包了,也学人家档案可以加密,虽说是噱头,但也还满好用的。

    开档的一些花招


      vim + 档名
      这样开档后,游标会落在档案最后一行的行尾,在档案屁屁后干什么呢?方便您可以继续编辑嘛!
      vim +n 档名
      游标会落在第 n 行的行首。
      vim +/string 档名
      还记得吗? / 就是寻找指令,这样进入档案后游标就会落在第一个找到的 string 上,还可以按 n 继续找 string 喔!哦,string 还可以使用 regexp 来表示喔。
      多档编辑
      多档编辑会有两种情形,一种是在进入 vim 前所用的参数就是多个档(这种情形称为 argument list)。另一种情形是进入 vim 后另外再开其它的档(称为 buffer list)。不过都可以统称为 buffer。

    :n 编辑下一个档案。
      :2n 编辑下二个档案。
      :N 编辑前一个档案。
       注意,这种用法只能用于 argument list 的情形。
      

    :e 档名 这是在进入 vim 后,在不离开 vim 的情形下再开其它档案。只要您要编辑的档案是在目前目录,Tab 补全键还是可以使用。
      :e# 或 Ctrl-^ 编辑前一个档案,用于两档互相编辑时相当好用。
       这种用法不管是 argument list 或 buffer list 档案间皆可使用。

    还记得吗? # 代表的是前一次编辑的档案。
      

    :files 或 :buffers 或 :ls 会列出目前 buffer 中的所有档案。
       在 elvis 中可使用 :b 来叫出 buffers。

    在 buffers 中,减号 - 表示这个 buffer 并未载入,不过,
      不必担心,载入相当快速的。加号 + 表示这个 buffer
      已经修改过了。
      

    :bn buffer next。
      :bl buffer last。
       以上两个指令 elvis 不适用。
      

    :b档名或编号 移至该档。
       在 :ls 中就会出示各档案的编号,这个编号在未离开 vim 前是不会变的。
      这个指令 elvis 也是可以使用。

    当然 :e#编号 也是可以的,这样的用法则是所有 vi clone 都通用了。

    如果您是使用 vim 的 GUI,那就在功能表上就会有 Buffers 这个选项,
      可以很容易的知道及移动各 buffer 间。
      

    :bd(elete)
      buffer 在未离开 vim 前是不会移除的,可使用这个指令移除。其实移除她干什么呢?vim 是您在叫用时才会载入的,因此这些 buffers 并不是像 cache 一般要占记忆体的。
      :e! 档名
      这样也是会开档,但会放弃目前编辑档案的改变,否则如果档案已有变动,vim 预设是不让您随便离开的。:e! 后不接什么的话,代表舍弃一切修改,重新载入编辑中档案。
      :f 或 Ctrl-g
      显示目前编辑的档名、是否经过修改及目前游标所在之位置。
      :f 档名
      改变编辑中的档名。(file)
      :r 档名
      在游标所在处插入一个档案内容。(read)
      :35 r 档名
      将档案插入至 35 行之后。
      gf
      这是 vim 的特殊叫档法,会叫出游标所在处的 word 为名的档案,当然,这个档案要在目前目录内,否则会开新档案。
      哦!好像有点给他复杂,主要原因是偶文笔不好啦!不过您何不选个顺手的来用就可以了,选定了,以后就是使用他,这样就不会那么复杂了。:-)
      离开


      :q 如本文有修改而没存档,会警告,且无法离开。(quit)
      :q! 舍弃所有修改,强迫离开。
      :wq 存档后离开。纵使档案未曾修改也是会再存一次档。
      :x 也是存档后离开,但如果档案没有修改,则不会做存档的动作。
      ZZ 和 :x 完全一样,随您高兴用哪一个。
      :w 档名 另存他档。不加档名就是写入原档。(write)
       :q 及 :q! 是对目前编辑中的档案作用,如果多档编辑的情形
      并不会离开 vim,这时可下 :qa 或 :qa! 来整个离开 vim。
      a 就是 all 的意思。
      

    vim 的加密功能
      vim -x [档名]
      这样进入 vim 后会要求输入密码。以后加密过的档案由 vim 开启时会自动要求输入密码。否则无法开启。其它的编辑器当然是无法开启的。

    进入 vim 编辑档案中,临时想加密,可用 :X 指令。
       小心!vim 一开档就会有个 .档名.swp 这个档,是为了紧急回复用的,
      一般是在您所开档案的所在目录,这是个隐藏档,ls 要有 -a 参数才看得到,
      您加密的功能并没有作用在这个 swp 档,因此 root 还是知道您在
      写些什么关于他的坏话的。:-) 当然啦!山不转,路转,路不转,人转,
      您也是可以把 swap 的功能关掉的 :set noswf 就行了!但如果您编辑的是
      大档案,则不建议您把 swap 关掉,这样会很吃记忆体的。

    elvis 的话,其暂存档是统一集中存放在 /var/tmp/*.ses,
      权限是档案所有者始能读写。vim 的早期版本,其 *.swp
      档是依原档案的权限来设定的,最近的版本则从善如流,
      已经改成档案所有人始能读写,就是 -rw------- 啦!
     
      紧急回复
      vim -r 档名,或进入 vim 后,下 :recover 档名,来回复。

      各种标示方法及视窗操作
      这个单元多了一种模式,那便是 visual mode(以下简称 v-mode)v-mode下的反白区(反黑区?^_^)在本文就统一称为标示区,不知各位是否有更好的中文名称?ㄟㄟㄟ,视窗操作和标示有什么关系?为什么摆在这里说明?ㄚ,是因为这两个单元内容都不多,没地方摆,所以就将凑在一起的啦!乱点鸳鸯谱就请各位见谅。

    标示指令


      v 小写 v 这是属于字元标示(character visual),按下 v 后您就可以移动游标,游标走过的地方就会标示起来。再按一次 v 就会结束 v-mode。您用 mouse 拉出的标示区也是属于这类的标示。
      V 大写 V 这是行标示(line visual),按下 V 后会整行标示起来(包括空白的部分),您移动上下键,会标示多行。mouse 连按三次左钮,也是属于此类的标示。再按一次 V 就会结束 v-mode。
       mouse 按两次左钮是标示一个 word。
      

    Ctrl-v 这是方块标示(block visual),可纵向标示矩形区域。再按一次 Ctrl-v 就会结束 v-mode。
       结束 v-mode 的方式亦可使用 Esc 键,或一使用 Ctrl-c。
      windows 系统下 Ctrl-v 是复制键,可以使用 Ctrl-Q 来替代。
      

    d 删除标示区内容。
      y 复制标示区内容。
       ㄟ…是要先标示好才按的。"ay 还能不能用呢?当然可以,
      这样就会把标示区内容存于 a 缓冲区中。可以用 "ap 来贴上。
      

    Shift-> 标示区内容向右移一个 Tab。
      Shift-
      可设成 dark 或 light,这是两种不同的 highlight 颜色设定,详见 $VIMRUNTIME/syntax/synload.vim。不过您要更动颜色的设定,最好是设在 ~/.vimrc 或 ~/.gvimrc 中,原始档最好不要去动她。
       ㄟㄟㄟ,你从没提过 $VIMRUNTIME 好不好!其实这是最近版本的 vim
      为了不至安装新版本时把旧版本的一些设定或 macro 档干掉,
      所以 $VIMRUNTIME 就是 $VIM/vimxx,xx 就是版本号码啦!
      例如您使用的是 vim 5.6 版,那么就是 $VIM/vim56。
      

    backup(bk)
      是否要 backup file。预设不打开。
      writebackup(wb)
      在写入档案前先备份一份,和 backup 的作用不尽相同,请:h backup-table。预设是打开的,所以您如果不要 backup,那要关掉的是这个项目,而不是 backup。但请先检查一下您编译时是不是有编译进去,请 :ver。
      backupdir(bdir)
      设定存放 backup file 的目录。预设在所编辑的档案之所在目录。
      binary(bin)
      设在编辑二进位档状态,这是防止存二进位档时把 EOL 也写进二进位档,那就会悔不当初,如果是图档将会无法再观看,如果是可执行档就无法执行了!因此预设是 off。
       elvis 会自动判断是否为二进位档,而且会分成左右两半,左半部会以 16 进位的方式显示,
      右半部则是以 ASCII 的方式来显示。
      

    browsedir(bsdir)
      浏览档案的目录,GUI 版本始有。预设是上一次浏览的目录。就是 GUI版本功能表上的 [File] -> [Open] 会打开的目录。
      cindent(cin)
      写 C 时很好用,indent 比一般敏感,专为 C 程序码而设。预设 off。编辑 C/C++ code 时会自动打开。
      cmdheight(ch)
      状态列的行数,预设一行,建议设成两行。
      compatible(cp)
      设为和原始 vi 相容的状态,vim 的扩充功能会被抑制。预设 off。
      confirm(cf)
      各种确认动作。预设 off。
      directory(dir)swap 档存放的目录。前面单元已有说明。
      fileformat(ff)
      这是写入档案时置放 EOL(end of line) 的形式
      dos 是以 0D 0A 来断行。
      unix 是以 0A 来断行。
      mac 是以 0D 来断行。
      预设以各系统平台而定,在 Linux 当然是 unix 形式。
      fileformats(ffs)
      可指定多个,会依载入的档案形式来调整 ff。例如 :set ffs=unix,dos ff=unix 则预设为 unix 格式,但如读入的是 dos 格式的档案,会自动调整为 dos 格式,这样存档时就会以 dos 格式存档(状态列会显示)。此时如要改成 unix 格式,可 set ff=unix 然后存档就会转成 unix 格式,反之亦然。
      注:

    如果不这样设,也就是您不管 ff 或 ffs 都设成 unix,那读入dos 格式的档案时在每行尾会出现 ^M 这个字元(就是 0D 啦!)这时纵使 :set ff=unix 也来不及了!只好 :%s/^M//g 来消去这个^M。ㄟ,还记得怎么替换吗?就是把 ^M 换成没有啦!而且 ^M 怎么打出来的还记得吧!翻一翻前面的单元吧!
      Hey,你怎么知道是 0D 呀!好吧!告诉您一个密秘,您把游标移到^M 那个位置,然后按 ga 在状态列就会显示 10,16,8 进位的值。其它的字元也是可以如此显示。a 就是 ascii 的意思。但这是 vim 的扩充功能,elvis 没有。
      elvis 纵使载入 dos 格式的档案,也是会自动把 ^M 隐藏起来。
      ignorecase(ic)
      寻找时不分大小写,这对中文会造成困扰。预设 off。
      incsearch(is)
      加强式寻找功能,在键入 patern 时会立即反应移动至目前键入之 patern 上。预设 off。
      hlsearch(hls)
      寻找时,符合字串会反白表示。预设 off。如果您是使用 vim 的预设的 vimrc 档的话,会设在 F8 键来切换。
      textwidth(tw)
      是一种 word wrap 的功能,从左起算之固定每行的最大字元宽度。超过此宽度就会自动折行,这可是真的折行,也就是说在折行处会插入 EOL。预设是 0,也就是没有 word wrap 的功能。
      wrapmargin(wm)
      和 textwidth 作用相同,只是是从右视窗边向左算起要几个字元起折行。预设是 0。textwidth 与 wrapmargin 的功能目前并不适用于中文,打中文还是您自行按 Enter 吧!
      wrap
      这也是折行功能,可是只是萤幕效果的折行,实际上并没有插入 EOL。
      wrapscan(ws)这和折行没有关系,是指寻找时,找至档尾时,是否要从档首继续找。预设是要。
      paste
      这是防止在做剪贴时位置会不正确,前面单元已有说明。
      ruler(ru)
      会在状态列显示游标所在处之行列状态,预设不打开,但建议打开。最右边之代号的意义如下:
      Top 档案第一行在萤幕可见范围。
      Bot 档案最后一行在萤幕可见范围。
      All 档案首尾皆在一个萤幕范围内。
      如非以上三种情形,则会显示相对百分比位置。
      statusline(stl)
      状态列显示的格式,使用预设就可以了,如果您想骚包一下的话,那就请您 :h stl。
      shiftwidth(sw)
      指由 >> 移动整行内容时,一次移动的字元宽度,一般是使用 Tab 的值,但可由这个设定来改变。
      tabstop(ts)
      一个 Tab 键宽度。预设是 8 个字元宽度。最好不要随便改,以免您写的东西由其它编辑器来阅读时造成困扰,为解决这个问题,vim 有一种 softtabstop 的机制,在下一节会详细说明。
      showcmd(sc)
      在状态列显示目前所执行的指令。
      showmode(smd)
      在状态列显示目前的模式,例如是 Insert mode 或是 Visual mode。当然平常的 normal mode(commond mode)是不显示的。
      viusalbell(vb)
      以萤幕闪动代替 beep 声。
      number(nu)
      显示行号。注意,冒号命令也有 :nu 这是显示游标所在行的行号,您嫌多打一个字的话,:# 也行。不过如果 ruler 打开的话,在状态列本就会显示门前游标所在处的行列值。
      list
      这也可以算是一种模式,list mode。就是 Tab 的地方会以 ^I 显示,而行尾之 EOL 会显示成 $。可以让您清楚的知道 Tab 在哪里,折行是不是真的。
      swapfile(swf)
      是否需 swap 至磁碟。如果设为 noswf 的话,那将不会有 swapfile产生,通通会载入在记忆体中。预设是要 swapfile。
      fileencoding(fe)
      首先先鼓掌一下,啪啪啪…,因为有支援 taiwan,也支援 XIM,也就是说可以使用 xcin-2.5x 来作输入,当然您用 xcin-2.3x 配合XA 也是可以啦!目前支援简繁中文、日文、韩文,unicode 尚未植入。但前提是您要把 multi_byte 编译进去,这在一开始就讲过了。预设是使用 ansi。set guifont 及 set guifontset 已在一开始讲过,在此就不重复了。
      history(hi)
      记录冒号命令的历史纪录档,就是可以用上下方向键叫出来的那锅。预设是 20 笔。
      关于 softtabstop(sts)
      几乎所有的 OS 及软件都设定 Tab 就是 8 个字元长,这已经是个公认值,您硬要去改变它的话恐怕带来许多不便,但实际上关于程序风格,许多人又认为 8 个字元太长了,几个巢状回圈下来就需折行,反而不方便。因此 vim 体贴您,内建了 softtabstop 的功能,就是由 vim 来代您制造出一个假的Tab,实际上是空白字元组成的 Tab。

    举个例子来说明比较清楚。
       set softtabstop=4
      set shiftwidth=4
      
      这样会由 4 个空白字元取代一个 Tab,您按 Tab 键 vim 就跳 4 格,需注意的是,如果您按了三次 Tab 键,那就是一个实际的 Tab 加上四个空白字元,可不是 12 个空白字元喔!是混合 Tab 及 space 的。

    问题来了!那我要按真正的 8 字元的 Tab 时怎么办?简单,还记得怎么按特殊字元吗? Ctrl-v Tab 或 Ctrl-v I 就可以了,那就是如假包换的 8 字元长之 Tab。当然,您按两次 Tab 不就得了!:-)

    关于折行
      前面已说过 set wrap 就可以造成萤幕折行,可是却会把一个英文单字折成两半,实在很不雅观。好了,vim 再体贴您一次,set linebreak(lbr) 就会避免这种问题发生,会在空白或标点符号的地方来折行,但也仍属萤幕折行,并不会插入 EOL。这个功能目前在中文判断上还是会出槌!:-(


    规则表示式的运用
      在本系列文章一开始就说明了学 vi(m) 可以顺便学规则表示式(regular expression,以下简称 regexp),那为什么到现在才来讲呢?因为 regexp
    发布人:netbull 来自:JJ的Linux世界