nvim 添加自定义代码段 snippets

我们在写代码时,会经常使用一些普遍的写法,比如一个 for 循环;或者是一些常用的代码段,比如 datetime 直接输入当前的日期。

1
2
3
4
for (int i = 0; i < n; ++i)
{
    ...
}

luasnip.lua

我们需要添加 luasnip 这个插件,里面定义了常用的代码段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
return {
	"L3MON4D3/LuaSnip",
	-- follow latest release.
	version = "v2.*", -- Replace <CurrentMajor> by the latest released major (first number of latest release)
	build = "make install_jsregexp",
    lazy = true,
    event = "InsertEnter",
    dependencies = {
        "rafamadriz/friendly-snippets", -- this is good!
    },
    config = function ()
        -- for friendly snippets
        require("luasnip.loaders.from_vscode").lazy_load()
        -- for custom snippets
        -- ref: <https://github.com/jmbuhr/quarto-nvim-kickstarter/tree/95c56fb29e0f7222dad0b1a432028bd610ab3dcb>
        require("luasnip.loaders.from_vscode").lazy_load({ paths = { vim.fn.stdpath("config") .. "/snips" } })
    end
}

我把用户自定义的代码段放在 ~/.config/nvim/snips/ 这个子目录。

luasnip.lua 里面提供了一些常用的函数可以用户自定义的 json 文件直接调用,~/.config/nvim/lazy/LuaSnip/lua/luasnip/util/_builtin_vars.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
-- DateTime Related
function lazy_vars.CURRENT_YEAR()
	return os.date("%Y")
end

function lazy_vars.CURRENT_YEAR_SHORT()
	return os.date("%y")
end

function lazy_vars.CURRENT_MONTH()
	return os.date("%m")
end

function lazy_vars.CURRENT_MONTH_NAME()
	return os.date("%B")
end

function lazy_vars.CURRENT_MONTH_NAME_SHORT()
	return os.date("%b")
end

function lazy_vars.CURRENT_DATE()
	return os.date("%d")
end

function lazy_vars.CURRENT_DAY_NAME()
	return os.date("%A")
end

function lazy_vars.CURRENT_DAY_NAME_SHORT()
	return os.date("%a")
end

function lazy_vars.CURRENT_HOUR()
	return os.date("%H")
end

function lazy_vars.CURRENT_MINUTE()
	return os.date("%M")
end

function lazy_vars.CURRENT_SECOND()
	return os.date("%S")
end

function lazy_vars.CURRENT_SECONDS_UNIX()
	return tostring(os.time())
end

function lazy_vars.CURRENT_TIMEZONE_OFFSET()
	return time_util
		.get_timezone_offset(os.time())
		:gsub("([+-])(%d%d)(%d%d)$", "%1%2:%3")
end

用户自定义代码段

在以上配置,我把代码段放在 ~/.config/nvim/snips/。里面的目录结构如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
tree -L 2
.
├── package.json
└── snippets
    ├── css.json
    ├── global.json
    ├── json.json
    ├── markdown.json
    ├── org.json
    ├── quarto.json
    └── tex.json

package.json

在这个配置文件,我们需要针对不同的文件类型,配置相应的代码段。其中,global.json 是所用文件通用。

 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
{
    "name": "snips",
    "engines": {
        "vscode": "^1.11.0"
    },
    "contributes": {
        "snippets": [
            {
                "language": [
                    "markdown",
                    "tex",
                    "html",
                    "quarto",
                    "org"
                ],
                "path": "./snippets/global.json"
            },
            {
                "language": "org",
                "path": "./snippets/org.json"
            },
            {
                "language": "quarto",
                "path": "./snippets/quarto.json"
            },
            {
                "language": "markdown",
                "path": "./snippets/markdown.json"
            },
            {
                "language": [
                    "json"
                ],
                "path": "./snippets/json.json"
            },
            {
                "language": ["css", "scss"],
                "path": "./snippets/css.json"
            },
            {
                "language": "tex",
                "path": "./snippets/tex.json"
            }
    ]
    }
}

org.json

比如,我们需要在 org 的文件快速添加 SCHEDULED 的日期,就需要编辑文件 ~/.config/nvim.20250115.ok/snips/snippets/org.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
    "codeblock": {
        "prefix": ["codeblock", "begin_src"],
        "body": ["#+BEGIN_SRC ${1:bash}", "${2}", "#+END_SRC"]
    },

    "schedule": {
        "prefix": ["sched"],
        "body": [
            "SCHEDULED: <${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_DAY_NAME_SHORT}>"
        ]
    }
}

如此以来,我只需要在 org 类型的文件里面输入 sched 就可以快速插入当前 TODOSCHEDULED

sched
sched

william 支付宝支付宝
william 微信微信
0%