1. 程式人生 > 其它 >vim 從嫌棄到依賴(2)——vim 模式

vim 從嫌棄到依賴(2)——vim 模式

在上一篇文章中我們獲取到了neovim 並對它進行了基礎配置。現在已經具備一般編輯器的基本功能了。讓我們先學會如何使用vim基本功能進行編輯,後面再看如何進行配置,以達到某某IDE或者編輯器的效果

vim 為何高效

這裡我們先聊聊vim為何高效。一般進行編輯工作,不管是使用Word,記事本,寫PPT,對於文字的操作無外乎這麼幾種操作

  • 移動游標到指定位置
  • 輸入
  • 刪除
  • 替換(刪除 + 輸入)

而vim之所以高效就是將這幾個部分分解為幾個模式,不同的模式針對這些場景進行了一些優化。下面是幾個簡單的示例

  1. 將多行文字合併為1行

  2. 刪除前5行

  3. 將每行後面的數字+1

這些操作先賣個關子,暫時不去管他們,接下來簡單說說vim的幾種模式,然後瞭解一下移動游標的一些命令,最後提供一個能描述vim操作邏輯的公式

vim的幾種模式

vim主要分為一下幾個模式

  • 普通模式 (normal mode)
    不出意外的話,在使用vim的時候大部分時間停留在普通模式下,並且很多操作都是在普通模式下完成的,例如上述的幾個例子全都是在普通模式下完成的。移動游標、切換模式都是在普通模式下進行的

  • 插入模式 (insert mode)
    插入模式主要用來編輯文字,在該模式下輸入的字元都會作為文字的一部分進行儲存,在該模式下可以進行文字的編輯操作

  • 可視模式(visual mode)
    該模式主要用來選擇一部分文字,實現的功能跟用滑鼠選中一段文字一樣,後續可以輸入命令針對被選中的文字進行處理

  • 命令列模式(command mode)
    可以在普通模式和可視模式下輸入 :

    進入命令列模式,嚴格意義上來說,它並不是一個真正的模式。許多複雜的操作其實都可通過一個簡單的命令來完成。在命令列中,我們可以執行 vim 自帶的命令,也可以執行自定義的命令(例如很多外掛都有一些自定義命令)。例如使用 :w 來將緩衝區中的內容寫入一個檔案中,或者使用:q 來退出vim。

vim 移動游標的幾種方式

移動游標可以說是vim 中所有操作裡面最基礎的操作了。因為 刪除, 輸入 和 替換 這三個操作都是以游標所在位置為基礎做的。可以說,高效的文字處理大多依賴於游標移動的效率,而如何高效的把游標移動到 “目標” 處是一個不小的學問。

一般來說普通的編輯器移動游標的方式都是通過手去移動滑鼠,通過滑鼠來定位到游標要移動的位置,這麼做並不高效。原因是在移動滑鼠的過程中涉及到將手由鍵盤移開,將手放到滑鼠上、找到對應位置然後移動游標,最後再將手由滑鼠移動到游標上。這些動作不僅打斷了鍵盤輸入,同時也打斷了我們輸入的思路。要做到高效移動游標首要的就是手不要離開鍵盤(儘量不要大範圍的移動手)。

vim 的普通模式完美的解決了這個問題,在普通模式下提供了豐富的操作來移動游標,下面列舉一些常用的

  • h: 向前移動一個字元
  • l: 向後移動一個字元
  • j: 向下移動一行
  • k: 向上移動一行
  • b: 向前移動一個單詞
  • w: 向後移動一個單詞
  • e: 移動游標到單詞尾部
  • ^: 移動游標到行首第一個非空字元處
  • $: 移動游標到行末最後一個非空字元處
  • gg: 移動游標至檔案首行的首個非空格位元組
  • G: 移動游標至整個文字最後一行的首個非空格位元組()
  • %: 移動游標到匹配括號的另一端
  • 0: 移動游標至行首

說句題外話,vim 使用 h j k l 來代替 ← ↓ ↑ → 主要是因為當年建立 vi 的時候鍵盤張這樣

如果僅僅使用上述介紹的內容進行移動游標,一次移動一個字元、一個單詞、一行,這效率也太低了,無法處理需要大幅度跳轉游標的需求。這裡介紹一個公式

數字 + 移動游標

