Learing VI  Version 1.2


                    made by flyingcamel July, 2000
                    last update         Mar.25.2002


前言:
    這份講義共分五個部份:

    vi的概說
    最基基基本的vi, --- 給想要在vi上能死纏爛打, 而不是只看著螢幕的人
    進階的vi,       --- 給對vi有些興趣, 想玩玩vi的人
    特殊技巧,       --- 給常在Word上打出一堆h, j, k, l的人
    特別的使用範例  --- 給有特別需要的人, 外加一些有趣的例子

    其實, 學好vi的最快方法就是---砍掉joe and ee, 若你不想用這麼激烈
    的手段, 你也可以這麼做
        在bash下:alias ee='vi'; alias joe='vi'
        在tcsh下:alias ee 'vi'; alias joe 'vi'
    相信你照了上面的方法作後, 一定可以迅速的學會vi的

    在這全部的文件裡, 跟在 # 後的為註解, 後有(vim)字樣的表vi內沒這指令
    ex:
        gg  # (vim)


            vi的概說
vi(Visual Editor), 顧名思義, 是個編輯器, 它是在UNIX上的第一個全螢幕編輯器,
它本身其實沒有太多功能, 但藉由和其它的小東東組合在一起使用, 可謂威力無窮,
在UNIX上, 唯一可以和它相提並論的, 只有emacs了.
emacs是一個功能強大得可怕的超級編輯器, 你可以在emacs下收e-mail, 做一些有的
沒的, 把它當個作業系統也不為過!但也正因如些, 當你的OS面臨危機時, emacs可能
無法執行, 這時, 你能仰賴的, 就只有vi之類的編器囉! 當然, 在更糟的情怳下你可
能必須用ed才能作事....

vi的使用模式可分成三種:
插入模式(Insert Mode), 命令模式(Command Mode), 延伸模式(Ex Mode),

只有在插入模式下才能輸入文字. 所以, 有一些人認為vi這個鳥玩意是用來殘害有志
於學UNIX的人的東東, 其實, vi只不過是在強調"觸覺式使用"罷了, 等到你用vi順手
後, 你就能深深地體會到它這樣的設計目的了

插入模式和命令模式都滿容易明白的, 一個打字, 一個使用命令, 那....延伸模式是
啥個玩意呢?
延伸模式包涵的很廣, 舉凡常規表示式(Reguler Expression), 執行命令, 功能設定,
巨集, 字串轉換, 存檔, 開檔等, 都是在延伸模式下完成的
而所有的提示字樣和延伸模式一樣, 都是出現在螢幕的最下面一行


            vi的最基基基本使用
要使用vi, 你只要在Shell下打:
$vi FILE_NAME

$是指Shell的提示符號, FILE_NAME是你想編輯的檔名, 若你不指定檔名, 直接打vi也
是可以進入編輯畫面的, 只是存檔時還是要指定檔名就是了

vi啟動後會先待在命令模式, 這時你可以打 i 進入插入模式 而在命令模式中打 : 會
進入延伸模式; 不管在那種模式下, 按ESC都會回到命令模式中, 或著是取消未打完的
命令

