Patch 9.0.0712
Problem: Wrong column when calling setcursorcharpos() with zero lnum.
Solution: Set the line number before calling buf_charidx_to_byteidx().
(closes #11329)
Files: src/evalfunc.c, src/eval.c, src/testdir/test_cursor_func.vim
*** ../vim-9.0.0711/src/evalfunc.c 2022-10-09 12:55:29.586190644 +0100
--- src/evalfunc.c 2022-10-10 12:36:36.103922429 +0100
***************
*** 3545,3551 ****
static void
set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol)
{
! long line, col;
long coladd = 0;
int set_curswant = TRUE;
--- 3545,3551 ----
static void
set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol)
{
! long lnum, col;
long coladd = 0;
int set_curswant = TRUE;
***************
*** 3567,3573 ****
emsg(_(e_invalid_argument));
return;
}
! line = pos.lnum;
col = pos.col;
coladd = pos.coladd;
if (curswant >= 0)
--- 3567,3573 ----
emsg(_(e_invalid_argument));
return;
}
! lnum = pos.lnum;
col = pos.col;
coladd = pos.coladd;
if (curswant >= 0)
***************
*** 3576,3592 ****
set_curswant = FALSE;
}
}
! else if ((argvars[0].v_type == VAR_NUMBER ||
! argvars[0].v_type == VAR_STRING)
! && (argvars[1].v_type == VAR_NUMBER ||
! argvars[1].v_type == VAR_STRING))
{
! line = tv_get_lnum(argvars);
! if (line < 0)
semsg(_(e_invalid_argument_str), tv_get_string(&argvars[0]));
col = (long)tv_get_number_chk(&argvars[1], NULL);
if (charcol)
! col = buf_charidx_to_byteidx(curbuf, line, col) + 1;
if (argvars[2].v_type != VAR_UNKNOWN)
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
}
--- 3576,3594 ----
set_curswant = FALSE;
}
}
! else if ((argvars[0].v_type == VAR_NUMBER
! || argvars[0].v_type == VAR_STRING)
! && (argvars[1].v_type == VAR_NUMBER
! || argvars[1].v_type == VAR_STRING))
{
! lnum = tv_get_lnum(argvars);
! if (lnum < 0)
semsg(_(e_invalid_argument_str), tv_get_string(&argvars[0]));
+ else if (lnum == 0)
+ lnum = curwin->w_cursor.lnum;
col = (long)tv_get_number_chk(&argvars[1], NULL);
if (charcol)
! col = buf_charidx_to_byteidx(curbuf, lnum, col) + 1;
if (argvars[2].v_type != VAR_UNKNOWN)
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
}
***************
*** 3595,3604 ****
emsg(_(e_invalid_argument));
return;
}
! if (line < 0 || col < 0 || coladd < 0)
return; // type error; errmsg already given
! if (line > 0)
! curwin->w_cursor.lnum = line;
if (col > 0)
curwin->w_cursor.col = col - 1;
curwin->w_cursor.coladd = coladd;
--- 3597,3606 ----
emsg(_(e_invalid_argument));
return;
}
! if (lnum < 0 || col < 0 || coladd < 0)
return; // type error; errmsg already given
! if (lnum > 0)
! curwin->w_cursor.lnum = lnum;
if (col > 0)
curwin->w_cursor.col = col - 1;
curwin->w_cursor.coladd = coladd;
*** ../vim-9.0.0711/src/eval.c 2022-10-07 14:31:04.320852668 +0100
--- src/eval.c 2022-10-10 12:41:33.332212016 +0100
***************
*** 6023,6032 ****
}
/*
! * Convert list in "arg" into a position and optional file number.
! * When "fnump" is NULL there is no file number, only 3 items.
* Note that the column is passed on as-is, the caller may want to decrement
* it to use 1 for the first column.
* Return FAIL when conversion is not possible, doesn't check the position for
* validity.
*/
--- 6023,6034 ----
}
/*
! * Convert list in "arg" into position "psop" and optional file number "fnump".
! * When "fnump" is NULL there is no file number, only 3 items: [lnum, col, off]
* Note that the column is passed on as-is, the caller may want to decrement
* it to use 1 for the first column.
+ * If "charcol" is TRUE use the column as the character index instead of the
+ * byte index.
* Return FAIL when conversion is not possible, doesn't check the position for
* validity.
*/
***************
*** 6069,6074 ****
--- 6071,6077 ----
if (n < 0)
return FAIL;
// If character position is specified, then convert to byte position
+ // If the line number is zero use the cursor line.
if (charcol)
{
buf_T *buf;
***************
*** 6078,6084 ****
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
return FAIL;
! n = buf_charidx_to_byteidx(buf, posp->lnum, n) + 1;
}
posp->col = n;
--- 6081,6088 ----
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
return FAIL;
! n = buf_charidx_to_byteidx(buf,
! posp->lnum == 0 ? curwin->w_cursor.lnum : posp->lnum, n) + 1;
}
posp->col = n;
*** ../vim-9.0.0711/src/testdir/test_cursor_func.vim 2022-05-27 21:52:46.000000000 +0100
--- src/testdir/test_cursor_func.vim 2022-10-10 12:34:13.623637663 +0100
***************
*** 399,406 ****
--- 399,412 ----
normal G
call setcursorcharpos([1, 1])
call assert_equal([1, 1], [line('.'), col('.')])
+
call setcursorcharpos([2, 7, 0])
call assert_equal([2, 9], [line('.'), col('.')])
+ call setcursorcharpos([0, 7, 0])
+ call assert_equal([2, 9], [line('.'), col('.')])
+ call setcursorcharpos(0, 7, 0)
+ call assert_equal([2, 9], [line('.'), col('.')])
+
call setcursorcharpos(3, 4)
call assert_equal([3, 1], [line('.'), col('.')])
call setcursorcharpos([3, 1])
*** ../vim-9.0.0711/src/version.c 2022-10-10 12:08:55.850043934 +0100
--- src/version.c 2022-10-10 12:42:25.064232035 +0100
***************
*** 701,702 ****
--- 701,704 ----
{ /* Add new patch number below this line */
+ /**/
+ 712,
/**/
--
CUSTOMER: You're not fooling anyone y'know. Look, isn't there something
you can do?
DEAD PERSON: I feel happy... I feel happy.
[whop]
CUSTOMER: Ah, thanks very much.
MORTICIAN: Not at all. See you on Thursday.
CUSTOMER: Right.
The Quest for the Holy Grail (Monty Python)
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///