Neovim 快捷鍵設定
前言
Vim motion 的核心之一就在於直觀且可高度客製化的快捷鍵設定,要想如臂使指般地使用 Neovim,一套精心調教過的快捷鍵絕對是不可或缺的,尤其無論是在 Vim 還是 Neovim 中,都遺留了一些老舊且稍微有些反人類的操作設定,以及缺少了現代人習以為常的方便功能。
所幸, Neovim 的快捷鍵設定相當直觀、便利且強大,你可以透過它來簡化一些繁瑣的操作、使用額外外掛的功能、你甚至可以直接實現一些組合功能,而不需要另外下載功能外掛,我將會在後續的介紹中進行示範。
在本篇裡,我將介紹如何設定 Neovim 的快捷鍵,並分享我的設定。如果想直接複製我的設定文件,可以到這裡(我的 github)來複製完整版的內容。
另外切記,在 Neovim 中,千萬不要去強記任何的快捷鍵,而是將你的習慣告訴 Neovim,讓它成為你的形狀。
建立設定文件與引用
還記得我們在上一篇: Neovim 設定文件結構與基礎功能設定 中提過的文件結構嗎,首先,到 imp/ 中建立這次要使用的設定文件 keymaps.lua。
接著,編輯 init.lua,加入以下的程式碼來引用它:
require("imp/keymaps") |
Leader Key
在 Neovim 中,Leader key是一個通用的快捷鍵前綴,用來做為大部分快捷鍵的起頭,預設為 \ ,有些人喜歡使用 ; 或 , ,而我則比較喜歡使用空白鍵。
編輯 keymaps.lua,加入以下內容:
vim.g.mapleader = " " |
這樣,我們就設定完成了。
如何設定快捷鍵?
在 Neovim 中,我們主要依靠以下兩個 api 來設定快捷鍵:
- vim.keymap.del():刪除快捷鍵。
- vim.keymap.set():設定快捷鍵。
不過,有鑑於 vim.keymap.set 本身就會覆寫原有的快捷鍵,所以其實我沒怎麽用過 vim.keymap.del,以下將著重說明 vim.keymap.set 的使用,如果想看更詳細的說明,也可以使用指令 :h vim.keymap 來查看官方的說明文件。

vim.keymap.set 包含了四個參數:
{mode}:快捷鍵作用的模式,包含 n、i、v、t、c 五個基本模式,可以傳入單個字元如“n",或一個 list 如{"n", "i"}來讓快捷鍵作用在複數模式中。{lhs}:你想設定的快捷鍵。{rhs}:快捷鍵觸發的操作,可以是一系列的按鍵組合、一條指令或是一個 expression。{opts}:快捷鍵的選項表,主要包含:- noremap:設定為
true時,表示這個快捷鍵的映射是非遞迴的。例如,當你同時有快捷鍵A->B和B->C時,如果你將這項設為false,則A就會被映射為C,反之則為B。 - silent:設定為
true時,執行快捷鍵時不會在命令行中顯示訊息。 - expr:設定為
true時,表示{rhs}的內容將做為 expression 求值。 - nowait:設定為
true時,表示立刻執行映射,不等待更多输入。 - desc:為快捷鍵添加描述,用於讓額外外掛(如 which-key)取用來顯示提示訊息。
- buffer:設定為
true時,表示這個快捷鍵只會對當前 buffer 作用。
- noremap:設定為
以上是我有使用過的一些 {opts},其他更多內容可以參考 :h maparg。
來舉個例子吧:
1 | -- Add empty line without get into Insert mode |
在第一個例子中,我將 Normal mode 中的 <CR> 鍵映射成了一段連續的操作 o<Esc>k,如果你很熟悉 Vim 指令的話,應該馬上就能反應過來它的意思:o 新增一行、<Esc> 返回 Normal mode、然後 k 將遊標移回原本的所在行。
也就是說,它會維持遊標的位置,並在下方插入一個空白行。
而在第二個例子中,我將 Insert mode 中的 jj 輸入映射成 <Esc> 鍵,也就是只要我在 Insert mode 時輸入 jj ,就可以退出 Insert mode。另外僅供參考,也有些人會將其設為 jk。
另外,你可能會注意到,<CR> 鍵是什麼?以及,如果我想加入 Ctrl 或 Shift 鍵時,我應該怎麽表示?放心,我也很常忘記,所以在這裡我列出了一些常見的功能鍵的表示方法,以供查詢:
| 鍵 | 符號 | 說明 |
|---|---|---|
| Leader | <leader> |
用於部分快捷鍵的前綴,預設是 \,可自行更改。 |
| Enter | <CR> |
Enter 鍵。 |
| Control | <C- |
Ctrl鍵,例如 <C-n> 表示 Ctrl + n。 |
| Shift | <S- |
Shift 鍵,例如 <S-h> 表示 Shift + h。 |
| Alt | <A- |
Alt 鍵,例如 <A-x> 表示 Alt + x。 |
| Meta | <M- |
Meta 鍵,一般就是指 Alt 鍵。 |
| Escape | <Esc> |
Esc 鍵。 |
| Backspace | <BS> |
退格鍵。 |
| Space | <Space> |
空白鍵。 |
| Tab | <Tab> |
Tab 鍵。 |
| Arrow Up | <Up> |
向上箭頭,可以用類似 <C-UP> 的方式與功能鍵組合。 |
| Arrow Down | <Down> |
向下箭頭。 |
| Arrow Left | <Left> |
向左箭頭。 |
| Arrow Right | <Right> |
向右箭頭。 |
| Delete | <Del> |
Delete 鍵。 |
| Function Key | <F1> to <F12> |
功能鍵 F1 到 F12。 |
keymaps.lua 完整說明
至此,想必你已經可以開始調整屬於你的快捷鍵了,而接下來我將對我的設定內容進行分類介紹,同樣地,完整的設定檔可以到這裡(我的 github)查看,你可以直接複製再根據需求進行調整,但就像我說的,這是我習慣的快捷鍵組合,它不一定適合你,不要去強記任何人的快捷鍵,而是要讓 Neovim 來配合你的習慣。
最好的驗證方法就是,當你設定完快捷鍵之後,你是不是能馬上想起大部分的內容,而不需要一再重新去查看。我個人的習慣是,盡量使用與動作單字相關的字母,例如 Delete 就用 d,Replace 就用 r 之類的。
preliminary setup
首先是一些基本設定:
1 | -- Set Leader key to Space -- |
這裡我首先將 Leader key 設為了空白鍵;接著,因為接下來我們會設定很多的快捷鍵,為了讓文件簡潔一些,我將一些會重複使用的內容保存為本地變數,包含將 vim.keymap.set 存為 keymap,以及將我常用的 {opts} 選項保存為 opts。
這樣,我們就可以透過 keymap("n", "快捷鍵", "映射", opts) 的方式來設定大多數的快捷鍵了。
cursor jumping
在 Neovim 的預設中,<C-u> 和 <C-d> 分別會將遊標向上或下移動半頁,再將遊標當前行捲到頁面頂部(會保留 scrolloff 的行數)。而這個「半頁」的行數是根據你當前視窗的可視行數來動態決定的,例如當你的視窗可以顯示 50 行,那半頁就是 25 行。
像這樣不固定的行數對我來說很煩,所以我決定將它固定在 15 行。以及,我喜歡在每次遊標進行例如翻頁、或搜尋關鍵字等大幅跳行的行為時,將遊標固定在特定位置,以避免找不到遊標在哪。
1 | -- Normal -- |
說明:
- 固定翻頁行數:設定
<C-u>和<C-d>的移動行數為 15 行。 - 移動後的遊標位置:
- zt:將遊標所在行捲到頂部。
- zz:將遊標所在行捲到中間。
- zb:將遊標所在行捲到底部。
- zv:展開遊標所在行的程式碼摺疊。

