1. 程式人生 > >Vim 快捷鍵 & 基本命令

Vim 快捷鍵 & 基本命令

  • vi 之大道如我心之禪,
  • vi 之漫路即為禪修,
  • vi 之命令禪印於心,
  • 未得此道者視之怪誕,
  • 與之為伴者洞其真諦,
  • 長修此道者鉅變人生。

簡介

  • Vim編輯程式有三種操作模式,分別稱為 編輯模式、插入模式 和 命令模式,當執行Vim時,首先進入編輯模式
  • 在 vim 內部通過 ! 字首可以執行 shell 命令

編輯模式

快捷鍵 Change Delete Yank(Copy)
Line cc dd yy
Letter cl dl yl
Word cw dw yw

跳轉

字元移動

  • h,j,k,l 左下上右

行內移動

  • w 正向移動到相鄰單詞的首字元
  • b 逆向移動到相鄰單詞的首字元
  • B 向前一個單詞,以空格和TAB為分隔符
  • e 正向移動到相鄰單詞的尾字元
  • ge 逆向移動到相鄰單詞的尾字元
  • 0 數字0,左移游標到本行的開始;
  • $ 右移游標,到本行的末尾;
  • ^ 移動游標,到本行的第一個非空字元

頁移動

  • H 跳轉到當前螢幕的第一行
  • M 跳轉到本屏顯示的中間一行
  • L 跳轉到最後一行
  • 2H 表示將游標移到螢幕的第2行
  • 3L 表示將游標移到螢幕的倒數第3行
  • z + enter 是當前行成為螢幕的第一行
  • z + - 是當前一行成為最後一行
  • ctrl + f 在檔案中前移一頁(相當於 page down);
  • ctrl + b 在檔案中後移一頁(相當於 page up);
  • ctrl + d 往下滾動半屏
  • ctrl + u 往上滾動半屏

檔案移動

  • gg 跳到首行
  • G 調到尾行
  • nG 跳轉到n行
  • % 跳到另一邊括號

配合查詢字元的方式移動

  • fa 正向移動到第一個字元 a 處
  • Fa 逆向移動到第一個字元 a 處

非相鄰的單詞或字元間移動

  • 8w 正向移動到相隔八個單詞的首字元
  • 4Fa 逆向移動到第四個 a 字元

更大範圍的移動

  • * 當游標停留在一個單詞上,* 鍵會在檔案內搜尋該單詞,並跳轉到下一處;
  • # 當游標停留在一個單詞上,# 在檔案內搜尋該單詞,並跳轉到上一處;
  • (/) 移動到 前/後 句 的開始;
  • {/} 跳轉到 當前/下一個 段落 的開始。
  • g_ 到本行最後一個不是 blank 字元的位置。
  • fa 到下一個為 a 的字元處,你也可以fs到下一個為s的字元。
  • t, 到逗號前的第一個字元。逗號可以變成其它字元。
  • 3fa 在當前行查詢第三個出現的 a。
  • F/T 和 f 和 t 一樣,只不過是相反方向;
  • gg 將游標定位到檔案第一行起始位置;
  • G 將游標定位到檔案最後一行起始位置;
  • NG或Ngg 將游標定位到第 N 行的起始位置

搜尋匹配

  • /text 向後搜尋
  • ?text 向前搜尋
  • :g/targetWord 全域性搜尋
  • :%s/oldWord/newWord/gc 全域性替換
  • n 搜尋下一個同樣的內容
  • N 搜尋上一個同樣的內容

替換和刪除

  • Vim常規的刪除命令是 d、 x (前者刪除 行 ,後者刪除 字元 ),結合Vim的其他特性可以實現基礎的刪除功能。將游標定位於檔案內指定位置後,可以用其他字元來替換游標所指向的字元,或從當前游標位置刪除一個或多個字元或一行、多行
  • gg dG 刪除全部內容
  • d0 刪除至行首
  • dl 刪除當前字元, dl=x
  • dh 刪除前一個字元
  • dd 刪除當前行
  • dj 刪除上一行
  • dk 刪除下一行
  • dw 刪除到下一個單詞開頭
  • de 刪除到本單詞末尾
  • dE 刪除到本單詞末尾包括標點在內
  • db 刪除到前一個單詞
  • dB 刪除到前一個單詞包括標點在內
  • 10d 刪除當前行開始的10行
  • d$ 刪除當前字元之後的所有字元(本行)
  • D 刪除當前字元至行尾。D=d$
  • kd gg 刪除當前行之前所有行(不包括當前行)
  • jdG 刪除當前行之後所有行(不包括當前行)
  • :1,10d 刪除1-10行
  • :11,$d 刪除11行及以後所有的行
  • :1,$d 刪除所有行
  • J 刪除兩行之間的空行,實際上是合併兩行
  • rc 用 c 替換游標所指向的當前字元;
  • nrc 用 c 替換游標所指向的前 n 個字元;
  • 5rA 用 A 替換游標所指向的前 5 個字元;
  • x 刪除游標所指向的當前字元;
  • nx 刪除游標所指向的前 n 個字元;
  • 3x 刪除游標所指向的前 3 個字元;
  • dw 刪除游標右側的字;
  • ndw 刪除游標右側的 n 個字;
  • 3dw 刪除游標右側的 3 個字;
  • db 刪除游標左側的字;
  • ndb 刪除游標左側的 n 個字;
  • 5db 刪除游標左側的 5 個字;
  • dd 刪除游標所在行,並去除空隙;
  • ndd 刪除(剪下) n 行內容,並去除空隙;
  • 3dd 刪除(剪下) 3 行內容,並去除空隙;
  • Vim常規的替換命令有 c 和 s ,結合Vim的其他特性可以實現基礎的替換功能,不過替換命令執行以後,通常會由 編輯模式 進入 插入模式
  • s 用輸入的正文替換游標所指向的字元;
  • S 刪除當前行,並進入編輯模式;
  • ns 用輸入的正文替換游標右側 n 個字元;
  • nS 刪除當前行在內的 n 行,並進入編輯模式;
  • cw 用輸入的正文替換游標右側的字;
  • cW 用輸入的正文替換從游標到行尾的所有字元(同 c$ );
  • ncw 用輸入的正文替換游標右側的 n 個字;
  • cb 用輸入的正文替換游標左側的字;
  • ncb 用輸入的正文替換游標左側的 n 個字;
  • cd 用輸入的正文替換游標的所在行;
  • ncd 用輸入的正文替換游標下面的 n 行;
  • c$ 用輸入的正文替換從游標開始到本行末尾的所有字元;
  • c0 用輸入的正文替換從本行開頭到游標的所有字元。

複製貼上

  • yy 拷貝當前行
  • nyy 拷貝當前後開始的n行,比如2yy拷貝當前行及其下一行
    *“+y 複製 1 行到作業系統的貼上板
    *“+nyy 複製 n 行到作業系統的貼上板
  • :1,10 co 20 將1-10行插入到第20行之後
  • :1,co 將整個檔案複製一份並新增到檔案尾部
  • 正常模式下按v(逐字)或V(逐行)進入可視模式,然後用jklh命令移動即可選擇某些行或字元,再按y即可複製
  • ddp 交換當前行和其下一行
  • xp 交換當前字元和其後一個字元
  • 正常模式下按v(逐字)或V(逐行)進入可視模式,然後用jklh命令移動即可選擇某些行或字元,再按d即可剪下
  • ndd 剪切當前行之後的n行。利用p命令可以對剪下的內容進行貼上
  • :1,10d 將1-10行剪下。利用p命令可將剪下後的內容進行貼上。
  • :1, 10 m 20 將第1-10行移動到第20行之後。
  • x 剪切當前字元
  • 3x 剪切當前游標開始向後三個字元
  • X 剪切當前字元的前一個字元。X=dh
  • p 貼上到下一行或右側,修改和刪除的資料自動到貼上板中
  • P 貼上到上一行或左側
  • 如果是要替換別的單詞,則先按 v 進入 visual mode,選中要替換的單詞,再按貼上即可,貼上板中就換成了被替換的單詞
  • yiw (yank inner word)在一個單詞的任意字母使用,就複製該單詞
  • yw 則只是複製從游標所在字母到詞尾的部分

撤銷和重複

  • u 撤銷最近一次修改 undo
  • . 重複最後一條修改正文的命令
  • U 撤銷所有修改
  • ctrl + r 取消最後一次的撤銷 redo

塊編輯

  • v 可進入visual模式,使用標準快捷鍵移動游標可選擇文字塊,之後可輸入標準編輯命令
  • ctrl + v 列編輯
  • 行尾塊…

命令列模式下的一些技巧

  • DTc 刪除從游標的c之間的所有字元
  • Rc 將游標的字元替換為c
  • nDD 刪除n行資料
  • nYY 複製n行資料
  • nX 刪除n個字元
  • R 進入替換狀態,esc退出

