vim 应该怎么做学习

im包含了一个广泛的帮助系统,可以用:h _subject_命令来访问。
_subject_主题可以是命令,配置选项,热键绑定,插件等。使用:h命令(不带任何subject)
来获取帮助系统的相关信息以及在不同的主题之间切换。

set foldmethod = indent 
set  foldlevel = 99
您将能够进入方法并键入“za”以打开和关闭折叠。

垂直分割: Ctrl + w + v 
水平分割: Ctrl + w + s 
关闭当前窗口: Ctrl + w + q

我还想绑定Ctrl + <moving>键来移动窗口,而不是使用Ctrl + w + <movement>:

map  <cj>  <cw> j 
map  <ck>  <cw> k 
map  <cl>  <cw> l 
map  <ch>  <cw> h


命令行模式
行首 0
行尾 $ 
文件头部 gg
文件尾部 G 
移动到某行 300G 
删除光标后表边 字符 x
删除光标前面 X 
删除单词 dw 光标移动到行首
删除光标 前 d n 
删除光标 后 d$
大d 后面内
删除  n行 ndd  也可 几行到1,ndd 
u 撤销
ctrl + r 撤销 
复制 yy
--多行 nyyF
粘贴 p  光所在的下一行
粘贴 P 光标所在的行
剪切 == 删除 放在缓冲区
单个字符的替换  r 命令行替换
 
可视模式 
选择 hkjl
复值某行里面某个部分 切换到可视模式 v  移动到某行
可视模式 一个 y 复制 一个d 删除     复制 粘贴不会换行 p 粘贴后面 P 前面

查找:
/ 内容  回车 黄色高亮  按n 会依次 往下查找 N 向上

区别  光标 / 向下 ?向上
#  --  需要把光标一移动到 单词身上
 
缩进 向右>>  向左 << 
命令行模式下 查man 文档  shift + k 默认在 第一章   跳到正确的章节 3  shift + k 

 
命令模式切换到 文件模型 的8 种情况
文本模式下 操作
进入编辑模式 
a 光标后插入内容
A 尾部插入内容

i 插入光标前面
I 当前行首
o 在光标所在行的下边创建新行
O 创建上面的新行
s 删除光标后单个字符
S  删除光标整行
I   分屏打开
:NERDTree  打开插件
m 移动文件   
Ctrl-f    即 PageDown 翻頁。
Crtl-b    即 PageUp 翻頁。

w  移至次一個字(word)字首。當然是指英文單字。
W  同上,但會忽略一些標點符號。
e  移至前一個字字尾。
E  同上,但會忽略一些標點符號。
b  移至前一個字字首。
B  同上,但會忽略一些標點符號。
H  移至螢幕頂第一個非空白字元。
M  移至螢幕中間第一個非空白字元。
L  移至螢幕底第一個非空白字元。
這和 PageDown,PageUp 不一樣,內文內容並未動,只是游標在動而已。
 n| 移至第 n 個字元(欄)處。注意,要用 Shift 鍵。n 是從頭起
   算的。
:n 移至第 n 行行首。或 nG。
dd 刪除一整行(delete line)。
dw 刪除一個字(delete word)。不能適用於中文。
dG 刪至檔尾。
d1G 刪至檔首。或 dgg(只能用於 vim)。
D  刪至行尾,或 d$(含游標所在處字元)。
d0 刪至行首,或 d^(不含游標所在處字元)。

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 鍵。
5dd  刪除游標所在處(含)起算以下五行內容。妙吧!
3r   按了 3r 後,您鍵入一個英文字,則三個字元皆會被您所鍵
       入的英文取代。很抱歉,這不能用於中文。
5J   將五行合併成一行。
3x   刪除三個字元。抱歉,不能用於中文。
5i A 然後按 Ecs,插入五個 A。中文也可以!
2i system Esc  插入 systemsystem。中文也可以!
5G 游標移至第五行,是從檔首開始起算。
5l 移至右第五個字元處,當然 j 是可以用方向鍵取代的。
   所有移動指令(參考第二單元)都可以加上數目字來控制,中
   文也通喔!elvis 當然是不能用於中文


yy  複製游標所在行整行。或大寫一個 Y。
2yy 或 y2y  複製兩行。ㄟ,請舉一反三好不好!:-)
y^  複製至行首,或 y0。不含游標所在處字元。
y$  複製至行尾。含游標所在處字元。
yw  複製一個 word。
y2w 複製兩個字。
yG  複製至檔尾。
y1G 複製至檔首。
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 中有十行內容了!
忘記誰是誰的時候怎麼辦? :reg(冒號命令)就會列出所有 registers 的代號及內容。

果要重複這個動作的話,就可以按 . ,
也可以把游標移到其它地方後再按。其它 dd,dw,r,cw 
等編輯指令都可以這樣來重複。如果您要重複做某些編輯動作時,
千萬千萬一定要想到有這麼一個英文句點重複指令。
ㄚ,拜託啦!您一定要常用這個指令

    
前單元    次單元    目 錄
大家來學VIM(一個歷久彌新的編輯器)[五]
尋找、替換
 

搜尋、替換的功能幾乎是每個編輯器必備的功能,那在 vi(m) 中有沒有特殊的地方呢?當然有,您忘了,vi(m) 是個性十足的編輯器。最特殊的地方是和規則表示式(regular expression,簡稱 regexp)結合在一起。簡單的說她是一種 pattern 的表示法,在執行動作,如尋找或替換,就會依據這個 pattern 去找,所有符合 pattern 的地方就會執行您所下的動作。在這個單元裡暫不討論 regexp,會另立一個單元來探討,以免搞得頭昏腦脹。目前就暫不使用 regexp,您要找什麼就直接鍵入什麼就對了。

 

