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 lengthtries to loop over a single number (not a valid range), andlist[length]references an out-of-bounds index (Vimscript arrays are 0-indexed). Also, you never pass individual bus items toExpandIt—instead,ExpandItkeeps reading the current line, which won't work for multi-bus input. ExpandItdoesn'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
- Clearer function naming:
SplitBusesandExpandBusmake the purpose of each function obvious. - Input brace handling: We strip the surrounding
{}from your input first to access the inner list of buses. - Proper item iteration: We split the input, trim extra whitespace from each bus item, and pass each one directly to
ExpandBus. - Parameterized expansion:
ExpandBustakes a single bus string as input, processes it, and returns an array of expanded elements. - Flexible range support: It automatically detects whether to count down (like
13:10) or up (like0:3) by checking the high/low index order. - 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
相关产品推荐
相关产品推荐