插入模式

進入

  • i 在當前位置生前插入
  • I 在當前行首插入
  • a 在當前位置後插入
  • A 在當前行尾插入
  • o 在當前行之後插入一行
  • O 在當前行之前插入一行
  • s 刪掉當前字元,並進行輸入
  • x 刪掉當前字元,停留在Normal模式

退出

  • Esc
  • ctrl + O 暫時性的
  • ctrl + C 取消當前的任何操作
  • ctrl + [ 官方推薦替換Esc

移動游標 儘量不要進入插入模式移動游標

  • ctrl + H 游標移當前行行首 imap
  • ctrl + J 游標移下一行行首 imap
  • ctrl + K 游標移上一行行尾 imap
  • ctrl + L 游標移當前行行尾 imap
  • Alt + H 游標左移一格 imap
  • Alt + J 游標下移一格 imap
  • Alt + K 游標上移一格 imap
  • Alt + L 游標右移一格 imap

命令模式

開啟、儲存

    :e path_to_file/filename 在已經啟動的Vim中開啟一個檔案
    :w 儲存當前編輯的檔案
    :w file_temp 將當前檔案另存為file_temp

退出

    ZZ 儲存並退出
    :wq 儲存並退出
    :e! 放棄所有修改,並開啟原來檔案
    Shift +Z,Q 無條件退出
    q! 無條件退出
    ctrl + Z 退出vim,不推薦,會生成.swp的檔案

行號與檔案

  • 編輯中的每一行正文都有自己的行號,用下列命令可以移動游標到指定行(效果與 編輯模式 下的 ngg 或 nG 相同)
    :n 將游標移到第 n 行
  • 命令模式下,可以規定命令操作的行號範圍。數值用來指定絕對行號;字元“.”表示游標所在行的行號;字元符“$”表示正文最後一行的行號;簡單的表示式,例如“.+5”表示當前行往下的第 5 行。例如
    :345         將游標移到第 345 行
    :345w file   將第 345 行寫入 file 檔案
    :3,5w file   將第 3 行至第 5 行寫入 file 檔案
    :1,.w file   將第 1 行至當前行寫入 file 檔案
    :.,$w file   將當前行至最後一行寫入 file 檔案
    :.,.+5w file 從當前行開始將 6 行內容寫入 file 檔案
    :1,$w file   將所有內容寫入 file 檔案,相當於 :w file 命令
  • 在命令模式下,允許從檔案中讀取正文,或將正文寫入檔案
    :w         將編輯的內容寫入原始檔案,用來儲存編輯的中間結果
    :wq        將編輯的內容寫入原始檔案並退出編輯程式(相當於 ZZ 命令)
    :w file    將編輯的內容寫入 file 檔案,保持原有檔案的內容不變
    :a,bw file 將第 a 行至第 b 行的內容寫入 file 檔案
    :r file    讀取 file 檔案的內容,插入當前游標所在行的後面
    :e file    編輯新檔案 file 代替原有內容
    :f file    將當前檔案重新命名為 file
    :f         列印當前檔名稱和狀態,如檔案的行數、游標所在的行號等

字串搜尋

  • 在 編輯模式 講過字串的搜尋,此處的 命令模式 也可以進行字串搜尋,給出一個字串,可以通過搜尋該字串到達指定行。如果希望進行正向搜尋,將待搜尋的字串置於兩個 / 之間;如果希望反向搜尋,則將字串放在兩個 ? 之間
    :/str/               正向搜尋,將游標移到下一個包含字串 str 的行
    :?str?               反向搜尋,將游標移到上一個包含字串 str 的行
    :/str/w file         正向搜尋,並將第一個包含字串 str 的行寫入 file 檔案
    :/str1/,/str2/w file 正向搜尋,並將包含字串 str1 的行至包含字串 str2 的行寫

Vim中的正則表示式

    :/struct/ 要搜尋一行正文,這行正文的開頭包含 struct 字
    因為它只找出在行中任意位置包含 struct的第一行,並不一定在行的開始包含 struct 。解決問題的辦法是在搜尋字串前面加上特殊字元^
    :/^struct/
    也可以用類似辦法在搜尋字串後面加上表示行的末尾的特殊字元 $ 來找出位於行末尾的字
    :/struct$/
  • 下表給出大多數特殊字元和它們的含義
    ^                放在字串前面,匹配行首的字;
    $                放在字串後面,匹配行尾的字;
    \<               匹配一個字的字頭;
    \>               匹配一個字的字尾;
    .                匹配任何單個正文字元;
    [str]            匹配 str 中的任何單個字元;
    [^str]           匹配任何不在 str 中的單個字元;
    [a-b]            匹配 a 到 b 之間的任一字元;
    *                匹配前一個字元的 0 次或多次出現;
    \                轉義後面的字元。

正文替換

  • 利用 :s 命令可以實現字串的替換
    :%s/str1/str2/        用字串 str2 替換行中首次出現的字串 str1
    :s/str1/str2/g        用字串 str2 替換行中所有出現的字串 str1
    :.,$ s/str1/str2/g    用字串 str2 替換正文當前行到末尾所有出現的字串 str1
    :1,$ s/str1/str2/g    用字串 str2 替換正文中所有出現的字串 str1
    :g/str1/s//str2/g     功能同上
    :m,ns/str1/str2/g     將從m行到n行的str1替換成str2
  • 從上述替換命令可以看到:
    1. g 放在命令末尾,表示對搜尋字串的每次出現進行替換,不止匹配每行中的第一次出現;不加 g,表示只對搜尋字串的首次出現進行替換;g 放在命令開頭,表示對正文中所有包含搜尋字串的行進行替換操作
    1. s 表示後面跟著一串替換的命令
    1. % 表示替換範圍是所有行,即全文

統計當前檔案中字串 str1 出現的次數

    :%s/str1/&/gn

刪除正文

  • Vim的初級刪除命令是用 d ,高階刪除命令可以用 正則替換 的方式執行
    :d                              刪除游標所在行
    :3d                             刪除 3:.,$d                           刪除當前行至正文的末尾
    :/str1/,/str2/d                 刪除從字串 str1 到 str2 的所有行
    :g/^\(.*\)$\n\1$/d              刪除連續相同的行,保留最後一行
    :g/\%(^\1$\n\)\@<=\(.*\)$/d     刪除連續相同的行,保留最開始一行
    :g/^\s*$\n\s*$/d                刪除連續多個空行,只保留一行空行
    :5,20s/^#//g                    刪除5到20行開頭的 # 註釋

恢復檔案

  • Vim 在編輯某個檔案時,會另外生成一個臨時檔案,這個檔案的名稱通常以 . 開頭,並以 .swp 結尾。Vim 在正常退出時,該檔案被刪除,若意外退出,而沒有儲存檔案的最新修改內容,則可以使用恢復命令 :recover 來恢復檔案,也可以在啟動Vim時用 -r 選項

選項設定

  • 為控制不同的編輯功能,Vim 提供了很多內部選項。利用 :set 命令可以設定選項。基本語法為
    :set option 設定選項 option
  • 常見的功能選項包括:
    autoindent        設定該選項,則正文自動縮排
    ignorecase        設定該選項,則忽略規則表示式中大小寫字母的區別
    number            設定該選項,則顯示正文行號
    ruler             設定該選項,則在螢幕底部顯示游標所在行、列的位置
    tabstop           設定按 Tab 鍵跳過的空格數。例如 :set tabstop=n,n 預設值為 8
    mk                將選項儲存在當前目錄的 .exrc 檔案中

分屏

  • :vsplit(可用縮寫 :vsp) 左右分屏
  • :split(可用縮寫 :sp) 上下分屏
  • ctrl + w + hjkl 視窗之間移動
  • ctrl + w + w 逆時針遍歷
  • ctrl + w = 讓所有的屏都有一樣的高度;
  • ctrl + w + 增加高度;
  • ctrl + w - 減少高度。
  • 另外,也可以在終端裡啟動vim時就開啟分屏操作
  • vim -On file1 file2… 開啟 file1 和 file2 ,垂直分屏
  • vim -on file1 file2… 開啟 file1 和 file2 ,水平分屏

標籤頁

  • Vim的標籤(Tab)頁,類似瀏覽器的標籤頁,一個標籤頁開啟一個Vim的視窗,一個Vim的視窗可以支援N個分屏
    :tabnewVim中新建一個標籤
    :tabnew filename 如果要在新建標籤頁的同時開啟一個檔案,則可以在命令後面直接附帶檔案路徑
  • Vim中的每個標籤頁有一個唯一的數字序號,第一個標籤頁的序號是0,從左向右依次加一。關於標籤頁有一系列操作命令,簡介如下
    :tN[ext]                跳轉到上一個匹配的標籤
    :tabN[ext]              跳到上一個標籤頁
    :tabc[lose]             關閉當前標籤頁
    :tabdo                  為每個標籤頁執行命令
    :tabe[dit]              在新標籤頁裡編輯檔案
    :tabf[ind]              尋找 'path' 裡的檔案,在新標籤頁裡編輯之
    :tabfir[st]             轉到第一個標籤頁
    :tabl[ast]              轉到最後一個標籤頁
    :tabm[ove]  N           把標籤頁移到序號為N位置
    :tabnew [filename]      在新標籤頁裡編輯檔案
    :tabn[ext]              轉到下一個標籤頁
    :tabo[nly]              關閉所有除了當前標籤頁以外的所有標籤頁
    :tabp[revious]          轉到前一個標籤頁
    :tabr[ewind]            轉到第一個標籤頁

外部工具整合

  • Vim可以與許多外部程式整合,功能十分強大,比如 diff , ctags , sort , xxd 等等

diff

  • Linux命令 diff 用來對比兩個檔案的內容,不過對比結果顯示在終端裡,可讀性比較差。結合Vim,在終端裡可以直接輸入命令 vimdiff,後面跟兩個檔名作為引數:
  • vimdiff file1 file2
  • 即可在Vim裡分屏顯示兩個檔案內容的對比結果,對檔案內容差異部分進行高亮標記,還可以同步滾動兩個檔案內容,更可以實時修改檔案內容,方便程度和使用者體驗大大提高。
  • vimdiff a.txt b.txt
  • 如果直接給 -d 選項是一樣的
  • vim -d a.txt b.txt
  • 除了在終端裡開啟vimdiff 功能,也可以在開啟Vim後,在Vim的命令模式輸入相關命令來開啟 vimdiff 功能:
  • :diffsplit abc.txt
  • 如果你現在已經開啟了一個檔案,想Vim幫你區分你的檔案跟 abc.txt 有什麼區別,可以在Vim中用 diffsplit 的方式開啟第二個檔案,這個時 候Vim會用 split(分上下兩屏)的方式開啟第二個檔案,並且通過顏色,fold來顯示兩個檔案的區別
  • 這樣Vim就會用顏色幫你區分開2個檔案的區別。如果檔案比較大(原始碼)重複的部分會幫你摺疊起來。
  • :diffpatch filename
  • 通過 :diffpatch 你的patch的檔名,就可以以當前檔案加上你的patch來顯示。vim會split一個新的屏,顯示patch後的資訊並且用顏色標明區別。
  • 如果不喜歡上下對比,喜歡左右(比較符合視覺)可以在前面加 vert ,例如:
  • :vert diffsplit abc.txt
  • :vert diffpatch abc.txt
  • 看完diff,用 :only 回到原本編輯的檔案,覺得diff的討厭顏色還是在哪裡,只要用 :diffoff 關閉就好了。
  • 還有個常用的diff中的就是 :diffu ,這個是 :diffupdate 的簡寫,更新的時候用

sort

  • Linux命令 sort 可以對文字內容進行按行中的字元比較、排序,但在終端裡使用 sort 命令處理檔案,並不能實時檢視檔案內容。具體用法請自查手冊。

xxd

  • vim+xxd 是Linux下最常用的二進位制文字編輯工具,xxd其實是Vim外部的一個轉換程式,隨Vim一起釋出,在Vim裡呼叫它來編輯二進位制文字非常方便。
  • 首先以二進位制模式在終端裡開啟一個檔案:
  • vim -b filename
  • Vim 的 -b 選項是告訴 Vim 開啟的是一個二進位制檔案,不指定的話,會在後面加上 0x0a ,即一個換行符。
  • 然後在Vim的命令模式下鍵入:
  • :%!xxd
  • 即可看到二進位制模式顯示出來的文字,看起來像這樣:
    0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49  ....9..;..tt.+NI
    0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30  K,......b..4^.0
    0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9  7;'1.".....i.59
  • 然後就可以在二進位制模式下編輯該檔案,編輯後儲存,然後用下面命令從二進位制模式轉換到普通模式:
    :%!xxd -r
  • 另外,也可以調整二進位制的顯示模式,預設是 2 個位元組為一組,可以通過 g 引數調整每組位元組數:
    :%!xxd -g 1         表示每1個位元組為1:%!xxd -g 2         表示每2個位元組為1組(預設)
    :%!xxd -g 4         表示每4個位元組為1