尋找
/  在 c-mode 的情形下,按 / 就會在左下角出現一個 /,然後鍵
   入您要尋找的字串,按個 Enter 就會開始找。
?  和 / 相同,只是 / 是向前(下)找,? 則是向後(上)找。
n  繼續尋找。
N  繼續尋找(反向)。

*  尋找游標所在處之 word(要完全符合)。
#  同上,但 * 是向前(下)找,# 則是向後(上)找。
g* 同 * ,但部份符合即可。
g# 同 # ,但部份符合即可。
n, N 之繼續尋找鍵仍適

 
替换 
:[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 不分大小寫。


書籤功能
這又是 vi(m) 的一個秘密武器,簡單的說,您可以在文章中的某處做個記號(marks),然後跑到其它地方去編輯,在呼叫這個 mark 時又會回到原處。妙吧!

mx  x 代表 26 個小寫英文字母,這樣游標所在處就會被 mark。
`x  回到書籤原設定位置。
` 是 backward quote,就是 Tab 鍵上面那一個。
'x  回到書籤設定行行首。
' 是 forward quote,是 Enter 鍵隔壁那一個。

书签功能
小寫字母  只作用於單一檔案內。
大寫字母  可作用於編輯中之各檔案間。
數目字    可作用於前次編輯的十個檔案。
數目字的用法比較特殊,'0 是回到前一次編輯檔案中離開前的最後位置,'1 則是回到前二次編輯檔案的最後位置,依此類推。您不必使用 m 來標示,vim 會自動記憶。很玄吧!其實這是 viminfo 的功能,您要認真追究的話,請 :h viminfo-file-marks。viminfo 關掉,就沒這個功能了!
所謂前次指的是前次啟動的 vim。
:marks  得知目前所有書籤的列表。


)  移至下一個句子(sentence)首。
(  移至上一個句子(sentence)首。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 -r 檔名,或進入 vim 後,下 :recover 檔名,來回復。

}  移至下一個段落(paragraph)首。
{  移至上一個段落(paragraph)首。
sentence 是以 . ! ? 為區格。
paragraph 是以空白行為區格。
 %  這是匹配 {},[],() 用的,例如您的游標現在在 { 上
   只要按 %,就會跑到相匹配的 } 上。寫程式時滿好用的。

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-<  標示區內容向左移一個 Tab。

Ctrl-w n  即 :new。開一空的新視窗。
這在 vim 會開在原視窗上半方,也就是視窗一分為二。在 elvis GUI 界面的話,則是實實在在的另開一個新視窗(可不是另啟動一個 elvis 喔!),當然 elvis 的 console 上也是和 vim 一樣,視窗一分為二。而且在 elvis 下,要放開 Ctrl-w 後才按 n,否則 elvis 會不鳥您的。
凡視窗操作的按鍵都是由 Ctrl-w 來起頭的,w 就是 window。
Ctrl-w s  即 :sp(lit),會開一新視窗,且原檔分屬兩個視窗。
Ctrl-w f  開一新視窗,並編輯游標所在處之 word 為檔名的檔案。
Ctrl-w q  即 :q 結束分割出來的視窗。
Ctrl-w o  即 :only! 使游標所在之視窗,成為目前唯一顯示的視窗
          其它視窗會隱藏起來。
Ctrl-w j  移至下視窗。
Ctrl-w k  移至上視

外部指令  執行外部指令。當然您的指令要在 PATH 內。
:!!  執行前一次執行之外部指令。
在這裡的 ! 可不是強迫中止喔!
vim 中有一個很特殊的指令 @:,是重複前一次的冒號命令。
:sh(ell)  執行 shell。使用 exit 回來。
這在 vim GUI 會在原視窗內顯示執行結果,在 elvis GUI 則會另開一 xterm 視窗。console 或 xterm 下的 vim 當然就是跳出 vim 進入 shell 中。
至於是用哪一種 shell 是可以另外設定的,可由 set shell= 來設定。在 windows 的版本中設定時如遇有空白字元檔名時要由 \ 來 escape,例如:
:set shell=\"c:\program\ files\unix\sh.exe\"\ -f
建議抓個 bash 來用啦,配合一些 Win32 中的 UNIX 指令會更適配。
在此補充一下補全的功能。不是只有 Tab 鍵的補全功能喔!也可以使用上下方向鍵,叫出歷史指令,叫出歷史指令可用於冒號命令及尋找命令(/)。例如,您前已下了 :!ps aux 這個指令,您可以按 : 後就直接按向上方向鍵。別忘了!尋找指令也是可以這樣用喔!
:r !commond
   這個就妙了!會在游標所在處次一行插入外部指令 commond 執行
   後的輸出內容。例如 :r !date 就會插入日期時間。這在 elvis
   是會插入在游標所在處那一行。
:n,mw !commond
   以 n 至 m 行內之資料,當做外部指令 commond 的 input。這算
   是相當高級的用法了,初學者大概還用不上,不過印象中留有一
   個這樣的功能,以後總是會用得上的。
K  大寫 K 會顯示游標所在處之 word 的 manpage。elvis 不適用。     
   windows 版本亦不適用。
 

求助系統
原始 vi 是沒有 on-line help 的,但 vim 及 elvis 則有相當豐富的說明系統。vim 沿用傳統 tag 的方式來找主題,而 elvis 就高明了,是使用 HTML 的格式。原來 elvis 是可以直接閱讀 HTML 檔的,當然不能顯示圖檔,但會標明圖檔的名稱。

F1  用過 pe2(3) 嗎?好像 F1 是救助鍵已讓大家公認。vim 預設
    按 F1 就會叫出說明檔。elvis 當然沒有,不過您可以自行設
    定,在 ~/.elvislib/elvis.rc 中加上
      map #1 :help^M
    就可以了。須注意的是 ^M 是按 Ctrl-v 後不放再按 M 或
    Enter 鍵,表示馬上執行。ㄟ,^M 是特殊字元,是一個字元
    ,而不是兩個字元,您移動游標在 ^M 上就知道了,不是我文
    中的,文中的是直接打出來的兩字元 ^M。

在 console 下要打特殊字元的話,要 Ctrl-Shift-V 然後按您要的鍵。

:h name  這樣就會叫出 name 這個說明檔,如果後面沒接 name,
    則會叫出 help.txt 這個總說明檔(在 evlis 是 elvis,html)
    h 是 help 的縮寫。ㄟ,name 記不清楚時,別忘了 Tab 補全。
    在 vim 的說明檔中,遇有兩個 | 圍住的主題,把游標移到上面
    就可以使用 Ctrl-] 來叫出這個主題的說明,Ctrl-T 可以回到
    原說明,elvis 中也是可以這樣用。mouse 按兩下也是可以叫出
    說明。:q 可結束說明檔,回到原編輯檔案。
:ver  會顯示版本、編譯資訊,編譯時加入之參數也會顯示出來,
    讓您知道有加入些什麼功能,因為有些功能在編譯時就得加入。
    其中正號 + 表示有此功能,減號 - 表示無此功能。elvis 只能
    顯示版本資訊,無法顯示編譯資訊。
在下都會編譯出一個全功能的 vim 來備用,而且 GUI 及 console 下使用的各編一個,以加快 console 下的啟動速度。
在此補充說明一點,各位有沒有覺得 :q 很常用到,好了!就依 pe2 的習慣設為 F4 吧!怎麼設?找上面叫出說明檔怎麼設,您就依樣畫葫蘆就可以了!vim 的設定檔在 ~/.vimrc。個人是直接設成 :q! 以免麻煩,但要記得存檔喔!
前單元    次單元    目 錄
 
  指前所綁住的字元或字元集合,出現 0 次或 0 次以上。
\+ 和 * 作用相同,但不包括出現 0 次。
\= 指前所綁住的字元恰好出現 0 或 1 次。
\| 這是多選,就是 or 的意思,被 \| 隔開的 pattern,任一個符
   合的話就算符合。
\+, \=, \| 會加上一個 \,是因原字元在 vi(m) 就具有特殊意義,在一般的 regexp 中是 +,?,| 就可以了,只是提醒您一下,以免搞混了!
記住 * \+ 是不可數的!用辭不是是精確,只是幫助您記憶啦!
在 elvis 及 ed 中是使用 \? 來匹配出現 0 或 1 次,而不是 \=,這裡要非常小心!


\s  表空白字元,即 <Space> 或 <Tab>。
不含換行字元,這是編輯器的特性使然。在 perl 的 \s 是包含換行字元的。而且 vim 及 elvis 皆不支援 \n 這種換行中介字元。
\S  表非空白字元。
\d  表數目字(digits),即 [0-9]。
\D  表非數目字,即 [^0-9]。
\w  表一般字元(word character),包括底線。即 [0-9a-zA-Z_]。
\W  表非一般字元,即 [^0-9a-zA-Z_]。
\a  表英文字母(alphabetic character),即 [a-zA-Z]。
\A  表非英文字母,即 [^a-zA-Z]。
\l  表小寫字母(lowercase character),即 [a-z]。
\L  表非小寫字母,即 [^a-z]。
\u  表大寫字母(uppercase),即 [A-Z]。
\U  表非大寫字母,即 [^A-Z]。
原始 vi 不支援此種中介字元。
使用中介字元的比對速度將會比使用字元集合 [] 的快。


[range]g/pattern/[cmd]
cmd 是 ed 可用的指令,預設是 p(print),您可查一下 man ed,就可以知道有什麼指令可用。這個小節裡主要是說明 d(delete) 的功能。因為是要說明如何消除空白行。需注意的是,d 是行刪除指令,凡含 pattern 的整行都會被刪掉,而且 range 不指定的話,預設是全篇文章,因為 g 就是代表 globe。
在 vim 的 help 檔裡說的是 ex 指令,但 ex 實際上是和 vim 連結的,因此這裡特別指出 ed。但 ed 的指令少數可能會和 vim 的 ex 不同,這是因為 ed 和 vim 並非同步在發展,作者也非同一人。
:g/^$/d
這樣就會刪除全文的空白行。前面已提過 ^$ 代表的是空白行。但這裡有個問題,如果空白行裡包含了其它空白字元(即 Space 或 Tab)的話。表面看起來是和一般空白行一模一樣,但卻暗藏玄機,用上面的方法就無法刪除這種空白行了!怎麼辦?來!看招!
:g/^[<Space><Tab>]*$/d
在 vim 或 elvis 裡您可以如此照打,也就是 <Space> 代表空白字元,<Tab> 代表按 Tab 鍵的結果。在原始 vi 則不行,得自行按出特殊字元出來,就是 Ctrl-v Space 及 Ctrl-v Tab。或採更簡單的打法:
:g/^\s*$/d
還記得中介中元嗎?好用吧!少打了不少字。:-) 意思就是刪除含 0 或 1 個以上空白字元的行。
有些書中寫成 :%s/^$//g 可以刪除空白行,這是錯誤的,因為 :s 這 個指令只更動一行裡的內容物,但不會做刪除一行的動作。


命令模式切换到 名莫行模式
查找 s/tom
替换
字符串的替换  移动到某行
s/源内容/替换的内容  只替换一个
s/  /   g 替换整行 
%s / /  替换 整个文件的第一个 全部加g 
27,30  s 替换几行到几行

末行行 !pwd 可以执行命苦   回到命令模式

