vi/vim 總結 | emacs evil 使用教程

使用 evil 之前,得了解 vi/vim 的一些基本常識。
命令模式下的遊標是一個方塊,它的當前位置是指塊的最左邊。下圖中當前遊標所在位置是兩個 e 的中間。
在這裏插入圖片描述

模式

命令模式(執行管理任務)

  • 所輸入的內容被解釋成命令,功能包括
    1. 保存文件、執行命令
    2. 移動遊標、剪切、粘貼多行或多個單詞、查找、替換
  • 所輸入的任何字符被解釋成命令
  • 命令模式包含末行模式(last line mode/指令列命令模式)

末行模式

末行模式在命令模式下輸入 : 進入。由於此時光標移動到最後一行,因此得名。

插入模式(向文件中輸入文本)

鍵入所有內容被認爲是文本輸入。

在命令模式下輸入以下命令將進入插入模式。沒有進入插入模式的會註明。

命令 結果
i 在當前遊標位置之前插入文本
I 在當前行的開始處插入文本(非空字符的行首)
a 在當前遊標位置之後插入文本
A 在當前行的結尾處插入文本
o 在當前行下面新建一行
O 在當前行的上面新建一行
s 刪除遊標後的一個字符
S 刪除遊標所在的行(刪除當前行)
r 替換(覆蓋)當前遊標位置之後的一個字符,然後進入命令模式
R 替換(覆蓋)當前遊標位置及後面的若干文本(進入替換模式
cc 刪除當前行內容
cw 刪除遊標所在位置到單詞末尾
ch 刪除遊標位置之前的一個字符
cl 刪除遊標位置之後的一個字符
cj 刪除當前行和下一行
ck 刪除當前行和上一行

提醒,想在下圖行末加個空格時,命令模式下移到最後一個字符,再鍵入 a (原來沒做這個總結時,不知道有向後插入的命令,我都是先鍵入 i,再 C-e 到最後的,邊摁邊想這也太麻煩了。現在再想真的太羞恥了 😒

當然也可以直接 A
在這裏插入圖片描述

可視模式

這個一開始不必掌握,而且能在命令模式下解決的就儘量不進入可視模式解決(使用 C-v 真的很方便)
在命令模式下輸入以下命令進入可視模式

命令 結果
v 逐個字符選擇文本
V 逐行選擇文本
C-v 按照塊的方式選擇文本(忽視行,可以理解爲面向列)
gv 重選上次的高亮區域

高亮選區由兩個端點確定:一個固定的端點,一個活動的端點。
字符 o 可以在不同的的端點之間來回的切換。

其中塊選中的理解可以參考 cmd 下選中文本塊。
在這裏插入圖片描述

當我們選中了一片高亮區域後,可以使用如下命令對高亮區域進行操作:

命令 效果
d 剪切選中文本
c 修改選中文本
r 替換選中文本
I 在選中文本前插入
A 在選中文本後插入
gu 選中區域轉爲小寫
gU 選中區域轉爲大寫
g~ 大小寫互調
> 向右縮進一個單位
< 向左縮進一個單位

比如我有如下這個文本,我想把它快速轉化成列表,就可以用到 C-v 命令
在這裏插入圖片描述
在第四行 C-v 進入可視模式後,使用 k 向上移動到第一行。我們再鍵入 c 刪除選中列,再輸入 .,最後鍵入 Esc 退出。就可以看到結果了。
在這裏插入圖片描述 在這裏插入圖片描述

模式間的切換

任何模式下使用 ESC 將退回到命令模式,實在不行摁兩下。

移動1

因而,在使用命令進行操作的時候,首先要搞清楚的就是要採用哪種操作單位,也就是說,是要操作一個字符,一個句子,一個段落,還是要操作一行,一屏、一頁。單位不同,命令也就不同。只要單位選用得當,命令自然就恰當,操作也自然迅速高效;否則,只能是費時費力。這也可以說是最能體現 Vi/Vim 優越於其它編輯器的地方之一,也是 Vi/Vim 有人愛有人恨的地方之一。

在操作單位確定之後,纔是操作次數,即確定命令重複執行的次數。要正確高效的運用 Vi/Vim 的各種操作,一定要把握這一原則:先定單位再定量。操作對象的範圍計算公式爲:操作範圍 = 操作次數 * 操作單位。比如:5h 命令左移 5 個字符,8w 命令右移 8 個單詞。

操作單位 命令 效果
字符 h
l
左移一個字符
右移一個字符
單詞 w/W
b/B
e/E
移到下一單詞的開頭
移到上一單詞的開頭
移到光標所在單詞末尾
j
k
0
^
g_
$
:n
nG
n+
n-
下移一行
上移一行
移到當前行開頭
移到當前行的首個非空字符
移到當前行末尾
移到當前行末尾
移動到第 n 行
移動到第 n 行
從光標當前行下移 n 行
從光標當前行上移 n 行
句子 )
(
移動到當前句子的末尾
移動到當前句子的開頭
段落 }
{
移動當前段落的末尾(下一個有空行的地方)
移到當前段落的開頭(上一個有空行的地方)
H
M
L
遊標移動到屏幕的第一行
遊標移動到屏幕的中間一行
遊標移動到屏幕的最後一行
C-f
C-b
C-u
C-d
zz
向前滾動一頁
向後滾動一頁
向前滾動半頁
向後滾動半頁
當前行居中
文件 G
gg
:0
:$
移動到文件末尾
移動到文件開頭
移動到文件第一行
移動到文件最後一行

說明:

  1. W、B、E 命令操作的單詞是以空白字符(空格、Tab)分隔的字串
    比如字符串 “str1-str2 str3-str4”
    對 W、B、E 命令來說是兩個單詞
    而對 w、b、e 命令來說則是四個單詞。
  2. 0 爲數字零(zero)
  3. 句子指以 ”.”、”?” 和 ”!” 結尾,後面至少有一個空格或換行符的字符串

複製、粘貼和刪除

以下命令都是在命令模式下進行,並且執行之後還在命令模式

複製

操作單位 命令 效果
字符 yl/vy(visual yank) 複製當前字符
單詞 yiw 複製當前單詞
yy 複製當前行

這一系列的 yank2 操作可以大致總結如下3

  • yl 複製單個字符(好像只支持 ASCII,具體討論可以看給出的鏈接)
  • yiw 複製整個單詞
  • yaw 複製整個單詞(帶空格)
  • yw 複製遊標所在單詞的後半部分
  • yy 複製整行
  • 3yy 複製含當前行在內的下三行
  • yap 複製整個自然段(包括換行符)

剪切

操作單位 命令 效果
字符 x
X
剪切遊標位置後一字符(相當於 DELETE)
剪切遊標位置前一字符(相當於 BACKESPACE)
單詞 dw (更多參考上面的 yank) 剪切當前遊標位置至下一個單詞前的字符
dd
D
d0
d$
剪切遊標所在的行
從遊標位置開始剪切到行尾
從遊標位置剪切至行首
從遊標位置剪切至行尾

用 v 進入可視模式後,選中文本之後可以按 y 進行復制,如果按 d 就表示剪切。

粘貼

命令 說明
p 將複製的單詞粘到遊標後面
複製後的行粘到遊標所在行下面
P 將複製的單詞粘貼到遊標前面
複製後的行粘到遊標所在行上面

刪除

刪除後改變當前模式的命令可以參考 插入模式 小節

操作單位 命令 效果
字符 x
X
剪切遊標位置後一字符(相當於 DELETE)
剪切遊標位置前一字符(相當於 BACKESPACE)
單詞 dw 剪切當前遊標位置至下一個單詞前的字符
dd
D
d0
d$
J
剪切遊標所在的行
從遊標位置開始剪切到行尾
從遊標位置剪切至行首
從遊標位置剪切至行尾
合併遊標所在行及下一行爲一行

其他命令

功能 命令 效果
重複操作 . 重複上次操作
交換相鄰字符或行 xp
ddp
交換光標位置的字符和它右邊的字符
交換光標位置的行和它的下一行
大小寫轉換 ~
guw
gUw
guu
gUU
g~~
將光標下的字母大小寫反向轉換
將光標所在的單詞變爲小寫
將光標所在的單詞變爲大寫
光標所在的行所有字符變爲小寫
光標所在的行所有字符變爲大寫
光標所在的行所有字符大小寫反向轉換

搜索和替換

搜索

下面的 前 是指 h 的方向

命令 說明
/ 從當前位置向後搜索
從當前位置向前搜索
n 搜索下一個
N 反向搜索下一個
* 在文件中向後搜索當前光標所在的單詞
# 在文件中向前搜索當前光標所在的單詞

顯示搜索歷史

q/q?

替換

命令 說明
:s/被換單詞/新單詞/ 替換光標所在行的第一個被換單詞
:s/被換單詞/新單詞/g 替換光標所在行的全部被換單詞
:x,ys/被換單詞/新單詞/ 在x和y行之間替換每一行的第一個被換單詞
:x,ys/被換單詞/新單詞/g 在x和y行之間替換全部被換單詞

:%s/被換單詞/新單詞/ 替換每一行的第一個被換單詞
:%s/被換單詞/新單詞/g 替換每一行中所有被換單詞

如果我們想要替換的字符串中包含 / 怎麼辦呢?
此時我們可以使用分隔符 # 來代替 分隔符 /
:s#vivian/#sky/#
替換當前行第一個 vivian/ 爲 sky/

:%s+/oradata/apras/+/user01/apras1+ (使用 + 來 替換 / )
將 /oradata/apras/ 替換成 /user01/apras1/

爲了防止替換錯了,我們可以在替換前加個提醒
:1,$s/misspelled/spelled correctly/gc
:1,$s/misspelled/spelled correctly/c
c 確認後再替換

標籤

使用 m 創建,`(ESC 下面的那個鍵)訪問。

比如 m a 創建一個叫做 a 的標籤,然後使用 ` a 到達該行。

當然這個只能是在同一個文件內,並且關閉文件再打開後得重新創建。

撤銷

命令模式下

  1. u 撤銷上一次編輯
  2. U 當前行恢復到原始狀態(撤銷對本行的所有操作)
  3. C-r 反反撤銷

重複命令

在命令模式輸入命令之前,可以先輸入一個數字,表示想要執行接下來輸入的命令的次數。

  1. 10j 下移10行
  2. 10l 右移10個字符
  3. 6h 左移6個字符
  4. 3dd 刪除三行

退出

命令 說明
:q 如果修改文件,vi詢問用戶是否保存文件,不保存則退出vi,否則不能退出。
:w 保存當前文件。如果用戶對當前文件沒有寫權限,不能保存文件並收到一條錯誤消息。
:wq 保存並退出,與:wq相同
:q!
:w!
:wq!
!表示直接執行命令,不提供保護措施,不考慮命令是否執行成功。
ZZ 保存並退出,與:wq相同
ZQ 無條件退出,與:q!相同
:x 保存並退出
:w filename 將編輯內容另存到文件 filename 中。啓動vi時未指定文件名,須用此命令保存編輯內容到文件中
:m,nw filename 將 m 行到 n 行部分的內容保存到文件 filename 中
:m,nw >> filename 將 m 行到 n 行的內容添加到文件 filename 的末尾
:e! 打開文件的上一次成功保存的版本。

總結

下圖來自 vi/vim 基本使用方法,侵刪。
在這裏插入圖片描述

參考

Vim 技巧之四大模式_可視模式
linux:vi 替換命令
Linux—vi/vim 複製剪切粘貼以及常用命令小結

補充

這篇文章我感覺有些因小失大了,我自己常用的命令翻來覆去也就 j k dd c-v ~ 那麼幾個。反而這段時間無意中嘗試到了幾個更加有用的,原來壓根不知道的快捷鍵:

  • C-c p (evilnc-comment-or-uncomment-paragraphs):快速註釋某一段代碼
    原來我都是 C-@ 然後 j k 選中要註釋掉的區域,運行 M-x comment/uncomment region 的,無意間發現這個命令心情真是久久難以平復。

  • C-c l (evilnc-quick-comment-or-uncomment-to-the-line):Comment/uncomment to line number by last digit(s) whose value is UNIT (這個不太理解)

  • 如果寫 lisp 程序的話,如下幾個處理括號的命令你一定不能錯過,來自

    • ci( 刪除這對括號裏的所有內容(不包括這對括號)
    • va( 選中這對括號在內的所有內容(包括這對括號)
    • % 在這對括號之間移動

如果你對在 evil 的 insert mode 移動感到不滿的話,或許 Traversing text in Insert mode 這篇帖子和 Evil Mode best practice 會對你有所啓發。

至於如果找到更多有用鍵位,我還不太清楚。大概是 evil-collection 吧。

TODO


  1. 技巧:快速提高 Vi/Vim 使用效率的原則與途徑
    Vi/Vim 中很多命令是針對不同的操作單位而設的,不同的命令對應不同的操作單位。 ↩︎

  2. 爲什麼在 vi 的世界, 拷貝都使用 yank 這個詞, 而不是 copy? ↩︎

  3. https://vi.stackexchange.com/questions/5806/how-can-i-yank-copy-the-single-character-on-which-the-cursor-rests ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章