Vim - 我可以在不编写函数的情况下将多个参数传递给自定义命令吗

Vim - 我可以在不编写函数的情况下将多个参数传递给自定义命令吗

我在 .vimrc 文件中写了以下自定义命令:

command! -nargs=+ Sub :%s/<args>/g

它允许我用一个词替换另一个词,执行方式如下:

:Sub <word>/<new word>

我更喜欢编写带有多个参数的命令,如下所示:

:Sub <word> <new word>

我可以重写命令以接受多个参数吗?

理想情况下我想要这样的东西:

command! -nargs=+ Sub :%s/<arg1>/<arg2>/g

先感谢您。

答案1

自行进行解析

如果你使用:help <q-args>,你会得到一个带引号的字符串,你可以split()分成两个用空格分隔的部分:

command! -nargs=+ Sub execute '%substitute/' . split(<q-args>, ' ')[0] . '/' . split(<q-args>, ' ')[1] . '/g'

我们可以使用一些元编程(call())来避免两次解析printf()

command! -nargs=+ Sub execute call('printf', ['%%substitute/%s/%s/g'] + split(<q-args>, ' '))

这有效,但错误处理仍然不太好(如果你只传递一个参数,它会抱怨E766: Insufficient arguments for printf())。通过将代码提取到中,你将获得更多控制权:function

Vim 可以解析参数

单独的命令:function还允许 Vim 为你解析参数,通过:help <f-args>

command! -nargs=+ Sub call Sub(<f-args>)
function! Sub( ... )
    execute printf('%%substitute/%s/%s/g', a:1, a:2)
endfunction

使用函数,您可以轻松检查参数的数量是否正确:

function! Sub( ... )
    if a:0 != 2
        echo "Need two arguments"
        return
    endif
    ...

函数的缺点是错误(例如模式不匹配、缓冲区不可修改)会导致多行、不友好的错误消息。try...catch必须使用它来派生出一个很好的单行错误消息。

奖金:接下来该怎么做

  • 由于您向用户隐藏了:s命令(以及使用的分隔符),我认为不需要对分隔符进行转义。请使用escape(a:1, '/')而不是a:1/ a:2
  • :help :command-range,您仍然可以默认该命令对整个缓冲区起作用,但也允许传递其他范围。

还要考虑命令是否真的发挥了作用。无论使用哪种解析,参数中的空格都是有问题的,这是原始命令:s没有的缺点。我看到的唯一好处是输入起来更容易一些,但也可以通过使用不完整命令预填充命令行:s并将光标置于中间的映射来实现相同的效果。

相关内容