x = wq

v 进入v  选择 hjkl  大写的I   inert  

"/*---------------------------------------*\
"           大小写转换  命令模式下
"/*---------------------------------------*\
"   g~~ : 行翻转
"   vEU : 字大写(广义字)
"   vE~ : 字翻转(广义字)
"   ~   将光标下的字母改变大小写
"   3~  将下3个字母改变其大小写
"   g~w 字翻转
"   U   将可视模式下的字母全改成大写字母
"   gUU 将当前行的字母改成大写
"   u   将可视模式下的字母全改成小写
"   guu 将当前行的字母全改成小写
"   gUw 将光标下的单词改成大写。
"   guw 将光标下的单词改成小写

"/*========================================*\
"               常用指令收集
"\*========================================*/
"   系统时间
"   :map <F7> a<C-R>=strftime("%c")<CR><esc>
"   :s/__date__/\=strftime("%c")/

"/*---------------------------------------*\
"               基础命令
"/*---------------------------------------*\
"   ctrl+q              可以联合复制,粘贴,替换用 行操作
"   ctrl+w+j ctrl+w+k (:bn :bp :bd)

"   '.                  它移动光标到上一次的修改行
"   `.                  它移动光标到上一次的修改点
"   .                   重复上次命令
"   <C-O> :             依次沿着你的跳转记录向回跳 (从最近的一次开始)
"   <C-I> :             依次沿着你的跳转记录向前跳
"   ju(mps) :           列出你跳转的足迹
"   :history :          列出历史命令记录
"   :his c :            命令行命令历史
"   :his s :            搜索命令历史
"   q/ :                搜索命令历史的窗口
"   q: :                命令行命令历史的窗口
"   g ctrl+g            计算文件字符
"   {,}                 前进至上一段落前进至后一段落
"   gg,G(2G)            文件首
"   gd dw gf ga(进制转化)
"   gg=G 全篇自动缩进 , =G 单行缩进

"* ci[ 删除一对 [] 中的所有字符并进入插入模式
"* ci( 删除一对 () 中的所有字符并进入插入模式
"* ci< 删除一对 <> 中的所有字符并进入插入模式
"* ci{ 删除一对 {} 中的所有字符并进入插入模式
"* cit 删除一对 HTML/XML 的标签内部的所有字符并进入插入模式
"* ci” ci’ ci` 删除一对引号字符 (” 或 ‘ 或 `) 中所有字符并进入插入模式
"
"* vi[ 选择一对 [] 中的所有字符
"* vi( 选择一对 () 中的所有字符
"* vi< 选择一对 <> 中的所有字符
"* vi{ 选择一对 {} 中的所有字符
"* vit 选择一对 HTML/XML 的标签内部的所有字符
"* vi” vi’ vi` 选择一对引号字符 (” 或 ‘ 或 `) 中所有字符

"   crl+] 函数原型处 crl+t 回 ( ctags )
"   ctl+p 自动补全( 编辑状态 )
"   :X 加密保存( 要输入密码 )
"   ? /         (N n)
"   f(F,t) 查找字符
"   w(e) 移动光标到下一个单词.
"   5fx 表示查找光标后第 5 个 x 字符.
"   5w(e) 移动光标到下五个单词.

"   b 移动光标到上一个单词.
"   0 移动光标到本行最开头.
"   ^ 移动光标到本行最开头的字符处.
"   $ 移动光标到本行结尾处.
"   H 移动光标到屏幕的首行.
"   M 移动光标到屏幕的中间一行.
"   L 移动光标到屏幕的尾行.

"   c-f (即 ctrl 键与 f 键一同按下)
"   c-b (即 ctrl 键与 b 键一同按下) 翻页
"   c-d (下半页) c-u(上半页) c-e (一行滚动)
"   zz 让光标所在的行居屏幕中央
"   zt 让光标所在的行居屏幕最上一行
"   zb 让光标所在的行居屏幕最下一行


"   在 vi 中 y 表示拷贝, d 表示删除, p 表示粘贴. 其中拷贝与删除是与光标移动命令
"   yw 表示拷贝从当前光标到光标所在单词结尾的内容.
"   dw 表示删除从当前光标到光标所在单词结尾的内容.
"   y0 表示拷贝从当前光标到光标所在行首的内容.
"   d0 表示删除从当前光标到光标所在行首的内容.
"   y$(Y) 表示拷贝从当前光标到光标所在行尾的内容.
"   d$(D) 表示删除从当前光标到光标所在行尾的内容.
"   yfa 表示拷贝从当前光标到光标后面的第一个a字符之间的内容.
"   dfa 表示删除从当前光标到光标后面的第一个a字符之间的内容.
"   s(S),a(A),x(X),D
"   yy 表示拷贝光标所在行.
"   dd 表示删除光标所在行.

"   5yy 表示拷贝光标以下 5 行.
"   5dd 表示删除光标以下 5 行.
"   y2fa 表示拷贝从当前光标到光标后面的第二个a字符之间的内容.
"   :12,24y 表示拷贝第12行到第24行之间的内容.
"   :12,y 表示拷贝第12行到光标所在行之间的内容.
"   :,24y 表示拷贝光标所在行到第24行之间的内容. 删除类似.
"   TAB 就是制表符, 单独拿出来做一节是因为这个东西确实很有用.
"   << 输入此命令则光标所在行向左移动一个 tab.
"   >> 输入此命令则光标所在行向右移动一个 tab.
"   5>> 输入此命令则光标后 5 行向右移动一个 tab.
"   :5>>(>>>) :>>(>>>)5
"   :12,24> 此命令将12行到14行的数据都向右移动一个 tab.
"   :12,24>> 此命令将12行到14行的数据都向右移动两个 tab.
"   :set shiftwidth=4 设置自动缩进 4 个空格, 当然要设自动缩进先.
"   :set sts=4 即设置 softtabstop 为 4. 输入 tab 后就跳了 4 格.
"   :set tabstop=4 实际的 tab 即为 4 个空格, 而不是缺省的 8 个.
"   :set expandtab 在输入 tab 后, vim 用恰当的空格来填充这个 tab.
"   :g/^/exec 's/^/'.strpart(line('.').' ', 0, 4) 在行首插入行号
"   set ai 设置自动缩进
"   5ia<esc> 重复插入5个a字符

"/*---------------------------------------*\
"               替换命令
"/*---------------------------------------*\
"   替换文字 2009-02-34 ----> 2009-02-34 00:00:00
"   :%s/\(\d\{4\}-\d\{2\}-\d\{2\}\)/\1 00:00:00/g

"  :%s/^/heaser/     在每一行头部添加header
"  :%s/$/ender/     在每一行尾部添加ender

"   :s/aa/bb/g              将光标所在行出现的所有包含 aa 的字符串中的 aa 替换为 bb
"   :s/\/bb/g               将光标所在行出现的所有 aa 替换为 bb, 仅替换 aa 这个单词
"   :%s/aa/bb/g             将文档中出现的所有包含 aa 的字符串中的 aa 替换为 bb
"   :12,23s/aa/bb/g         将从12行到23行中出现的所有包含 aa 的字符串中的 aa 替换为 bb
"   :12,23s/^/#/            将从12行到23行的行首加入 # 字符
"   :%s/fred/joe/igc            一个常见的替换命令,修饰符igc和perl中一样意思
"   s/dick/joe/igc则        对于这些满足条件的行进行替换

"   :g/^\s*$/d              空行(空格也不包含)删除.
"   :%s/\r//g               删除DOS方式的回车^M
"   :%s/ *$//               删除行尾空白(%s/\s*$//g)
"   :g!/^dd/d               删除不含字符串'dd'开头的行
"   :v/^dd/d                同上,译释:v == g!,就是不匹配!
"   :v/./.,/./-1join        压缩空行(多行空行合并为一行)
"   :g/^$/,/./-j            压缩空行(多行空行合并为一行)
"   :g/^/pu _               把文中空行扩增一倍 (pu = put),原来两行间有一个空行,现在变成2个
"   :g/^/m0                 按行翻转文章 (m = move)
"   :g/fred/,/joe/d         not line based (very powerfull)
"   :g/<input\|<form/p      或者 要用\|
"   :g/fred/t$              拷贝行,从fred到文件末尾(EOF)

"   :%norm jdd              隔行删除,译释:%指明是对所有行进行操作,norm指出后面是normal模式的指令,j是下移一行,dd是删除行

"   :'a,'bg/fred/s/dick/joe/igc   ('a,'b指定一个范围:mark a ~ mark b)
"   g//用一个正则表达式指出了进行操作的行必须可以被fred匹配,g//是一个全局显示命令

"   /joe/e                  光标停留在匹配单词最后一个字母处
"   /joe/e+1                光标停留在匹配单词最后一个字母的下一个字母处
"   /joe/s                  光标停留在匹配单词第一个字母处
"   /^joe.*fred.*bill/      标准正则表达式
"   /^[A-J]\+/              找一个以A~J中一个字母重复两次或以上开头的行
"   /forum\(\_.\)*pent      多行匹配
"   /fred\_s*joe/i          中间可以有任何空白,包括换行符\n
"   /fred\|joe              匹配FRED或JOE
"   /\<fred\>/i             匹配fred,fred必须是一个独立的单词,而不是子串
"   /\<\d\d\d\d\>           匹配4个数字 \<\d\{4}\>

"   列,替换所有在第三列中的str1
"   :%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
"   交换第一列和最后一列 (共4列)
"   :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:

"   全局(global)显示命令,就是用 :g+正则表达式
"   译释: :g/{pattern}/{cmd} 就是全局找到匹配的,然后对这些行执行命令{cmd}
"   :g/\<fred\>/                                显示所有能够为单词fred所匹配的行
"   :g/<pattern>/z#.5                           显示内容,还有行号
"   :g/<pattern>/z#.5|echo '=========='         漂亮的显示

"/*---------------------------------------*\
"           多文档操作 (基础)
"/*---------------------------------------*\
"    用 :ls! 可以显示出当前所有的buffer
"   :bn                 跳转到下一个buffer
"   :bp                 跳转到上一个buffer
"   :wn                 存盘当前文件并跳转到下一个
"   :wp                 存盘当前文件并跳转到上一个
"   :bd                 把这个文件从buffer列表中做掉
"   :b 3                跳到第3个buffer
"   :b main             跳到一个名字中包含main的buffer

"/*---------------------------------------*\
"           列复制
"/*---------------------------------------*\
"   译注:@#%&^#*^%#$!
"   :%s= [^ ]\+$=&&= : 复制最后一列
"   :%s= \f\+$=&&= : 一样的功能
"   :%s= \S\+$=&& : ft,还是一样
"   反向引用,或称记忆
"   :s/\(.*\):\(.*\)/\2 : \1/ : 颠倒用:分割的两个字段
"   :%s/^\(.*\)\n\1/\1$/ : 删除重复行
"   非贪婪匹配,\{-}
"   :%s/^.\{-}pdf/new.pdf/ : 只是删除第一个pdf
"   跨越可能的多行
"   :%s/<!--\_.\{-}-->// : 又是删除多行注释(咦?为什么要说「又」呢?)
"   :help /\{-} : 看看关于 非贪婪数量符 的帮助
"   :s/fred/<c-r>a/g : 替换fred成register a中的内容,呵呵
"   写在一行里的复杂命令
"   :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
"   译注:就是用 | 管道啦

"/*---------------------------------------*\
"           大小写转换
"/*---------------------------------------*\
"   g~~ : 行翻转
"   vEU : 字大写(广义字)
"   vE~ : 字翻转(广义字)
"   ~   将光标下的字母改变大小写
"   3~  将下3个字母改变其大小写
"   g~w 字翻转
"   U   将可视模式下的字母全改成大写字母
"   gUU 将当前行的字母改成大写
"   u   将可视模式下的字母全改成小写
"   guu 将当前行的字母全改成小写
"   gUw 将光标下的单词改成大写。
"   guw 将光标下的单词改成小写。


"   文件浏览
"   :Ex : 开启目录浏览器,注意首字母E是大写的
"   :Sex : 在一个分割的窗口中开启目录浏览器
"   :ls : 显示当前buffer的情况
"   :cd .. : 进入父目录
"   :pwd
"   :args : 显示目前打开的文件
"   :lcd %:p:h : 更改到当前文件所在的目录
"    译释:lcd是紧紧改变当前窗口的工作路径,% 是代表当前文件的文件

命令模式下ZZ 退出

切屏 
sp 水平 分屏 切换 ctrl ww 
sp + 当前文件的名字
vsp  遵旨直分屏 

vim  打造ide   修改 系统配置文件 /etc/vim/vimrc  
                    用户的配置文件  /.vim/vimrc   ~/.vimrc

映射 不同模式下 
:nmap \ dd
在normal模式下,按下\。Vim会删除当前行。

:vmap \ U
进入visual模式并选中一些文字,按下\。Vim将把选中文本转换成大写格式
inert 模式
:imap <c-d> dd
按键Ctrl+d删除整行。这个映射很实用,
因为你不必每次都要为了删除某些行而切回到normal模式。
需要:imp <c-d> <esc>dd  强指定  退出删除一行 但是没告诉我们回到insert
:imap <c-d> <esc>ddi 结尾的i告诉Vim进入insert模式,至此我们的映射才最终完成。
:imap <c-u> <esc>gUUi 将当前光标所在的单词转换成 大写格式 返回在inset中
在~/.vimrc  直接设置 imap <c-u> <esc>gUUi
nunmap - 删除映射 其他类似

*map系列命令的一个缺点就是存在递归的危险。另外一个是如果你安装一个插件,
插件 映射了同一个按键为不同的行为,两者冲突,有一个映射就无效了。
每一个*map系列的命令都有个对应的*noremap命令,包括:noremap/nnoremap、
 vnoremap和inoremap。这些命令将不递归解释映射的内容。任何时候都可以
 你几乎永远不会用到-、 H、L、<space>、<cr> 和<bs>这些按键的功能(当然,是在normal模式下)。依据你的工作方式,可能还有其他你 不会用到的按键。

这些按键都可以随意映射,但是只有这6个按键貌似不够吧
、。难道为Vim称道的可定制传说 有问题?

可组合-d   
:nnoremap -d dd
:nnoremap -c ddi 删除并进入insert

let mapleader = "-" 
设置前缀当你创建新的映射时,你可以使用<leader>表示“我设置的leader按键”
。运行命令:
:nnoremap <leader>d dd
然而为何每次都要繁琐的设置<leader>?为什么创建映射时不直接敲入你的“前缀”按键? 原因主要有三个。

首先,你某天可能会想要更换你的“leader”。在一个地方定义它使得更方便更换它。

第二,其他人看你的~/.vimrc文件时,一旦看到<leader>就能够立即知道你的用意。如果他们 喜欢你的~/.vimrc配置,即使他们使用不同的leader也可以简单的复制你的映射配置。

最后,许多Vim插件都会创建以<leader>开头的映射。如果你已经设置了leader,你会更容易上手 使用那些插
Local Leader
Vim有另外一个“leader”成为“local leader“。这个leader用于那些只对某类文件 (如Python文件、HTML文件)而设置的映射。
帮助文档 help mapleader   同上
我们在一个分屏中打开~/.vimrc文件以快速编辑添加映射,然后退出继续编码。运行命令:

:nnoremap <leader>ev :vsplit $MYVIMRC<cr>
:vsplit打开一个新的纵向分屏。如果你喜好横向的分屏,你可以用:split替换它。

花一分钟彻底理解理解那个映射命令。命令的目的是:在一个新的分屏中打开我的~/.vimrc。 它是如何工作的?映射中的每一个字符都是必不可少的?

通过哪个映射,你只要三个键就可以打开你的~/.vimrc文件。只要你多用几次,你就能 半秒内敲出这个命令。

当你编码过程中突然想到一个可以提高效率的新映射要加到~/.vimrc文件中, 现在对你来说简直就是小菜一碟。
:nnoremap <leader>sv :source $MYVIMRC<cr>
我称这个命令为“ 重读 我的 vimrc 文件”。

source命令告诉Vim读取指定的文件,并将其当做Vimscript执行。

现在在编码时你可以方便的添加新映射了。

<leader>ev打开配置文件。
添加映射。
使用:wq<cr>或ZZ保存文件并关闭分屏,回到之前的文件。
使用<leader>sv重读配置使修改生效。
定义一个映射需要8次按键。减少了中断思维的可能性
help myvimrc


Vim有个称为"abbreviations"的特性,与映射有点类似
,但是它用于insert、replace和 command模式
:iabbrev adn and    在insert中  把 adn转换成and 
可重复使用
Keyword Characters
紧跟一个abbreviation输入"non-keyword character"后Vim会替换那个abbreviation。 "non-keyword character"指那些不在iskeyword选项中的字符。运行命令:

:set iskeyword?
你将看到类似于iskeyword=@,48-57,_,192-255的结果。这个格式很复杂,但本质上 "keyword characters"包含一下几种:

下划线字符 (_).
所有字母字符,包括大小写。
ASCII值在48到57之间的字符(数字0-9)。
ASCII值在192到255之间的字符(一些特殊ASCII字符)。
如果你想阅读这个选项格式的 完整 描述,你可以运行命令:help isfname,另外 阅读之前最好准备点吃的。

你只要记住输入非字母、数字、下划线的字符就会引发abbreviations替换。
:help isfname
当输入@@ 会自动替换 成后面那个 

错,abbreviations和mappings很像,但是他们的定位不同。看个例子:

运行命令:

:inoremap ssig -- <cr>Steve Losh<cr>steve@stevelosh.com
这个 mapping 用于快速插入你的签名。进入insert模式并输入ssig试试看。

看起来一切正常,但是还有个问题。进入insert模式并输入如下文字:

Larry Lessig wrote the book "Remix".
注意到Vim将Larry名字中的ssig也替换了!mappings不管被映射字符串的前后字符是什么-- 它只在文本中查找指定的字符串并替换他们。

运行下面的命令删除上面的mappings并用一个abbreviation替换它:

:iunmap ssig
:iabbrev ssig -- <cr>Steve Losh<cr>steve@stevelosh.com
再次试试这个abbreviation。

这次Vim会注意ssig的前后字符,只会在需要的时候替换它。

Exercises
在你的~/.vimrc文件中为经常拼写错误的单词增加abbreviations配置。一定要使用 上一章中你创建的mappings来重新打开读取~/.vimrc文件。

为你的邮箱地址、博客网址、签名添加abbreviations配置。

为你经常输入的文本添加abbreviations配置。

一个更为复杂的Mapping
你已经见过很多简单的mappings了,是时候看看一些复杂的了。运行下面的命令:

:nnoremap <leader>" viw<esc>a"<esc>hbi"<esc>lel
那是一个有趣的mappings!你自己可以先试试。进入normal模式,移动光标至一个单词, 输入<leader>"。Vim将那个单词用双引号包围!

它是如何工作的呢?我们拆分这个映射并逐个解释:

viw<esc>a"<esc>hbi"<esc>lel
viw: 高亮选中单词
<esc>: 退出visual模式,此时光标会在单词的最后一个字符上
a: 移动光标至当前位置之 后 并进入insert模式
": 插入一个"
<esc>: 返回到normal模式
h: 左移一个字符
b: 移动光标至单词头部
i: 移动光标至当前位置之 前 并进入insert模式
": 插入一个"
<esc>: 返回到normal模式
l: 右移一个字符,光标置于单词的头部
e: 移动光标至单词尾部
l: 右移一个字符,置光标位置在第一个添加的引号上
记住:因为我们使用的是nnoremap而不是nmap,所以尽管你映射了字符序列中的字符 也不会有影响。Vim会将其中的字符按默认功能执行。

希望你能看出Vim mappings的潜能及随之引发的阅读困难。

Exercises
像刚才一样创建一个mapping,用单引号而不是双引号。

