用纯vimscript代替(不带`:s`)


12

我的vimrc中有以下内容:

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

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

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

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

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

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

Answers:


10

这是您的函数的简化实现,写为substitute()

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

调整搜索模式以品尝。


10

警告您有关意外副作用的原因是因为:substitute它确实会移动光标并覆盖先前的搜索(如果在函数外部使用)。但是,这并不意味着您不应使用它,因为您可以逆转的副作用:substitute。例如,这是我制作的一个函数,它使用替代命令去除尾随空格:

function! StripTrailingWhitespace()
    " Save cursor position
    let l:save = winsaveview()
    " Remove trailing whitespace
    %s/\s\+$//e
    " Move cursor to original position
    call winrestview(l:save)
    echo "Stripped trailing whitespace"
endfunction

请注意,您还可以使用该:mark命令保存光标位置,但这也意味着您将覆盖您决定使用的标记。我以前没有使用过vint,但是关于短绒棉的一个提示是,您可以用一点盐来警告他们。在这种情况下,:substitute确实有副作用,但是可以避免。另外,确实没有更好的方法来进行搜索和替换文件。


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

1
而是使用winsaveview()/ winrestview()而不是cursor()
Christian Brabandt 2015年

1

:s命令是纯Vimscript方法。

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

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

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

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.