在Vim中开启拼写检查时,若缺少某个spelllang,就无法消除「Cannot find word list」警告
我已经和Vim搏斗好几天了,想在启用 spell 检查时抑制出现在窗口底部的“无法找到单词列表”警告。
问题在于,除了英语之外,我还需要同时检查多种语言;并且在统一配置中使用的某些系统,可能具备也可能不具备所需的(额外的)单词表。操作系统和Vim版本多样,大多数系统与互联网隔离,由管理员团队管理,因此在所有系统上带来完整的单词表并非可选项。另一方面,在孤立系统上我很可能只需要系统中自带的英语,对我来说只启用英语拼写检查就已经完全可以接受,而在其他系统上再添加其他语言也完全可以。我不想拆分并管理不同的Vim配置——多年前我就犯过这个错误,发现维护几个配置相当繁琐。与此同时,在某一特定系统上仅对可用语言进行拼写检查对所有情况来说都是完全可行的。
不幸的是,每次我为一组语言启用 spell,其中有些语言在系统上并不可用时,我就会看到那条 Cannot find word list "XX.utf-8.spl" or "XX.ascii.spl" 警告,让我很恼火。
我已经在帮助文档和互联网上尝试了所有方法,但都没有成功——警告仍然会出现(不过现在不会再出现创建目录和下载请求):
set spelllang=en,pl
let loaded_spellfile_plugin = 1
autocmd! SpellFileMissing
set eventignore+=SpellFileMissing
我知道可以用Vimscript写一个插件,在开启拼写检查之前检查并只选择可用的语言,但我相信这有点大材小用。一定存在一个简单的解决方案,只是我还没想到。
那么,是否有办法在某些已选择的语言不可用时,抑制或至少隐藏这个恼人且对我来说没用的警告?对我来说,只使用可用语言而不去在意缺失的语言就完全可以。
解决方案
摆脱该警告的唯一方法是加载确实存在的拼写文件。
你可以通过从可用拼写文件列表中构造一个有效的 :help 'spelllang' 值来实现。下面是一段代码片段,应该在所有支持拼写检查的Vim版本(从7.4及以上)中都能工作:
let &spelllang = join(map(globpath(&rtp, "**/*.spl", 0, 1), 'fnamemodify(v:val, ":t:r:r:r")'), ",")
在这里我们…
- 在
:help 'runtimepath'目录下,使用:help globpath()列出所有拼写文件, - 使用
:help map()和:help fnamemodify()将每个文件名简化为其“基名”, - 并用
:help join()将该列表转换为适用于'spelllang'的有效值。
请注意,我们利用了一个小技巧:Vim对同一语言代码多次使用并不在意。我们本可以在最后一步之前清理这个列表,但在8.0之前,这样做并不容易。
如果你所使用的Vim版本大多在8.0及以上,你可以使用 :help uniq() 来实现一个没有怪癖的命令,并用 :help method 让它看起来更好看:
let &spelllang = globpath(&rtp, "**/*.spl", 0, 1)
\ ->map('fnamemodify(v:val, ":t:r:r:r")')
\ ->sort()
\ ->uniq()
\ ->join(",")