move in warpline
在 Neovim 中,當一行文字過長而被換行顯示時,在使用普通模式下的 j 和 k 鍵移動時,會跳到實際的下一行或上一行,而不是視覺上的換行。要在視覺行內移動,則必須使用 gj 和 gk 來移動。為了方便,我決定把它們的功能互換。
1 | -- Move in warpline |

normal trick
以下是一些我在 Normal mode 中的自定功能:
1 | -- Add empty line without get into Insert mode |
說明:
<CR>會在下方新增空行且不進入插入模式。<leader>d:Neovim 中使用 d 來刪除文字時會同時將刪除的內容放入剪貼簿中,這有時很煩,所以我多設定了一個快捷鍵,來將不要的內容刪除且不放入剪貼簿中。<leader>r:選中遊標當前所在的單字,並對文件中所有相同的單字進行替換操作。

window navigation
以下是一些自定的視窗管理快捷鍵,包含切換視窗,以及調整視窗大小:
1 | -- Window navigation |
說明:
- 視窗導航:
<C-h>:移動到左側視窗。<C-j>:移動到下方視窗。<C-k>:移動到上方視窗。<C-l>:移動到右側視窗。
- 調整視窗大小:
<C-Up>:增加視窗高度。<C-Down>:減少視窗高度。<C-Left>:減少視窗寬度。<C-Right>:增加視窗寬度。

insert and visual trick
以下是一些我在 Insert 和 Visual mode 中的自定快捷鍵:
1 | -- Insert -- |
說明:
- 插入模式:使用
jj來退出插入模式。 - 縮排改進:在 Visual mode 時,輸入
>或<會增加或減少遊標所在行的縮排,並回到 Normal mode。這不太直覺,所以我將其改為縮排後仍保持原先的選取狀態,這樣就能進行連續縮排了。 - 貼上改進:在 Visual mode 時,輸入
p會將選取的內容與剪貼簿中的內容交換,這太反人類了,所以我將它改成在貼上後仍保持剪貼簿的內容不變,而如果今天我就是要交換內容,則改使用<leader>p。 - 行移動:當在 Visual mode 時輸入
J或K,可以將選取的行下移或上移,這超好用,個人強推。

後記
至此,就是本章的所有內容了,相信你也見識到了 keymaps 的便捷與強大,只要你想,你甚至可以將 h/j/k/l 的移動方式改成 w/a/s/d ,雖然我不建議這麼做就是了。
這份 keymaps.lua 可能會是你將來在使用 Neovim 時最常更動的設定文件,無論是不斷的調教,還是在安裝了眾多的額外外掛後,替外掛的功能設定新的快捷鍵,都可以透過編輯這個檔案,來將各式各樣的功能快捷統一整理在一個文檔當中,相當方便。
而在下一章裡,我們將開始進入到 Neovim 最深遠的巨坑:外掛的安裝與管理。
上一篇: Neovim 設定文件結構與基礎功能設定
下一篇: Neovim 外掛管理工具 —— lazy.nvim


