安裝
下載windows安裝包, 最新版在這裡
下載中文幫助安裝包, 最新版在這裡
安裝vim-plug外掛, 原檔案在這裡, 下載plug.vim,然後把它放到vim安裝路徑的autoload目錄下
VIM簡介
VIM是一種信仰。
對我來說vi是禪, 使用vi就是使用禪。每個命令都是心印,這對使用者來說是深奧的,對未入門者來說是無法瞭解的。每次使用它你都能發現真理。 --Satish Reddy
商業化產品可能是有用的, 但最好的東西往往是免費的, 空氣, 水, vim
高效編輯的原則
形成過程
- 自省, 找出重複/低效的部分
- 尋找solution
- 使之成為習慣
7 Habits
- 他們能做事主動。 (“積極主動”)
- 他們能關注目標。 (“以終為始”)
- 他們能確定要務。 (“要事第一”)
- 他們能與人共贏。 (“雙贏思維”)
- 他們能與人溝通交流。 (“知彼解己”)
- 他們能與人合作。 (“統合綜效”)
- 他們能反省自己並彌補不足。 (“自我更新”)
區分學習和使用
- 學習是投入,使用是產出
- 學習是投資,使用是收益
- 不要第二次尋找同一問題的解決方案(DRY)
拿來主義
- 選擇性收集技巧, 有用的 VS 對你有用的
- 避免收集對自己無用的高度特殊化的技巧
不要為用不到的功能買單
- 不要提前買單
- 技能的投入產出比
- 遺忘曲線
- 打磨技藝持續前進
不斷提高
- 理解而非記憶
- 培植而非收藏
- 精心經營個人化功能子集
- 全面瞭解,不要淺嘗輒止
態度
- 學而不用,積而不發
- 瞭解工具實際被設計能做的事, 而不是你希望它能做的事.
高效與否, 操之在你
- 工具只會跟使用者一樣好
開放態度, 不要拒絕其它工具
- 手持錘子,滿世界都是釘子
第一課
學會自己搜尋答案
第二課
完成vimtutor
vimtutor位於vim安裝目錄裡,一個可執行程式(指令碼)
它大約需要20分鐘
第三課 Motion
通用
h/l/k/j
G/{num}G/gg/:{num}
%
gk/gj
0/^/$
f{char}/F{char}/t{char}/T{char}/;/,
: t=till=find-1-/+/_
練習
To err is human. To really foul up you need a computer.
<------------ ------------->
Th tn
單詞級移動
key | action |
---|---|
w 或 W | 移動到下一單詞的開頭 |
b 或 B | 移動到上一單詞的開頭 |
e 或 E | 移動到游標所在單詞的末尾 |
ge b w e
<- <- ---> --->
This is-a line, with special/separated/words (and some more).
<----- <----- --------------------> ----->
gE B W E
ge b w e
大範圍移動
key | action |
---|---|
% | 移動游標到括號左半部分( 包括(、{、[ )對應右半匹配部分( )、}、] ) |
} | 移動游標到當前段落的末尾 |
{ | 移到游標到當前段落的開頭 |
H | 移動游標到螢幕的第一行 |
M | 移動游標到螢幕的中間一行 |
L | 移動游標到螢幕的最後一行 |
Ctrl + f | 向前滾動一頁 |
Ctrl + b | 向後滾動一頁 |
Ctrl + u | 向前滾動半頁 |
Ctrl + d | 向後滾動半頁 |
/<string> | 向前查詢, 結合n/N可以重複向前向後查詢同一字元 |
?<string> | 向後查詢, 可以結合n/N |
關於查詢
.*[]^%/\?~$
有特殊含義,如果要查詢它們,在在前面加上\
.- 可以用
:set ic
或:set noic
來忽略或不忽略大小寫 - 輸入
/
或?
後可以用<Up>或<Down>來查詢歷史記錄。 - 可以在單詞上用
*
或#
來向前或向後查詢游標下單詞 - 如果要精確匹配, 用
\<
或\>
來精確匹配開頭或結尾,兩者可以同時使用,如/\<the\>
,這樣three不會被匹配
位置標記
key | desciption |
---|---|
m{a-zA-Z} | 把位置標記 {a-zA-Z} 設在當前游標位置 (不移動游標,這不是動作命令)。 |
g'{mark} | 跳轉到指定的位置標記 {mark},但在當前緩衝區內跳轉時,不改變跳轉表。 |
:marks | 列出所有的位置標記 (這不是動作命令),第一列的編號為零。 |
標誌說明
mark | description |
---|---|
'a - 'z | 小寫位置標記,在每個檔案內有效。 |
'A - 'Z | 大寫位置標記,也叫做檔案標記,在檔案間都有效。 |
'0 - '9 | 數字位置標記,在 .viminfo 檔案裡設定。 |
跳轉
key | action |
---|---|
CTRL-O | 轉到跳轉表裡第 [count] 個較舊的游標位置 (不是動作命令)。 |
CTRL-I | 轉到跳轉表裡第 [count] 個較新的游標位置 (不是動作命令)。 |
:ju[mps] | 打出跳轉表 (不是動作命令)。 |
:cle[arjumps] | 清除當前視窗的跳轉表。 |
編輯命令
<number> <operator> <text object or motion>
<次數> <操作符> <文字物件或移動命令>
操作符
key | action |
---|---|
c | 修改 (change) |
d | 刪除 (delete) |
y | 抽出 (yank) 到暫存器 (不改變文字) |
~ | 變換大小寫 (只有當 'tildeop' 置位時有效) |
g~ | 變換大小寫 |
gu | 變為小寫 |
gU | 變為大寫 |
! | 通過外部程式過濾 |
= | 通過 'equalprg' (若為空,C-indenting) 過濾 |
gq | 文字排版 |
gw | 文字排版,不移動游標 |
> | 右移 |
< | 左移 |
zf | 定義摺疊 |
高階技巧: 可以用":"命令定義一個動作, 例如d:call search("f")<CR>
, 如果該命令多於一行,則不能用"."重複。
物件導向型別
一共三種: 字元/行/列
key | type |
---|---|
v | 在操作符後和動作命令之前應用: 即使該動作是面向行的,也強制該操作面向字元。 |
V | 在操作符後和動作命令之前應用: 即使該動作是面向字元的,也強制該操作面向行。 |
CTRL-V | 在操作符後和動作命令之前應用: 強制該動作面向列塊。 |
練習: dj
, dvj
, d<C-V>j
物件定義
- word: 一個單詞由字元、數字和下劃線序列或者其他的非空白字元的序列組成。單詞間可以空白
字元 (空格、製表、換行) 分隔。這一規則可以用 'iskeyword' 選項改變。空行也被認
作單詞。 - WORD: 一個字串由非空白字元序列組成。字串以空白分隔。空行也被認作字串。
- sentence: 一個句子以 '.'、'!' 或者 '?' 結尾並緊隨著一個換行符、空格或者製表符。標點和空
白字元之間可以出現任何數量的閉括號和引號: ')'、']'、'"' 和 '''。另,段落和小節
的邊界也視為句子的邊界。 - paragraph: 一個段落從空行或某一個段落巨集命令開始,段落巨集由 'paragraphs' 選項裡成對出現的字
符所定義。它的預設值為 "IPLPPPQPP TPHPLIPpLpItpplpipbp",也就是巨集 ".IP"、".LP"
等 (這些是 nroff 巨集,所以句號一定要出現在第一列)。小節邊界也被視為段落邊界。
注意 空白行 (只包含空白) 不是 段落邊界。 - section: 一個小節從首列出現的換頁符 (<C-L>) 或某一個小節巨集命令開始。小節巨集由 'sections'
選項裡成對出現的字元所定義。它的預設值是 "SHNHH HUnhsh",也就是說小節可以從如
下的 nroff 巨集開始: ".SH"、".NH"、".H"、".HU"、".nh" 和 ".sh"。
文字物件
key | description | ||
---|---|---|---|
aw | "一個單詞",選擇 [count] 個單詞 (見 | word | )。包括開頭或拖尾的空白,但不單獨計算。在可視面向行的模式下,"aw" 切換到可視面向字元的模式。 |
iw | "內含單詞",選擇 [count] 個單詞 (見 | word | )。單詞之間的空白也被算為一個單詞。在可視面向行的模式下,"iw" 切換到可視面向字元的模式。 |
aW | "一個字串",選擇 [count] 個字串 (見 | WORD | )。包括開頭或拖尾的空白,但不單獨計算。在可視面向行的模式下,"aW" 切換到可視面向字元的模式。 |
iW | "內含字串",選擇 [count] 個字串 (見 | WORD | )。字串之間的空白也被算為一個字串。在可視面向行的模式下,"iW" 切換到可視面向字元的模式。 |
as | "一個句子",選擇 [count] 個句子 (見 | sentence | )。可視模式下它切換為面向字元的模式。 |
is | "內含句子",選擇 [count] 個句子 (見 | sentence | )。可視模式下它切換為面向字元的模式。 |
ap | "一個段落",選擇 [count] 個段落 (見 | paragraph | )。特例: 空白行 (只包含空白的行) 也被視為段落邊界。可視模式下它切換為面向行的模式。 |
ip | "內含段落",選擇 [count] 個段落 (見 | paragraph | )。特例: 空白行 (只包含空白的行) 也被視為段落邊界。可視模式下它切換為面向行的模式。 |
a( 或ab | "一個()塊",包括'(' 和 ')' | ||
i( 或ib | "一個()塊",不包括'(' 和 ')' | ||
a{ 或a{ | "一個{}塊",包括'{' 和 '}' | ||
i{ 或i{ | "一個{}塊",不包括'{' 和 '}' | ||
a" 或a' 或a\ ` | "一個引號字串", 包括引號 | ||
i" 或i' 或i\ ` | "一個引號字串", 不包括引號 |
常見命令
key | actions |
---|---|
x | 刪除游標下的字元 ("dl" 的縮寫) |
X | 刪除游標前的字元 ("dh" 的縮寫) |
D | 從當前位置刪除到行尾 ("d$" 的縮寫) |
dw | 從當前位置刪除到下一個單詞開頭 |
db | 從當前位置刪除到前一個單詞的開頭 |
diw | 刪除游標上的單詞 (不包括空白字元) |
daw | 刪除游標上的單詞 (包括空白字元) |
dG | 刪除到檔案末 |
dgg | 刪除到檔案首 |
上面的d可以改成c或y
插入和替換
插入模式命令
key | action |
---|---|
a | 在游標後附加文字 [count] 次。如果游標在空行的第一列,啟動插入模式。但在置位了 'virtualedit' 以後就不是! |
A | 在行尾附加文字 [count] 次。 |
i | 在游標前插入文字 [count] 次。在插入模式裡使用 CTRL-O 的時候,i_CTRL-O 不支援計數。 |
I | 在本行第一個非空白字元之前插入文字 [count] 次。如果 'cpoptions' 裡有 'H' 標誌位而本行只有空白,在最後一個空白前插入。 |
gI | 在第一列插入文字 [count] 次。 |
gi | 在當前緩衝區最近一次插入模式停止的位置繼續插入文字。該位置記在 '^ 位置標記裡。如果標記在行末之後,和 "^i" 有所差異。該位置在插入/刪除行時會自動修正。但_不_在插入/刪除字元時被修正。使用 :keepjumps 命令修飾符時,不改變 '^` 位置標記。 |
o | 在游標下方開啟新行,並插入文字,重複 [count] 次。如果 'cpoptions' 裡有 '#' 標誌位,忽略計數。 |
O | 在游標上方開啟新行,並插入文字,重複 [count] 次。如果 'cpoptions' 裡有 '#' 標誌位,忽略計數。 |
用<Esc>或<Ctrl-C>退出插入模式
Ex插入命令
key | Actions |
---|---|
:{range}a[ppend][!] | 在指定行下方新增若干行。如果沒有給出 {range},文字會在當前行之後插入。加入 [!] 切換此命令執行時的 'autoindent'。 |
:{range}i[nsert][!] | 在指定行上方新增若干行。如果沒有給出 {range},文字會在當前行之前插入。加入 [!] 切換此命令執行時的 'autoindent'。 |
這兩個命令會繼續要求行,直到你輸入了只包含 "." 的一行。小心反斜槓開始的行,見 line-continuation
。
Ex 模式 (見 -e
) 下,行尾的反斜槓可用來插入 NUL 字元。所以要使一行以反斜槓結尾,用兩個反斜槓。也就是說僅在行尾情況下,反斜槓數目減半。
注意: 這些命令不能和 :global
或 :vglobal
一起使用。":append" 和 ":insert" 在 ":if" 和 ":endif"、":for" 和 ":endfor" 還有 ":while" 和 ":endwhile" 之間不能很好的工作。
插入檔案
key | action |
---|---|
:r[ead] [++opt] [name] | 在游標下方插入檔案 [name] (預設: 當前檔案)。 |
:{range}r[ead] [++opt] [name] | 在指定行下方插入檔案 [name] (預設: 當前檔案)。 |
:[range]r[ead] [++opt] !{cmd} | 執行 {cmd} 並把它的標準輸出插入到游標下方。臨時檔案會建立來儲存命令輸出的結果,並被讀到緩衝區裡。'shellredir' 用來儲存命令的輸出結果,它可以設定是否包含標準錯誤的輸出。 |
插入模式下的一些快捷鍵
key | action |
---|---|
<Esc> 或 CTRL-[ | 結束插入或替換模式,回到普通模式。結束縮寫。 |
CTRL-C | 退出插入模式,回到普通模式。不檢查縮寫。不啟用 InsertLeave 自動命令事件。 |
CTRL-@ | 插入最近插入的文字,並停止插入。 |
CTRL-A | 插入最近插入的文字。 |
<BS> 或 CTRL-H | 刪除游標前的字元 。 |
<Del> | 刪除游標下的字元。如果游標在行尾,並且 'backspace' 選項包括 "eol",刪除 <EOL> ;下一行就此附加於當前行之後。如果你的 <Del> 鍵不正確,見 :fixdel。 |
CTRL-W | 刪除游標前的單詞 |
CTRL-U | 刪除當前行上游標前的所有輸入字元。 |
<Tab> 或 CTRL-I | 插入製表。如果開啟 'expandtab' 選項,等價數目的空格被插入 也可使用 CTRL-Q <Tab> 。 |
<NL> 或 CTRL-J | 開始新行。 |
<CR> 或 CTRL-M | 開始新行。 |
CTRL-K {char1} [char2] | 輸入二合字母 (見digraphs)。當 {char1} 為特殊字元時,該鍵的鍵碼以 <> 形式插入。例如字串 <S-Space> 可以這樣輸入: <C-K><S-Space> (兩個鍵)。兩個鍵都不考慮對映。 |
CTRL-N | 查詢下一個關鍵字 (見 i_CTRL-N)。 |
CTRL-P | 查詢上一個關鍵字 (見 i_CTRL-P)。 |
CTRL-T | 在當前行開始處插入一個 shiftwidth 的縮排。縮排總是取整到 'shiftwidth' 的倍數 (這是 vi 相容的)。 |
CTRL-D | 在當前行開始處刪除一個 shiftwidth 的縮排。縮排總是取整到 'shiftwidth' 的倍數 (這是 vi 相容的)。 |
0 CTRL-D | 刪除所有當前行的縮排。 |
^ CTRL-D | 刪除當前行的所有縮排。縮排在下一行上恢復。這可以用於插入卷標。 |
CTRL-V | 如果下一個是非數字,按本義插入。對特殊鍵而言,插入其終端程式碼。CTRL-V 之後緊接著輸入的字元不經過對映。注意: 當 CTRL-V 被對映時 (例如,用來貼上文字),你可能經常需要使用 CTRL-Q 來代替 |
CTRL-SHIFT-V | 與 CTRL-V 類似,除非啟用了 modifyOtherKeys,此時插入帶修飾符的鍵的轉義序列。 |
CTRL-Q | 等同於 CTRL-V。 |
CTRL-X | 進入 CTRL-X 模式,一個子模式。那裡你可以給出命令來補全單詞或者滾動視窗。見 i_CTRL-X 和 ins-completion 。 |
CTRL-E | 插入游標下面的字元。 |
CTRL-Y | 插入游標上面的字元。注意 CTRL-E 和 CTRL-Y 不使用 'textwidth',從而可以從長行裡複製字元。 |
CTRL-] | 切換縮寫,不插入字元。 |
<Insert> | 切換插入和替換模式。 |
插入暫存器內容
CTRL-R {register}
用於插入暫存器內容,在輸入CTRL-R之後會有"
顯示出來,這時你需要輸入暫存器名字
register | Usage |
---|---|
" | 無名暫存器,包含最近刪除或抽出的文字 |
% | 當前檔名 |
# | 輪換檔名 |
* | 剪貼簿內容 (X11: 主選擇) |
+ | 剪貼簿內容 |
/ | 最近的搜尋模式 |
: | 最近的命令列 |
. | 最近插入的文字 |
- | 最近的行內 (少於一行) 刪除 |
= | 表示式暫存器;你會被提示輸入一個表示式 (見expression) |
CTRL-R {register}
還有幾個變種:
CTRL-R CTRL-R {register}
: 文字按本義插入,這意味著如果暫存器包含 <BS> 這樣的字元,結果會不同。例如,如果暫存器包含 "ab^Hc":CTRL-R a
產生 "ac"。CTRL-R CTRL-R a
產生 "ab^Hc"。CTRL-R CTRL-O {register}
: 按本義插入暫存器內容,並且不進行自動縮排。CTRL-R CTRL-P {register}
: 按本義插入暫存器內容,修正縮排
複製並移動
keys | Usage | ||
---|---|---|---|
"{a-zA-Z0-9.%#:-"} | 指定下次的刪除、抽出和放置命令使用的暫存器 {a-zA-Z0-9.%#:-"} (大寫字元使得刪除和抽出命令附加到該暫存器) ({.%#:} 只能用於放置命令)。 | ||
["x]y{motion} | 抽出 {motion} 跨越的文字 [到暫存器 x]。如果沒有字元被抽出 (例如,在第一列執行 "y0") 並且 'cpoptions' 裡包括 'E' 標誌位,這是一個錯誤。 | ||
["x]yy | 抽出 [count] 行 [到暫存器 x] | linewise | 行動作。 |
["x]Y | 抽出 [count] 行 [到暫存器 x] (等同於 yy, | linewise | 行動作)。如果你想要 "Y" 執行從游標到行尾的操作 (更合乎邏輯,但是與 Vi 不相容),用 ":map Y y$"。 |
{Visual}["x]y | 抽出高亮文字 [到暫存器 x] (關於 {Visual} 見 | Visual-mode | )。 |
{Visual}["x]Y | 抽出高亮行 [到暫存器 x] (關於 {Visual} 見 | Visual-mode | )。 |
["x]p | 放置文字 [從暫存器 x] 在游標之後 [count] 次。 | ||
["x]<MiddleMouse> | 從一個暫存器放置文字在游標之前 [count] 次。除非另外指定,否則用 "* 暫存器。游標停留在新文字的尾部。 | ||
["x]gp | 如同 "p",但游標停留在新文字之後。 | ||
["x]gP | 如同 "P",但游標停留在新文字之後。 |
Ex Command | Usage | ||
---|---|---|---|
:reg[isters] | 顯示所有編號和命名暫存器的型別和內容。但不列出用於 :redir 目的地的暫存器。型別可以是以下之一: "c" 用於 characterwise 文字; "l" 用於 linewise 文字; "b" 用於 blockwise-visual 文字 | ||
:reg[isters] {arg} | 顯示 {arg} 裡提到的編號和命名暫存器的內容。例如: :reg 1a | ||
:di[splay] [arg] | 和 :registers 相同。 | ||
:[range]y[ank] [x] | 抽出 [range] 所指定的行 [到暫存器 x]。僅當包含 | +clipboard | 特性時才可以抽出到 "* 或 "+ 暫存器。 |
:[range]y[ank] [x] {count} | 從 [range] 的最後一行開始 (預設: 當前行 | cmdline-ranges | ) 抽出 {count} 行 [到暫存器 x]。 |
:[line]pu[t] [x] | 放置文字 [從暫存器 x] 在行號 [line] (預設為當前行) 之後。 | ||
:[line]pu[t]! [x] | 放置文字 [從暫存器 x] 在行號 [line] (預設為當前行) 之前。 | ||
:[range]co[py] {address} | 把 [range] 指定的行復制到 {address} 給出的行之下。 | ||
:[range]m[ove] {address} | 把 [range] 指定的行移動到 {address} 給出的行之下。 |
put
總是 linewise 行動作,因而這個命令可以用來把抽出的塊放置在新行上。暫存器也可以是 '=',跟隨一個可選的表示式。表示式繼續到該命令結束為止。你需要在 '|' 和 '"' 字元前加上反斜槓不讓它們終止你的命令列。例如: :put ='path' . \",/test\"
;如果 '=' 之後沒有表示式,Vim 使用前一個表示式。用 :dis =
你可以看到它。
上面這些命令也可以用於global命令, 詳細列表檢視help ex-cmd-index
暫存器型別:
- 無名暫存器 ""
用 "d"、"c"、"s"、"x" 等命令刪除或者用 "y" 等抽出命令複製的文字都被 Vim 用來填
充該暫存器 - 10 個編號暫存器 "0 到 "9
Vim 把抽出和刪除命令的文字儲存在這些暫存器裡。 - 行內刪除暫存器 "-
該暫存器儲存刪除不到一行內容的命令的文字 - 26 個命名的暫存器 "a 到 "z 或者 "A 到 "Z
Vim 只有在你指定的時候才使用這些暫存器。指定為小寫字母時替換原來的內容,指定為大寫字母時附加到原來的內容。 - 三個只讀暫存器 ":、". 和 "%
". 包含最近插入的文字
"% 包含當前檔名
“: 包含最近執行過的命令列。 - 輪換緩衝區暫存器 "#
包含當前視窗buf檔名 - 表示式暫存器 "=
其實並沒有這麼一個暫存器,這是可讀寫的 - 選擇和拖放暫存器 "*、"+ 和 "~
用這些暫存器來儲存和取得 GUI 介面選擇的文字。 只讀的 "~ 暫存器儲存最近一次拖放操作放下的文字 - 黑洞暫存器暫存器 "_
- 最近搜尋模式暫存器 "/
常用選項
組 | 選項 | 描述 |
---|---|---|
用法 | :set all | 顯示所有選項和設定; |
:set | 顯示當前設定的所有選項; | |
:set num? | 顯示num選項的當前設定;num可以換成其他選項; | |
:set num | 開啟選項與關閉選項; | |
:set nonum | num可以換成其他選項; | |
num/nonum | 是/否顯示行號; | |
wrap/nowrap | 是(預設)/否自動換行; | |
wrapmargin=n | 設定右邊界的值,當輸入時到達右邊界,並遇到空格時,會自動插入換行; | |
aw/noaw | 臨時轉入shell或使用":n"編輯其他檔案時,是/否自動儲存當前檔案已做的修改; | |
flash/noflash | 在出錯處使用閃爍提醒/使用嗚叫提醒; | |
縮排 | ai/noai | autoindent是/否使用自動縮排方式,新行與前面的行保持—致的縮排; |
smartindent | smartindent/nosmartindent:是否使用能識別類C語法的智慧縮排方式; | |
cindent | cindent/nocindent:是/否使用cindent縮排方式; | |
indentexpr | indentexpr/noindentexpr:是/否使用indentexpr縮排方式; | |
indenttype= | 縮排方式:autoindent、smartindent、cindent、indentexpr(同上); | |
shiftwidth=n | 自動縮排字元數; | |
tabstop=n | 將TAB鍵的寬度設定為n個寧符寬度,預設為8; | |
編碼 | encoding= | 設定vim內部使用的編碼字符集;如:prc; |
fileencoding= | 設定當前編輯的檔案的字元編碼方式;如:utf-8; | |
fileencodings= | 設定vim自動探測fileencoding的順序列表;如:"ucs-bom,utf-8,latin1"; | |
termencoding= | vim工作的終端的編碼方式;如:utf-8; | |
ambiwidth= | 設定漢字所佔字元寬度;如:double; | |
搜尋 | ic/noic | 搜尋時忽賂大小寫/不忽略大小寫(預設); |
wrapscan | 在搜尋時到達檔案尾後是/否跳檔案頭繼續搜尋; | |
incsearch | incsearch/noincsearch:輸入搜尋關鍵字時,是/否(預設)自動高亮匹配的字元; | |
hlsearch | hlsearch/nohlsearch:搜尋後,是/否(預設)保留匹配字元的高亮顯示 | |
程式設計 | syntax= | on/off:是/否顯示語法高亮; |
儲存 | ro/noro | 是/否只讀模式,只讀模式寫只能通過強制方式":w!"寫入,否則無法寫入; |
history=n | history記錄的行數,預設100個歷史記錄; | |
file | filetype on | 偵測檔案型別; |
filetype plugin on | 載入檔案型別外掛; | |
filetype indent on | 為特定檔案型別載入相關縮排檔案; | |
report=n | 複製或者刪除了多少行時顯示提示資訊,預設為2; | |
laststatus=0,1,2 | 是否顯示狀態列,0:不顯示,1:需要時間顯示,2:總是顯示; | |
list/nolist | 是/否將tab、換行符使用替代字元顯示(^I、$); | |
shell=path | 設定vim執行外部命令時使用的shell路徑,如:/bin/bash; | |
showmatch | 設定輸入右半邊括號時,是/否(預設)提示所對應的左半邊括號; | |
showmode | 設定是(預設)/否在視窗左下角顯示當前的模式:插入、替換等模式; | |
compatible | 除非.vimrc檔案存在,預設vim會嘗試採用vi相容的模式; |
正規表示式
- 表示目標字元的元字元
元字元 | 說明 |
---|---|
. | 匹配任意字元 |
[abc] | 匹配方括號中的任意一個字元,可用-表示字元範圍。如[a-z0-9]匹配小寫字母和數字 |
[^abc] | 匹配除方括號中字元之外的任意字元 |
\d | 匹配阿拉伯數字,等同於[0-9] |
\D | 匹配阿拉伯數字之外的任意字元,等同於1 |
\x | 匹配十六進位制數字,等同於[0-9A-Fa-f] |
\X | 匹配十六進位制數字之外的任意字元,等同於2 |
\l | 匹配[a-z] |
\L | 匹配3 |
\u | 匹配[A-Z] |
\U | 匹配4 |
\w | 匹配單詞字母,等同於[0-9A-Za-z_] |
\W | 匹配單詞字母之外的任意字元,等同於5 |
\t | 匹配<TAB> 字元 |
\s | 匹配空白字元,等同於[\t] |
\S | 匹配非空白字元,等同於6 |
- 需要轉義的字元
元字元 | 說明 |
---|---|
\* | 匹配* 字元 |
. | 匹配. 字元 |
\/ | 匹配 / 字元 |
\ | 匹配 \ 字元 |
\[ | 匹配 [ 字元 |
\] | 匹配 ] 字元 |
- 表示數量的元字元
元字元 | 說明 |
---|---|
* | 匹配0-任意個 |
\+ | 匹配1-任意個 |
\? | 匹配0-1個 |
\{n,m} | 匹配n-m個 |
\{n} | 匹配n個 |
\{n,} | 匹配n-任意個 |
\{,m} | 匹配0-m個 |
- 表示位置的元字元
元字元 | 說明 |
---|---|
$ | 匹配行尾 |
^ | 匹配行首 |
\< | 匹配單詞詞首 |
\> | 匹配單詞詞尾 |
- 表示子模式的元字元
用\(
和)
括起來的正規表示式,在後面使用時可以依次用\1
, \2
等變數來表示括號裡的內容
- 表示非列印字元的元字元
元字元 | 說明 |
---|---|
\n | 表示匹配 一個換行符。 |
\r | 表示匹配 一個回車符。 |
\t | 表示匹配 一個製表符 ( Tab 鍵)。 |
\s | 表示匹配 任意一個空白字元,包括空格、製表符、換頁符等。 |
\S | 表示匹配 任意一個非空白字元。 |
替換
substitue的縮寫是s, 基本語法是: [range]substitue/search/replace/[flags] [count]
對 [range] 指定的行把 {pattern} 的匹配替代成 {string}。關於 {pattern},參見 |pattern|。{string} 可以是按本義出現的字串,也可包含特殊字元。參見 |sub-replace-special|。如果不指定 [range] 和 [count],僅在當前行進行替代。如果指定 [count],在 [range] 最後一行開始的 [count] 行進行替代。如果不指定 [range] ,則從當前行開始。[count] 必須為正數。另見 |cmdline-ranges|。
- range
range
是同一個或多個被,
或;
分割的行限定符組成。當用;時, 游標位置會被設定為前一個行限定符確定的行值。
如果行限定符個數多於命令需要的數量,那麼前面的限定符被忽略。
行號可以用下列符號:
符號 | 行號 |
---|---|
{number} | 行號 |
. | 當前行 |
$ | 檔案的最後一行 |
% | 相當於 1,$ (整個檔案) |
't | 標記 t 的位置 (小寫) |
'T | 標記 T 的位置 (大寫);如果標記存在於另一個檔案中,則不能在範圍裡應用。 |
/{pattern}[/] | 下一個 匹配 {pattern} 的行 |
?{pattern}[?] | 前一個 匹配 {pattern} 的行 |
\/ | 下一個 與前次搜尋模式匹配的行 |
\? | 前一個 與前次搜尋模式匹配的行 |
\& | 下一個 與前次替代模式匹配的行 |
這些符號後面可以跟一個或多個+
或-
和一個可靠數字,如果數字省略,則認為是1/
和?
前面可能有另一個地址,那麼查詢就從那裡開始。如果使用;
, 那麼游標會移動
/pat1//pat2/
:不移動游標7;/pat2/
: 游標留在第7行
例子:
.+3
/that/+1
.,$
0;/that
1;/tath
- replace中的特殊字元
nomagic | 動作 |
---|---|
\& | 替代為完整的匹配 |
& | 替代為 & |
\0 | 替代為完整的匹配 |
\1 | 替代為匹配的第一個 () 裡面的內容 |
\2 | 替代為匹配的第二個 () 裡面的內容 |
.. | .. |
\9 | 替代為匹配的第九個 () 裡面的內容 |
\~ | 替代為前一個 substitute 的替代字串 |
~ | 替代為 ~ |
\u | 下一個字元成為大寫 |
\U | 其後字元成為大寫,直到 \E 出現 |
\l | 下一個字元成為小寫 |
\L | 其後字元成為小寫,直到 \E 出現 |
\e | 結束 \u、\U、\l 和 \L (注意: 不是 <Esc>!) |
\E | 結束 \u、\U、\l 和 \L |
<CR> | 把該行在此位置一分為二 (<CR> 以 CTRL-V <Enter> 方式輸入) |
\r | 同上 |
\<CR> | 插入一個回車 (CTRL-M) (<CR> 以 CTRL-V <Enter> 方式輸入) |
\n | 插入一個 <NL> (檔案裡的 <NUL>) (此處並不是換行) |
\b | 插入一個 <BS> |
\t | 插入一個 <Tab> |
\\ | 插入單個反斜槓 |
\x | 其中 x 是上面沒提到的任何一個字元: 保留作將來的擴充套件 |
\1
,\2
等裡的數字是基於模式裡 \(
出現的順序 (從左到右)。如果一個括號組匹配多次,最後一次的匹配被使用在 \1
,\2
等裡。例如:
:s/\(\(a[a-d] \)*\)/\2/ # 修改 "aa ab x" 為 "ab x"
\2
對應 \(a[a-d] \)
。第一次匹配 "aa ",第二次匹配 "ab ", 最後一次匹配"ab "被用於\2
。
- Flags
Flags | Usage | |
---|---|---|
`& | 必須是首個使用的標誌位,保留和上次substitue相同的標誌位 | ` |
`c | ` 確認每個替代 | |
`e | ` 如果搜尋不成功,不給出錯誤資訊 | |
`g | ` 對行內所有匹配進行替代 | |
`i | ` 忽略模式的大小寫 | |
`I | ` 不忽略模式大小寫 | |
`n | ` 只報告匹配次數,不實際進行替代 | |
`p | ` 顯示包含最後一次替代的行 | |
`# | ` 類似p, 且在前面加上行號 | |
`l | ` 類似p,但顯示方式類似:list | |
`r | ` 如果匹配模式為空,優先使用上一次使用的搜尋模式,之後再是上一次substitute或global使用的模式 |
- 示例
:s/a\|b/xxx\0xxx/g # 修改 "a b" 為 "xxxaxxx xxxbxxx"
:s/\([abc]\)\([efg]\)/\2\1/g # 修改 "af fa bg" 為 "fa fa gb"
:s/abcde/abc^Mde/ # 修改 "abcde" 為 "abc"、"de" (兩行)
:s/$/\^M/ # 修改 "abcde" 為 "abcde^M"
:s/\w\+/\u\0/g # 修改 "bla bla" 為 "Bla Bla"
:s/\w\+/\L\u\0/g # 修改 "BLA bla" 為 "Bla Bla"
:s/aa/a^Ma/ # 修改 "aa" 為 a<line-break>a
:s/aa/a\^Ma/ # 修改 "aa" 為 a^Ma
:s/aa/a\\^Ma/ # 修改 "aa" 為 a\<line-break>a
多檔案編輯
已經開啟一個檔案
- 開啟一個新檔案
edit[!] foo.txt
- 儲存
write
- 開啟一個新檔案
- 開啟多個檔案
vim one.c two.c three.c
然後可以用:[num]next
,:wnext
,:[num]previous
,:wprevious
,:last
,:first
來切換 多檔案跳轉
可以用args one.c two.c three.c
來新增多個檔案
然後可以用CTRL-^
來切換到上一個檔案
有兩個標記非常重要:`'"`: 你上次離開這個檔案的位置 `'.`: 你最後一次修改檔案的位置
可以用
m[a-zA-Z]
來標記檔案, 然後用'[mark]
來跳轉
還可以用CTRL-O
和CTRL-I
來在整個跳轉序列中前後跳轉
多視窗
分割視窗
可以直接用vim -O one.c two.c
來直接以分割方式開啟多個檔案-O
: 垂直分割-o
: 水平分割
如果已經開啟檔案,可以使用命令來開啟/關閉視窗
:sp[lit] {file} 水平分屏
:new {file} 水平分屏
:sv[iew] {file} 水平分屏,以只讀方式開啟
:vs[plit] {file} 垂直分屏
:clo[se] 關閉當前視窗
:only 只顯示當前視窗
上述命令都有快捷鍵, 共同字首是: CTRL-W
Ctrl+w s 水平分割當前視窗
Ctrl+w v 垂直分割當前視窗
Ctrl+w q 關閉當前視窗
Ctrl+w n 開啟一個新視窗(空檔案)
Ctrl+w o 關閉除當前視窗之外的所有視窗
Ctrl+w T 移動當前視窗到新標籤頁
切換視窗
Ctrl+w h 切換到左邊視窗
Ctrl+w j 切換到下邊視窗
Ctrl+w k 切換到上邊視窗
Ctrl+w l 切換到右邊視窗
Ctrl+w w 遍歷切換視窗
移動視窗
Ctrl+w H 向左移動當前視窗
Ctrl+w J 向下移動當前視窗
Ctrl+w K 向上移動當前視窗
Ctrl+w L 向右移動當前視窗
調整視窗大小
Ctrl+w + 增加視窗高度
Ctrl+w - 減小視窗高度
Ctrl+w = 統一視窗高度
對映
$$ <map command> <args> {lhs} {rhs} $$
command
Command | Normal | Visual | Operator Pending | Insert Only | Command Line | |
---|---|---|---|---|---|---|
命令 | 常規模式 | 視覺化模式 | 運算子模式 | 插入模式 | 命令列模式 | |
:map | noremap | y | y | y | ||
:nmap | nnoremap | y | ||||
:vmap | vnoremap | y | ||||
:omap | onoremap | y | ||||
:map! | noremap! | y | y | |||
:imap | inoremap | y | ||||
:cmap | cnoremap | y |
Operator-pending模式,是指當你輸入操作符(比如d)時,然後繼續輸入的移動步長和文字物件(dw)的狀態
nore的含義是, 禁止對{rhs}再進行對映掃描,以防止巢狀和遞迴,通常用於重定義一個命令
args
<buffer>
,<nowait>
,<silent>
,<special>
、<script>
、<expr>
和 <unique>
可以按任意順序使用。它們必須緊跟在命令的後邊,而在其它任何引數的前邊。
<buffer>
: 只作用於當前buffer<silent>
: 不回顯命令<script>
: 只能使用<SID>
開關的指令碼來對映{rhs}<unique>
: 如果對映或縮寫的命令已存在,只命令失敗<expr>
: 那個{rhs}是一個表示式,會用計算後的返回值代替{rhs}
強大的g
和v
:global
命令是 Vim 中一個更強大的命令 (之一)。它允許你找到一個匹配點並且在那裡執行一個命令。它的一般形式是:
:[range]g/{pattern}/{command}
在每一匹配行上執行命令command. 這個命令只能是冒號命令, 普通模式命令不能在這裡使用。如果需要,可以使用:normal
命令。
如果要檢視可以使用的命令,可以help ex-cmd-index
。 如果要檢視詳細解釋, 檢視help 10.4
和 help multi-repeat
。
vglobal
相當於global!
, 兩者可以組合使用, 如:g/found/v/notfound/{cmd}
利用global
我們可以把我們之前學的很多東西都串連起來,以完全一些非常奇妙的動作。
簡單示例,
- 要刪除所有空行:
:g/^$/d
- 要在含有always..begin的行後加上:label:
:g/always.*begin/s/$/ :label
exec和normal
execute
命令用來把一個字串當作Vimscript命令執行。比如: :execute "rightbelow vsplit " . bufname("#")
normal
命令把我們的指令碼跟日常的文字編輯按鍵結合起來, 比如: :normal ggdd
。 為了防止遞迴解析, 建議永遠使用normal!
利用exec和normal的組合可以將動作變成可重複的命令, 並消除轉義字元問題。比如: :execute "normal! mqA;\<esc>'q"