0
votes

I'm trying to implement Macro to expand Verilog Bus as Vim - Macro to expand verilog bus and this is really working good for one variable.

But I've got the problem because I want to implement multiple bus as the below

Source:

{test[13:10],thisistest[3:0],BUS[2:1]}

Result:

test[13]
test[12]
test[11]
test[10]
thisistest[3]
thisistest[2]
thisistest[1]
thisistest[0]
BUS[2]
BUS[1]

What I tried to do : I made similar function as

fun! split()
    let line = getline('.')
    let result = []
    let list = split(line, ",")
    let length = len(list)

    for i in length
        call ExpandIt(list[length])
    endfor
endf


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 split()<cr>

Could you please let me know what am I supposed to do to go with right way?

1

1 Answers

1
votes

Based on the obvious errors in your added split() function (the function name must be capitalized to avoid E128, you pass an argument to ExpandIt(), but it doesn't take any, length is not iterable by :for), you seem to have a limited understanding of Vimscript, and just try to "make it work" through brute-force attempts. Therefore it was good to ask here on Stack Overflow, but please be aware that just relying on helpful strangers to fix things for you is a lopsided approach, so please use this and future questions to slowly but steadily learn about Vim, to become a master of it yourself!

The following seems to do what you're asking for, by doing the following modifications:

  • fixing the obvious errors listed above
  • collecting the result List in Split() is the right idea, but the actual insertion (:call append()) and deletion of the original line has to be moved there as well, and ExpandIt() has to return the result
  • likewise, ExpandIt() needs to be passed the extracted element instead of directly getting the current line
  • the split() of the line into comma-separated elements needs to drop the surrounding { and }; substitute() can do this.
fun! Split()
    let line = getline('.')
    let result = []

    for l in split(substitute(line, '[{}]', '', 'g'), ",")
        let result += ExpandIt(l)
    endfor

    let lnr = line('.')
    call append(lnr, result)
    exec lnr'.d'
endf

fun! ExpandIt(line)
    let pat = '^\(.*\)\[\(\d\+\):\(\d\+\)\]\s*$'
    if a:line !~ pat
        return
    endif
    let exestr = substitute(a:line,pat,'range(\2,\3,-1)','g')
    let text = substitute(a:line,pat,'\1','g')
    exec 'let range='.exestr
    let result = []
    for i in range
        call add(result, text.'['.i.']')
    endfor
    return result
endf

nnoremap <F6> :call Split()<cr>