忽略拼写文件中的URL和电子邮件地址


12

有没有办法让vim不将HTTP URL和电子邮件地址标记为拼写错误?或者,更一般地,一种列出有效拼写正则表达式的方法?

Answers:


16

您可以添加自定义语法规则,并@nospell为其指定 关键字,这将告诉Vim不要对该语法匹配应用拼写检查。例如:

:syn match UrlNoSpell "\w\+:\/\/[^[:space:]]\+" contains=@NoSpell

上面的方法适用于文本文件和某些文件类型(例如markdown),但不适用于所有文件类型。

注意,我在这里使用了一个非常简单的正则表达式。有关其他选择,请参见如何从文本中解析URL


对于其他文件类型,您需要做更多的工作。例如,对于python文件,注释pythonComment 来自/usr/share/vim/vim74/syntax/python.vim以下组:

syn match   pythonComment   "#.*$" contains=pythonTodo,@Spell

要覆盖此问题,我们需要执行以下操作:

:syn match UrlNoSpellComment "\w\+:\/\/[^[:space:]]\+" contains=@NoSpell containedin=pythonComment
:highlight def link UrlNoSpellComment Comment

诀窍是添加在我们自定义的语法匹配可包含与先前匹配的语法匹配的列表containedin=它告诉Vim要查找的 UrlNoSpell正则表达式pythonComment匹配。

我们还需要使用highlight来设置正确的颜色,因为这些颜色不是继承的。

您需要在许多地方执行此操作,例如Python字符串:

:syn match UrlNoSpellString "\w\+:\/\/[^[:space:]]\+" contains=@NoSpell containedin=pythonString
:highlight def link UrlNoSpellString String

我们需要2个不同的语法匹配组,因此我们可以应用正确的语法突出显示。

当然,对于其他文件类型,您需要使用其他containedin=语法匹配... AFAIK没有“通用”解决方案,但是在其中查找正确的文件/usr/share/vim/vim74/syntax/*.vim应该不太困难。


注意,上述所有命令必须在语法文件之后执行;有两种方法可以做到这一点:

  • 从命令或键映射,必须每次手动调用它。例如

    fun! NoUrlSpell()
        if &filetype == 'python'
            :syn match UrlNoSpellComment "\w\+:\/\/[^[:space:]]\+" contains=@NoSpell containedin=pythonComment
            :highlight def link UrlNoSpellComment Comment
            :syn match UrlNoSpellString "\w\+:\/\/[^[:space:]]\+" contains=@NoSpell containedin=pythonString
            :highlight def link UrlNoSpellString String
        elseif &filetype == 'ruby'
            " ...
        else
            syn match   pythonComment   "#.*$" contains=pythonTodo,@Spell
        endif
    endfun
    command NoUrlSpell :call NoUrlSpell()
    
  • 将命令放在中~/.vim/after/syntax/[filetype].vim。Vim将拾取这些文件并在默认语法文件之后执行它们(请参见:) :help after-directory


3

马丁Tournoij,否则出色答卷未能像预期的那样,我-可能是由于我的杠杆diraol惊人的python-mode插件,而不是为Python Vim的默认语法文件。

为避免在下方的Python注释,字符串或docstring中突出显示URI,请在python-mode您的用户特定~/.vim/after/syntax/python.vim文件中添加以下简洁明了的代码:

syntax match NoSpellUriPython '\w\+:\/\/[^[:space:]]\+' transparent contained containedin=pythonComment,python.*String contains=@NoSpell

而已。至关重要的是,请注意,这会将马丁回答中的十二行分开压缩为一行。怎么样?小学,我亲爱的基于Vim的Watson。我们增加:

  • transparent指示Vim从其父语法(例如,注释,字符串)继承该子语法的高亮属性的关键字。这使我们能够避免highlight def link为每个子语法组显式地重新声明。
  • contained关键字,防止这个孩子从语法延伸越过其父语法的边界(例如,EOL征求意见,字符串字符串分隔符)。
  • 所有父语法组,以逗号分隔containedin关键字。在.*正则表达式运算符使我们能够巧妙地配合所有的Python字符串语法组(即pythonStringpythonUniStringpythonRawStringpythonUniRawStringpythonDocstring),以最小的痛苦和最大的向前兼容性。

尽管从技术上讲是有效的,但嵌入马丁回答中的vimscript违反了DRY(请勿重复自己)原则。有关更多详细信息,另请参见此类似答案

但是等等... 还有更多。

追求伟大的荣耀

我充分双方Vim的过于天真默认拼写检查恼火第三方插件(例如,Spelunker,无条件地拼写检查整个缓冲区,而不是仅仅代码中的注释和字符串),我已经决定... 真正做一些事情关于那个。 </gasp>

经过充分测试的Vim以下片断智能避免拼写检查所有的Python注释和字符串中的以下内容:

  • URI(如上所述)。
  • CamelCase 身份标识。
  • snake_case 身份标识。
  • UPPERCASE 身份标识。
  • @前缀的标识符(例如@muhdecorator)。
  • "分隔的文件类型文件名(例如"muh_module.py")。
  • :分隔的子字符串(例如,:func:在.func:`re.sub`中)。
  • -分隔的子字符串(例如,re.sub在:func:`re.sub`中)。

~/.vim/after/syntax/python.vim在Vim实际上一次检查一次RightStuff™时,请将以下部分或全部添加到您特定于用户的文件中,并大吃一惊:

" Avoid spell checking URIs.
syntax match NoSpellPythonUri /\v\w+:\/\/[^[:space:]]+/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

" Avoid spell checking both CamelCase-formatted identifiers and uppercase
" identifiers. Since most languages (excluding Raku) prohibit Unicode in
" identifiers, these matches are intentionally confined to ASCII codepoints
" (e.g., "[A-Z]" rather than "[[:upper:]]").
syntax match NoSpellPythonCaps /\v<[A-Z]([A-Z0-9]{-1,}|[a-z0-9]+[A-Z0-9].{-})>/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

" Avoid spell checking snake_case-formatted identifiers.
syntax match NoSpellPythonSnake /\v<\w+_.{-1,}>/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

" Avoid spell checking "@"-prefixed identifiers.
syntax match NoSpellPythonDecorator /\v\@[a-zA-Z].{-}>/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

" Avoid spell checking ":"-delimited substrings.
syntax match NoSpellPythonColons /\v:[^:]+:/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

" Avoid spell checking "`"-delimited substrings.
syntax match NoSpellPythonTicks /\v`[^`]+`/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

" Avoid spell checking '"'-delimited filetyped filenames matched as a
" double-quoted substring containing a filename prefix, a period, and one to
" four characters comprising a filetype.
syntax match NoSpellPythonPath /\v"[^"]+.[^"]{1,4}"/ transparent contained containedin=pythonComment,python.*String contains=@NoSpell

当然,以上所有内容都可以(可能应该)简化为与一个类似于哥斯拉的正则表达式匹配的单行代码,包括我在内的任何人都无法维护甚至阅读。为了所有人的理智,我没有这样做。

如果不是我的人想要制作一个由GitHub托管的Vim插件,将上述内容扩展到其他流行语言,那将是很好的。伙计们,Vim的默认拼写检查实现几乎已经存在。它只需要开源社区的帮助。

在此之前,StackOverflow永远与您同在!


2
在这里写答案时,我有点想出了整个Vim语法突出显示的内容。我并不总是知道我在做什么,说实话,所以尤其是一些上了年纪的答案可能会低于最佳😅
马丁Tournoij

马丁,你太谦虚了。没有您的“破冰”答案,我和许多其他人甚至都不知道从哪里开始。感谢您开始这个编辑聚会!罗马也许不是一天建成的,但至少我们现在可以一拼而过。
Cecil Curry,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.