为何Vim自定义LastMod函数无法运行,但单独执行命令却正常?
问题原因与解决方案
这个问题的核心是Vim字符串中的反斜杠转义规则在搞鬼!让我一步步给你拆解:
为什么单独执行命令没问题?
当你在命令行直接敲1,8g/Modified Times:/s/\d\+/\=submatch(0) + 1/时,Vim会把这个命令直接当作Ex命令解析,其中的\d是正则表达式里的“匹配数字”元字符,\+是“匹配一次或多次”的量词,完全符合你的需求,所以能正常把Modified Times:后面的数字加1。
为什么放到函数里就失效了?
你用exe执行的是一个双引号包裹的字符串,而Vim对双引号字符串的处理逻辑不一样:双引号字符串会解析内部的转义序列。也就是说,字符串里的\d会被Vim尝试当作特殊转义字符处理(虽然\d不是Vim预定义的转义序列,但关键是反斜杠会被“消耗”),最终传递给:g命令的正则表达式变成了d+——这显然匹配不到任何数字,所以命令看起来就“失效”了。
两种修复方案
方案1:转义双引号字符串里的反斜杠
把字符串中的每个\都改成\\,这样Vim在解析字符串时会把\\转换为单个\,传递给:g的就是正确的正则表达式了:
autocmd BufWritePre,FileWritePre *vimrc call LastMod() fun LastMod() let l = min([line('$'), 8]) exe "1," . l . "g/Modified Times:/s/\\d\\+/\\=submatch(0) + 1/" endfun
方案2:改用单引号字符串
Vim的单引号字符串是字面量字符串,不会解析任何转义序列,里面的所有字符都会原样传递给exe命令。这种写法更直观,也不容易出错:
autocmd BufWritePre,FileWritePre *vimrc call LastMod() fun LastMod() let l = min([line('$'), 8]) exe '1,' . l . 'g/Modified Times:/s/\d\+/\=submatch(0) + 1/' endfun
现在你再测试这个函数,应该就能正常更新Modified Times:后面的数字了!
内容的提问来源于stack exchange,提问作者Hervey
相关产品推荐
相关产品推荐

