You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vim宏实现多Verilog总线展开的问题求助

Hey there, let's fix your Vim script step by step—your core idea works for single buses, but the multi-bus handling has a few key issues in how you loop through items and pass data between functions. Here's the breakdown of what was wrong and the corrected implementation:

Key Issues in Your Original Script

  • Broken loop logic in split(): for i in length tries to loop over a single number (not a valid range), and list[length] references an out-of-bounds index (Vimscript arrays are 0-indexed). Also, you never pass individual bus items to ExpandIt—instead, ExpandIt keeps reading the current line, which won't work for multi-bus input.
  • ExpandIt doesn't accept parameters: It's hardcoded to operate on the current line, but we need it to process specific bus strings from your split list.
  • Unaccounted input format: You didn't handle the surrounding {} in your input, and the original logic appends lines instead of generating a single space-separated output line.

Corrected Vim Script

fun! SplitBuses()
    " Get current line and strip surrounding curly braces
    let original_line = getline('.')
    let stripped_line = substitute(original_line, '^\{\(.*\)\}$', '\1', '')
    
    let all_results = []
    " Split by commas and trim whitespace from each bus item
    for bus_item in split(stripped_line, ',')
        let trimmed_item = trim(bus_item)
        " Collect expanded results from each bus
        call extend(all_results, ExpandBus(trimmed_item))
    endfor
    
    " Replace original line with space-separated expanded items
    call setline('.', join(all_results, ' '))
endf

fun! ExpandBus(item)
    let pat = '^\(.*\)\[\(\d\+\):\(\d\+\)\]$'
    " Return non-bus items as-is if they don't match the pattern
    if a:item !~ pat
        return [a:item]
    endif
    
    " Extract bus name, high index, and low index from the pattern
    let bus_name = substitute(a:item, pat, '\1', '')
    let high = str2nr(substitute(a:item, pat, '\2', ''))
    let low = str2nr(substitute(a:item, pat, '\3', ''))
    
    let expanded = []
    " Handle both high-to-low and low-to-high ranges automatically
    let step = high > low ? -1 : 1
    for idx in range(high, low, step)
        call add(expanded, bus_name . '[' . idx . ']')
    endfor
    
    return expanded
endf

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

What Changed

  1. Clearer function naming: SplitBuses and ExpandBus make the purpose of each function obvious.
  2. Input brace handling: We strip the surrounding {} from your input first to access the inner list of buses.
  3. Proper item iteration: We split the input, trim extra whitespace from each bus item, and pass each one directly to ExpandBus.
  4. Parameterized expansion: ExpandBus takes a single bus string as input, processes it, and returns an array of expanded elements.
  5. Flexible range support: It automatically detects whether to count down (like 13:10) or up (like 0:3) by checking the high/low index order.
  6. Direct line replacement: Instead of appending lines and deleting the original, we join all results into one line and replace the original line directly.

Test It

If you have the line {test[13:10],thisistest[3:0],BUS[2:1]} and hit <F6>, it will turn into:
test[13] test[12] test[11] test[10] thisistest[3] thisistest[2] thisistest[1] thisistest[0] BUS[2] BUS[1]

内容的提问来源于stack exchange,提问作者Carter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:39:19