试试用vnoremap添加一个mapping,使其能够用引号将你 高亮选中 的文本包裹。 你可能会需要<``和>命令,所以先执行:help `<``看看帮助文档。

将normal模式下的H映射为移动到当前行的首部。h是左移,所以你可以认为H是 “加强版”的h、

将normal模式下的L映射为移动到当前行的尾部。l是右移,所以你可以认为L是 “加强版”的l、

读取帮助文档:help H和:help L看看你覆盖了哪些命令。考虑考虑这会不会影响你。

将这些mappings添加到你的~/.vimrc文件中,确保用你的“编辑~/.vimrc”和“重读~/.vimrc” 映射操作~
 ok,现在你已经有了一个新的mapping,你会怎么学习使用它呢?特别是你已经用了这么久的escape按键,使用escape按键都已经刻入了你的脑子中,以至于在编辑的时候你会不假思索的敲击它。

重新学习一个mapping的窍门就是_强制_将之前的按键设置为不可用,_强迫_自己使用新的mapping。执行下面的命令:

:inoremap <esc> <nop>
这个命令会告诉Vim在插入模式下敲击escape按键后执行<nop>(no operation),这样escape按键在插入模式下就无效了。ok,现在你就_不得不_使用jk这个mapping来退出插入模式了。

一开始你可能不太适应,你还是会在插入模式下敲击escape按键,并且以为已经退出到了常用模式,然后开始敲击按键准备在常用模式下做一些事情,从而导致一些不需要的字符出现在你的文本中。这会让你感到有些不爽,但如果你坚持一段时间后,你会惊讶的发现你的思维和手指会多么快的适应 新的mapping。用不到一到两个小时你就不会再在插入模式下敲击escape了。

这个方法适用于所有的用于替代原有操作方式的新mapping,包括在生活中也是如此。当你想改掉一个坏习惯的时候,你最好能够想一些办法使得这个坏习惯很难甚至是不能发生。

如果你想学会自己做饭,不想每天都吃盖浇饭,那么每天下班的时候就不要去成都小吃了。这样你就会在饿了的时候想办法去做点东西吃,当前你先要确保你家里没有泡面。

如果你想戒烟,那你就不要把烟带在身上,把它放到车上。这样当你的烟瘾又犯了的时候,你会觉得走到车里去取烟是一件很蛋疼的事,这样你就不会吸了。

练习
如果还是会在Vim的常用模式中使用方向键移动光标,那么就将它们映射为<nop>。

如果你在编辑模式下也会使用方向键,同样的,映射为<nop>吧。

正确使用Vim的关键就是使得自己能够快速的离开插入模式,然后在常用模式下进行移动。

映射
选择文件foo,然后执行下面的命令:

:nnoremap          <leader>d dd
:nnoremap <buffer> <leader>x dd
现在保持在文件foo下面,确保当前处于常用模式下,然后敲击<leader>d。Vim会删除一行。这个之前讲到过,没什么新鲜的。

仍然保持在文件foo下面,敲击<leader>x。Vim也会删除一行。这很正常,因为我们也将<leader>x映射到dd了。

现在切换到文件bar。在常用模式下敲击<leader>d。同样的,Vim会删除当前行,也没有什么新鲜的。

ok,现在来点新鲜的:在文件bar下敲击<leader>x。

Vim只删除了一个字符,而不是删除整个行! 为什么会这样?

第二个nnoremap命令中的<buffer>告诉Vim这个映射只在定义它的那个缓冲区中有效:

当你在bar文件下敲击<leader>x,Vim找不到一个跟它匹配的映射,它将会被解析了两个命令:
<leader>(这个什么都不会干)和 x(通常会删除一个字符)。
本地Leader
在这个例子中,<leader>x是一个本地缓冲区映射,不过这种定义方式并不合适。如果我们需要设定一个只会用于特定缓冲区的映射,一般会使用<localleader>,而不是<leader>。

使用两种不同的leader按键就像设置了一种命名空间,这会帮助你保证所有不同的映射对你而言更加清晰直接。

但你在编写一个会被其他人用到的插件的时候,这点显得尤其重要。使用<localleader>来设置本地映射会防止你的插件覆盖别人用<leader>设置的全局映射,因为他们可能已经对他们做设置的全局映射非常之习惯了。

设置
在这本书的前面几个章节里,我们谈论了使用set来设置选项。有一些选项总是会适用于整个Vim,但是有些选项可以基于缓冲区进行设置。

切回到文件foo,执行下面的命令:

:setlocal wrap
然后切换到文件bar,执行下面的命令:

:setlocal nowrap
把你的Vim窗口调小一些,你会发现有些行在foo中会自动换行,而在bar中则不会。

让我们来测试下另外一个选项。切换到foo执行下面的命令:

:setlocal number
现在切换到bar,然后执行下面的命令:

:setlocal nonumber
现在在文件foo中会出现行号,而在bar则没有。

不是所有的选项都可以使用setlocal进行设置。如果你想知道某个特定的选项是否可以设置为本地选项,执行:help查看它的帮助文档。

对于本地选项如何_真正地_地工作,我说的有些简略。在练习中你会学到更多这方面的细节。

遮盖
ok,在开始下一节之前,我们先来看关于本地映射的一个非常有趣的特性。切换到文件foo,然后执行下面的命令:

:nnoremap <buffer> Q x
:nnoremap          Q dd
然后敲击Q,看看会发生什么?

当你敲击Q,Vim会执行第一个映射,而不是第二个,因为第一个映射比起第二个要显得更具体,这可以看成第二个映射被第一个映射遮盖了。

切换回文件bar,然后敲击Q,Vim会使用第二个映射。这是因为在这个缓冲区中第二个映射没有被第一个映射遮盖。

练习
阅读:help local-options。

阅读:help setlocal。

阅读:help map-local。

Vimscript 自动命令

edit 打开 一个文件编辑

现在我们谈论一个跟映射一样重要的东西:自动命令。

自动命令可以让Vim自动执行某些指定的命令,这些指定的命令会在某些事件发生的时候执行。我们先看一个例子。

使用:edit foo打开一个新文件,然后立即使用:quit关闭。查看你的硬盘,你会发现这个文件并不存在。这是因为在你第一次保存这个文件之前,Vim_实际上_并没有真正创建它。

让我们对Vim做一些改变,使得Vim可以在你开始编辑文件的时候就创建它们。执行下面的命令:

:autocmd BufNewFile * :write
这里面有很多需要进一步说明的,不过在此之前我建议你先感受下它是怎么工作的。执行:edit foo,使用:quit关闭,然后查看硬盘。这个时候文件会存在(当然文件内容为空)。

你只有关闭Vim才能删除这个自动命令。

自动命令结构
让我们来深入分析下我们刚才创建的自动命令:

:autocmd BufNewFile * :write
         ^          ^ ^
         |          | |
         |          | 要执行的命令
         |          |
         |          用于事件过滤的“模式(pattern)”
         |
         要监听的“事件”
这个命令的第一部分是我们想监听的事件的类型。Vim提供了_很多_可以监听的事件。这些事件包括:

开始编辑一个当前并不存在的文件。
读取一个文件,不管这个文件是否存在。
改变一个缓冲区的filetype设置。
在某段时间内不按下键盘上面的某个按键。
进入插入模式。
退出插入模式。
上面只举出了可用事件里面的很小一部分。还有很多其他的事件,你可以利用这些事件来做一些有趣的事情。

这个自动命令的下一部分是一个“模式”,这个模式可以进一步限定你要执行的命令的执行范围。新开一个Vim实例,执行下面的命令:

:autocmd BufNewFile *.txt :write
这个跟之前的那个自动命令基本一样,不过这个自动命令只对后缀为.txt的文件有效,也就是说当你新建的文件为txt文件的时候,Vim会在文件创建的时候自动执行write命令将文件保存到硬盘上。

试试执行:edit bar,然后执行:quit,再执行:edit bar.txt,然后再执行:quit。你会发现Vim会自动创建bar.txt,但不会创建bar,因为它的后缀名不是txt,不跟模式匹配。

这个自动命令的最后一部分是事件发生时我们想执行的命令。这个部分很容易理解,跟我们执行其他命令一样,除了不能在这个命令中使用特殊的字符,例如<cr>。
我们再定义一个自动命令,这次使用一个不同的事件。执行下面的命令:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值