10

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

[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。我还发现如果 a {count}or[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是数?还是参数?
    • g是arg还是flag?
    • 或'5 g'是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
    -------------------------------------
    

谢谢。

4

2 回答 2

12

对于复杂的自定义命令,不能只依赖 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是将 bang 转换为布尔值的一个很好的技巧,这通常是您所需要的。

于 2013-04-06T10:03:15.100 回答
1

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

: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\+

于 2013-04-05T23:21:07.693 回答