Vim - 用于扩展Verilog总线的宏

3

我似乎无法创建一个vim宏来实现以下操作:

源代码:

this_is_a_bus[10:0]
another_bus[2:0]

需要目标:

this_is_a_bus[10]
this_is_a_bus[9]
this_is_a_bus[8]
this_is_a_bus[7]
this_is_a_bus[6]
this_is_a_bus[5]
this_is_a_bus[4]
this_is_a_bus[3]
this_is_a_bus[2]
this_is_a_bus[1]
this_is_a_bus[0]
another_bus[2]
another_bus[1]
another_bus[0]

我试图做的事情: 我可以搜索\d\+:\d\+,并将光标放在第一个数字上,然后使用 yw 将其复制到内存中。但是我似乎无法告诉 Vim 根据寄存器中的数字运行粘贴命令。
我是不是走错了路?有什么建议的方法来创建这样的东西吗?

如果你想要它是动态的,你需要编写函数来实现。比如自动生成[10:3], [20:1], [8:5]等等。虽然vim肯定可以做到,但这是必须的吗?awk或其他脚本语言可以更容易地实现。 - Kent
你为什么想要扩展总线?Verilog 有很多方法可以将多个值分配给单个总线。当我使用 Verilog 时,从来没有必要像这样拆分总线。 - FDinoff
@Kent:不幸的是,在vim中这是必须的,因为其他基础设施都是基于它的。一个函数也很好,但我不熟悉vimrc函数语法。任何帮助都将不胜感激!谢谢 - ygoncho
@FDinoff:你的回答让我感到困惑。在过去的十年中,我一直在使用Verilog,这是一个非常简单的需求。例如,在跟踪分配或其他脚本使用时需要它。当您想要将某个总线的几个位发送到不同的路由时,它也很方便。 :) - ygoncho
1
@ygoncho发布了一个答案,祝你好运。 - Kent
2个回答

3

这里有一个函数,可以通过按下一个按键(在本例中为<F6>)自动进行扩展。

fun! ExpandIt()
    let pat = '^\([^][]\+\)\[\(\d\+\):\(\d\+\)\]\s*'
    let line = getline('.')
    let lnr = line('.')
    if line !~ pat
        return
    endif
    let exestr = substitute(line,pat,'range(\2,\3,-1)','g')
    let text = substitute(line,pat,'\1','g')
    exec 'let range='.exestr
    let result = []
    for i in range
        call add(result, text.'['.i.']')
    endfor
    call append(lnr, result)
    exec lnr'.d'    
endf
nnoremap <F6> :call ExpandIt()<cr>
  • source这个文件,或者将它放入你的vimrc文件。
  • 最后一行创建了一个映射,它允许你在该行按下<F6>进行扩展。
  • 如果该行不是xxxx[number:number]格式,则不会发生任何事情。
  • 我没有检查错误情况,比如xxx[1:10]xxx[000:000]

我做了一个小测试,看起来像这样:

enter image description here


顺便问一下,有没有办法让它适用于带有括号和空格前缀的总线,例如:xxxx [a to b] my_bus[10:0] - ygoncho
@ygoncho,我没听懂你的意思。如果代码行是这样的,输出会是什么? - Kent
xxxx [a 到 b] my_bus[10] \n xxxx [a 到 b] my_bus[9] \n ... 等等。只是第一个正则表达式不能捕获这些类型的公交车。 - ygoncho
1
@ygoncho 哦,我可能明白了,尝试用这个替换func中相应的行 let pat = '^\(.*\)\[\(\d\+\):\(\d\+\)\]\s*$' 我没有测试过,但你可以试试看。 - Kent
完美。非常感谢你。 - ygoncho

1
我会使用宏来完成这个任务。从以下行开始:
this_is_a_bus[10]

然后记录宏:
qqyyp<c-x>q

然后通过@q播放宏。更好的是,我们可以给它一个计数,9@q

宏的解释

  • q{reg} 开始录制宏,并将宏保存到寄存器 {reg} 中,例如: qq
  • yy 复制整行
  • p 将新复制的行粘贴到当前行下方(光标在新行上)
  • <c-x> 会将光标位置后找到的第一个数字减一
  • 在录制宏时按下 q 可以结束录制
  • @{reg} 将播放寄存器 {reg} 中的宏。例如: @q 播放寄存器 q
  • [count]@{reg}: @ 可以接受计数来多次播放宏。例如: 9@q
  • @@ 会重新播放最后使用的 @{reg} 命令。可选地,@@ 也可以接受计数

更多帮助请参见:

:h q
:h @
:h @@
:h ctrl-x

感谢您的评论和解释,然而,正如我的问题所述,虽然这是我不情愿采取的方法 - 我正在寻找更自动化的东西,只需单击一下即可运行由寄存器表示的宏的次数,而不是手动进行(例如,您的解决方案中的9@q)。如果我有很多巴士的列表,并且我想以单个操作扩展它,则您的解决方案存在问题。 - ygoncho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接