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