首页 > 解决方案 > 对 Vim 的 sed 语法着色文件的这种更改是好的还是破坏性的?

问题描述

概括

原始问题

我在 Vim 的 GitHub 页面上创建了issue #5876来提议对vim/runtime/syntax/sed.vim.

事实上,我创建了一个问题而不是 PR,因为我并不完全相信这种变化不会造成破坏,因此提出了这个问题。

问题在于第 20 行:

syn match sedComment    "^\s*#.*$"

因为只有“全行”评论被着色为评论。在命令之后使用尾随注释(例如,GNU sed 允许)会刺激一些红色背景着色(因为它被语法着色逻辑认为是错误,我猜)。

我认为放宽注释的定义以允许 GNU sed 样式的注释是合理的,原因很简单,该规则的限制较少。

在这方面,我注意到将该行更改为

syn match sedComment    "\s*#.*$"

即只是移除锚^,似乎就足够了。我还尝试通过#在 sed 脚本中放入一些搜索和替换字符串来对其进行测试,看起来还不错。

但是我对 Vim 语法着色文件没有信心,所以我想确保我编辑的正则表达式不会导致误报。

为了说明为什么我对此没有信心,请使用这个单行sed脚本

s/aaa/bbb/#ccc

这里#没有作为注释着色,并且ccc的背景是红色的(就像一个错误?),而只是添加一个空格,给出正确的着色:

s/aaa/bbb/ #ccc

因此,我认为我的编辑工作(或似乎工作)是因为几个语法着色指令之间的优先规则(关于这个带有 的特定示例s/aaa/bbb/#ccc,我认为命令#的结束分隔符s在语言中具有含义,但我不知道;GNU Sedman页面对此没有任何说明)。

编辑

评论中建议的另一个示例如下,其语法着色不会被提议的更改破坏

s/#if !defined(\([^)]*)/#ifndef \1/ # with or without this comment is fine

标签: vimsedsyntax-highlighting

解决方案


我的研究

我终于找到了一些时间来学习:h E410,现在我有了答案。

从那里我读到

1. Keyword
    [...] It will only match with a complete word [...]
2. Match
    This is a match with a single regexp pattern.
3. Region
    This starts at a match of the "start" regexp pattern and ends with a match with the
    "end" regexp pattern.  Any other text can appear in between.  A "skip" regexp
    pattern can be used to avoid matching the "end" pattern.

由于我要更改的行使用语法 2.,

  • 第 1 点不相关,
  • 第 3 点syn match相关的,因为一般而言,what和syn regionmatch之间可能存在重叠。

(顺便说一句,我验证了它syn region使用了一个惰性正则表达式,\_.\{-}之后可能会查看一些示例,以匹配 thestartendregexp 模式之间的内容。)

然后从:h :syn-priority

An item that starts in an earlier position has priority over items that start in later positions.

答案

因此,改变

syn match sedComment    "^\s*#.*$"

syn match sedComment    "\s*#.*$"

不应引入任何语法错误,原因是如果与上述正则表达式匹配的文本实际上不是注释(例如 command 的情况s/#/hash/),则必须在其前面加上一些非注释语法,该语法将由其他syn match/syn region组。由于本场比赛在小组sedComment开始比赛之前开始,因此前者优先于后者。

总之,除非某些内容sed.vim已经被破坏,否则建议的更改不会导致错误的语法着色。

进一步的观察

实际上, 中已经有问题了sed.vim,我建议的编辑并没有解决它(我应该编辑其他行sed.vim来修复它,但我现在有点懒)。

例如,在以下行中,由于a不是有效标志而非法,a它没有得到Error着色。

s/x/y/a

我建议的编辑没有解决这个错误。

出于同样的原因,由于其他一些语法规则在替换命令中的第三个分隔符之后吃 1 个字符,sed因此以下命令中的 GNU--valid 注释颜色不正确

s/x/y/#hello
#     │└───┴─── colored as Error
#     └─ not colored

即使对于sed不允许尾随注释的旧版本,着色也是错误的,因为Error着色也应该包括#。我提议的编辑也没有解决这个错误。

再观察

我提出的更改导致单字母命令被突出显示,就Error好像它们后跟注释一样

p # this is a comment
│ └─────────────────┴─── colored as Comment (ok)
└────── colored as Error (bad)

这又不是恶化,因为当前的sed.vim颜色几乎将上面的整条线作为Error.


推荐阅读