diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 4 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 20 | ||||
-rw-r--r-- | src/nvim/ops.c | 7 |
3 files changed, 23 insertions, 8 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 58f2ac0acf..b377643917 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -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' } }, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 1d01f3ad98..7453bbb601 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -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 { diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 707cf5ca9a..5c1e291ac6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -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; |