Đây là lý do tại sao câu hỏi nên có trên SO: kịch bản không tầm thường là bắt buộc ...
" Public Mappings {{{1
onoremap <silent> i% :<c-u>call <sid>SelectFirstPair(1,0)<cr>
xnoremap <silent> i% :<c-u>call <sid>SelectFirstPair(1,1)<cr><esc>gv
onoremap <silent> a% :<c-u>call <sid>SelectFirstPair(0,0)<cr>
xnoremap <silent> a% :<c-u>call <sid>SelectFirstPair(0,1)<cr><esc>gv
" Public Mappings }}}1
"------------------------------------------------------------------------
" Private Functions {{{1
" Note: most functions are best placed into
" autoload/«your-initials»/«omap_any_bracket».vim
" Keep here only the functions are are required when the plugin is loaded,
" like functions that help building a vim-menu for this plugin.
let s:k_pairs = {
\ '(': ')',
\ '[': ']',
\ '{': '}',
\ '<': '>'
\ }
let s:k_begin = '[([{<]'
let s:k_end = '[)\]}>]'
function! s:SelectFirstPair(inner, visual)
" In case we already are in visual mode, we may have to extend the current
" zone if it selects a pair of brackets
if a:visual
let char_b = lh#position#char_at_mark("'<")
if char_b =~ s:k_begin
\ && s:k_pairs[char_b] == lh#position#char_at_mark("'>")
call search('.', 'bW') " previous char
elseif a:inner
" handle case the case "vi%i%i%"
let current_pos = getpos('.')
call setpos('.', getpos("'<"))
call search('.', 'bW') " previous char
let pos_b = getpos('.')
call setpos('.', getpos("'>"))
call search('.', 'W') " next char
let pos_e = getpos('.')
let char_b = lh#position#char_at_pos(pos_b)
let char_e = lh#position#char_at_pos(pos_e)
echomsg "chars = ".char_b.char_e
if char_b =~ s:k_begin
\ && s:k_pairs[char_b] == char_e
call setpos('.', pos_b) " restore start_pos
call search('.', 'bW') " previous char
else
call setpos('.', current_pos) " restore init_pos
endif
endif
endif
" Searching the n outer blocks requested
let cnt = v:count <= 0 ? 1 : v:count
while cnt > 0
let cnt -= 1
let char_c = lh#position#char_at_pos(getpos('.'))
let accept_at_current = char_c =~ s:k_begin ? 'c' : ''
" Begin of the current outer block
if 0 ==searchpair(s:k_begin, '', s:k_end, 'bW'.accept_at_current, 'lh#syntax#skip()')
throw "No outer bloc"
endif
if cnt > 0
call search('.', 'bW') " previous char
endif
endwhile
let char_b = lh#position#char_at_pos(getpos('.'))
normal! v
" End of the outer block
let pos_e = searchpair(s:k_begin, '', s:k_end, 'W', 'lh#syntax#skip()')
let char_e = lh#position#char_at_pos(getpos('.'))
if pos_e == 0
throw "pos_e == 0"
elseif s:k_pairs[char_b] != char_e
echomsg "unbalanced blocks"
endif
" Adjusting the extremities
if a:inner
call search('.', 'b')
normal! o
call search('.')
normal! o
endif
endfunction
" Private Functions }}}1
Lưu ý: Tôi đã sử dụng lại chức năng từ lh-vim-lib - BTW, có một lỗi nhỏ trong phiên bản lh#position#char_at_pos()
in conf: col()
không được sử dụng.
line 13: E15: Invalid expression: E15: Invalid expression: {
(Hoài). Tôi có vim 7.2, mã của bạn có cần 7.3 không? Nhân tiện, trong khi các câu hỏi lập trình thường được chuyển hướng đến SO, câu trả lời kịch bản (cho shell, trình soạn thảo và các chương trình scriptable khác) là phổ biến ở đây.