forked from aniani/vim
patch 9.1.0443: Can't use blockwise selection with width for getregion()
Problem: Can't use a blockwise selection with a width for getregion(). Solution: Add support for blockwise selection with width like the return value of getregtype() or the "regtype" value of TextYankPost (zeertzjq). closes: #14842 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
5e45715084
commit
afc2295c22
@@ -4288,14 +4288,13 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
|
|||||||
The optional argument {opts} is a Dict and supports the
|
The optional argument {opts} is a Dict and supports the
|
||||||
following items:
|
following items:
|
||||||
|
|
||||||
type Specify the region's selection type
|
type Specify the region's selection type.
|
||||||
(default: "v"):
|
See |getregtype()| for possible values,
|
||||||
"v" for |characterwise| mode
|
except it cannot be an empty string.
|
||||||
"V" for |linewise| mode
|
(default: "v")
|
||||||
"<CTRL-V>" for |blockwise-visual| mode
|
|
||||||
|
|
||||||
exclusive If |TRUE|, use exclusive selection
|
exclusive If |TRUE|, use exclusive selection
|
||||||
for the end position
|
for the end position.
|
||||||
(default: follow 'selection')
|
(default: follow 'selection')
|
||||||
|
|
||||||
You can get the last selection type by |visualmode()|.
|
You can get the last selection type by |visualmode()|.
|
||||||
|
@@ -5492,12 +5492,13 @@ getregionpos(
|
|||||||
pos_T *p2,
|
pos_T *p2,
|
||||||
int *inclusive,
|
int *inclusive,
|
||||||
int *region_type,
|
int *region_type,
|
||||||
oparg_T *oa)
|
oparg_T *oap)
|
||||||
{
|
{
|
||||||
int fnum1 = -1, fnum2 = -1;
|
int fnum1 = -1, fnum2 = -1;
|
||||||
char_u *type;
|
char_u *type;
|
||||||
buf_T *findbuf;
|
buf_T *findbuf;
|
||||||
char_u default_type[] = "v";
|
char_u default_type[] = "v";
|
||||||
|
int block_width = 0;
|
||||||
int is_select_exclusive;
|
int is_select_exclusive;
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
@@ -5533,8 +5534,17 @@ getregionpos(
|
|||||||
*region_type = MCHAR;
|
*region_type = MCHAR;
|
||||||
else if (type[0] == 'V' && type[1] == NUL)
|
else if (type[0] == 'V' && type[1] == NUL)
|
||||||
*region_type = MLINE;
|
*region_type = MLINE;
|
||||||
else if (type[0] == Ctrl_V && type[1] == NUL)
|
else if (type[0] == Ctrl_V)
|
||||||
|
{
|
||||||
|
char_u *p = type + 1;
|
||||||
|
|
||||||
|
if (*p != NUL && ((block_width = getdigits(&p)) <= 0 || *p != NUL))
|
||||||
|
{
|
||||||
|
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
*region_type = MBLOCK;
|
*region_type = MBLOCK;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
|
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
|
||||||
@@ -5608,16 +5618,18 @@ getregionpos(
|
|||||||
|
|
||||||
getvvcol(curwin, p1, &sc1, NULL, &ec1);
|
getvvcol(curwin, p1, &sc1, NULL, &ec1);
|
||||||
getvvcol(curwin, p2, &sc2, NULL, &ec2);
|
getvvcol(curwin, p2, &sc2, NULL, &ec2);
|
||||||
oa->motion_type = MBLOCK;
|
oap->motion_type = MBLOCK;
|
||||||
oa->inclusive = TRUE;
|
oap->inclusive = TRUE;
|
||||||
oa->op_type = OP_NOP;
|
oap->op_type = OP_NOP;
|
||||||
oa->start = *p1;
|
oap->start = *p1;
|
||||||
oa->end = *p2;
|
oap->end = *p2;
|
||||||
oa->start_vcol = MIN(sc1, sc2);
|
oap->start_vcol = MIN(sc1, sc2);
|
||||||
if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
|
if (block_width > 0)
|
||||||
oa->end_vcol = sc2 - 1;
|
oap->end_vcol = oap->start_vcol + block_width - 1;
|
||||||
|
else if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
|
||||||
|
oap->end_vcol = sc2 - 1;
|
||||||
else
|
else
|
||||||
oa->end_vcol = MAX(ec1, ec2);
|
oap->end_vcol = MAX(ec1, ec2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the trailing byte of a multi-byte char.
|
// Include the trailing byte of a multi-byte char.
|
||||||
|
@@ -1964,6 +1964,14 @@ func Test_visual_getregion()
|
|||||||
#" using invalid value for "type"
|
#" using invalid value for "type"
|
||||||
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
|
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
|
||||||
call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
|
call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
|
||||||
|
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
|
||||||
|
call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
|
||||||
|
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
|
||||||
|
call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
|
||||||
|
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
|
||||||
|
call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
|
||||||
|
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
|
||||||
|
call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
|
||||||
|
|
||||||
#" using a mark from another buffer to current buffer
|
#" using a mark from another buffer to current buffer
|
||||||
new
|
new
|
||||||
@@ -2542,30 +2550,65 @@ func Test_getregion_invalid_buf()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_getregion_maxcol()
|
func Test_getregion_after_yank()
|
||||||
new
|
func! Check_Results(type)
|
||||||
|
call assert_equal(g:expected_region,
|
||||||
|
\ getregion(getpos("'["), getpos("']"), #{ type: a:type }))
|
||||||
|
call assert_equal(g:expected_regionpos,
|
||||||
|
\ getregionpos(getpos("'["), getpos("']"), #{ type: a:type }))
|
||||||
|
call assert_equal(g:expected_region,
|
||||||
|
\ getregion(getpos("']"), getpos("'["), #{ type: a:type }))
|
||||||
|
call assert_equal(g:expected_regionpos,
|
||||||
|
\ getregionpos(getpos("']"), getpos("'["), #{ type: a:type }))
|
||||||
|
let g:checked = 1
|
||||||
|
endfunc
|
||||||
|
|
||||||
autocmd TextYankPost *
|
autocmd TextYankPost *
|
||||||
\ : if v:event.operator ==? 'y'
|
\ : if v:event.operator ==? 'y'
|
||||||
\ | call assert_equal([
|
\ | call Check_Results(v:event.regtype)
|
||||||
\ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
|
|
||||||
\ ],
|
|
||||||
\ getregionpos(getpos("'["), getpos("']"),
|
|
||||||
\ #{ mode: visualmode() }))
|
|
||||||
\ | call assert_equal(['abcd'],
|
|
||||||
\ getregion(getpos("'["), getpos("']"),
|
|
||||||
\ #{ mode: visualmode() }))
|
|
||||||
\ | call assert_equal([
|
|
||||||
\ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
|
|
||||||
\ ],
|
|
||||||
\ getregionpos(getpos("']"), getpos("'["),
|
|
||||||
\ #{ mode: visualmode() }))
|
|
||||||
\ | call assert_equal(['abcd'],
|
|
||||||
\ getregion(getpos("']"), getpos("'["),
|
|
||||||
\ #{ mode: visualmode() }))
|
|
||||||
\ | endif
|
\ | endif
|
||||||
call setline(1, ['abcd', 'efghij'])
|
|
||||||
|
new
|
||||||
|
call setline(1, ['abcd', 'efghijk', 'lmn'])
|
||||||
|
|
||||||
|
let g:expected_region = ['abcd']
|
||||||
|
let g:expected_regionpos = [
|
||||||
|
\ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
|
||||||
|
\ ]
|
||||||
|
let g:checked = 0
|
||||||
normal yy
|
normal yy
|
||||||
|
call assert_equal(1, g:checked)
|
||||||
|
call Check_Results(getregtype('"'))
|
||||||
|
|
||||||
|
let g:expected_region = ['cd', 'ghijk', 'n']
|
||||||
|
let g:expected_regionpos = [
|
||||||
|
\ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
|
||||||
|
\ [[bufnr('%'), 2, 3, 0], [bufnr('%'), 2, 7, 0]],
|
||||||
|
\ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 3, 0]],
|
||||||
|
\ ]
|
||||||
|
let g:checked = 0
|
||||||
|
call feedkeys("gg0ll\<C-V>jj$y", 'tx')
|
||||||
|
call assert_equal(1, g:checked)
|
||||||
|
call Check_Results(getregtype('"'))
|
||||||
|
|
||||||
|
let g:expected_region = ['bc', 'fg', 'mn']
|
||||||
|
let g:expected_regionpos = [
|
||||||
|
\ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 3, 0]],
|
||||||
|
\ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 3, 0]],
|
||||||
|
\ [[bufnr('%'), 3, 2, 0], [bufnr('%'), 3, 3, 0]],
|
||||||
|
\ ]
|
||||||
|
let g:checked = 0
|
||||||
|
call feedkeys("gg0l\<C-V>jjly", 'tx')
|
||||||
|
call assert_equal(1, g:checked)
|
||||||
|
call Check_Results(getregtype('"'))
|
||||||
|
|
||||||
bwipe!
|
bwipe!
|
||||||
|
|
||||||
|
unlet g:expected_region
|
||||||
|
unlet g:expected_regionpos
|
||||||
|
unlet g:checked
|
||||||
|
autocmd! TextYankPost
|
||||||
|
delfunc Check_Results
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_visual_block_cursor_delete()
|
func Test_visual_block_cursor_delete()
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
443,
|
||||||
/**/
|
/**/
|
||||||
442,
|
442,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user