如何将参数从:命令传递给函数?

时间:2013-04-05 22:42:37

标签: vim

我想写一个命令,这个命令会有这样的格式:

[range]MyCMD[!] [count] [oneArg] [flags]

[range]MyCMD[!] [oneArg] [count] [flags]

类似于

:[range]P[rint] [count] [flags]

:[range]d[elete] [x] {count}

命令MyCMD最终会调用一个函数来完成一些工作。我写了这一行(无效

command! -nargs=+ -range -bang -count=0  MyCMD <line1>,<line2>call MyFUNC(<q-args>, "<bang>","<count>", .... ..)

问题在于,如何处理这些论点:

  • 问题1 我读到了有关帮助的信息,-range-count不能同时使用,但我需要它们。我还看了一些vim命令,比如:delete,:print,当我们使用这些命令时,我们可以同时给出rangecount。另外,如果{count}[count]可用,我发现vim doc有两个相同命令的条目。像:

    :[range]d[elete] [x]    
    :[range]d[elete] [x] {count}
    

:[range]p[rint] [flags]
:[range]p[rint] {count} [flags]

为什么?为什么不只是[count]? (这将是另一个小问题

    根据我的设计,
  • 问题2 ,所有这些参数都是可选的,它们都有默认值(参见下表)。如何将这些参数传递给函数(我检查<q-args> and <f-args>),我如何区分哪个用户输入是哪个参数?例如,用户提供

    :MyCMD 5 g

     5 is count? or arg? 
     g is arg or flag?
     or '5 g' is arg? 
    

这是args的默认值:

    argName | Default value | description
    -------------------------------------
    range   | current line  | this could be get by function xxx ( ) range
    count   | 0             | this could be get by <count>
    bang    | ""            | this is easy too, with <bang>
    arg     | " "           | this argument could have space
    flags   | ""            | no space allowed for flags
    -------------------------------------

感谢。

2 个答案:

答案 0 :(得分:10)

对于复杂的自定义命令,您不能仅仅依赖于Vim有限的解析选项;您可以使用-range来处理范围,但必须自己解析您的参数组合。

:command! -nargs=* -range -bang MyCMD <line1>,<line2>call MyFUNC(<bang>0, <q-args>)

MyFUNC里面(可能只用:function MyFUNC( ... ) range定义,只能调用一次),split()在空格上的参数。或者,您可以定义函数以使用可变数量的参数并使用<f-args>,但请注意函数参数的数量是有限的(到20 IIRC)。

<bang>0是将爆炸转换为布尔值的好方法,通常是你需要的。

答案 1 :(得分:0)

不得不提出棘手的问题。我真的没有任何解决方案,但这是我的发现。

:command! -range -bang -nargs=* MY echo [<bang>0, <line1>, <line2>, <count>, <q-args>]

运行以下方案后:

:MY
[0, 3, 3, -1, '']
:MY!
[1, 3, 3, -1, '']
:%MY
[0, 1, 10, 10, '']
:%MY 4
[0, 1, 10, 10, '4']
:MY 4
[0, 3, 3, -1, '4']
:%MY flag
[0, 1, 10, 10, 'flag']
:MY flag
[0, 3, 3, -1, 'flag']
:%MY 4 flag
[0, 1, 10, 10, '4 flag']

现在使用-count代替-range

:command! -count -bang -nargs=* MY echo [<bang>0, <line1>, <line2>, <count>, <q-args>]

结果:

:MY
[0, 3, 1, 0, '']
:MY!
[1, 3, 1, 0, '']
:%MY
[0, 1, 10, 10, '']
:%MY 4
[0, 1, 4, 4, '']
:MY 4
[0, 3, 4, 4, '']
:%MY flag
[0, 1, 10, 10, 'flag']
:MY flag
[0, 3, 1, 0, 'flag']
:%MY 4 flag
[0, 1, 4, 4, 'flag']

你可以看到它并不容易。我的建议是在您的命令中使用-range。然后通过<q-args>解析\d\+寻找号码。