以下, 以 : 開頭的表ex mode command, 其餘為command mode command(回文ㄟ!! ^^)
:w              (write) 存檔
:w hahacamel    (write) 存檔, 檔名為hahacamel
:q              (quit)  離開
:w!         強迫存檔(當你要存在唯讀檔時使用, 當然, 你的權限也要夠)
:q!         強迫離開(若在未存檔的情況下, vi是不會讓你離開的
:set bs=2   設定可以在插入模式下刪除上一次寫入的文字(預設值為不行)  # (vim)

相信聰明如你, 一定也發現了.....對沒錯, 在命令後加 ! 就是表示強迫執行命令!!!!

x   刪除字元(就像delete鍵一般)
X   刪除字元(就像Backspace一般, 注意這個為大寫X, 上面的是小寫的x
i   (insert) 進入插入模式

所以, 若你只是想讓vi像普通的編輯一般, 不會讓你想砸了鍵盤, 我建議的做法是:
vi YOURFILE
:set bs=2               # bs就是backspace啦   (vim)
i
然後快樂的在插入模式下猛敲鍵盤
好啦, 相信具備上述命令, 你已能夠獨當一面了

            進階的vi
一些基本指令:

在命令模式下:
u   回覆上一個動作
U   回覆對這一行做的動作
J   把下一行"提上來"和目前這一行合併
/   往下搜尋
?   往上搜尋
n   到下一個符合搜尋的目標處
搜尋的字是用Regular Expression表示之, 所以某特殊字元需以 \ 將之化為一般字元
ex:
    /\*     #表示搜尋 * 這個字元
            #Regular Expression, 中譯有多種, 我個人較偏好"常規表示法"

Ctrl+r  還原"回覆"的動作, (好像有點繞口)
Ctrl+l  重讀畫面, 當你是用terminal時, 有可能用到
Ctrl+g  顯示訊息, 包含檔名, 目前在第幾行, 共幾行...等

在ex 模式下:
:h HELP_COMMAND 線上說明, 如同F1一般, 要離開線上說明, 和離開vi一樣是:q
:f              同Ctrl+g
:n FILE_NAME    開啟檔案(新舊皆可), e 的功能和它一樣

進入插入模式的指令:
i   (insert) 從游標處進入插入模式
I            從游標所在的那行開頭處進入
a   (append) 從游標右邊進入
A            從游標所在的那行尾端進入
o            從游標處往下新增一行, 並進入插入模式
O            從游標處往上新增一行, 並進入插入模式

快速的移動游標的指令:

在命令模式下:

  k         上          # 你可能會這麼想: hjkl快速? 不會搞混就好了! >_<
h   l     左  右        # 嘿嘿...在vi裡, 連上下左右都很強的!!稍後會說明
  j         下

0   (數字零)移至行開頭
^   移至行中第一個出現文字處
$   移至行尾
gg  移至文章開頭    # (vim)
G   移至文章尾端
b   往前移一個單字
w   往後移一個單字
H   移到畫面的頂端
M   移到畫面的中間
L   移到畫面的底端
Ctrl+u  往上半頁
Ctrl+d  往下半頁
Ctrl+b  往上整頁
Ctrl+f  往下整頁
ex:
    Camel can fly
    ^       # 游標目前位置
            # 在命令模式下按 ww
    Camel can fly
             ^  # 游標目前位置
但...在中文的世界裡. 必須設定好w b才能移動正確,
ex: for MS win32的gvim, 可以使用w b在中文間移動,
    Un*x上的vim預設不能

在ex 模式下:

:num    移至第num行
ex:
    :33 # 移到33行
    :$  # 移到最後一行

刪除的指令

在命令模式下:

x   功能和delete一樣
X   功能和Backspace一樣
d*  (delete) *表所欲刪除的對像, 其實也可以看成刪除游標所經過處
ex:
    dw  刪除單字    # delete word(s)
    dd  刪除一行    # 按起來特別順手
    D   從游標處砍到行尾# 用起來特別爽
    dgg 砍到文章開頭處  # (vim)
    dG  砍到文章結尾    # 實在是太師了
    dj  砍掉目前和下一行# 同理, dk; 但dh, dl就沒啥用了

也就是說, 只要能移動的指令, 都能和d配合
在ex 模式下你可以這麼做:
    :1,10 d 砍了1-10行
    :1,$ d          # 猜得出來吧

試著組合出屬於你的用法吧

修改的指令:

所以謂的修改, 就是指"先刪除, 再進入插入模式"
r   直在命令模式下更改單一字元
s   吃掉一個字元, 再進入插入模式, 功能就如同 xa
S   同cc, 改變一行
c*  (change) 用法同d*, 只不過是砍完後再進入插入模式

複製/貼上:

不管是被刪除的字或是被修改的字, 都會先被存到buffer(緩衝區)裡, 還可以
待機貼回文章裡(可重複貼上多次), 也就是說, 在vi裡刪除和剪下是一樣的
p   (paste) 在游標後貼上
v   選取反白部分, 就好比Windows下按住shift再移動遊標
    可搭配x, d, s, c, y...一同使用
    用法為:1.按一下v  2.移動游標選取範圍  3.按下x或是d, s, c, y
y*  (yank)  用法同d*, y*, 但不會刪掉文字

注意, 當第二次做刪除(或修改, 複製)的動作時, 原buffer內的文字會被蓋掉
ex:
    Ha ha Camel!
    # 在Ha上按xx
    # 按p, 結果如下
     aha Camel!

若不懂為何會如上行的結果, 請自行演練一遍

再來, 就是重頭戲了, 在vi中, 所有的在命令模式下的命令都可以和數字搭配,
用來表示希望執行的次數
ex:
    10j     # 往下移10行
    5dd     # 砍5行
    3yy     # 複製3行
    4s      # 吃掉4個字後進入插入模式
    1000o       # 新增1000行
    100p        # 貼上100次, 當你不會寫迴圈時, 這是個好幫手

在"特別的使用範例"中, 會有更好的例子教你如何善用這功能;
相信現在你已大概了解vi的精神所在了, vi彈性十足, 就像UNIX下的命令
一般, 可以互相搭配使用, 功能簡便好記
記往, 這裡提到的, 還只是皮毛罷, 若你真的要發揮vi強大的功能, 請看後兩篇

            特殊技巧
我把一些較少用到, 但功能不錯, 或是功能強大卻不好學的技令歸在這裡

在命令模式下:

~       將英文字母的大寫轉為小寫, 小寫轉為大寫
m*      (mark)設定書籤, *是a-z或A-Z, 共有52個, 往後只要用
`*      (反單引號)就會回到mark處, 用'*(單引號)會回到那一行, ''(單引號)會回到原處
{       (左大括號) 跳到上一段的開頭
}       (右大括號) 跳到下一段的的開頭.
ZZ  同:wq
K   man游標所在處的單字 # (vim)
ex:
    By the Camel who can fly high and fall down to the ground.
    # 從B處開始, 打80~(這就好比對整行用 ~ 指令, 結果如下
    bY THE cAMEL WHO CAN FLY HIGH AND FALL DOWN TO THE GROUND.

    # 在Camel的'C'處按mc, 接著隨便亂移你的游標, 再打'c, 就會回到那一行
    # 接著打'', 就會回到"跳到mark前的位置", 也就是....自己試吧

在ex 模式下:

:!cmd   執行cmd, 這就好比直接在Shell下打入cmd一般
ex:
    :!pwd       # 看看目前是在那裡打字

:r  讀取檔案或文字等從目前游標的下方插入文字
ex:
    :r !ls      # 把目錄下的檔桉讀到文字中
    :27 r !ls   # 游標移到第27行處, 再把ls的結果讀到檔案中

:[num] new [file]   # (vim)
[]表可以選擇的參數, :new會打開新檔 :new file會打開一個叫做file的檔案
兩著皆會顯示出一個新窗和目前的視窗水平並排
:10 new 會打開一個新檔, 並只讓這個新檔占畫面中的10行
(在console下只有24行, 第25行是用來顯示訊息和對ex 模式輸入用的
在多個視窗間用Ctrl+w,w or j or k來切換
ex:
    :new camel  # 開啟camel
    Ctrl+w,w    # 切換游標到camel檔中

:ab 1 2 (abbreviate) 縮寫, 以1來取代2
當你在插入模式下打入1後, 若接著按ESC或標點符號等, 1就會轉變成2
:unab 1 則是取消原來的取代命令
:ab 則是列出所以已設定的abbreviation
ex:
    :ab ccc Flying Camel in the sky
    # 在插入模式下打ccc. 結果如下
    Flying Camel in the sky.

"*  此命令為配合複製, 刪除等指令使用, *是a-z, 或A-Z, 共52個
    可永久保留文字(當然, 一離開vi的環境, 還是會消失的),
ex:
    You know I don't know, but I don't know you know.
    # 先在開頭的You處打"gdw
    # 在know的地方打D
    # 這時, 若用p, 會貼回被D砍掉的文字, 用"gp, 會貼回You

=====================================================================

真正的重量級指令來啦......
沒錯, 就是巨集!!
在vi裡, 是在ex mode下用map來設定巨集的, 尤於vi的彈性很大, 相對的也促使
它的巨集好設又好用

:map             列出所有已設定的巨集
:map a macro...  設定在命令模式下, 當使用者按下a時, 就等於使用了macro...這些命令
:map! a macro... 設定在插入模式下, 功能同上
:unmap a         取消在命令模式下a的巨集功能
:unmap! a        取消在插入模式下a的巨集功能
:map #n macro    設定功能鍵(Functional Key), n為1-12, 相對應為F1-12
:so FILE         從FILE處讀入己設定的巨集

設定巨集前, 請先記得確認該鍵是否有衝到, 別小看vi的命令哦, 數量可是多得驚人
ex:
    map E oHello Camel  # 新增一行並輸入Hello Camel
    map #2 :1,$ d       # 按F2後再按Enter就會砍光光哩

進階說明:
有些控制字元, 或特殊按鍵, 無法像1, 2, a, ...等字直接打出,
像 ESC, 插入模式下的"上下左右", Enter, ...等
這時, 你要用Ctrl+V來配合使用
首先, 先按一下Ctrl+V(不用壓往), 再按你要的特殊鍵就好了, 簡單吧
ex:
    map #3 :1,$ d^V[ENTER]  # ^V表示按一下Ctrl+V; 記得最後要按一下Enter讓命令生效
                # 接著按一下F3就全砍光光囉, 不用再按一下Enter哦

另外, 若記不起來#n是表示Funtional Key時, 你可以用Ctrl+V來達成一樣的事, try it.

有關map等的強大例子, 在下一篇會說明


            特別的使用範例
還有一些常用的指令我沒講到, 但它們的常用度是適你寫程式的次數而定 :D
它們功能不是專針對一門程式語言而設的, 實際上, 可以應用的範圍很廣

在命列模式下:
%   對大括號
>>  往右縮排一個shiftwidth
<<  往左縮排一個shiftwidth
[[  跳到上一個函式處        # 前提是你的函式需為     foo    的形式
]]  跳到下一個函式處        #           {
                    #           }
在延伸模式下:
:mak    相當於 :!make,:make也是一樣的功用


    設定你的vi

.exrc           vi的起始設定檔, 需放在$HOME目錄下
.vimrc          vim的起始設定檔, 需放在$HOME目錄下

set ai
set cin         對程式做排版 # (vim)
set ru          顯尺規, 標示(x, y)坐標位置, etc
set showcmd
set bs=2        讓backspace可以吃掉之前insert mode輸入的資料 # (vim)
syntax on       以特殊顏色標示key word # (vim)


    使用實例

Ctrl+V  用vi秀出色彩( ANSI color )
>>,<<   巢狀的縮排
ab  變數名稱, 簽名檔
map 簡易取代s//的功能, HTML, PHP, Shell script


    有趣的巨集範例  (在RH Linux下/usr/share/vim/macro/中有)

河內塔
生命遊戲
走迷宮

FAQ
1. 為什麼我用terminal時, 在插入模式下按上下左右會出現一堆ABCD?
Ans:    若你是在使用vim時遇到這種問題, 在你的HOME下產生.vimrc就會好了

2. 為什麼我在用vim時無法連續用u?
Ans: 在你的HOME下產生.vimrc就好了

3. 我要怎麼樣在使用terminal時, 使色彩像在console下一樣豐富?
Ans: 若你的Shell是bash, 請在你的HOME下的.profile中加入這行
    export  TERM='xterm-color'
 若你是用tcsh 或 csh, 請在你的HOME下的.cshrc中加入這行
    setenv  TERM xterm-color
並記得在.vimrc中加入syntax on

4. 為什麼syntax on後卻沒有多種顏色?
Ans: vim是依據副檔名來判斷的, 記確定你的副檔名有沒有加對?
    若是寫Perl 或 Python, Shell script之類的, 請記得在檔案的第一行加上
    #! /bin/sh          ( 以Shell script為例 )


END_OF_FILE
Back