代码之家  ›  专栏  ›  技术社区  ›  Kent

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

vim
  •  10
  • Kent  · 技术社区  · 11 年前

    我想写一个命令,这个命令的格式如下:

    [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,当我们使用这些命令时,我们可以同时给出 range count 。此外,我发现vim-doc有两个相同命令的条目,如果 {count} [count] 可用。比如:

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

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

      为什么会这样?为什么不只是和 [计数] ? (这将是 另一个小问题 )

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

      :MyCMD 5 g

      • 5是计数吗?还是arg?
      • g是arg还是flag?
      • 还是“5g”是arg?

      以下是参数的默认值:

      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 回复  |  直到 5 年前
        1
  •  12
  •   Ingo Karkat    11 年前

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

        2
  •  1
  •   Peter Rincker    11 年前

    必须提出棘手的问题。我真的没有任何解决方案,但以下是我的发现。

    :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']
    

    正如你所看到的,这并不容易。我的建议是使用 -范围 你的命令。然后解析 <q-args> 通过查找号码 \d\+ .