缓冲区中的文本可附属文本属性。属性可跟随文本移动: 增删行时,属性会随着绑定文本
移动。在文本属性所在行中,在属性之前增删文本时也会如此。在文本属性内部增删文本
时,属性长度会相应增减。
文本属性的主要用途是文本高亮。可看作语法高亮的替代方案。无需定义匹配文本的正则
模式,则脚本设置高亮 (可使用外部解析器的输出)。仅需执行一次绑定,屏幕重绘时不
用重复执行,因此在完成初始设置文本属性的开销后,性能会提高不少。
文本属性也可用于其他文本标识用途。例如,可在函数名上附加文本属性,以便定义搜
索,跳转到下个/上个函数。
文本属性绑定在指定的行列位置,并拥有指定长度,可以跨行。
文本属性包含以下字段:
"id" 用户自定义编号
"type" 属性类型名
属性类型
E971
文本属性一般绑定属性类型名,类型定义文本的高亮风格。属性类型包含以下条目:
"highlight" 所用的高亮组名
"combine" 省略或为 TRUE 时,文本属性高亮会与语法高亮叠加;
为 FALSE 时,文本属性高亮会覆盖语法高亮
"priority" 类型优先级。多个属性有重叠时,优先级高的生效
"start_incl" 为 TRUE 时,在起始位置插入的文本会纳入该文本属性
"end_incl" 为 TRUE 时,在结束位置插入的文本会纳入该文本属性
示例
假定缓冲区第 11 行有如下文本 (不含缩进):
The number 123 is smaller than 4567.
要高亮其中数值部分:
call prop_type_add('number', {'highlight': 'Constant'})
call prop_add(11, 12, {'length': 3, 'type': 'number'})
call prop_add(11, 32, {'length': 4, 'type': 'number'})
尝试在这段文本上方插入或删除行,会看到文本属性始终跟随文本,行号会自动调整。
目标文本两侧有空白字符 (如函数名) 时,置位 "start_incl" 和 "end_incl" 很有用。
如果文本首尾是特定字符 (如包围字符串的引号),则适合设为 false。
func FuncName(arg)
^^^^^^^^ 属性应置位 start_incl 和 end_incl
var = "text";
^^^^^^ 属性应复位 start_incl 和 end_incl
不过有文本增删时,仍可能需要重新解析文本以更新文本属性。但此项工作可异步进行。
内部错误 E967
如果遇到 E967,请通过 Github 提供漏洞报告:
https://github.com/vim/vim/issues/new
管理文本属性类型:
prop_type_add({name}, {props}) 定义新属性类型
prop_type_change({name}, {props}) 修改已有属性类型
prop_type_delete({name} [, {props}]) 删除属性类型
prop_type_get({name} [, {props}]) 获取属性类型配置
prop_type_list([{props}]) 列出属性类型
管理文本属性:
prop_add({lnum}, {col}, {props}) 新增文本属性
prop_add_list({props}, [{item}, ...])
在多个位置新增文本属性
prop_clear({lnum} [, {lnum-end} [, {bufnr}]])
删除全部文本属性
prop_find({props} [, {direction}]) 查找文本属性
prop_list({lnum} [, {props}]) 获取第 {lnum} 行上的文本属性
prop_remove({props} [, {lnum} [, {lnum-end}]])
删除单个文本属性
text-prop-functions-details
prop_add() E965
prop_add({lnum}, {col}, {props})
在指定位置 {lnum},{col} 上绑定文本属性。{col} 按字节计数,首
列为一。
如果 {lnum} 非法,报错。 E966
如果 {col} 非法,报错。 E964
{props} 为字典,支持以下字段:
type 文本属性类型名
length 文本字节长度,仅用于不会跨行的属性;可为零
end_lnum 文本结束行号 (含)
end_col 文本结束位置的后一列;给出 "length" 时不用;
{col} 和 "end_col" 相等且 "end_lnum" 省略或与
{lnum} 相等时,代表零宽度文本属性
bufnr 要绑定属性的缓冲区;省略时,使用当前缓冲区
id 用户自定义属性 ID;必须为正数 E1510 ;
给出 "text" 时,"id" 值忽略,自动分配负数 ID;
否则默认 ID 为零
E1305
text 显示在第 {col} 列之前的虚拟文本,{col} 为零则
显示在该行上方或下方;可在前后填充空白,用于高
亮留白;不可与 "length"、"end_lnum" 和
"end_col" 同时使用。详见 virtual-text 。
E1294
text_align "text" 给出且 {col} 为零时;指定虚拟文本的显示
位置:
after 行尾之后
right 窗口内右对齐 (文本回绕到下一屏幕行
除外)
below 下一屏幕行
above 紧贴本行上方
省略时默认 "after"。每行仅可放置一个 "right"
属性,如果有两个或更多,它们将放在单独的行上,
仍保持右对齐。
text_padding_left E1296
"text" 给出且 {col} 为零时;文本行末尾
("above" 和 "below" 模式下则为最左列) 与虚拟文
本之间的留白宽度,该空白不被高亮
text_wrap "text" 给出且 {col} 为零时,定义文本溢出的处理
方式:
wrap 文本回绕到下行显示
truncate 截断文本以适配窗口
省略时默认 "truncate"。
注意 此字段作用于单个文本属性,而 'wrap' 选项
设置全局行为。"wrap" 值仅当 'wrap' 选项置位时
才生效;'nowrap' 时文本总会在窗口右边缘截断。
除 "type" 外所有字段均可选。
不能同时给出 "length" 与 "end_lnum" / "end_col"。单行属性可以
选用 "length" 或 "end_col",跨多行属性必须用 "end_lnum" 以及
"end_col"。
既不给出 "length" 也不给出 "end_col" 时,属性为零宽度。这意味
着它类似位置标记,会跟随文本移动。所用属性类型指定高亮时,则会
高亮一个字符。
属性可以正好结束在文本最后一个字符处,也可以延伸到该行末尾 (此
时在最后一个字符之后)。在后一种情况下,向该行追加文本时,文本
属性会自动扩展,即使本属性类型不置位 "end_incl" 时也是如此。
"type" 会优先在添加属性的缓冲区中查找。找不到再查找全局属性类
型。仍不存在则报错。
virtual-text
"text" 给出且 {col} 不为零时,在文本属性起始位置绘制该文本。缓
冲区原有文本会向后腾出空间。这被称为 "虚拟文本"。
{col} 为零时,虚拟文本绘制在缓冲区文本的上方、行尾或下方。由
"text_align" 和 "text_wrap" 参数控制。
要区分虚拟文本和缓冲区文本,可在 "text" 字段前后补空白,或配置
"text_padding_left" 值。
务必选用合适高亮,清楚告知用户这是虚拟文本且不可编辑,否则很容
易引起混淆。使用 "above" 时要明确该文本归属下方行,而使用
"below" 时要明确该文本归属上方行。
虚拟文本仅用于展示,不属于实际缓冲区内容,光标也无法定位其上。
鼠标点击时,光标会跳到该文本之后的首个字符,或该行末尾字符。
虚拟文本内的制表符和其他控制字符会转换为空格 (理据: 否则难以计
算文本宽度)。
使用虚拟文本时,函数会分配并返回负数 "id"。
负数 "id" 保留给带 "text" 的文本属性,其他情况下禁止使用。如果
使用,会报错 E1293 。
返回属性 ID (手动指定的 "id" 字段或自动分配的负数 "id")。
也可用作 method :
GetLnum()->prop_add(col, props)
返回类型: Number
prop_add_list({props}, [{item}, ...]) prop_add_list()
类似 prop_add() ,但用于在缓冲区的多个位置绑定文本属性。
{props} 为字典,支持以下字段:
bufnr 要绑定属性的缓冲区;省略时,使用当前缓冲区
id 用户自定义属性 ID;必须为数值;省略时默认为零
type 文本属性类型名
除 "type" 外,其余字段均可选。
第二个参数是项目列表,每个 {item} 为列表,指定一段文本的起止位
置,格式为: [{lnum}, {col}, {end-lnum}, {end-col}]
或: [{lnum}, {col}, {end-lnum}, {end-col}, {id}]
前两项 {lnum} 和 {col} 指定属性绑定文本的起始位置。
后两项 {end-lnum} 和 {end-col} 指定文本结束位置的后一列。
可选第五项 {id} 为此条属性单独指定 ID。省略时,沿用 {props} 中
的 id,如果没有则使用零。
本函数不支持添加带 "text" 字段的文本属性。
示例:
call prop_add_list(#{type: 'MyProp', id: 2},
\ [[1, 4, 1, 7],
\ [1, 15, 1, 20],
\ [2, 30, 3, 30]])
也可用作 method :
GetProp()->prop_add_list([[1, 1, 1, 2], [1, 4, 1, 8]])
返回类型: 无
prop_clear({lnum} [, {lnum-end} [, {props}]]) prop_clear()
删除第 {lnum} 行上全部文本属性。
给出 {lnum-end} 时,删除 {lnum} 到 {lnum-end} (含) 所有行上的
全部文本属性。
{props} 包含 "bufnr" 字段时,使用指定缓冲区,否则默认使用当前
缓冲区。
也可用作 method :
GetLnum()->prop_clear()
返回类型: 无
prop_find({props} [, {direction}]) prop_find()
按 {props} 指定的条件,查找文本属性:
id 匹配该 ID 的属性
type 匹配该类型名的属性
both "id" 和 "type" 必须同时匹配
bufnr 搜索目标缓冲区;给出时,必须提供 "lnum" 和
"col",指定起始位置;省略时,使用当前缓冲区
lnum 搜索起始行 (省略时从光标所在行开始)
col 搜索起始列 (省略且 "lnum" 给出时: 从第 1 列开
始,否则从光标所在列开始)
skipstart 不在起始位置进行匹配
"id" 或 "type" 两者匹配其中之一即可 (除非给出 "both")。
{direction} 可选值为: "f" 正向搜索,"b" 反向搜索。省略时默认正
向搜索。
匹配成功时,返回类似 prop_list() 的字典,但额外包含 "lnum"
字段。如果未找到匹配,返回空字典。
返回类型: dict<any>
prop_list({lnum} [, {props}]) prop_list()
返回列表,包含第 {lnum} 行上的全部文本属性。
{props} 为字典,支持以下可选字段:
bufnr 使用指定缓冲区,默认使用当前缓冲区
end_lnum 返回 {lnum} 到 {end_lnum} (含) 所有行上的全部
文本属性。
可用负值指定相对于缓冲区末行的偏移;-1 指向缓
冲区末行。
types 属性类型名列表。仅返回类型匹配列表中任意一项的
文本属性。
ids 属性 ID 列表。仅返回 ID 匹配列表中任意一项的文
本属性。
返回属性按起始列和优先级排序。每个属性为字典,包含以下字段:
lnum 起始行号。仅当查询 {lnum} 到 {end_lnum} 间多行
文本属性时才存在。
col 起始列
length 字节长度,包含换行符则长度加一
id 属性 ID
text 在 {col} 之前展示的虚拟文本。仅存在于
virtual-text 虚拟文本属性。
text_align virtual-text 的对齐属性。
text_padding_left
virtual-text 的左侧留白宽度。
text_wrap virtual-text 是否使用回绕。
type 属性类型名,类型已被删除则此字段省略
type_bufnr 定义该类型的缓冲区编号;全局类型为 0
start 为 TRUE 时,属性从此行开始
end 为 TRUE 时,属性在此行结束
"start" 为零 (假值) 时,属性起始行在上方,本行属于后续行。
"end" 为零 (假值) 时,属性会延续到下一行。本行末尾的换行符会被
计入。
如果出错,返回空列表。
示例:
" 获取放置在第 5 行的文本属性
echo prop_list(5)
" 获取放置在 4 号缓冲区第 20 行的全部文本属性
echo prop_list(20, {'bufnr': 4})
" 获取放置在第 1 行到第 20 行的全部文本属性
echo prop_list(1, {'end_lnum': 20})
" 获取所有类型为 'myprop' 的文本属性
echo prop_list(1, {'types': ['myprop'],
\ 'end_lnum': -1})
" 获取所有类型为 'prop1' 或 'prop2' 的文本属性
echo prop_list(1, {'types': ['prop1', 'prop2'],
\ 'end_lnum': -1})
" 获取所有 ID 为 8 的文本属性
echo prop_list(1, {'ids': [8], 'end_lnum': line('$')})
" 获取所有 ID 为 10 和 20 的文本属性
echo prop_list(1, {'ids': [10, 20], 'end_lnum': -1})
" 获取在 4 号缓冲区、类型为 'myprop' 且 ID 为 100 的全部文
" 本属性
echo prop_list(1, {'bufnr': 4, 'types': ['myprop'],
\ 'ids': [100], 'end_lnum': -1})
也可用作 method :
GetLnum()->prop_list()
返回类型: list<dict<any>> 或 list<any>
prop_remove() E968 E860
prop_remove({props} [, {lnum} [, {lnum-end}]])
删除第 {lnum} 行内匹配的文本属性。{lnum-end} 给出时,删除
{lnum} 到 {lnum-end} (含) 所有行内匹配的文本属性。
{lnum} 省略时,在全部行中删除匹配的文本属性 (需要遍历全部行,
缓冲区行数很多时会稍慢)。
{props} 为字典,支持以下字段:
id 删除带此 ID 的文本属性
type 删除带此类型名的文本属性
types 删除类型名在此列表内的文本属性
both "id" 和 "type"/"types" 必须同时匹配
bufnr 使用指定缓冲区,而非当前缓冲区
all 为 TRUE 时,删除所有匹配项,而非仅第一项
"type" 和 "types" 只能提供其中一个。 E1295
"id" 或类型名两者匹配其中之一即可 (除非给出 "both")。
如果 "bufnr" 指定的缓冲区不存在,报错。
如果 "bufnr" 指定的缓冲区未加载,无任何操作。
返回被删除的属性数量。
也可用作 method :
GetProps()->prop_remove()
返回类型: Number
prop_type_add({name}, {props}) prop_type_add() E969 E970
新增名为 {name} 的文本属性类型。如果同名类型已存在则报错。无返
回值。
{props} 为字典,支持以下可选字段:
bufnr 仅在指定缓冲区内定义属性类型;可避免命名冲突,
且缓冲区删除时会自动清理缓冲区局部的属性类型。
highlight 所用高亮组名
priority 优先级。单个字符存在多个文本属性时,所属类型的
优先级最高者生效;可取负值,缺省优先级为零
combine 省略或为 TRUE 时,该高亮会与语法高亮叠加;
为 FALSE 时,该高亮会覆盖语法高亮
override 为 TRUE 时,高亮覆盖所有其他高亮,包括
'cursorline' 和可视高亮
start_incl 为 TRUE 时,在起始位置插入的文本会纳入该文本属
性
end_incl 为 TRUE 时,在结束位置插入的文本会纳入该文本属
性
也可用作 method :
GetPropName()->prop_type_add(props)
返回类型: 无
prop_type_change({name}, {props}) prop_type_change()
修改已有文本属性类型的配置。如果相应的属性类型不存在,报错。
{props} 参数同 prop_type_add() 。
也可用作 method :
GetPropName()->prop_type_change(props)
返回类型: 无
prop_type_delete({name} [, {props}]) prop_type_delete()
删除名为 {name} 的文本属性类型。如果仍存在使用此类型的文本属
性,这些属性将失效,且无法通过类型名删除。
{props} 可包含 "bufnr" 字段。给出时,删除指定缓冲区内的属性类
型,而非全局属性类型。
找不到名为 {name} 的文本属性类型时,不报错。
也可用作 method :
GetPropName()->prop_type_delete()
返回类型: 无
prop_type_get({name} [, {props}]) prop_type_get()
返回名为 {name} 的文本属性类型的配置字典。字段同
prop_type_add() 。
找不到名为 {name} 的文本属性类型时,返回空字典。
{props} 可包含 "bufnr" 字段。给出时,使用指定缓冲区内的属性类
型,而非全局属性类型。
也可用作 method :
GetPropName()->prop_type_get()
返回类型: dict<any>
prop_type_list([{props}]) prop_type_list()
返回全部属性类型名组成的列表。
{props} 可包含 "bufnr" 字段。给出时,使用指定缓冲区内的属性类
型,而非全局属性类型。
返回类型: list<string> 或 list<any>
Vim 会尽量保持文本属性绑定在原始文本上。插入或删除文本后,属性会相应移动。
删除文本导致某个文本属性不再包含任何文本时,该属性被删除。但定义为零宽度的文本
属性,除非整行都被删除,仍会保留。多行替换命令合并行时,被删除行上的虚拟文本属
性会自动转移到合并后的目标行。
E275
缓冲区卸载后,所有文本属性都会消失。文本属性无法存入文件。只能重新创建。缓冲区
隐藏时,文本与文本属性都会保留。无法向已卸载的缓冲区添加文本属性。
使用替换模式时,即使字符内容发生变化,文本属性仍保持在相同字符位置。
文本发生变更后,如需更新文本属性,可用 listener_add() 注册回调。例如,拼写检
查插件可在回调里更新变更文本中的拼写错误。Vim 会自动移动变更文本下方的属性,使
其仍然高亮相同的文本,因此这些属性无需更新。
text-prop-cleared
以下情况下,文本属性的列位置不会自动更新或复制:
- 通过 setline() 或 Lua、Tcl 或 Python 等接口设置行内容时,Vim 无法得知哪些
文本被增删。
- 使用 :move 这类将整行文本移出原有位置的命令。
vim:tw=78:ts=8:noet:ft=help:norl: