mirror of
https://github.com/neovim/neovim.git
synced 2025-10-08 02:46:31 +00:00
vim-patch:9.1.0430: getregionpos() doesn't handle one char selection (#28924)
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: vim/vim#14825
52a6f34887
This commit is contained in:
@@ -4433,8 +4433,8 @@ M.funcs = {
|
||||
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.
|
||||
]=],
|
||||
name = 'getregionpos',
|
||||
params = { { 'pos1', 'table' }, { 'pos2', 'table' }, { 'opts', 'table' } },
|
||||
|
@@ -3041,7 +3041,6 @@ static void f_getregionpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
|
||||
}
|
||||
|
||||
for (linenr_T lnum = p1.lnum; lnum <= p2.lnum; lnum++) {
|
||||
struct block_def bd;
|
||||
pos_T ret_p1, ret_p2;
|
||||
|
||||
if (region_type == kMTLineWise) {
|
||||
@@ -3050,19 +3049,34 @@ static void f_getregionpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
|
||||
ret_p2.col = MAXCOL;
|
||||
ret_p2.coladd = 0;
|
||||
} else {
|
||||
struct block_def bd;
|
||||
|
||||
if (region_type == kMTBlockWise) {
|
||||
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 == kMTBlockWise) {
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
} else {
|
||||
|
@@ -4253,11 +4253,12 @@ void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T
|
||||
{
|
||||
colnr_T startcol = 0;
|
||||
colnr_T endcol = MAXCOL;
|
||||
bool is_oneChar = false;
|
||||
colnr_T cs, ce;
|
||||
char *p = ml_get(lnum);
|
||||
|
||||
bdp->startspaces = 0;
|
||||
bdp->endspaces = 0;
|
||||
bdp->is_oneChar = false;
|
||||
bdp->start_char_vcols = 0;
|
||||
|
||||
if (lnum == start.lnum) {
|
||||
@@ -4287,7 +4288,7 @@ void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T
|
||||
&& utf_head_off(p, p + endcol) == 0)) {
|
||||
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;
|
||||
} else {
|
||||
@@ -4300,7 +4301,7 @@ void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T
|
||||
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;
|
||||
|
Reference in New Issue
Block a user