我在入Linux坑之前就已經在Windows下折騰vim配置, 當時是使用GitBash改裝的PosixShell環境做開發, 因為厭倦了Windows下複雜的環境配置. 我的第一份.vimrc在僅僅使用了3個月後便被我拋棄, 雖然當時沒少花時間配置. 至今這份文件還躺在我的舊Nvim配置倉庫的根目錄下.後來在B站看到帕特里柯基老師的視頻, 基於他的Nvim配置抄寫改裝了一個配置, 也就是上一個倉庫. 這份配置文件我用了將近一年. 雖然在用了大概半年的時候我就有了自己重新編寫配置的想法, 卻因為AstroNvim的配置實在太好用, 於是一直咕咕.

直到AstroNvim上個月從V4遷移到V5, 有很多的BreakingChange, 導致這個配置Bug頻發, 我才想起重新寫一份配置. 至今這份配置已經完全替代了之前基於AstroNvim的配置. 我裁減了大部分配置, 只保留了不到30個插件, 啟動速度只有短短的30ms左右(這個啟動時間和機器有關係)

新的配置倉庫已經開放, 也歡迎來抄我的配置或提出Issue什麼的

Nvim Start Page

Editor Workspace

Git Status

0.0 環境配置

網上鮮有對Nvim開發環境配置的介紹, 我自己也走了不少彎路.

首先建立倉庫, 結構如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.
├── init.lua 入口文件
├── lua
│   └── default
│   ├── config
│   │   ├── autocmd.lua 自定義指令
│   │   ├── diagnostics.lua 診斷信息
│   │   ├── keymaps.lua 鍵位映射
│   │   ├── options.lua 選項
│   │   └── preload.lua 預加載配置
│   └── plugins
│   └── plugin.lua 插件放在這個目錄下, 這裡只是示意
├── nvim-debug 配置啟動腳本
├── README
├── stylua.toml Lua格式化
└── venv 調試環境起動器

第一個需要解決的問題是環境隔離. 在新的配置能夠Bootstrap之前, 我們還需要使用老的Nvim配置, 這就需要將Nvim的緩存隔離起來. 因為調試的過程中會大量刪除緩存, 也可能損害原本的緩存.

Note

如果你不是依賴之前的Nvim配置, 而是使用額外的編輯器進行配置, 那麼你不需要看這篇, 因為你不需要環境隔離

Nvim的緩存文件路徑主要由這三個環境變量控制, 因此首要的工作是進行隔離.

1
2
3
XDG_DATA_HOME  # 存放Lazy和插件的倉庫
XDG_STATE_HOME # 存放狀態(?)
XDG_CACHE_HOME # 緩存文件, 如日誌, 崩潰殘留的文件和swap file

Info

以下文章中的文件路徑以倉庫根目錄為/

下面的 /venv 用來啟動一個修改了環境變量的Bash, 調試工作將在這個Shell裡進行.

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /usr/bin/bash

PROJ_ROOT=`pwd`
TEST_ENV=$PROJ_ROOT/nvim-cache
mkdir -p $TEST_ENV/{share,state,cache}

export XDG_DATA_HOME=$TEST_ENV/share
export XDG_STATE_HOME=$TEST_ENV/state
export XDG_CACHE_HOME=$TEST_ENV/cache

export PATH="$PROJ_ROOT:$PATH"

bash

下面的 /nvim-debug 是啟動文件, 在 venv 啟動的調試Shell中輸入 nvim-debug 就能使用當前倉庫配置啟動Nvim

1
2
3
4
5
#! /usr/bin/bash

SCRIPT_DIR=$(dirname "$(realpath "$0")")

nvim -u $SCRIPT_DIR/init.lua $@

現在開始編寫/init.lua, 我的配置使用Lazy作為插件管理器, 事實上大部分的Nvim配置都使用Lazy. 我們現在的init.lua 中會帶有一些”插入性”的代碼, 用來輔助進行環境隔離. 這些代碼在配置穩定下來之後會被刪掉.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
-- DEBUG: set an sepearate environment while debugging
function set_rtpath()
vim.opt.rtp:prepend("/Absolute/Path/To/Your/Dev/Dir") -- 這裡填寫你正在開發的這個工作目錄的絕對路徑
end
-- DEBUG: end env settings

-- DEBUG: Move this when using it
set_rtpath()
-- DEBUG

-- Load user defined settings after Lazy initialization
vim.api.nvim_create_autocmd('User', {
pattern = 'LazyVimStarted',
callback = function()
vim.schedule(function()
-- 這裡是在插件加載之後加載的全局配置, 會覆蓋插件的一些行為
require('default.config.keymaps').apply()
require('default.config.options').apply()
require('default.config.autocmd').apply()
require('default.config.diagnostics').apply()
end)
end,
})

-- set global leader
vim.g.mapleader = ' '
vim.g.maplocalleader = ' '

-- Load preload options
require('default.config.preload').apply()

-- set lazy path
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }
if vim.v.shell_error ~= 0 then
error('Error cloning lazy.nvim:\n' .. out)
end
end ---@diagnostic disable-next-line: undefined-field
vim.opt.rtp:prepend(lazypath)

-- import plugins
require('lazy').setup {
-- all the plugins' configure files should be put under `lua/plugins`
spec = {
{ import = 'default.plugins' },
},
-- }, --[[@as LazySpec]] {
-- Configure any other `lazy.nvim` configuration options here

install = {
colorscheme = { 'catppuccin' },
},
ui = {
backdrop = 100,
border = 'rounded',
},
performance = {
rtp = {
-- disable some rtp plugins, add more to your liking
disabled_plugins = {},
},
},
config = function()
-- apply options and keymaps
-- must be put here as hook because plugin loading is async
-- require('default.config.autocmd')
end,
} --[[@as LazyConfig]]

現在就可以正常編寫和調試Nvim配置了.