注:本文出自博主 Chloneda:個人博客 | 博客園 | Github | Gitee | 知乎
本文源鏈接:https://www.cnblogs.com/chloneda/p/vim-cheatsheet.html
Vim 命令速查表
簡介
Vim 命令速查表,注釋化 vimrc 配置文件,經典 Vim 鍵盤圖,實用 Vim 書籍,Markdown 格式,目錄化檢索,快速熟悉使用!
- vim-cheatsheet | Vim官網 | Github | Vim中文文檔
- Vim 自定義配置文件 - vimrc
- Chrome 瀏覽器神級插件 - Vimium
- 簡體中文 | English
重復的威力
. # 小數點,重復上一次的命令
N<command> # 重復某個命令 N 次,例如:10k,光標上移 10 行
光標移動
注:一般模式下,任意一個動作都可以重復。
h # 光標左移,同 <Left> 鍵
j # 光標下移,同 <Down> 鍵
k # 光標上移,同 <Up> 鍵
l # 光標右移,同 <Right> 鍵
Ctrl+e # 向上滾動一行
Ctrl+y # 向下滾動一行
Ctrl+u # 向上滾動半屏 --> Move up 1/2 a screen
Ctrl+d # 向下滾動半屏 --> Move down 1/2 a screen
Ctrl+f # 向下滾動一屏 --> Move forward one full screen
Ctrl+b # 向上滾動一屏 --> Move back one full screen
0 # 跳到行首,數字 0,效用等同於 <Home> 鍵
^ # 跳到從行首開始第一個非空白字符
$ # 跳到行尾,效用等同於 <End> 鍵
gg # 跳到第一行,效用等同於 Ctrl+<Home>
G # 跳到最后一行,效用等同於 Ctrl+<End>
NG # 跳到第 N 行,比如 10G 是移動到第十行
:N # 跳到第 N 行,比如 :10<Enter> 是移動到第十行
10% # 移動到文件 10% 處
15| # 移動到當前行的 15 列
w # 跳到下一個單詞開頭(word:標點或空格分隔的單詞)
W # 跳到下一個單詞開頭(Word:空格分隔的單詞)
e # 跳到下一個單詞尾部(word:標點或空格分隔的單詞)
E # 跳到下一個單詞尾部(Word:空格分隔的單詞)
b # 跳到上一個單詞開頭(word:標點或空格分隔的單詞)
B # 跳到上一個單詞開頭(Word:空格分隔的單詞)
ge # 跳到前一個單詞結尾
) # 向前移動一個句子(句號分隔)
( # 向后移動一個句子(句號分隔)
} # 向前移動一個段落(空行分隔)
{ # 向后移動一個段落(空行分隔)
<Enter> # 移動到下一行首個非空字符
N<Enter> # 光標向下移動 N 行
+ # 移動到下一行首個非空字符(同回車鍵)
- # 移動到上一行首個非空字符
H # 移動到屏幕上部(H: High)
M # 移動到屏幕中部(M: Middle)
L # 移動到屏幕下部(L: Low)
<S+Left> # 按住 Shift 按左鍵,向左移動一個單詞
<S+Right> # 按住 Shift 按右鍵,向右移動一個單詞
<S+Up> # 按住 Shift 按上鍵,向上翻頁
<S+Down> # 按住 Shift 按下鍵,向下翻頁
gm # 移動到的行中間
gj # 光標向下移動一個屏幕行(忽略自動換行)
gk # 光標向上移動一個屏幕行(忽略自動換行)
zz # 調整光標所在行到屏幕中央
zt # 調整光標所在行到屏幕上部
zb # 調整光標所在行到屏幕下部
插入模式
i # 在光標處進入插入模式
I # 在行首進入插入模式
a # 在光標后進入插入模式
A # 在行尾進入插入模式
o # 在下一行插入新行並進入插入模式
O # 在上一行插入新行並進入插入模式
gi # 進入到上一次插入模式的位置
<Esc> # 退出插入模式
Ctrl+[ # 退出插入模式,等價於 Esc 鍵
插入模式的命令
注:由 i, I, a, A, o, O 等命令進入插入模式。
<Up> # 光標向上移動
<Down> # 光標向下移動
<Left> # 光標向左移動
<Right> # 光標向右移動
<S+Left> # 按住 Shift 按左鍵,向左移動一個單詞
<S+Right> # 按住 Shift 按右鍵,向右移動一個單詞
<S+Up> # 按住 Shift 按上鍵,向上翻頁
<S+Down> # 按住 Shift 按下鍵,向下翻頁
<PageUp> # 向上翻頁
<PageDown> # 向下翻頁
<Delete> # 刪除光標處字符
<Backspace> # Backspace 鍵是向后刪除字符
<Home> # 光標跳轉行首
<End> # 光標跳轉行尾
Ctrl+d # 減少縮進
Ctrl+f # 減少縮進
Ctrl+t # 增加縮進
Ctrl+h # 刪除前一個字符,相當於回格鍵 Backspace
Ctrl+o # 臨時退出插入模式,執行單條命令又返回插入模式
Ctrl+u # 當前行刪除到行首所有字符
Ctrl+w # 刪除光標前的一個單詞
Ctrl+\ Ctrl+O # 臨時退出插入模式(光標保持),執行單條命令又返回插入模式
Ctrl+R 0 # 插入寄存器(內部 0 號剪貼板)內容,Ctrl+R 后可跟寄存器名
Ctrl+R " # 插入匿名寄存器內容,相當於插入模式下 p 粘貼
Ctrl+R = # 插入表達式計算結果,等號后面跟表達式
Ctrl+R : # 插入上一次命令行命令
Ctrl+R / # 插入上一次搜索的關鍵字
Ctrl+v {char} # 插入非數字的字面量
Ctrl+v {code} # 插入用三位數字表示的 ASCII/Unicode 字符編碼,如 Ctrl+v 065
Ctrl+v 065 # 插入 10 進制 ASCII 字符(兩數字) 065 即 A 字符
Ctrl+v x41 # 插入 16 進制 ASCII 字符(三數字) x41 即 A 字符
Ctrl+v o101 # 插入 8 進制 ASCII 字符(三數字) o101 即 A 字符
Ctrl+v u1234 # 插入 16 進制 Unicode 字符(四數字)
Ctrl+v U12345678 # 插入 16 進制 Unicode 字符(八數字)
Ctrl+K {ch1} {ch2} # 插入 digraph(見 :h digraph),快速輸入日文或符號等
自動補全
在插入模式下,最常用的補全。
Ctrl+n # 插入模式下文字自動補全
Ctrl+P # 插入模式下文字自動補全
Ctrl+e # 有補全列表時,終止這次補全,繼續輸入
智能補全 命令均以組合鍵 Ctrl+X 作為起始操作。
Ctrl+X # 進入補全模式
Ctrl+X Ctrl+L # 整行補全
Ctrl+X Ctrl+N # 插入模式下,根據當前文件里關鍵字補全
Ctrl+X Ctrl+K # 根據字典補全
Ctrl+X Ctrl+T # 根據同義詞字典補全
Ctrl+X Ctrl+F # 插入模式下補全文件名
Ctrl+X Ctrl+I # 根據頭文件內關鍵字補全
Ctrl+X Ctrl+] # 根據標簽補全
Ctrl+X Ctrl+D # 補全宏定義
Ctrl+X Ctrl+V # 補全 Vim 命令
Ctrl+X Ctrl+U # 用戶自定義補全方式
Ctrl+X Ctrl+S # 拼寫建議,例如:一個英文單詞
Ctrl+X Ctrl+O # 插入下 Omnifunc 補全
文本編輯
r # 替換當前字符
R # 進入替換模式,直至 Esc 離開
s # 替換字符(刪除光標處字符,並進入插入模式,前可接數量)
S # 替換行(刪除當前行,並進入插入模式,前可接數量)
cc # 改寫當前行(刪除當前行並進入插入模式),同 S
cw # 改寫光標開始處的當前單詞
ciw # 改寫光標所處的單詞
caw # 改寫光標所處的單詞,並且包括前后空格(如果有的話)
c0 # 改寫到行首
c^ # 改寫到行首(第一個非零字符)
c$ # 改寫到行末
C # 改寫到行尾(同 c$)
ci" # 改寫雙引號中的內容
ci' # 改寫單引號中的內容
cib # 改寫小括號中的內容
cab # 改寫小括號中的內容(包含小括號本身)
ci) # 改寫小括號中的內容
ci] # 改寫中括號中內容
ciB # 改寫大括號中內容
caB # 改寫大括號中的內容(包含大括號本身)
ci} # 改寫大括號中內容
cit # 改寫 XML tag 中的內容
cis # 改寫當前句子
c2w # 改寫下兩個單詞
ct( # 改寫到小括號前
x # 刪除當前字符,前面可以接數字,3x 代表刪除三個字符
X # 向前刪除字符
dd # 刪除(剪切)當前行,並把刪除的行存到剪貼板里 --> Delete (cut) a line
d0 # 刪除(剪切)到行首
d^ # 刪除(剪切)到行首(第一個非零字符)
d$ # 刪除(剪切)到行末
D # 刪除(剪切)到行末(同 d$)
dw # 刪除(剪切)當前單詞
diw # 刪除(剪切)光標所處的單詞
daw # 刪除(剪切)光標所處的單詞,並包含前后空格(如果有的話)
di" # 刪除雙引號中的內容
di' # 刪除單引號中的內容
dib # 刪除小括號中的內容
di) # 刪除小括號中的內容
dab # 刪除小括號內的內容(包含小括號本身)
di] # 刪除中括號中內容
diB # 刪除大括號中內容
di} # 刪除大括號中內容
daB # 刪除大括號內的內容(包含大括號本身)
dit # 刪除 XML 中 tag 中的內容
dis # 刪除當前句子
d2w # 刪除下兩個單詞
dt( # 刪除到小括號前
dgg # 刪除到文件頭部
dG # 刪除到文件尾部
d} # 刪除下一個段落
d{ # 刪除上一個段落
10d # 刪除當前行開始的 10 行
:10d # 刪除第 10 行
:1,10d # 刪除 1-10 行
J # 將多行合並為一行
. # 重復上一次操作
~ # 替換大小寫
g~iw # 替換當前單詞的大小寫
gUiw # 將單詞轉成大寫
guiw # 將當前單詞轉成小寫
guu # 全行轉為小寫
gUU # 全行轉為大寫
<< # 減少縮進
>> # 增加縮進
== # 自動縮進
Ctrl+A # 增加數字
Ctrl+X # 減少數字
復制粘貼
copy 命令的格式為:
:[range]copy{address}
參數說明:
- [range]:表示要復制的行范圍,其中 copy 可縮寫為 :co 或 :t。
- {address}:表示復制的目標位置,這兩個參數都可以缺省,用於表示 Vim 光標所在當前行。
例如 :5copy. 表示復制 Vim 當前打開的文件的第 5 行到當前行(用 . 表示),即為第 5 行創建一份副本,並放到當前行下方。
下標列出了使用 copy 命令的縮寫形式 t 進行文件復制的一些實例及用途,用於理解復制命令 copy 的用途。
:3,5t. # 把第 3 行到第 5 行的內容復制到當前行下方
:t5 # 把當前行復制到第 5 行下方
:t. # 復制當前行到當前行下方(等價於普通模式下的 yyp)
:t$ # 把當前行復制到文本結尾
:'<,'>t0 # 把高亮選中的行復制到文件開頭
常用復制粘貼命令:
p # 粘貼到光標后
P # 粘貼到光標前
v # 進入可視模式
y # 復制標記內容
V # 可視模式按行標記
Ctrl+V # 可視模式按列標記
y$ # 復制當前位置到本行結束的內容
yy # 復制當前行 --> Yank (copy) a line
Y # 復制當前行,同 yy
yiw # 復制當前單詞
Nyy # 復制光標下 N 行內容
ddp # 剪切當前行並粘貼(先刪除當前行復制到寄存器,並粘貼)
v0 # 選中當前位置到行首
v$ # 選中當前位置到行末
viw # 選中當前單詞
vib # 選中小括號內的內容
vi) # 選中小括號內的內容
vi] # 選中中括號內的內容
viB # 選中大括號內的內容
vi} # 選中大括號內的內容
vis # 選中句子中的內容
vab # 選中小括號內的內容(包含小括號本身)
va) # 選中小括號內的內容(包含小括號本身)
va] # 選中中括號內的內容(包含中括號本身)
vaB # 選中大括號內的內容(包含大括號本身)
va} # 選中大括號內的內容(包含大括號本身)
:set paste # 允許粘貼模式(避免粘貼時自動縮進影響格式)
:set nopaste # 禁止粘貼模式
"?yy # 復制當前行到寄存器 ? ,問號代表 0-9 的寄存器名稱
"?d3j # 刪除光標下三行內容,並放到寄存器 ? ,問號代表 0-9 的寄存器名稱
"?p # 將寄存器 ? 的內容粘貼到光標后
"?P # 將寄存器 ? 的內容粘貼到光標前
:registers # 顯示所有寄存器內容
:[range]y # 復制范圍,比如 :20,30y 是復制 20 到 30 行,:10y 是復制第十行
:[range]d # 刪除范圍,比如 :20,30d 是刪除 20 到 30 行,:10d 是刪除第十行
"_[command] # 使用 [command] 刪除內容,並且不進行復制(不會污染寄存器)
"*[command] # 使用 [command] 復制內容到系統剪貼板(需要 Vim 版本有 clipboard 支持)
文本編輯、復制粘貼中的內容可以簡單總結為:
ci'、ci"、ci(、ci[、ci{、ci< # 分別更改這些配對標點符號中的文本內容
di'、di"、di( 或 dib、di[、di{ 或 diB、di< # 分別刪除這些配對標點符號中的文本內容
yi'、yi"、yi(、yi[、yi{、yi< # 分別復制這些配對標點符號中的文本內容
vi'、vi"、vi(、vi[、vi{、vi< # 分別選中這些配對標點符號中的文本內容
cit、dit、yit、vit,分別操作一對標簽之間的內容,編輯 HTML、XML 很好用!另外,如果把上面的 i 改成 a 可以同時操作配對標點和配對標點內的內容。
移動文本
:[range]move{address}
參數說明
- [range]:表示要移動的行范圍。
- {address}:表示移動的目標位置,這兩個參數都可以缺省。
例如:
:m+1 # 下移 1 行
:m-2 # 上移 1 行
:8,10m2 # 把當前打開文件的第 8~10 行內容移動到第 2 行下方
文本對象
0 # 到行首,數字 0
^ # 到行首非空字符,可以使用 0w 代替 ^,按鍵更方便
$ # 到行尾
iw # 整個單詞 Word(不包括分隔符)
aw # 整個單詞 Word(包括分隔符)
iW # 整個 Word(不包括分隔符)
aW # 整個 Word(包括分隔符)
is # 整個句子 (s: sentence)(不包括分隔符)
ib # 小括號內(b: brackets)
ab # 小括號內(包含小括號本身)
iB # 大括號內
aB # 大括號內(包含大括號本身)
i) # 小括號內
a) # 小括號內(包含小括號本身)
i] # 中括號內
a] # 中括號內(包含中括號本身)
i} # 大括號內
a} # 大括號內(包含大括號本身)
i' # 單引號內
a' # 單引號內(包含單引號本身)
i" # 雙引號內
a" # 雙引號內(包含雙引號本身)
2i) # 往外兩層小括號內
2a) # 往外兩層小括號內(包含小括號本身)
2f) # 到第二個小括號處
2t) # 到第二個小括號前
撤銷與恢復
u # 撤銷命令(u: undo),可以組合,例如 Nu,N 是任意整數,表示撤銷 N 步操作,下同
U # 撤銷整行操作
Ctrl+r # 撤銷上一次 u 命令(r: redo)
Ctrl+R # 回退前一個命令
查找替換
一般模式下的查找命令:
/pattern # 從光標處向文件尾搜索 pattern
?pattern # 從光標處向文件頭搜索 pattern
n # 向同一方向執行上一次搜索
N # 向相反方向執行上一次搜索
% # 匹配括號移動,包括 (),{},[]。結合以下兩個命令對程序員來說是相當強大(前提:需要把光標先移到括號上)
* # 向下搜索光標所在的單詞
# # 向前搜索光標所在的單詞
f<char> # 向后搜索當前行第一個為 <char> 的字符,2fv 可以找到第二個 v 字符
F<char> # 向前搜索當前行第一個為 <char> 的字符
t<char> # 向后搜索當前行第一個為 <char> 的字符前
T<char> # 向前搜索當前行第一個為 <char> 的字符前
; # 重復上次的字符查找命令(f/t命令)
, # 反轉方向查找上次的字符查找命令(f/t命令)
tx # 搜索當前行到指定 字符串 之前
fx # 搜索當前行到指定 字符串 之處
一般模式下的替換命令:
:[range]s[ubstitute]/{pattern}/{string}/[flags]
參數說明:
- pattern:就是要被替換掉的字串,可以用 regexp 來表示。
- string:將 pattern 由 string 所取代。
- [range]:有以下一些取值。
[range]取值 | 含義 |
---|---|
無 | 默認光標所在行 |
. | 光標所在當前行 |
N | 第 N 行 |
$ | 最后一行 |
'a | 標記 a 所在的行(之前要用 ma 做過標記) |
$-1 | 倒數第二行,可以對某一行加減某個數值獲得確定的某行 |
1,10 | 第 1~10 行 |
1,$ | 第一行到最后一行 |
1,. | 第一行到當前行 |
.,$ | 當前行到最后一行 |
'a,'b | 標記 a 所在的行 到 標記 b 所在的行(之前要用 ma、mb 做過標記) |
% | 所有行(和 1,$ 等價) |
?str? | 從當前位置向上搜索,找到第一個 str 的行(str 可以是正則) |
/str/ | 從當前位置向下搜索,找到第一個 str 的行(str 可以是正則) |
注意,上面的所有用於 range 的表示方法都可以通過 +、- 操作來設置相對偏移量。
- [flags]有以下一些取值:
[flags]取值 | 含義 |
---|---|
g | 對指定范圍內的所有匹配項(global)進行替換 |
c | 在替換前請求用戶進行確認(confirm) |
e | 忽略執行過程中的錯誤 |
i | 不區分大小寫 |
無 | 只在指定范圍內的第一個匹配項進行替換 |
舉例:
:s/p1/p2/g # 將當前行中全替換 p1 為 p2
:%s/p1/p2/g # 將當前文件中全替換 p1 為 p2
:%s/p1/p2/gc # 將當前文件中全替換 p1 為 p2,並且每處詢問你是否替換
:10,20s/p1/p2/g # 將第 10 到 20 行中所有 p1 替換為 p2
:%s/1\\2\/3/123/g # 將 "1\2/3" 替換為 "123"(特殊字符使用反斜杠標注)
:%s/\r//g # 刪除 DOS 換行符 ^M
:%s///gn # 統計某個模式的匹配個數
:%s/^\s*$\n//g # 刪除 Vim 打開文件中所有空白行
:g/^\s*$/d # 刪除 Vim 打開文件中所有空白行
:%s/^M$//g # 刪除 Vim 文件中顯式的 ^M 符號(操作系統換行符問題)
可視模式
注:Vim 可視模式下可以選擇一塊編輯區域,然后對選中的文件內容執行插入、刪除、替換、改變大小寫等操作。
v # 切換到面向字符的可視模式
V # 切換到面向行的可視模式
Ctrl+V # 切換到面向列塊的可視模式
> # 增加縮進
< # 減少縮進
d # 刪除高亮選中的文字
x # 刪除高亮選中的文字
c # 改寫文字,即刪除高亮選中的文字並進入插入模式
s # 改寫文字,即刪除高亮選中的文字並進入插入模式
y # 拷貝文字
~ # 轉換大小寫
o # 跳轉到標記區的另外一端
O # 跳轉到標記塊的另外一端
u # 標記區轉換為小寫
U # 標記區轉換為大寫
gv # 重選上次的高亮選區
g Ctrl+G # 顯示所選擇區域的統計信息
ggVG # 選擇全文
<Esc> # 按 Esc 鍵退出可視模式
此外: Vim Normal 命令可以在命令行模式執行普通模式下的命令,當 Normal 命令與 Vim 可視化模式結合時,只需很少的操作就能完成大量重復性工作。
注釋命令
多行注釋
Ctrl+v # 進入命令行模式,按 Ctrl+v 進入可視模式,然后按 j,或者 k 選中多行,把需要注釋的行標記起來
I # 按大寫字母 I,再插入注釋符,例如 #、//
<Esc> # 按 Esc 鍵就會全部注釋了
取消多行注釋
Ctrl+v # 進入命令行模式,按 Ctrl+v 進入可視模式,按字母 l 橫向選中列的個數,例如 #、//(需要選中 2 列)
j 或 k # 按字母 j,或者 k 選中注釋符號
d # 按 d 鍵就可全部取消注釋
復雜注釋
:起始行號,結束行號 s/^/ 注釋符 /g(注意冒號) # 在指定的行首添加注釋
:起始行號,結束行號 s/^ 注釋符 //g(注意冒號) # 在指定的行首取消注釋
:3,5 s/^/#/g # 注釋第 3-5 行
:3,5 s/^#//g # 解除 3-5 行的注釋
:1,$ s/^/#/g # 注釋整個文檔
:1,$ s/^#//g # 取消注釋整個文檔
:%s/^/#/g # 注釋整個文檔,此法更快
:%s/^#//g # 取消注釋整個文檔
位置跳轉
Ctrl+O # 跳轉到上一個位置
Ctrl+I # 跳轉到下一個位置
Ctrl+^ # 跳轉到 alternate file(當前窗口的上一個文件)
% # 匹配跳轉到對應的 {} () []
gd # 跳轉到局部定義(光標下的單詞的定義)
gD # 跳轉到全局定義(光標下的單詞的定義)
gf # 打開名稱為光標下文件名的文件
[[ # 跳轉到上一個頂層函數(比如C語言以大括號分隔)
]] # 跳轉到下一個頂層函數(比如C語言以大括號分隔)
[m # 跳轉到上一個成員函數
]m # 跳轉到下一個成員函數
[{ # 跳轉到上一處未匹配的 {
]} # 跳轉到下一處未匹配的 }
[( # 跳轉到上一處未匹配的 (
]) # 跳轉到下一處未匹配的 )
[c # 上一個不同處(diff時)
]c # 下一個不同處(diff時)
[/ # 跳轉到 C 注釋開頭
]/ # 跳轉到 C 注釋結尾
`` # 回到上次跳轉的位置
'' # 回到上次跳轉的位置
`. # 回到上次編輯的位置
'. # 回到上次編輯的位置
文件操作
:w # 寫入文件並保存,會修改文件的時間戳
:w <filename> # 按名稱保存文件
:w !sudo tee % # 以超級用戶權限保存文件,也可以這樣 :w !sudo tee % > /dev/null
:wa # 保存所有文件
:wall # 保存所有文件
:wqall # 保存所有文件並退出
:q # 關閉光標所在的窗口並退出(q: quit)
:q! # 不保存文件並強制退出(q: quit)
:qa! # 放棄所有文件操作並強制退出
:qall # 放棄所有文件操作並退出
:x # 保存文件並退出,不會修改文件的時間戳
:edit <filename> # 打開文件並編輯,縮寫(:e file),通過文件的絕對或相對路徑打開文件,Tab 鍵補全路徑
:edit . # 打開文件管理器,縮寫(:e .),瀏覽當前目錄下的文件,選中並編輯
:Explore # 打開文件管理器,縮寫(:E),並顯示活動緩沖區所在的目錄
:saveas <filename> # 另存為指定文件
:o <filename> # 在當前窗口打開(o: open)另一個文件
:r <filename> # 讀取文件並將內容插入到光標后
:r !dir # 將 dir 命令的輸出捕獲並插入到光標后
:on[ly] # 關閉除光標所在的窗口之外的其他窗口,同 Ctrl+W o
:clo[se] # 關閉光標所在窗口的文件,同 Ctrl+W c
:cd <path> # 切換 Vim 當前路徑
:pwd # 顯示 Vim 當前路徑
:n <filename> # 打開一個新的窗口編輯新文件 filename
:new # 打開一個新的窗口編輯新文件
:enew # 在當前窗口創建新文件
:vnew # 在左右切分的新窗口中編輯新文件
:tabnew # 在新的標簽頁中編輯新文件
:version # 查看 Vim 版本,同時也查看 Vim 載入配置文件的優先順序
ZZ # 保存已改動的文件,並關閉退出窗口
ZQ # 不保存文件關閉窗口
打開文件
vim . # 打開文件管理器,顯示目錄文件,通過選中文件編輯
vim filename # 打開或新建文件,並將光標置於第一行首
vim + filename # 打開文件,並將光標置於最后一行首
vim +n filename # 打開文件,並將光標置於第 n 行首
vim -c cmd file # 在打開文件 file 前,先執行指定的 Vim 命令 cmd
vim -b file # 以二進制模式打開文件,該模式某些特殊字符(如換行符 ^M)都可以顯示出來
vim -d file1 file2 # 使用 Vim 同時打開 file1 和 file2 文件並 diff 兩個文件的差異
vim -r filename # 在上次正用 Vim 編輯時發生系統崩潰,恢復文件
vim -R file # 以只讀形式打開文件,但是仍然可以使用 :wq! 寫入
vim -M file # 強制性關閉修改功能,無法使用 :wq! 寫入
vim -o file1 file2 # 終端中要打開 Vim 文件時,橫向分割顯示多個文件
vim -O file1 file2 # 終端中要打開 Vim 文件時,縱向分割顯示多個文件
vim -x file # 以加密方式打開文件
vim +/target file # 打開 file 並將光標移動到找到的第一個 target 字符串上
已打開文件操作
:ls # 查案緩存列表
:bn # 切換到下一個緩存
:bp # 切換到上一個緩存
:bd # 刪除緩存
:b 1 # 切換到 1 號緩存
:b abc # 切換到文件名為 abc 開頭的緩存
:badd <filename> # 將文件添加到緩存列表
:set hidden # 設置隱藏模式(未保存的緩存可以被切換走,或者關閉)
:set nohidden # 關閉隱藏模式(未保存的緩存不能被切換走,或者關閉)
n Ctrl+^ # 切換緩存,先輸入數字的緩存編號,再按 Ctrl+6
多窗口操作
分屏窗口是基於 Ctrl+W 快捷鍵的,Ctrl 是控制功能鍵,W 是代表 Windom,Ctrl+W 代表控制窗口的意思。
:sp <filename> # 上下橫向切分(split)窗口並在新窗口打開文件 filename
:vs <filename> # 左右縱向切分(vertical split)窗口並在新窗口打開文件 filename
:split # 將當前窗口再復制一個橫向窗口出來,內容同步,游標可以不同
:vsplit # 將當前窗口再復制一個縱向窗口出來,內容同步,游標可以不同
Ctrl+W # 切換到下一個窗口(Window)
Ctrl+W s # 上下橫向(split)切分窗口
Ctrl+W v # 左右縱向(vertical split)切分窗口
Ctrl+W w # 循環切換到下一個窗口
Ctrl+W W # 循環切換到上一個窗口
Ctrl+W p # 跳到上一個訪問過的窗口
Ctrl+W r # 互換(r: reverse)窗口
Ctrl+W c # 關閉(c: close)當前窗口,但不能關閉最后一個窗口
Ctrl+W q # 退出(q: quit)當前窗口,如果是最后一個窗口,則關閉 vi
Ctrl+W o # 只保留活動窗口,關閉其他(o: other)窗口,同 :on[ly]
Ctrl+W h # 跳到左邊的窗口
Ctrl+W j # 跳到下邊的窗口
Ctrl+W k # 跳到上邊的窗口
Ctrl+W l # 跳到右邊的窗口
Ctrl+W + # 增加當前窗口的行高,前面可以加數字
Ctrl+W - # 減少當前窗口的行高,前面可以加數字
Ctrl+W < # 減少當前窗口的列寬,前面可以加數字
Ctrl+W > # 增加當前窗口的列寬,前面可以加數字
Ctrl+W = # 讓所有窗口寬高相同
Ctrl+W H # 將當前窗口移動到最左邊
Ctrl+W J # 將當前窗口移動到最下邊
Ctrl+W K # 將當前窗口移動到最上邊
Ctrl+W L # 將當前窗口移動到最右邊
Ctrl+W x # 交換窗口
Ctrl+W f # 在新窗口中打開名為光標下文件名的文件
Ctrl+W gf # 在新標簽頁中打開名為光標下文件名的文件
Ctrl+W T # 將當前窗口移到新的標簽頁中
Ctrl+W P # 跳轉到預覽窗口
Ctrl+W z # 關閉預覽窗口
Ctrl+W _ # 縱向最大化當前窗口
Ctrl+W | # 橫向最大化當前窗口
標簽頁
:tabs # 顯示所有標簽頁
:tabe <filename> # 在新標簽頁中打開文件 filename
:tabn # 下一個標簽頁
:tabp # 上一個標簽頁
:tabc # 關閉當前標簽頁
:tabo # 關閉其他標簽頁
:tabn N # 切換到第 N 個標簽頁,比如:tabn 3 切換到第三個標簽頁
:tabm n # 標簽移動
:tabfirst # 切換到第一個標簽頁
:tablast # 切換到最后一個標簽頁
:tab help # 在標簽頁打開幫助
:tab drop <file> # 如果文件已被其他標簽頁和窗口打開則跳過去,否則新標簽打開
:tab split # 在新的標簽頁中打開當前窗口里的文件
:tab ball # 將緩存中所有文件用標簽頁打開
:set showtabline=? # 設置為 0 就不顯示標簽頁標簽,1 會按需顯示,2 會永久顯示
Ngt # 切換到第 N 個標簽頁,比如 2gt 將會切換到第二個標簽頁
gt # 下一個標簽頁
gT # 上一個標簽頁
Vim 書簽
:marks # 顯示所有書簽
ma # 保存當前位置到書簽 a ,書簽名小寫字母為文件內,大寫全局
'a # 跳轉到書簽 a 所在的行
`a # 跳轉到書簽 a 所在位置
`. # 跳轉到上一次編輯的行
'A # 跳轉到全文書簽 A
[' # 跳轉到上一個書簽
]' # 跳轉到下一個書簽
'< # 跳到上次可視模式選擇區域的開始
'> # 跳到上次可視模式選擇區域的結束
幫助信息
:help <command> # 顯示相關命令的幫助,也可以就輸入 :help 而不跟命令,退出幫助需要輸入 :q
:h tutor # 入門文檔
:h quickref # 快速幫助
:h index # 查詢 Vim 所有鍵盤命令定義
:h summary # 幫助你更好的使用內置幫助系統
:h Ctrl+H # 查詢普通模式下 Ctrl+H 是干什么的
:h i_Ctrl+H # 查詢插入模式下 Ctrl+H 是干什么的
:h i_<Up> # 查詢插入模式下方向鍵上是干什么的
:h pattern.txt # 正則表達式幫助
:h eval # 腳本編寫幫助
:h function-list # 查看 VimScript 的函數列表
:h windows.txt # 窗口使用幫助
:h tabpage.txt # 標簽頁使用幫助
:h +timers # 顯示對 +timers 特性的幫助
:h :! # 查看如何運行外部命令
:h tips # 查看 Vim 內置的常用技巧文檔
:h set-termcap # 查看如何設置按鍵掃描碼
:viusage # Normal 模式幫助
:exusage # EX 命令幫助
:version # 顯示當前 Vim 的版本號和特性
外部命令
:!command # 執行一次性 Shell 命令,如下命令::!pwd,當前 Vim 模式下改變目錄
:shell # 啟動一個交互的 Shell 執行多個命令,exit 命令退出並返回 Vim
:!ls # 運行外部命令 ls,並等待返回
:r !ls # 將外部命令 ls 的輸出捕獲,並插入到光標后
:w !sudo tee % # sudo 以后保存當前文件,也可以這樣 :w !sudo tee % > /dev/null
:call system('ls') # 調用 ls 命令,但是不顯示返回內容
:!start notepad # Windows 下啟動 Notepad,最前面可以加 silent
:sil !start cmd # Windows 下當前目錄打開 cmd
:%!prog # 運行文字過濾程序,如整理 JSON 格式 :%!python -m json.tool
Quickfix 窗口
:copen # 打開 quickfix 窗口(查看編譯,grep 等信息)
:copen 10 # 打開 quickfix 窗口,並且設置高度為 10
:cclose # 關閉 quickfix 窗口
:cfirst # 跳到 quickfix 中第一個錯誤信息
:clast # 跳到 quickfix 中最后一條錯誤信息
:cc [nr] # 查看錯誤 [nr]
:cnext # 跳到 quickfix 中下一個錯誤信息
:cprev # 跳到 quickfix 中上一個錯誤信息
拼寫檢查
:set spell # 打開拼寫檢查
:set nospell # 關閉拼寫檢查
]s # 下一處錯誤拼寫的單詞
[s # 上一處錯誤拼寫的單詞
zg # 加入單詞到拼寫詞表中
zug # 撤銷上一次加入的單詞
z= # 拼寫建議
代碼折疊
za # 切換折疊
zA # 遞歸切換折疊
zc # 折疊光標下代碼
zC # 折疊光標下所有代碼
zd # 刪除光標下折疊
zD # 遞歸刪除所有折疊
zE # 刪除所有折疊
zf # 創建代碼折疊
zF # 指定行數創建折疊
zi # 切換折疊
zm # 所有代碼折疊一層
zr # 所有代碼打開一層
zM # 折疊所有代碼,設置 foldlevel=0,設置 foldenable
zR # 打開所有代碼,設置 foldlevel 為最大值
zn # 折疊 none,重置 foldenable 並打開所有代碼
zN # 折疊 Normal,重置 foldenable 並恢復所有折疊
zo # 打開一層代碼
zO # 打開光標下所有代碼折疊
文檔加/解密
文檔加密:加密方式打開文件時,並在屏幕左下角提示輸入密碼兩次才可進行操作,保存文件退出后必須輸入正常密碼才能正確打開文件,否則會顯示亂碼。
vim -x file_name # 輸入加密密碼 -> 確認密碼! 注意:不修改內容也要保存。:wq,不然密碼設定不會生效。
:X # 命令行模式下,輸入加密密碼 -> 確認密碼! 注意:不修改內容也要保存。:wq,不然密碼設定不會生效。
:set key=密碼 # 命令行模式下,輸入加密密碼 -> 確認密碼! 注意:不修改內容也要保存。:wq,不然密碼設定不會生效。
文檔解密
:X # 命令行模式下,提示輸入密碼,不輸入而是按 Enter。注意:不修改內容也要保存。:wq,不然解密設定不會生效。
:set key= # 命令行模式下,設置 key 的密碼為空。注意:不修改內容也要保存。:wq,不然密碼設定不會生效。
宏錄制
宏是錄制和播放功能,是一系列 Vim 命令操作的集成,利用宏可以實現很多重復的勞動。
qa # 開始錄制名字為 a 的宏
q # 結束錄制宏
@a # 播放名字為 a 的宏
@@ # 播放上一個宏
@: # 重復上一個 ex 命令(即冒號命令)
宏 舉例:需要將如下多行文本的行首鍵入一個 Tab 鍵進行行首縮進。
set nu
set tabstop=4
set shiftwidth=4
set softtabstop=4
set autoindent
set wrap
syntax on
錄制宏
- 先將光標移動到第一行。
- 在 Normal 模式下,按 q 鍵加一個字母開始錄制。例如按下 qa,將該宏注冊為 a。
- 按下 I 在行首插入,在編輯模式按下 Tab 鍵。按 Esc 鍵返回到 Normal 模式。
- 按下 j 鍵將光標移動到下一行。
- 按下 q 鍵完成錄制。
使用宏
- 使用上面錄制的宏 a,按下 @a,播放名字為 a 的宏。
- Normal 模式下將光標移動到第二行,按下 @a,再使用了一次宏 a。
- 多次操作按下 N@a,其中 N 為正整數,代表執行 N 次宏。例如將光標移動到第 3 行,對余下的 5 行操作宏 a,按下 5@a。
以上 錄制宏、使用宏 兩個共同操作,完成多行文本的行首鍵入一個 Tab 鍵進行行首縮進!
其他命令
Ctrl+X Ctrl+E # 插入模式下向上滾屏
Ctrl+X Ctrl+Y # 插入模式下向下滾屏
Ctrl+G # 顯示正在編輯的文件名,文件大小和位置信息
g Ctrl+G # 顯示文件的大小、字符數、單詞數和行數,可視模式下也可用
ga # 顯示光標下字符的 ASCII 碼或者 Unicode 編碼
g8 # 顯示光標下字符的 UTF-8 編碼字節序
gi # 回到上次進入插入的地方,並切換到插入模式
K # 查詢光標下單詞的幫助
Ctrl+PgUp # 上個標簽頁,GVim OK,部分終端軟件需設置對應鍵盤碼
Ctrl+PgDown # 下個標簽頁,GVim OK,部分終端軟件需設置對應鍵盤碼
Ctrl+R Ctrl+W # 命令模式下插入光標下單詞
Ctrl+Insert # 復制到系統剪貼板(GVim)
Shift+Insert # 粘貼系統剪貼板的內容(GVim)
:set ff=unix # 設置換行為 unix
:set ff=dos # 設置換行為 dos
:set ff? # 查看換行設置
:set nohl # 清除搜索高亮
:set termcap # 查看會從終端接收什么以及會發送給終端什么命令
:set guicursor= # 解決 SecureCRT/PenguiNet 中 NeoVim 局部奇怪字符問題
:set t_RS= t_SH= # 解決 SecureCRT/PenguiNet 中 Vim8.0 終端功能奇怪字符
:set fo+=a # 開啟文本段的實時自動格式化
:earlier 15m # 回退到 15 分鍾前的文件內容
:map # 來查看當前 Vim 配置的 map 快捷鍵
:inoremap # 來查看當前 Vim 配置的 inoremap 快捷鍵
:nnoremap # 來查看當前 Vim 配置的 nnoremap 快捷鍵
:.!date # 在當前窗口插入時間
:%!xxd # 開始二進制編輯
:%!xxd -r # 保存二進制編輯
:r !curl -sL {URL} # 讀取 URL 內容添加到光標后
:g/^\s*$/d # 刪除空行
:g/green/d # 刪除所有包含 green 的行
:v/green/d # 刪除所有不包含 green 的行
:g/gladiolli/# # 搜索單詞打印結果,並在結果前加上行號
:g/ab.*cd.*efg/# # 搜索包含 ab,cd 和 efg 的行,打印結果以及行號
:v/./,/./-j # 壓縮空行
:Man bash # 在 Vim 中查看 man,先調用 :runtime! ftplugin/man.vim 激活
/fred\|joe # 搜索 fred 或者 joe
/\<\d\d\d\d\> # 精確搜索四個數字
/^\n\{3} # 搜索連續三個空行
查看歷史命令
命令行模式下:
:history # 查看所有命令行模式下輸入的命令歷史
:history search 或 / 或 ? # 查看搜索歷史
普通模式下:
q/ # 查看使用 q/ 輸入的搜索歷史
q? # 查看使用 q?輸入的搜索歷史
q: # 查看命令行歷史
寄存器
查看寄存器值
:reg # 查看所有寄存器值
:reg {register_name} # 查看指定寄存器值
調取寄存器值
"{register_name} # 普通模式下調取寄存器值
:Ctrl+r "寄存器名稱 # 命令模式下輸入 Ctrl+r 后 Vim 會自動打出 "寄存器引用符號
Ctrl+r 寄存器名稱 # 插入模式下(無需輸入寄存器引用符號")
Vim 寄存器分類
寄存器名稱 | 引用方式 | 說明 |
---|---|---|
無名寄存器 | "" | 默認寄存器,所有的復制和修改操作(x、s、d、c、y)都會將該數據復制到無名寄存器 |
字母寄存器 | "a - "z 或 "A - "Z | {register_name}只能是一位的 26 個英文字母,從 a-z,A-Z 寄存器內容將會合並到對應小寫字母內容后邊 |
復制專用寄存器 | "0(數字 0) | 僅當使用復制操作(y)時,該數據將會同時被復制到無名寄存器和復制專用寄存器 |
逐級臨時緩存寄存器 | "1 - "9 | 所有不帶范圍(‘(’,‘)’,‘{’,‘}’)、操作涉及 1 行以上的刪除修改操作(x、s、d、c)的數據都會復制到逐級臨時緩存寄存器,並在新的數據加入時,逐級先后推移。1 的數據復制到 2,2 到 3,最后的 9 寄存器內容將會被刪除 |
黑洞寄存器 | "_ | 幾乎所有的操作涉及的數據都會被復制到寄存器,如果想讓操作的數據不經過寄存器,可以指定黑洞寄存器,數據到該寄存器就會消失掉,不能顯示,也不存在 |
系統剪切板 | "+ 或 "* | 與 Vim 外部的 GUI 交互數據時,需要使用專用的系統剪切板 |
表達式寄存器 | "= | 所有寄存器里最特殊的一個,用於計算表達式。輸入完該寄存器應用后,會在命令行里提示“=”,按需輸入表達式,結果將會顯示到光標處 |
其他寄存器 | - | - |
Vim 配置文件
編輯 Vim 配置文件:
:edit $MYVIMRC # Vim 命令模式下使用該命令打開 Vim 配置文件
:source $MYVIMRC # Vim 配置文件改動后,使用該命令加載新的配置選項,若 vimrc 文件恰好是當前活動的緩沖區,則此命令可簡化為:so %。
Vim 配置說明,詳情請查看 vimrc 配置文件。注意:Vim 配置可以在命令模式下單個設置,只在當前窗口生效!
syntax # 列出已經定義的語法項
syntax clear # 清除已定義的語法規則
syntax on # 允許語法高亮
syntax off # 禁止語法高亮
set history=200 # 記錄 200 條歷史命令
set bs=? # 設置 Backspace 鍵模式,現代編輯器為 :set bs=eol,start,indent
set sw=4 # 設置縮進寬度為 4
set ts=4 # 設置制表符寬度為 4
set noet # 設置不展開 Tab 成空格
set et # 設置展開 Tab 成空格
set winaltkeys=no # 設置 GVim 下正常捕獲 Alt 鍵
set nowrap # 關閉自動換行
set ttimeout # 允許終端按鍵檢測超時(終端下功能鍵為一串 Esc 開頭的掃描碼)
set ttm=100 # 設置終端按鍵檢測超時為 100 毫秒
set term=? # 設置終端類型,比如常見的 xterm
set ignorecase # 設置搜索是否忽略大小寫
set smartcase # 智能大小寫,默認忽略大小寫,除非搜索內容里包含大寫字母
set list # 設置顯示制表符和換行符
set nu # 設置顯示行號,禁止顯示行號可以用 :set nonu
set number # 設置顯示行號,禁止顯示行號可以用 :set nonumber
set relativenumber # 設置顯示相對行號(其他行與當前行的距離)
set paste # 進入粘貼模式(粘貼時禁用縮進等影響格式的內容)
set nopaste # 結束粘貼模式
set spell # 允許拼寫檢查
set hlsearch # 設置高亮查找
set ruler # 總是顯示光標位置
set nocompatible # 設置不兼容原始 vi 模式(必須設置在最開頭)
set incsearch # 查找輸入時動態增量顯示查找結果
set insertmode # Vim 始終處於插入模式下,使用 Ctrl+o 臨時執行命令
set all # 列出所有選項設置情況
Vim 常用插件
vim-commentary:Vim 批量注釋工具,可以注釋多行和去除多行注釋。
gcc # 注釋當前行
gc{motion} # 注釋 {motion} 所標注的區域,比如 gcap 注釋整段
gci{ # 注釋大括號內的內容
gc # 在 Visual Mode 下面按 gc 注釋選中區域
:7,17Commentary # 注釋 7 到 17 行
NERDTree:該插件用於列出當前路徑的目錄樹。
? # 快速幫助文檔
o # 打開一個目錄或者打開文件,創建的是 buffer,也可以用來打開書簽
go # 打開一個文件,但是光標仍然留在 NERDTree,創建的是 buffer
t # 打開一個文件,創建的是 Tab,對書簽同樣生效
T # 打開一個文件,但是光標仍然留在 NERDTree,創建的是 Tab,對書簽同樣生效
i # 水平分割創建文件的窗口,創建的是 buffer
gi # 水平分割創建文件的窗口,但是光標仍然留在 NERDTree
s # 垂直分割創建文件的窗口,創建的是 buffer
gs # 和 gi,go 類似
x # 收起當前打開的目錄
X # 收起所有打開的目錄
e # 以文件管理的方式打開選中的目錄
D # 刪除書簽
P # 大寫,跳轉到當前根路徑
p # 小寫,跳轉到光標所在的上一級路徑
K # 跳轉到第一個子路徑
J # 跳轉到最后一個子路徑
Ctrl+j Ctrl+k # 在同級目錄和文件間移動,忽略子目錄和子文件
C # 將根路徑設置為光標所在的目錄
u # 設置上級目錄為根路徑
U # 設置上級目錄為跟路徑,但是維持原來目錄打開的狀態
r # 刷新光標所在的目錄
R # 刷新當前根路徑
I # 顯示或者不顯示隱藏文件
f # 打開和關閉文件過濾器
q # 關閉 NERDTree
A # 全屏顯示 NERDTree,或者關閉全屏
asyncrun.vim:該插件使用 Vim 8 / NeoVim 的異步機制,讓你在后台運行 shell 命令,並將結果實時顯示到 Vim 的 Quickfix 窗口中。
:AsyncRun ls # 異步運行命令 ls 結果輸出到 quickfix 使用 :copen 查看
:AsyncRun -raw ls # 異步運行命令 ls 結果不匹配 errorformat
Vim 模式
普通模式 # 按 Esc 或 Ctrl+[ 進入,左下角顯示文件名或為空
插入模式 # 按 i 進入,左下角顯示 --INSERT--
可視模式 # 按 v 進入,左下角顯示 --VISUAL--
替換模式 # 按 r 或 R 開始,左下角顯示 --REPLACE--
命令行模式 # 按 : 或者 / 或者 ? 開始
網絡資源
- 最新版本:https://github.com/vim/vim
- Windows 版:https://github.com/vim/vim-win32-installer/releases
- 插件瀏覽:http://vimawesome.com
- 正確設置 Alt 鍵:http://www.skywind.me/blog/archives/2021
- 視頻教程:http://vimcasts.org/
- 中文幫助:http://vimcdoc.sourceforge.net/doc/help.html
- 中文版入門到精通:https://github.com/wsdjeg/vim-galore-zh_cn
- 五分鍾腳本入門:http://www.skywind.me/blog/archives/2193
- 腳本精通:http://learnvimscriptthehardway.stevelosh.com/
- 十六年使用經驗:http://zzapper.co.uk/vimtips.html
- 配色方案:http://vimcolors.com/
Vim 使用建議
- 永遠不要用 Ctrl+C 代替
完全不同的含義,容易錯誤中斷運行的后台腳本。 - 很多人使用 Ctrl+[ 代替
,左手小指 Ctrl,右手小指 [ 熟練后很方便。 - 某些終端中使用 Vim 8 內嵌終端如看到奇怪字符,使用 :set t_RS= t_SH= 解決。
- 某些終端中使用 NeoVim 如看到奇怪字符,使用 :set guicursor= 解決。
- 多使用 ciw, ci[, ci", ci( 以及 diw, di[, di", di( 命令來快速改寫/刪除文本。
- 在行內左右移動光標時,多使用 w b e 或 W B E,而不是 h l 或方向鍵,這樣會快很多。
- Shift 相當於移動加速鍵, w b e 移動光標很慢,但是 W B E 走的很快。
- 自己要善於總結新技巧,比如移動到行首非空字符時用 0w 命令比 ^ 命令更容易輸入。
- 在空白行使用 dip 命令可以刪除所有臨近的空白行,viw 可以選擇連續空白。
- 縮進時使用 >8j >}
ap =i} == 會方便很多。 - 插入模式下,當你發現一個單詞寫錯了,應該多用 Ctrl+W 這比
快。 - y d c 命令可以很好結合 f t 和 /X 比如 dt) 和 y/End
。 - c d x 命令會自動填充寄存器 "1 到 "9 , y 命令會自動填充 "0 寄存器。
- 用 v 命令選擇文本時,可以用 0 掉頭選擇,有時很有用。
- 寫文章時,可以寫一段代碼塊,然后選中后執行 :!python 代碼塊就會被替換成結果。
- 搜索后經常使用 :nohl 來消除高亮,使用很頻繁,可以 map 到
上。 - 搜索時可以用 Ctrl+R Ctrl+W 插入光標下的單詞,命令模式也能這么用。
- 映射按鍵時,應該默認使用 noremap ,只有特別需要的時候使用 map。
- 用 y 復制文本后,命令模式中 Ctrl+R 然后按雙引號 0 可以插入之前復制內容。
- Windows 下的 GVim 可以設置 set rop=type:directx,renmode:5 增強顯示。
- 當你覺得做某事很低效時,你應該停下來,然后思考正確的高效方式來完成。
相關書籍
Vim鍵盤圖
參考
- https://github.com/skywind3000/awesome-cheatsheets/blob/master/editors/vim.txt
- http://blog.g-design.net/post/4789778607/vim-cheat-sheet
- http://www.fprintf.net/vimCheatSheet.html
- http://www.ouyaoxiazai.com/article/24/654.html
- http://bbs.it-home.org/thread-80794-1-1.html
- http://www.lpfrx.com/wp-content/uploads/2008/09/vi.jpg
- https://github.com/glts/vim-cottidie/blob/master/autoload/cottidie/tips
- https://github.com/hobbestigrou/vimtips-fortune/blob/master/fortunes/vimtips
- http://michael.peopleofhonoronly.com/vim/