缓冲区中的文本可附属文本属性。可随着文本移动: 如果删除或插入了行,属性会随着附
属的文本移动。在文本属性之前的行上插入/删除文本也是如此。如果插入/删除文本属性
内的文本,文本属性会增加/减少长度。
文本属性的主要用途是文本的高亮。可以看作是语法高亮的替代。它不定义匹配文本的模
式,而是用脚本来设置高亮,可能使用了外部解析器的输出。这只需要做一次,而不是每
次重画屏幕的时候,所以会快许多,而付出的是附属文本属性的最初代价。
文本属性也可用于其它识别文本的目的。例如,给函数名加上文本属性,这样就可以定义
跳转到下个/上个函数的搜索了。
文本属性附属在指定的行和列上,有指定的长度。属性可以跨多行。
文本属性有以下字段:
        "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'})
        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",且会自动设为负
                                数;否则使用零
                                                         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' 选项设
                                置全局行为
                除 "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)
                返回类型:  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,如果没有 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]])
{lnum} [, {lnum-end} [, {props}]])            prop_clear() 
                删除所有行 {lnum} 上的文本属性。
                如果给出 {lnum-end},删除从行 {lnum} 到 {lnum-end} (闭区间) 所
                有的文本属性。
                如果 {props} 包含 "bufnr" 项目,使用此缓冲区,否则使用当前缓冲
                区。
                也可用作  method :
                        GetLnum()->prop_clear()
                返回类型:  Number 
prop_find({props} [, {direction}])                       prop_find() 
                搜索 {props} 指定的文本属性:
                   id           带此 ID 的属性
                   type         带此类型名的属性
                   both         "id" 和 "type" 必须同时匹配
                   bufnr        在其中搜索的缓冲区;如果给出必须用 "lnum" 和
                                "col" 指定开始位置;如果省略使用当前缓冲区
                   lnum         从此行开始 (省略时从光标所在行开始)
                   col          从此列开始 (省略且给出 "lnum" 时: 使用列 1,否
                                则从光标开始)
                   skipstart    不寻找开始位置所在的匹配
                "id" 或 "type" 之一匹配时,属性匹配。
                {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          属性标识符列表。只返回带有其中之一标识符的文本
                                属性。
                属性以开始列和优先级排序。每个属性是带下列项的字典:
                   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" 或提供的类型名之一匹配则属性匹配。
                如果缓冲区 "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)
                返回类型:  Number 
prop_type_change({name}, {props})                        prop_type_change() 
                修改已有的文本属性类型的属性。如果带此名的属性不存在则报错。
                {props} 参数可见  prop_type_add() 。
                也可用作  method :
                        GetPropName()->prop_type_change(props)
                返回类型:  Number 
prop_type_delete({name} [, {props}])                     prop_type_delete() 
                删除文本属性类型 {name}。如果带类型 {name} 的文本属性还在使用
                中,它们不再有效,而且也不能依名字删除。
                {props} 可以包含 "bufnr" 项目。如果给出,删除来自此缓冲区的属
                性类型而不是全局属性类型。
                如果找不到文本属性类型 {name},不报错。
                也可用作  method :
                        GetPropName()->prop_type_delete()
                返回类型:  Number 
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: