我的vimrc中有以下内容:

func! AddSpaceBeforeEqual()
  s/\([a-z)_0-9"'\[\]]\)=/ =/ge
endfunc


我正在使用vint擦拭我的vimrc,并收到以下警告:


ProhibitCommandWithUnintendedSideEffect避免具有意外副作用的命令。避免使用:s [ubstitute],因为它会移动光标并显示错误消息。首选更适合脚本的函数(例如search())。对于许多vim命令而言,存在执行相同功能且副作用较少的函数。有关内置函数的列表,请参见:help functions()。 Google Vimscript样式指南


但是,我不认为它们是不使用:s命令进行替换的一种方法。

例如search()函数提供与模式匹配的行,但无法进行替换。
substitute()函数对字符串进行操作,并且不能对整个文件进行替换。

我应该实现我自己的替代方法,还是重写我的函数的更聪明的方法?

#1 楼

这是用substitute()编写的功能的简单实现:

function! AddSpaceBeforeEqualInWholeBuffer()
    let l = 1
    for line in getline(1,"$")
        call setline(l, substitute(line, '\([^= ]\)=', ' =', "g"))
        let l = l + 1
    endfor
endfunction


调整搜索模式以适应口味。

#2 楼

警告您有关意外副作用的原因是因为:substitute确实会移动光标并覆盖先前的搜索(如果在函数外部使用)。但是,这并不意味着您不应该使用它,因为您可以逆转:substitute的副作用。例如,这是我使用替代命令去除尾随空格的功能: ,但这也意味着您将覆盖您决定使用的商标。我以前没有使用过vint,但是关于短绒棉的一个提示是,您可以用一点盐来警告他们。在这种情况下,:mark确实有副作用,但它们是可以避免的副作用。另外,确实没有更好的方法来进行搜索和替换文件。

评论


最后使用的搜索词在离开函数后会自动恢复,因此在函数内部使用它时不需要保存和恢复。参见:help function-search-undo

–马丁·图尔诺伊(Martin Tournoij)
15年12月24日在17:30



而是使用winsaveview()/ winrestview()而不是cursor()

–克里斯蒂安·布拉班特(Christian Brabandt)
2015年12月25日15:16

#3 楼

:s命令是纯Vimscript方法。

我的猜测是警告仅意味着,光标在使用后很可能会错位(您可以使用之前的winsaveview()函数和winrestview()来规避使用后的命令)。另外,您还需要注意可能发生的错误。这通常是通过使用e标志来处理的。另外,还需要注意一些设置,例如gdefault设置,它会反转g标志的含义。

一个人需要注意这些细节,这可能是这些警告的根本原因。但这并不意味着避免使用:s命令。如果要替换当前缓冲区中的内容,则完全可以使用:s命令。

(注意,当然可以遍历所有行并使用search()/ getline()/ setline()方法。但这通常比较慢。)