例如上述介紹的移動游標的方式都可以採用這個公式。前面的數字表示按同意的操作移動游標的次數,例如 2w 表示向後移動兩個單詞,3j 表示向下移動3行。

我們把這個公式總結為

motion = [數字] + 移動游標

上述公式可以理解為 motion就是定義瞭如何移動游標

vim 基礎操作之刪除和替換

移動游標之後,接下來應該就是進入輸入模式進行輸入操作,但是這裡我們先不談輸入模式。其實在忽略在輸入模式下的各種操作技巧,輸入模式中剩下的就是輸入各種字元完成輸入操作,相對比較基礎,這裡先不談它。我們先來說說在普通模式下的刪除和替換操作。

刪除操作使用 d(你可以理解為英文單詞 delete 的首字母),替換操作使用 c(也就是 change)

我們輸入 d 或者 c 發現操作卡住了,其實這個時候vim在等使用者輸入對應的範圍即 motion ,表示針對哪個範圍的文字進行該操作,這裡我們引入第二個公式

operate = operator + motion

公式可以理解為,一個操作等於我們想要多多大範圍的文字進行何種操作。例如cw 表示針對一個單詞進行替換操作,d2w 表示對游標後2個單詞進行刪除操作,這麼寫也比較符合我們平時使用的日常語言,例如 d2w = delete 2 words (刪除兩個單詞)

  • 示例: 使用 c2w 刪除兩個單詞並進入插入模式

  • 示例: 使用 d$ 刪除游標後至行尾的所有內容

其實類似 dc 的操作還有很多,例如

  • >: 右縮排

  • <: 左縮排

  • =: 自動縮排

  • y: 賦值

  • p: 貼上

  • gu: 變為小寫

  • gU: 變為大寫

  • g~: 反轉大小寫

  • 示例:使用>G 將當前行至檔案尾部的程式碼進行縮排

我們也可以在 operator 前新增數字,表示執行操作重複次數,這裡我們的公式就可以進行改寫

operat = [數字] + operator + motion

例如2dw 表示刪除一個單詞並將該操作執行兩遍。它與前面演示的 d2w 能達到相同的操作,但是含義不同。d2w 表示一次刪除兩個字元。理解了這個,這裡我提出一個簡單的問題 2d2w 的等效操作是哪兩個呢,歡迎評論區給出。

以行為單位的操作

例如我們要刪除一行,根據以上學習的內容可以想到使用 dj ,但是實際嘗試的時候發現它刪除了兩行。我們還可以想到先使用 0將游標移動到行首,然後使用 d$ 刪除整行,但是會發現它會留下一個空白行。

如果想針對行本身進行操作的話,需要將同樣的操作同時按兩下,即dd 表示刪除一行,>> 表示縮排當前行。這裡我們可以擴充套件一個公式

operat = [數字] + 2 * operator

即重複按下兩次同樣的操作命令表示針對行進行操作,前面加上數字表示重複多少次。舉幾個例子

  • 5dd 刪除5行
  • 4>> 將4行程式碼進行縮排
  • 2cc 更改接下來的兩行,並進入插入模式

最後的總結

本篇到這裡就結束了,最後做一下總結,我們提到幾個公式

motion = [數字] + 移動游標
operat = [數字] + operator + motion
operat = [數字] + 2 * operator

根據這些公式我們可以根據具體情形自由發揮想象。它是vim的基礎也是體現它高效的一個地方。

另外還介紹了一些常用的移動游標的方式和常用的操作符,這裡再次將他們列舉出來以供查閱
幾種常用motion

motion 含義
h 左移
j 下移
k 上移
l 右移動
w 向後移動一個詞
b 向前移動一個詞
e 移動游標至詞末
$ 移動游標至行末
0 移動游標至行首
^ 移動游標至本行首個非空格位元組
gg 移動游標至檔案首行的首個非空格位元組
G 移動游標至整個文字最後一行的首個非空格位元組()
% 移動游標到匹配括號的另一端

幾種常用操作符

operator 含義
c 修改,刪除當前並切換到insert mode
d 刪除,該命令與motion配置使用,表示刪除游標移動過的所有內容
> 右縮排
< 左縮排
= 自動縮排
y 賦值
p 貼上
gu 變為小寫
gU 變為大寫
g~ 反轉大小寫