vi - 螢幕導向 (可顯式在螢幕上) 的顯示器編輯程式
敘述
vi 命令 (visual; 看得見的) 是一種螢幕導向的本文編輯程式. 它是以
行列編輯程式 ex(1) 為基準而設計的. 因此我們可以在兩者間切換, 並
可從 vi 中執行 ex 命令.
使用 vi 時, 終端機螢幕即為編輯中的檔案的視窗. 對檔案所做的任
何改變, 都會在螢幕上顯示出來; 螢幕上游標的位置即表示它在檔案
中的位置.
使用者必須在環境變數 TERM 中指定終端機類型, 且指定的終端機在
terminfo(4) 資料庫中必須有定義. 像 ex(1) 一樣, 編輯程式起始設定
script 可置於環境變數 EXINIT 中, 或現行目錄或起始目錄的 .exrc
檔案中.
view 的使用法與 vi 一樣, 差別只在於會設定 readonly 編輯程式選擇
項.
而 vedit 則是設計給初學者使用的編輯程式. 報表編輯程式選擇項設定為
1, 亦設定了 showmode 和初學者編輯程式選擇項. 這些功能可使初學者
學起來更加輕鬆.
選擇項
下列選擇項可在命令行中使用:
- 所有交談式的使用者回饋均不出現. 這個選擇項可用於
處理編輯程式 sccript 之時.
-v 調用 vi (此選擇項是為了 ex(1) 而設計的, 對 vi 不
產生效果).
-r 若編輯程式或系統故障, 復原為編輯之前的檔案. 若未指
定檔案, 則列印存入的所有檔案. 您必須是這些存入的
檔案的所有者, 才能將檔案復原 (即使是高階使用者,
也無法復原其他使用者名下的檔案).
-R 設定 唯讀 模態, 以免不小心覆寫過原來的檔案.
+command 以執行指定的 ex 搜尋, 或將命令定位於適當的位置開
始編輯.
-l lisp 模態; 會有適當內縮, 以配合 lisp 碼; vi 的 ()
{} [[ 及 ]], 都會修改成在 lisp 中有意義的形態.
-t tag 編輯包含 tag 的檔案, 並將編輯程式定位於其定義上 (請
參閱 ex(1) 的 tag 命令).
-V verbose 模態; 若從 .exrc 檔案或是某一個來源檔案輸
入, 則編輯程式命令在執行時便會顯示出來 (請參閱 ex(1)
中的 cource 命令).
-wsize 將視窗編輯程式選擇項的值設定為 size.
-x 密碼模態; 系統會提示使用者敲一個鍵, 表示允許建立
或編輯一個密碼檔案 (請參閱在 ex(1) 中的 crypt 命
令).
ex 完整的描述, 請參閱 ex(1). 此處僅描述編輯程式的 visual 模態.
vi 被調用時是處於命令模態; 要進入輸入模態, 可以數個用來插入或
改變本文的命令所設定. 在輸入模態中, 可使用 ESC (escape; 轉義)
離開; 但若設定了 doubleescape 編輯程式選擇項, 則需要連續兩個 ESC
字元才能離開輸入模態 (請參閱 ex(1)). 在命令模態中, ESC 可用來
取消部分命令; 若編輯程式並非處於輸入模態, 且沒有鍵入部分命令,
則終端機的鈴會響.
螢幕的最後 (底端) 一行可用來回應搜尋命令 (/ 和 ?) ex(1) 命令
(:) 以及系統命令 (!) 的輸入. 也可用來報告錯誤訊息或列印其他
訊息.
在輸入本文, 或在螢幕最後一行輸入命令時, 若系統接收到 SIGINT,
則會中止輸入 (或取消命令), 且編輯程式回復命令模態. 若在命令模
態中接收到 SIGINT, 則鈴聲響起; 一般而言, 鈴聲響起則表示有錯誤
發生 (例如所敲的鍵不被認可等情形).
一行中若只包含一個∼, 則表示該行上一行是檔案的最後一行 (檔案
末尾之後各行, 均為 ∼形態). 區域智慧 (local intelligence) 有
限的終端機, 螢幕上顯示的可能是 @, 表示這是螢幕上的空白, 並不
會對應到檔案中任何一行 (這幾行可以 ^R 刪除, 強迫編輯程式重新顯
示螢幕內容, 不要出現空白行).
命令摘要
大部分的命令前面可接受一個數字作為引數, 表示大小或位置 (適用
於顯示或移動命令); 或作為重複計數 (適用於改變本文內容的命令).
為了簡明起見, 若描述到此選擇性引數, 則代表這是一個計數.
下列運算子後面可以跟著一個移動 (move) 命令, 指明影響到本文的
範圍: c d y <, > ! 和 =. 指定區域開始於目前游標所在的位置,
一直到 move 指出的游標位置為止. 若此命令以行為單位來操作, 則
指定區域中所有或某些行會受影響. 否則就只有標示出來的區域會受
到影響.
下面所列各項中, 控制字元的形態為 "^X", 表示 "control-X". 空白
(whitespace) 定義為字元空格 跳格及替代空格 (alternative space).
替代空格為 LANG 環境變數指定的語言中, langinfo(3C) ALT_PUNCT
項目的第一個字元 (請參閱 environ(5)).
除非特別指定, 否則命令只在命令模態下會被解譯, 對於輸入模態沒
有特殊影響.
^B 向後捲動, 顯示前一個視窗的本文. 也可加上一個數目,
指定要倒退的視窗數. 通常兩個視窗之間, 會有兩行重疊.
^D 向前捲動半個視窗的本文. 也可加上一個數目, 指定捲動
的 (邏輯上的) 行數, 此數會被記錄下來, 以供後面的 ^D
和 ^U 利用.
在輸入模態中, ^D 以 autoindent 或 ^T 指定的內縮格式
為準, 再縮入 shiftwidth 格.
^E 向前捲動一行, 通常游標位置不動.
^F 向前捲動, 顯示下一個視窗的本文. 若加上一個數目, 表
示前捲的視窗數. 通常兩個視窗之間, 會有兩行重疊.
^G 列印現行檔案的檔名和其他資訊, 包括行數及目前的位置.
(相當於 ex 命令中的 f).
^H 左移一格 (游標停在左界). 若加上一個數目, 表示左移格
數. (同 h).
在輸入模態中, ^H 會將游標移到最後一個輸入字元的位置,
但不會刪除該字元.
^J 將游標移到下一行同一欄的位置. 若加上一個數目, 表示
下移的行數. (同 ^N 及 j).
^L 清除並重現螢幕內容. (可用在螢幕因某種原因變得混亂時).
^M 移到下一行第一個非空白字元位置上. 若加上一個數目,
表示下移的行數.
^N 同 ^J 和 j.
^P 將游標移到上一行同一欄的位置. 若加上一個數目, 表示
上移的行數. (同 k).
^R 重現目前螢幕內容, 將有 @ 的那幾行刪除 (這幾行並不出
現於檔案中).
^T 在輸入模態中, 若游標位為一行行開頭或前面只有空白,
則 ^T 會插入 shiftwidth 格空白. 插入的空白只能以 ^D
刪除.
^U 向前捲動半個視窗的本文. 也可加上一個數目, 指定捲動
的 (邏輯上的) 行數, 此數會被記錄下來, 以供後面的 ^D
和 ^U 命令使用.
^V 在輸入模態中, ^V 替下一個字元加上引號, 以便於檔案中
插入特殊字元 (包括 ESC).
^W 在輸入模態中, ^W 會退回一個字; 刪除掉的字元仍然會顯
示出來.
^Y 向後捲動一行, 通常游標不動.
^[ 取消鍵入一部分的命令; 如果沒有這種形式的命令, 則鈴
聲會響起.
在輸入模態中, ^[ 會使輸入模態終止. 但若設定了 double-
escape 編輯程式選擇項, 則需要連續兩個 ESC 字元才能離
開輸入模態 (請參閱 ex(1)).
若在螢幕最下面一行輸入一個命令 (ex 命令行或以 \ 或
? 搜尋字型), 則會終止輸入而執行命令.
在許多種終端機上, 可以 ESC 或 ESCAPE 鍵來代替 ^[.
^\ 離開 vi, 進入 ex 命令模態. 若當時處於輸入模態下, 則
先終止輸入模態.
^] 將游標後面的那個字做為特殊標記, 然後執行特殊標記編
輯器命令 (請參閱 ex(1)).
^^ 回到前一個檔案 (同 :ex #).
右移一格 (以一行之末為限). 若加上數字, 表示右移格數.
(同 l).
erase 消除, erase 是一個使用者指定的消除字元 (請參閱 tty
(1)). (同 ^H).
kill 清除, kill 是一個使用者指定的清除字元 (請參閱 tty(1)).
在輸入模態中, kill 會使游標回到現行輸入行的開頭, 且
螢幕上不會刪除此行.
susp 編輯程式活動暫停, 回到呼叫 shell. susp 是使用者指定的
程序控制暫停字元 (請參閱 stty(1)). suspend 編輯程式命
令的詳細資訊, 請參閱 ex(1).
! 一個運算子, 可從緩衝區傳遞指定的各行作為指定的系統
命令的標準輸入, 並以該命令的標準輸出來替換這幾行.
! 的後面跟著一個移動命令, 指定所要傳遞的那幾行 (從
目前游標所在的位置到移動終點的那一行) 及所要執行的
命令 (同樣以 retern 作為命令的終止). ! 前面的數目會
傳遞給移動命令後面的 !.
兩個 !! (或者前面還有數字) 代表由現行行開始, 傳遞過
許多行.
" 用在指定的緩衝區規格之前. 1-9 九個緩衝區可用來存放
編輯程式刪除的本文. a-z 二十六個緩衝區可用來儲存刪除
或拿出的本文; 請參閱下面的 y.
$ 移到本行行末. 若加上數字, 代表前進的行數 (例如 2$
可使游標前進到下一行結尾).
% 移到與目前游標所在位置的括弧或大括弧吻合的括弧或大
括弧.
& 同 ex 命令 z (亦即 z 重複前一個取代命令).
' 若後面有一個 ', vi 會回到前文中, 游標位於一行開頭.
(只要作了非相對的移動 (non-relative move), 都會設定
前文). 若後面有字母 a-z, 則會回到標有這些字母的那一
行 (請參閱 m 命令) 的第一個非空白位置.
若和運算子 (如 d) 一起使用, 指明影響本文的範圍, 則
整行都會受到影響. (請參閱 `).
` 若後面跟著一個 `, vi 會回到前面的上下文, 游標則位於
標示的字元位置. (只要作了非相對的移動 (non-relative
move), 都會設定前文). 若後面有字母 a-z, 則會回到標
有這些字母的那一行 (請參閱 m 命令) 的第一個非空白位
置.
若和運算子 (如 d) 一起使用, 指明影響本文的範圍, 則
整行都會受到影響. (請參閱 ').
[[ 回到前面一段的邊界. 所謂的 一段 是以段落選擇項的
值來定義, 若一行以饋列 (^L 字元) 或 { 開頭, 則可中
止 [[.
若設定了 lisp 選擇項, 游標會停在每行開頭的 ( 上.
]] 移到前一段的邊界 (請參閱 [[)
^ 移動到本行第一個非空白字元的位置.
( 往後移動到某一句的開頭. 一個句子是以 . ! 或 ? 等符
號, 後面是行末或兩個空格為結束. 任何數量的 ) ] "
和 ' 字元可以在 . , ! 或 ? 符號以及空格或行末之間
出現. 若加上一個數字, 表示游標移動的句數.
若設定了 lisp 選擇項, 則游標會移到一個 lisp s-敘述
的開頭. 句子也可開始於段落 (paragraph) 或是一段
(section) 的邊界 (請參閱 { 和 [[).
) 前移到句子開頭. 若加上一個數字, 表示移動的行數. (請
參閱 "(")
{ 移回前一個段落的開頭. 所謂的 一個段落 , 是由段落
選擇項的值所指定. 一個空行和段界限 (section boundary)
(請參閱 [[) 也可解釋為一個段落的開頭. 若加上數字,
表示游標移回的段落數.
} 前移至下一個段落的開頭. 若加上數字, 表示游標前移的
段落數. (請參閱 "{").
| 前面必須有一個數目; 游標會移到本行指定的那一欄 (若
該欄存在的話).
+ 移到下一行第一個非空白字元的位置. 若加上數字, 表示
前進的行數. (同 ^M).
, 逗號 (,) 表示執行與前面發出的 f F t 或 T 命令相反
的動作, 即於本行反方向搜尋. 若加上數字, 表示重複搜
尋動作指定的次數.
- 連字號 (-) 會將游標移至前一行第一個非空白字元的位置.
若加上數字, 表示前移指定的次數.
_ 底線 (_) 會將游標移到本行第一個非空白字元的位置. 若
加上數字, 表示往前移的行數, 且原來所在的那一行變成
第一行; 若未加上數字或該數字為 1, 表示目前所在的那
一行.
. 重複前一個改變暫存器內容的命令. 若加上數字, 表示重
複該命令指定的次數.
/ 從螢幕上最後一行讀取一串字串, 解譯成一般運算式, 然
後向前掃瞄下一個吻合的字串. 搜尋的動作於使用者鍵入
return 作為字型結束時開始; 若要終止搜尋動作, 可送出
一個 SIGINT (或使用者設定的中斷字元).
若配合一個運算子來指定影響本文的範圍, 定義的區域開
始於目前游標所在的位置, 結束於吻合的字串的開頭. 若
要指定一整行, 可從吻合的那一行給定一個差值 (在 / 符
號之後加上 +n 或 -n).
0 移到本行第一個字元的位置. (若前面是一個非零的數字,
則 0 不會被當作一個命令).
: 冒號 (:) 表示 ex 命令的開始. : 及鍵入的命令會出現在
螢幕的下面一行; 使用者鍵入 return 之後, ex 命令便會
被執行.
; 重複最後一個以 f F t 或 T 找到的字元. 如果加上一
個數字, 則搜尋的動作會重複指定的次數.
< 將一行左移 shiftwidth 格的運算子. < 後面可以跟著一
個移動命令, 指定移動的行數. 數目會被傳遞給移動命令.
若有兩個 < (即 <<), 則轉移現行行 (或者計算由現行行
開始的行數).
> 將一行右移 shiftwidth 格的運算子. (請參閱 <).
= 若設定了 lisp 選擇項, 則 = 會重新縮排指定的那幾行,
雖然他們和 lisp 同時鍵入, 且已設定 sutoindent. = 前
面可以有一個數字, 指定往前進行幾行, 或在後面加上一
個移動命令, 效果相同.
? 向後掃瞄, 為 / 的相反. (請參閱 /).
@buffer 執行儲存在指定的緩衝區中的命令. 小心不要在緩衝區內
容的結尾加上 字元, 除非 是命令串
的一部分. 要在 ex 模態中執行的命令, 前面須加上冒號
(:).
∼ ∼改變游標所在字元 (若為字母) 的字體, 並將該字元往
右移到一行最後. 若加上數字, 表示本行要改變多少個字
元的字體.
A 在行尾加上內容. (同 $a).
B 移回一個字 (任合一個非空白序列), 游標停在該字的開頭.
若加上數字, 表示要移回的字數.
C 改變本行其餘本文. (同 c$).
D 刪除本行其餘本文. (同 d$).
E 前移到一個字 (任何非空白序列) 的結尾. 若加上數字,
表示游標前進的字數
F 後面必須跟一個字元; 往後掃瞄尋找該字元, 游標停在該
字元的位置. 若加上數字, 表示搜尋的次數.
G 跳到後面的引數所指定的行號, 若前面沒有數字, 則跳到
檔案末尾.
H 將游標移到螢幕最上面一行. 若加上數字, 表示從螢幕上
端往下算, 指定行數的位置. 游標會停在該行第一個非空
白字元上. 若作為某一個運算子的目標, 則整行都會受影
響.
I 在一行開頭插入內容. (同 ^ 後面加上 i).
J 將下面一行連到本行後面, 中間加上適當的空格: 字與字
之間一格 句點之後兩格 若下一行的第一個字元是右括
弧, 則不加空格. 若加上數字, 表示要結合的行數.
L 將游標移到螢幕上最後一行的第一個非空白字元. 若加上
數字, 表示從螢幕底端往上算指定的行數. 若與運算子一
起使用, 則整行都會受影響.
M 將游標移到螢幕中間那一行的第一個非空白位元.
N 掃瞄下一個有最後的 / 或 ? 指定的字型, 但方向相反;
這是 n 的相反.
O 在本行上面加上一行新行, 並進入輸入模態.
P 在游標之前/之上放回 (替換) 最後一個刪除的本文. 如果
本文整個被刪除, 則全部會回到游標的位置上. 否則, 本
文會加到游標之前.
P 之前可以指定一個緩衝區 ("x), 以檢索其內容.
Q 離開 vi, 進入 ex 命令模態.
R 用鍵入的字元取代螢幕上的字元, 直到以 ESC 終止輸入.
S 改變整行 (同 cc), 若加上數目, 表示改變的行數.
T 後面必須跟著一個字元; 往後搜尋本行是否有該字元. 若
找到該字元, 則游標置於其後. 若加上數字, 表示搜尋的
次數.
U 將現行行回復成游標移到該行之前的狀態.
W 向前移到本行某個字 (一串非空白字元) 的開頭. 若加上
數字, 表示前進的字數.
X 刪除游標前面的字元. 若加上數字, 表示刪除的字元數,
但只有本行的字元會被刪除.
Y 將本行複製一份放到不命名的緩衝區 (同 yy). 若加上一
個數字, 表示複製的行數. 若 Y 6前面有一個緩衝區名稱,
這幾行就會被複製到指定的緩衝區中.
ZZ 退出編輯程式, 若緩衝區內容曾被改變, 則寫出其內容. (同
ex 命令 x).
a 進入輸入模態, 在目前游標的位置加上全部的本文. 若加
上數字, 表示要重複的行數, 但只有在要加入的本文都在
同一行上才可以.
b 移回本行前一個字的開頭. 所謂的一個字, 是指一串文數
字或特輸字元. 若加上數字, 表示動作重複的次數.
c 後面必須跟著一個移動命令. 刪除指定區域的本文, 然後
進入輸入模態, 以新的本文取代刪除的本文. 如果受影響
的部分超過一行的部分區域, 則刪除調的本文會存入數字
緩衝區中. 如果只有本行部分受影響, 則最後刪除的那個
字元會標上 $. 數字會被傳遞給移動命令. 若命令是 cc,
則整行都會被改變.
d 後面必須跟著一個移動命令.
刪除指定區域的本文. 如果受影響的部分超過一行的部分
區域, 則刪除調的本文會存入數字緩充區中. 數字會被傳
遞給移動命令. 若命令是 dd, 則整行都會被刪除.
e 移到下一個字的末尾, 字的定義同 b. 若加上數字, 表示
執行該動作的次數.
f 後面必須跟著一個字元; 掃瞄本行其餘部分是否有該字元,
並游標移到其上. 若加上數字, 表示動作重複的次數.
h 游標左移一個字元. (同 ^H). 若加上數字, 表上動作重複
的次數.
i 進入輸入模態, 在游標前面插入鍵入的文字. (請參閱 a).
j 將游標移到下一行同一欄中. (同 ^J 和 ^N).
k 游標上移一行. (同 ^P).
l 游標右移一個字元. (同 ).
m 後面必須跟著一個小寫的 ASCII 字母 x; 將目前游標的位
置標上該字母. 可藉由 `x 參考到正確位置; 而游標位置
的字元則以指定的字元取代. (新字元可以是一個換行鍵).
若 r 前面有一個數字, 表示以指定的字元替代.
s 刪除游標所在位置的字元, 並進入輸入模態; 以鍵入的文
字替換刪除調的字元. s 前面的數字表示本行改變的字元
數. 最後一個改變字元會標上 $, 如同 c 一樣.
t 後面必須跟著一個字元; 掃瞄本行的剩餘部分是否有該字
元. 若找到該字元, 則游標停在前一格. 若加上數字, 表
示搜尋的次數.
u 使得現行緩衝區最後一次改變的效果相反. 若有兩個 u,
則兩個狀態交替變換; 即狀態自行變換. 若在插入一行以
上本文之後使用, 則這些行會存在以數字命名的緩衝區中.
w 往前移到下一個字的開頭. (字的定義同 b). 若加上數字,
表示游標前進的字數.
x 刪除游標所在位置的字元. 若前面加上數字, 則會刪除從
游標位置算起的指定字元數, 但只刪除本行的字元.
y 後面必須跟著一個移動命令; 指定的本文會被複製到未命
名的暫時緩衝區. 若前面有一個指定的緩衝區 "x, 則本文
也會存到該緩衝區中. 若命令為 yy, 則整行都會被複製.
z 重現螢幕內容, 現行行的位置因選擇項不同而有異: z, 在螢幕頂端; z., 在螢幕中央; z-, 在螢幕底部.
z^ 和 z+ 兩個命令分別同 ^B 和 ^F; 然而 z^ 和 z+ 在
兩個螢幕之間並不會有兩行重疊. 在 z 和後面的字元中間
加上數字, 可指定重現螢幕的行數. 若在 z 前面加上數字,
則表示作為參考行的行數, 內定是現行行.
鍵盤編輯鍵
在起始設定中, 編輯程式會自動把一些終端機鍵盤的編輯鍵, 對應到
等義的視覺模態命令. 這些對應關係只能建立於列在下表的那些鍵上,
而且此對應關係將在 terminfo(4) 資料庫中有所定義, 而且定義之
後, 其效用一如現行終端機 (正如 TERM 環境變數指定的).
命令和輸入模態的對應關係都應該建立(請參閱 ex(1) 的 map 命令).
除了插入字元鍵之外, 這些字元鍵的作用只是不時地把輸入模態打開
或關閉 ,若執行與命令模態對應的相同動作, 然後重新進入輸入模態,
輸入模態的對應也會終止輸入模態.
在某些終端機上, 從鍵盤編輯鍵所送出的字元順序, 可以當作使用者
輸入的順序, 則執行其他命令或是命令組時, 這種鍵盤編輯鍵將對應
到視覺模態命令. 以上敘述的是在透過輸入模態對應時, 最可能發生
的情況, 因此, 在具有這些特性的終端機上, 系統的內定是把輸入模
態的對應取消. 使用者的自訂可以凌駕系統的取消動作, 而藉 key-
boardedit 和 keyboardedit! 編輯程式選擇項的適當設定, 可以啟動
命令和輸入模態編輯鍵對應. (請參閱 ex(1)). timeout timeoutlen
以及 doubleescape 編輯程式選擇項, 都是提出該問題的選擇方式.
terminfo 命令模 輸入模 對應名稱 敘述
項目 態對應 態對應
key_ic i ^[ inschar insert char
key_eic i ^[ inschar end insert char
key_up i ^[ka up arrow up
key_down i ^[ja down arrow down
key_left i ^[ha left arrow left
key_right i ^[la right arrow right
key_home i ^[Ha home arrow home
key_il o^[ ^[o^[a insline 插入一行
key_dl dd ^[dda delline 刪除一行
key_clear ^L ^[^La clear 清除螢幕
key_eol d$ ^[d$a clreol 清除本行
key_sf ^E ^[^Ea scrollf 往下捲動
key_dc x ^[xa delchar 刪除字元
key_npage ^F ^[^Fa npage 下一頁
key_ppage ^B ^[^Ba ppage 上一頁
key_sr ^Y ^[^Ya sr 往上捲動
key_eos dG ^[dGa clreos 清除本螢幕游
標以下部分
外在影響
環境變數
LC_COLLATE 決定一般表示式的值, 以及特殊標記檔處理的合訂對併順
序.
LC_CTYPE 決定應解譯本文為單一及 (或) 多位元組字元, 把字元分為
大寫或者小寫字母, 並符合一般表示式中的字元分級表示式.
LANG 決定顯示訊息的語言.
LANGOPTS 指明的選擇項, 可以決定從右到左行的語言, 其本文應如何
儲存在輸入和輸出檔案裡. 請參閱 environ(5).
如果 LC_COLLATE 或 LC_CTYPE 沒有在環境中指定, 或是設定為空字
串, 則 LANG 的值就當作未指定變數, 或空變數的內定值. 而如果
LANG 未指定, 或者是設定為空字串, 則 LANG 的值為 "C" (請參閱
lang(5)). 如果一個跨國變數包含無效的設定值, 則編輯程式會將所
有的跨國變數視為 "C". 請參閱 environ(5).
跨國內碼集支援
目前已提供單位元組及多位元組字元內碼集.