Merge pull request #26909 from zeertzjq/vim-9.1.0007

vim-patch:9.1.{0007,0012}: can select empty inner text blocks
This commit is contained in:
zeertzjq 2024-01-06 06:45:11 +08:00 committed by GitHub
commit a18b4af759
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 145 additions and 8 deletions

View File

@ -578,7 +578,8 @@ i] *v_i]* *v_i[* *i]* *i[*
i[ "inner [] block", select [count] '[' ']' blocks. This i[ "inner [] block", select [count] '[' ']' blocks. This
goes backwards to the [count] unclosed '[', and finds goes backwards to the [count] unclosed '[', and finds
the matching ']'. The enclosed text is selected, the matching ']'. The enclosed text is selected,
excluding the '[' and ']'. The |cpo-M| option flag excluding the '[' and ']'. It's an error to select an
empty inner block like "[]". The |cpo-M| option flag
is used to handle escaped brackets. is used to handle escaped brackets.
When used in Visual mode it is made charwise. When used in Visual mode it is made charwise.
@ -596,7 +597,8 @@ i( *vib* *v_ib* *v_i(* *ib*
ib "inner block", select [count] blocks, from "[count] [(" ib "inner block", select [count] blocks, from "[count] [("
to the matching ')', excluding the '(' and ')' (see to the matching ')', excluding the '(' and ')' (see
|[(|). If the cursor is not inside a () block, then |[(|). If the cursor is not inside a () block, then
find the next "(". The |cpo-M| option flag find the next "(". It's an error to select an empty
inner block like "()". The |cpo-M| option flag
is used to handle escaped parenthesis. is used to handle escaped parenthesis.
When used in Visual mode it is made charwise. When used in Visual mode it is made charwise.
@ -610,8 +612,9 @@ a< "a <> block", select [count] <> blocks, from the
i> *v_i>* *v_i<* *i>* *i<* i> *v_i>* *v_i<* *i>* *i<*
i< "inner <> block", select [count] <> blocks, from i< "inner <> block", select [count] <> blocks, from
the [count]'th unmatched '<' backwards to the matching the [count]'th unmatched '<' backwards to the matching
'>', excluding the '<' and '>'. The |cpo-M| option flag '>', excluding the '<' and '>'. It's an error to
is used to handle escaped '<' and '>'. select an empty inner block like "<>". The |cpo-M|
option flag is used to handle escaped '<' and '>'.
When used in Visual mode it is made charwise. When used in Visual mode it is made charwise.
*v_at* *at* *v_at* *at*
@ -640,7 +643,8 @@ i} *v_i}* *i}* *i{*
i{ *v_iB* *v_i{* *iB* i{ *v_iB* *v_i{* *iB*
iB "inner Block", select [count] Blocks, from `[count] [{` iB "inner Block", select [count] Blocks, from `[count] [{`
to the matching "}", excluding the "{" and "}" (see to the matching "}", excluding the "{" and "}" (see
|[{|). The |cpo-M| option flag is used to handle |[{|). It"s an error to select an empty inner block
like "{}". The |cpo-M| option flag is used to handle
escaped braces. escaped braces.
When used in Visual mode it is made charwise. When used in Visual mode it is made charwise.

View File

@ -955,6 +955,13 @@ int current_block(oparg_T *oap, int count, bool include, int what, int other)
} }
} }
// In Visual mode, when resulting area is empty
// i.e. there is no inner block to select, abort.
if (equalpos(start_pos, *end_pos) && VIsual_active) {
curwin->w_cursor = old_pos;
return FAIL;
}
// In Visual mode, when the resulting area is not bigger than what we // In Visual mode, when the resulting area is not bigger than what we
// started with, extend it to the next block, and then exclude again. // started with, extend it to the next block, and then exclude again.
// Don't try to expand the area if the area is empty. // Don't try to expand the area if the area is empty.

View File

@ -402,7 +402,7 @@ func Test_paragraph()
call assert_beeps("normal Vipip") call assert_beeps("normal Vipip")
exe "normal \<C-C>" exe "normal \<C-C>"
close! bw!
endfunc endfunc
" Tests for text object aw " Tests for text object aw
@ -608,7 +608,7 @@ func Test_textobj_quote()
normal $hhyi" normal $hhyi"
call assert_equal('bar', @") call assert_equal('bar', @")
close! bw!
endfunc endfunc
" Test for i(, i<, etc. when cursor is in front of a block " Test for i(, i<, etc. when cursor is in front of a block
@ -640,7 +640,133 @@ func Test_textobj_find_paren_forward()
normal 0di) normal 0di)
call assert_equal('foo ()', getline(1)) call assert_equal('foo ()', getline(1))
close! bw!
endfunc
func Test_inner_block_empty_paren()
new
call setline(1, ["(text)()", "", "(text)(", ")", "", "()()", "", "text()"])
" Example 1
call cursor(1, 1)
let @" = ''
call assert_beeps(':call feedkeys("0f(viby","xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('(', @")
" Example 2
call cursor(3, 1)
let @" = ''
call assert_beeps('call feedkeys("0f(viby", "xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('(', @")
" Example 3
call cursor(6, 1)
let @" = ''
call assert_beeps('call feedkeys("0f(viby", "xt")')
call assert_equal(3, getpos('.')[2])
call assert_equal('(', @")
" Change empty inner block
call cursor(8, 1)
call feedkeys("0cibtext", "xt")
call assert_equal("text(text)", getline('.'))
bwipe!
endfunc
func Test_inner_block_empty_bracket()
new
call setline(1, ["[text][]", "", "[text][", "]", "", "[][]", "", "text[]"])
" Example 1
call cursor(1, 1)
let @" = ''
call assert_beeps(':call feedkeys("0f[viby","xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('[', @")
" Example 2
call cursor(3, 1)
let @" = ''
call assert_beeps('call feedkeys("0f[viby", "xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('[', @")
" Example 3
call cursor(6, 1)
let @" = ''
call assert_beeps('call feedkeys("0f[viby", "xt")')
call assert_equal(3, getpos('.')[2])
call assert_equal('[', @")
" Change empty inner block
call cursor(8, 1)
call feedkeys("0ci[text", "xt")
call assert_equal("text[text]", getline('.'))
bwipe!
endfunc
func Test_inner_block_empty_brace()
new
call setline(1, ["{text}{}", "", "{text}{", "}", "", "{}{}", "", "text{}"])
" Example 1
call cursor(1, 1)
let @" = ''
call assert_beeps(':call feedkeys("0f{viby","xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('{', @")
" Example 2
call cursor(3, 1)
let @" = ''
call assert_beeps('call feedkeys("0f{viby", "xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('{', @")
" Example 3
call cursor(6, 1)
let @" = ''
call assert_beeps('call feedkeys("0f{viby", "xt")')
call assert_equal(3, getpos('.')[2])
call assert_equal('{', @")
" Change empty inner block
call cursor(8, 1)
call feedkeys("0ciBtext", "xt")
call assert_equal("text{text}", getline('.'))
bwipe!
endfunc
func Test_inner_block_empty_lessthan()
new
call setline(1, ["<text><>", "", "<text><", ">", "", "<><>"])
" Example 1
call cursor(1, 1)
let @" = ''
call assert_beeps(':call feedkeys("0f<viby","xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('<', @")
" Example 2
call cursor(3, 1)
let @" = ''
call assert_beeps('call feedkeys("0f<viby", "xt")')
call assert_equal(7, getpos('.')[2])
call assert_equal('<', @")
" Example 3
call cursor(6, 1)
let @" = ''
call assert_beeps('call feedkeys("0f<viby", "xt")')
call assert_equal(3, getpos('.')[2])
call assert_equal('<', @")
bwipe!
endfunc endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab