vim從入門到精通

語言: CN / TW / HK

安裝

下載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}/;/,
-/+/_

練習

To err is human.  To really foul up you need a computer. 
           <------------  ------------->
                    Th     tn

單詞級移動

key action
wW 移動到下一單詞的開頭
bB 移動到上一單詞的開頭
eE 移動到游標所在單詞的末尾
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 自動命令事件。
[email protected] 插入最近插入的文字,並停止插入。
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-Xins-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

暫存器型別:

  1. 無名暫存器 ""
    用 "d"、"c"、"s"、"x" 等命令刪除或者用 "y" 等抽出命令複製的文字都被 Vim 用來填
    充該暫存器
  2. 10 個編號暫存器 "0 到 "9
    Vim 把抽出和刪除命令的文字儲存在這些暫存器裡。
  3. 行內刪除暫存器 "-
    該暫存器儲存刪除不到一行內容的命令的文字
  4. 26 個命名的暫存器 "a 到 "z 或者 "A 到 "Z
    Vim 只有在你指定的時候才使用這些暫存器。指定為小寫字母時替換原來的內容,指定為大寫字母時附加到原來的內容。
  5. 三個只讀暫存器 ":、". 和 "%
    ". 包含最近插入的文字
    "% 包含當前檔名
    “: 包含最近執行過的命令列。
  6. 輪換緩衝區暫存器 "#
    包含當前視窗buf檔名
  7. 表示式暫存器 "=
    其實並沒有這麼一個暫存器,這是可讀寫的
  8. 選擇和拖放暫存器 "*、"+ 和 "~
    用這些暫存器來儲存和取得 GUI 介面選擇的文字。 只讀的 "~ 暫存器儲存最近一次拖放操作放下的文字
  9. 黑洞暫存器暫存器 "_
  10. 最近搜尋模式暫存器 "/

常用選項

選項 描述
用法 :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相容的模式;

正則表示式

  1. 表示目標字元的元字元
元字元 說明
. 匹配任意字元
[abc] 匹配方括號中的任意一個字元,可用-表示字元範圍。如[a-z0-9]匹配小寫字母和數字
[^abc] 匹配除方括號中字元之外的任意字元
\d 匹配阿拉伯數字,等同於[0-9]
\D 匹配阿拉伯數字之外的任意字元,等同於
\x 匹配十六進位制數字,等同於[0-9A-Fa-f]
\X 匹配十六進位制數字之外的任意字元,等同於
\l 匹配[a-z]
\L
\u 匹配[A-Z]
\U
\w 匹配單詞字母,等同於[0-9A-Za-z_]
\W 匹配單詞字母之外的任意字元,等同於
\t 匹配 <TAB> 字元
\s 匹配空白字元,等同於[\t]
\S 匹配非空白字元,等同於
  1. 需要轉義的字元
元字元 說明
\* 匹配* 字元
. 匹配. 字元
\/ 匹配 / 字元
\ 匹配 \ 字元
\[ 匹配 [ 字元
\] 匹配 ] 字元
  1. 表示數量的元字元
元字元 說明
* 匹配0-任意個
\+ 匹配1-任意個
\? 匹配0-1個
\{n,m} 匹配n-m個
\{n} 匹配n個
\{n,} 匹配n-任意個
\{,m} 匹配0-m個
  1. 表示位置的元字元
元字元 說明
$ 匹配行尾
^ 匹配行首
\< 匹配單詞詞首
\> 匹配單詞詞尾
  1. 表示子模式的元字元

\() 括起來的正則表示式,在後面使用時可以依次用 \1 , \2 等變數來表示括號裡的內容

  1. 表示非列印字元的元字元
元字元 說明
\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|。
  1. 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

  1. 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

  1. Flags
Flags Usage
`& 必須是首個使用的標誌位,保留和上次substitue相同的標誌位 `
`c ` 確認每個替代
`e ` 如果搜尋不成功,不給出錯誤資訊
`g ` 對行內所有匹配進行替代
`i ` 忽略模式的大小寫
`I ` 不忽略模式大小寫
`n ` 只報告匹配次數,不實際進行替代
`p ` 顯示包含最後一次替代的行
`# ` 類似p, 且在前面加上行號
`l ` 類似p,但顯示方式類似:list
`r ` 如果匹配模式為空,優先使用上一次使用的搜尋模式,之後再是上一次substitute或global使用的模式
  1. 示例
: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

多檔案編輯

  1. 已經開啟一個檔案

    • 開啟一個新檔案
      edit[!] foo.txt
    • 儲存
      write
  2. 開啟多個檔案
    vim one.c two.c three.c
    然後可以用 :[num]next , :wnext:[num]previous , :wprevious , :last , :first 來切換
  3. 多檔案跳轉

    可以用 args one.c two.c three.c 來新增多個檔案

    然後可以用 CTRL-^ 來切換到上一個檔案

    有兩個標記非常重要:

    `'"`: 你上次離開這個檔案的位置
     `'.`: 你最後一次修改檔案的位置

    可以用 m[a-zA-Z] 來標記檔案, 然後用 '[mark] 來跳轉

    還可以用 CTRL-OCTRL-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 =        統一視窗高度

對映

< m a p c o m m a n d > < a r g s > l h s r h s <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}

強大的 gv

:global 命令是 Vim 中一個更強大的命令 (之一)。它允許你找到一個匹配點並且在那裡執行一個命令。它的一般形式是:

:[range]g/{pattern}/{command}

在每一匹配行上執行命令command. 這個命令只能是冒號命令, 普通模式命令不能在這裡使用。如果需要,可以使用 :normal 命令。

如果要檢視可以使用的命令,可以 help ex-cmd-index 。 如果要檢視詳細解釋, 檢視 help 10.4help multi-repeat

vglobal 相當於 global! , 兩者可以組合使用, 如 :g/found/v/notfound/{cmd}

利用 global 我們可以把我們之前學的很多東西都串連起來,以完全一些非常奇妙的動作。

簡單示例,

:g/^$/d
:g/always.*begin/s/$/ :label

exec和normal

execute 命令用來把一個字串當作Vimscript命令執行。比如: :execute "rightbelow vsplit " . bufname("#")

normal 命令把我們的指令碼跟日常的文字編輯按鍵結合起來, 比如: :normal ggdd 。 為了防止遞迴解析, 建議永遠使用 normal!

利用exec和normal的組合可以將動作變成可重複的命令, 並消除轉義字元問題。比如: :execute "normal! mqA;\<esc>'q"