Neovim 一直在迭代更新,本文以 Neovim v0.10.0 版本为基础进行功能演示。
什么是 extmark
按照 :h extmark 描述 Extended marks (extmarks) 是跟踪缓冲区文本变化的的特定位置的注释。位置从 0 开始,位于第一个字符的前方。
     f o o b a r      line contents
     0 1 2 3 4 5      character positions (0-based)
    0 1 2 3 4 5 6     extmark positions (0-based)
相关函数
与 Neovim Extended marks 相关的函数有两个:nvim_buf_get_extmark 和 nvim_buf_set_extmark。
nvim_buf_set_extmark
nvim_buf_set_extmark 的函数签名是:
nvim_buf_set_extmarks({buffer}, {ns_id}, {start}, {col}, {opts})
可以看到函数调用的参数包括 buffer、ns_id、start、col、opts。
buffer 指的是设置 extmarks 对应的缓冲区 ID,ns_id 全称是 name space id, 可以由 nvim_create_namespace 新建。
其中 opts 是一个 Lua table,比如:
vim.api.nvim_buf_set_extmark(
  0,
  vim.api.nvim_create_namespace('test_extmark'),
  28,
  3,
  { end_row = 28, end_col = 5, hl_group = 'TODO' }
)
opts 支持的 Key 值及其含义包括:
id
如果是新建一个 extmark 可以缺省,如果是修改某个已存在的 extmark,需要指定 id.
end_row 和 end_col
指定 extmark 结束的行和列,这里的列指的是行首、行尾或者字符之间,都是从 0 开始。
hi_group
hl_eol
这是一个布尔值,控制 extmark 覆盖的行尾无字符区域是否需要高亮。
virt_text
这是一个列表,其中每一个元素结构是 [text, highlight]。默认是添加在 extmark 开始的行行尾。
示例代码:
vim.api.nvim_buf_set_extmark(4, vim.api.nvim_create_namespace("test_extmark"), 47, 3, {
	end_row = 47,
	end_col = 5,
	hl_group = "TODO",
	virt_text = { { "This is ", "Comment" }, { "hello", "Number" }, { " extmarks", "TODO" } },
})
virt_text_pos
设置虚拟文本的位置,可以设定的值为:
- eol:行尾最后一个字符右边
- overlay: 在 extmark 起始位置显示虚拟文本,覆盖的字符不右移
- right_align: 在窗口最右侧显示
- inline: 在 extmark 起始位置显示虚拟文本,覆盖的字符右移
virt_text_win_col
将 virtual text 展示在 fixed screen line,屏幕中可见的第一行为 0,往下依次加1。
virt_text_hide
hl_mode
设置高亮颜色的模式:
- replace: 默认,只显示 virtual text 颜色
- combine: combine with background text color
- blend: blend with background text color
virt_lins
设置虚拟多行文本,每一行结构是多个 [text, highlight] 组成的列表。
virt_lines_above
当设置虚拟多行文本时,默认是在 extmark 起始行下方,该选项设为 true,可以在上方显示。
virt_lines_leftcol
虚拟多行文本左对齐,绕过 sign 和 行号列
right_gravity 和 end_right_gravity
控制在 extmark 左右侧末端添加字符时 extmark 的位置扩展行为