缓冲区中的文本可附属文本属性。可随着文本移动: 如果删除或插入了行,属性会随着附
属的文本移动。在文本属性之前的行上插入/删除文本也是如此。如果插入/删除文本属性
内的文本,文本属性会增加/减少长度。
文本属性的主要用途是文本的高亮。可以看作是语法高亮的替代。它不定义匹配文本的模
式,而是用脚本来设置高亮,可能使用了外部解析器的输出。这只需要做一次,而不是每
次重画屏幕的时候,所以会快许多,而付出的是附属文本属性的最初代价。
文本属性也可用于其它识别文本的目的。例如,给函数名加上文本属性,这样就可以定义
跳转到下个/上个函数的搜索了。
文本属性附属在指定的行和列上,有指定的长度。属性可以跨多行。
文本属性有以下字段:
"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" 可用于空白围绕文本,比如函数名的场合。为假时可
用于文本以特定字符开始和/或结束,比如引号包围字符串的场合。
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}
]])
删除一个文本属性
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;必须为正的数值;使用 "text"
时不应给出 "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}
为零时;文本行结尾
("below" 时最左列) 和虚拟文本间的填充,此处的
空白不高亮
text_wrap "text" 给出且 {col}
为零时,指定文本放不下时行
为:
wrap 回绕文本到下行
truncate 截短文本以放进
省略时使用 "truncate"。
注意
这应用于指定的文本属性,而 'wrap' 选项设
置全局行为
除 "type" 外,所有域均是可选的。
同时提供 "length" 和 "end_lnum" 或 "end_col" 是错误。要么用
"length" 或 "end_col" 用于单行的属性,或者用 "end_lnum" 和
"end_col" 用于跨多行的属性。
如果不给 "length" 也不给 "end_col",属性为零宽度。这意味着它会
随着文本移动,就像位置标记一样。如果该类型指定高亮的话,高亮一
个字符。
属性可以正好在文本的最后字符上结束,也可以在它之后结束。后者如
果在行上附加文本,文本属性会跟着变长,属性类型不置位
"end_incl" 时也是如此。
先在加入属性的缓冲区中寻找 "type"。如果找不到,再使用全局属性
类型。还找不到的话会报错。
virtual-text
使用 "text" 且列不为零时,在文本属性指定的开始位置显示此文本。
缓冲区行的文本会移动以腾出空间。这被称为 "虚拟文本"。
如果列为零,虚拟文本会在缓冲区文本之上、之后或之下显示。
"text_align" 和 "text_wrap" 参数决定如何显示。
要分隔虚拟文本和缓冲区文本,给 "text" 域前面和/或后面加上空白,
或者使用 "text_padding_left" 值。
确保使用高亮以清楚告知用户这是虚拟文本,否则出现了不能编辑的文
本会很让人混淆。使用 "above" 时要明确此文本属于下面的文本行,
而使用 "below" 时要明确此文本属于上面的文本行。
此文本会显示,但不是实际缓冲区行的一部分,光标也不能放置其上。
鼠标点击此文本会移动光标到文本之后的第一个字符,或者行末尾的字
符。
文本中的任何制表符和其它控制字符会被替换为空格 (理据: 否则很难
计算文本的尺寸)。
会选择负数的 "id" 并返回。
提供带 text 的文本属性的支持之前,可以使用负数 "id",但很罕
见。现在负数 "id" 专为带 text 的文本属性保留,给出负数 "id" 会
报错。一旦缓冲区加入了有 "text" 的文本属性,任何其它的文本属性
如果使用负数 "id" 会报错 E1293 。 如果先使用了负数 "id",之
后使用了带 "text" 的文本属性,则会报错 E1339 。
也可用作 method :
GetLnum()->prop_add(col, props)
prop_add_list()
prop_add_list({props}
, [{item}
, ...])
类似于 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,如果没有 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()
prop_find({props}
[, {direction}
])
搜索 {props}
指定的文本属性:
id 带此 ID 的属性
type 带此类型名的属性
both "id" 和 "type" 必须同时匹配
bufnr 在其中搜索的缓冲区;如果给出必须用 "lnum" 和
"col" 指定开始位置;如果省略使用当前缓冲区
lnum 从此行开始 (省略时从光标所在行开始)
col 从此列开始 (省略且给出 "lnum" 时: 使用列 1,否
则从光标开始)
skipstart 不寻找开始位置所在的匹配
"id" 或 "type" 之一匹配时,属性匹配。
{direction}
可以是 "f" 用于正向,"b" 用于反向。如果省略执行正
向搜索。
如果找到匹配,返回字典,其项和 prop_list() 相同,另有 "lnum"
项。如果没找到匹配,返回空字典。
prop_list({lnum}
[, {props}
]) prop_list()
返回行 {lnum}
上的所有文本属性的列表。
{props}
支持以下可选项目:
bufnr 使用此缓冲区,否则使用当前缓冲区
end_lnum 返回 {lnum}
和 {end_lnum}
(闭区间) 之间所有行
的文本属性。
负值是相对于缓冲区末行的位移;-1 指向缓冲区末
行。
types 属性类型名的列表。只返回匹配其中之一类型名的文
本属性。
ids 属性标识符列表。只返回带有其中之一标识符的文本
属性。
属性以开始列和优先级排序。每个属性是带下列项的字典:
lnum 起始行号。仅当返回 {lnum}
和 {end_lnum}
之间的
文本属性时才存在。
col 开始列
length 以字节计的长度,如果包含换行符加一
id 属性 ID
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()
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" 或提供的类型名之一匹配则属性匹配。
如果缓冲区 "bufnr" 不存在会报错。
如果缓冲区 "bufnr" 未载入,什么都不会发生。
返回删除的属性个数。
也可用作 method :
GetProps()->prop_remove()
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}
。如果带类型 {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()
prop_type_list([{props}
]) prop_type_list()
返回掺属性类型名的列表。
{props}
可以包含 "bufnr" 项目。如果给出,使用来自此缓冲区的属
性类型而不是全局属性类型。
Vim 会尽力保持文本属性在原先附属的文本上。插入或删除文本后,属性会相应地移动。
当文本删除后导致文本属性不再包含任何文本,会删除文本属性。不过,定义时就是零宽
度的文本属性会保留,除非整行都被删除。
E275
卸载缓冲区时,所有的文本属性都消失了。没有办法把属性保存在文件里。你可以重建它
们。缓冲区隐藏时,保留文本所以也保留文本属性。不可以给卸载的缓冲区增加文本属
性。
使用替换模式时,在相同的字符位置上保留文本属性,虽然字符本身发生了改变。
要在文本有改动后更新文本属性,用 listener_add() 安装回调。例如,如果你的插件
进行拼写检查,可以用回调为改动过的文本更新拼写错误。Vim 会移动改动文本下方的属
性,这样它们还能高亮相同的文本,你不需要自己去更新。
不更新或复制文本属性列:
- 通过 setline() 或 Lua、Tcl 或 Python 等界面设置行时,Vim 不知道插入或删除
的是什么文本。
- 使用 :move 这样接受上下文以外的文本行的命令时。
vim:tw=78:ts=8:noet:ft=help:norl: