summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-05-22 16:42:44 +0200
committerChristian Brabandt <cb@256bit.org>2024-05-22 16:42:44 +0200
commit52a6f348874778cf315b47d9e8b5f818f4b97277 (patch)
tree9445db2ad79338de8626f28b473892cc24ff189d
parent95ff39f8e3d5e16d4ef55f47d8f50da29df05f9e (diff)
patch 9.1.0430: getregionpos() doesn't handle one char selectionv9.1.0430
Problem: getregionpos() doesn't handle one char selection. Solution: Handle startspaces differently when is_oneChar is set. Also add a test for an exclusive charwise selection with multibyte chars (zeertzjq) closes: #14825 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--runtime/doc/builtin.txt6
-rw-r--r--src/evalfunc.c28
-rw-r--r--src/ops.c6
-rw-r--r--src/testdir/test_visual.vim59
-rw-r--r--src/version.c2
5 files changed, 87 insertions, 14 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index b9dd4d20bf..4177a01811 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt* For Vim version 9.1. Last change: 2024 May 20
+*builtin.txt* For Vim version 9.1. Last change: 2024 May 22
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4345,8 +4345,8 @@ getregionpos({pos1}, {pos2} [, {opts}]) *getregionpos()*
the offset in screen columns from the start of the character.
E.g., a position within a <Tab> or after the last character.
If the "off" number of an ending position is non-zero, it is
- the character's number of cells included in the selection,
- otherwise the whole character is included.
+ the offset of the character's first cell not included in the
+ selection, otherwise all its cells are included.
Can also be used as a |method|: >
getpos('.')->getregionpos(getpos("'a"))
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 903205ad31..b65df5dd90 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -5793,7 +5793,6 @@ f_getregionpos(typval_T *argvars, typval_T *rettv)
for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
{
- struct block_def bd;
pos_T ret_p1, ret_p2;
if (region_type == MLINE)
@@ -5805,11 +5804,28 @@ f_getregionpos(typval_T *argvars, typval_T *rettv)
}
else
{
+ struct block_def bd;
+
if (region_type == MBLOCK)
block_prep(&oa, &bd, lnum, FALSE);
else
charwise_block_prep(p1, p2, &bd, lnum, inclusive);
- if (bd.startspaces > 0)
+
+ if (bd.is_oneChar) // selection entirely inside one char
+ {
+ if (region_type == MBLOCK)
+ {
+ ret_p1.col = bd.textcol;
+ ret_p1.coladd = bd.start_char_vcols
+ - (bd.start_vcol - oa.start_vcol);
+ }
+ else
+ {
+ ret_p1.col = p1.col + 1;
+ ret_p1.coladd = p1.coladd;
+ }
+ }
+ else if (bd.startspaces > 0)
{
ret_p1.col = bd.textcol;
ret_p1.coladd = bd.start_char_vcols - bd.startspaces;
@@ -5819,7 +5835,13 @@ f_getregionpos(typval_T *argvars, typval_T *rettv)
ret_p1.col = bd.textcol + 1;
ret_p1.coladd = 0;
}
- if (bd.endspaces > 0)
+
+ if (bd.is_oneChar) // selection entirely inside one char
+ {
+ ret_p2.col = ret_p1.col;
+ ret_p2.coladd = ret_p1.coladd + bd.startspaces;
+ }
+ else if (bd.endspaces > 0)
{
ret_p2.col = bd.textcol + bd.textlen + 1;
ret_p2.coladd = bd.endspaces;
diff --git a/src/ops.c b/src/ops.c
index 605a66494a..1dd36ab286 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -2444,13 +2444,13 @@ charwise_block_prep(
int inclusive)
{
colnr_T startcol = 0, endcol = MAXCOL;
- int is_oneChar = FALSE;
colnr_T cs, ce;
char_u *p;
p = ml_get(lnum);
bdp->startspaces = 0;
bdp->endspaces = 0;
+ bdp->is_oneChar = FALSE;
bdp->start_char_vcols = 0;
if (lnum == start.lnum)
@@ -2487,7 +2487,7 @@ charwise_block_prep(
if (start.lnum == end.lnum && start.col == end.col)
{
// Special case: inside a single char
- is_oneChar = TRUE;
+ bdp->is_oneChar = TRUE;
bdp->startspaces = end.coladd - start.coladd + inclusive;
endcol = startcol;
}
@@ -2501,7 +2501,7 @@ charwise_block_prep(
}
if (endcol == MAXCOL)
endcol = ml_get_len(lnum);
- if (startcol > endcol || is_oneChar)
+ if (startcol > endcol || bdp->is_oneChar)
bdp->textlen = 0;
else
bdp->textlen = endcol - startcol + inclusive;
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 8c850d1ace..621be298d6 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1889,7 +1889,7 @@ func Test_visual_getregion()
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
call assert_equal([
\ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
- \ [[bufnr('%'), 2, 10, 1], [bufnr('%'), 2, 10, 0]],
+ \ [[bufnr('%'), 2, 10, 1], [bufnr('%'), 2, 10, 2]],
\ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
\ ],
\ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
@@ -1900,6 +1900,7 @@ func Test_visual_getregion()
\ ],
\ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ #" characterwise selection with multibyte chars
call cursor(1, 1)
call feedkeys("\<Esc>vj", 'xt')
call assert_equal(['abcdefghijk«', "\U0001f1e6"],
@@ -1910,8 +1911,17 @@ func Test_visual_getregion()
\ ],
\ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ set selection=exclusive
+ call feedkeys('l', 'xt')
+ call assert_equal(['abcdefghijk«', "\U0001f1e6"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
#" marks on multibyte chars
- :set selection=exclusive
call setpos("'a", [0, 1, 11, 0])
call setpos("'b", [0, 2, 16, 0])
call setpos("'c", [0, 2, 0, 0])
@@ -1997,6 +2007,7 @@ func Test_visual_getregion()
call assert_equal(["c", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
set selection&
+ bwipe!
#" Exclusive selection 2
new
@@ -2033,7 +2044,24 @@ func Test_visual_getregion()
set virtualedit=all
call cursor(1, 1)
- call feedkeys("\<Esc>2lv2lj", 'xt')
+ call feedkeys("\<Esc>lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call feedkeys('j', 'xt')
call assert_equal([' c', 'x '],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
call assert_equal([
@@ -2043,12 +2071,33 @@ func Test_visual_getregion()
\ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
call cursor(1, 1)
+ call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
+ call assert_equal([' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
call assert_equal([' ', ' ', ' '],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
call assert_equal([
- \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
- \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
\ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 2]],
\ ],
\ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
diff --git a/src/version.c b/src/version.c
index b2f04169fd..28dad45260 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 430,
+/**/
429,
/**/
428,