To: vim_dev@googlegroups.com Subject: Patch 9.0.0863 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0863 Problem: col() and charcol() only work for the current window. Solution: Add an optional winid argument. (Yegappan Lakshmanan, closes #11466, closes #11461) Files: runtime/doc/builtin.txt, src/evalfunc.c, src/testdir/test_cursor_func.vim, src/testdir/test_functions.vim, src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_expr.vim *** ../vim-9.0.0862/runtime/doc/builtin.txt 2022-11-05 23:46:30.720146269 +0000 --- runtime/doc/builtin.txt 2022-11-12 16:00:49.725535590 +0000 *************** *** 116,128 **** changenr() Number current change number char2nr({expr} [, {utf8}]) Number ASCII/UTF-8 value of first char in {expr} charclass({string}) Number character class of {string} ! charcol({expr}) Number column number of cursor or mark charidx({string}, {idx} [, {countcc}]) Number char index of byte {idx} in {string} chdir({dir}) String change current working directory cindent({lnum}) Number C indent for line {lnum} clearmatches([{win}]) none clear all matches ! col({expr}) Number column byte index of cursor or mark complete({startcol}, {matches}) none set Insert mode completion complete_add({expr}) Number add completion match complete_check() Number check for key typed during completion --- 116,128 ---- changenr() Number current change number char2nr({expr} [, {utf8}]) Number ASCII/UTF-8 value of first char in {expr} charclass({string}) Number character class of {string} ! charcol({expr} [, {winid}]) Number column number of cursor or mark charidx({string}, {idx} [, {countcc}]) Number char index of byte {idx} in {string} chdir({dir}) String change current working directory cindent({lnum}) Number C indent for line {lnum} clearmatches([{win}]) none clear all matches ! col({expr} [, {winid}]) Number column byte index of cursor or mark complete({startcol}, {matches}) none set Insert mode completion complete_add({expr}) Number add completion match complete_check() Number check for key typed during completion *************** *** 1321,1327 **** echo "A window containing buffer 1 is " .. (bufwinid(1)) < ! Only deals with the current tab page. Can also be used as a |method|: > FindBuffer()->bufwinid() --- 1321,1328 ---- echo "A window containing buffer 1 is " .. (bufwinid(1)) < ! Only deals with the current tab page. See |win_findbuf()| for ! finding more. Can also be used as a |method|: > FindBuffer()->bufwinid() *************** *** 1473,1479 **** Returns 0 if {string} is not a |String|. ! charcol({expr}) *charcol()* Same as |col()| but returns the character index of the column position given with {expr} instead of the byte position. --- 1474,1480 ---- Returns 0 if {string} is not a |String|. ! charcol({expr} [, {winid}]) *charcol()* Same as |col()| but returns the character index of the column position given with {expr} instead of the byte position. *************** *** 1556,1563 **** Can also be used as a |method|: > GetWin()->clearmatches() < ! *col()* ! col({expr}) The result is a Number, which is the byte index of the column position given with {expr}. The accepted positions are: . the cursor position $ the end of the cursor line (the result is the --- 1557,1564 ---- Can also be used as a |method|: > GetWin()->clearmatches() < ! col({expr} [, {winid}) *col()* ! The result is a Number, which is the byte index of the column position given with {expr}. The accepted positions are: . the cursor position $ the end of the cursor line (the result is the *************** *** 1572,1577 **** --- 1573,1580 ---- and column number. Most useful when the column is "$", to get the last column of a specific line. When "lnum" or "col" is out of range then col() returns zero. + With the optional {winid} argument the values are obtained for + that window instead of the current window. To get the line number use |line()|. To get both use |getpos()|. For the screen column position use |virtcol()|. For the *************** *** 1582,1597 **** col("$") length of cursor line plus one col("'t") column of mark t col("'" .. markname) column of mark markname ! < The first column is 1. Returns 0 if {expr} is invalid. For an uppercase mark the column may actually be in another buffer. For the cursor position, when 'virtualedit' is active, the column is one higher if the cursor is after the end of the ! line. This can be used to obtain the column in Insert mode: > ! :imap :let save_ve = &ve ! \:set ve=all ! \:echo col(".") .. "\n" ! \let &ve = save_ve < Can also be used as a |method|: > GetPos()->col() --- 1585,1599 ---- col("$") length of cursor line plus one col("'t") column of mark t col("'" .. markname) column of mark markname ! < The first column is 1. Returns 0 if {expr} is invalid or when ! the window with ID {winid} is not found. For an uppercase mark the column may actually be in another buffer. For the cursor position, when 'virtualedit' is active, the column is one higher if the cursor is after the end of the ! line. Also, when using a mapping the cursor isn't ! moved, this can be used to obtain the column in Insert mode: > ! :imap echowin col(".") < Can also be used as a |method|: > GetPos()->col() *************** *** 10205,10210 **** --- 10208,10214 ---- FALSE otherwise. This will fail for the rightmost window and a full-width window, since it has no separator on the right. + Only works for the current tab page. *E1308* Can also be used as a |method|: > GetWinnr()->win_move_separator(offset) *************** *** 10219,10224 **** --- 10223,10229 ---- movement may be smaller than specified (e.g., as a consequence of maintaining 'winminheight'). Returns TRUE if the window can be found and FALSE otherwise. + Only works for the current tab page. Can also be used as a |method|: > GetWinnr()->win_move_statusline(offset) *** ../vim-9.0.0862/src/evalfunc.c 2022-10-19 14:02:34.961276576 +0100 --- src/evalfunc.c 2022-11-12 16:03:05.997700716 +0000 *************** *** 1058,1063 **** --- 1058,1064 ---- static argcheck_T arg2_string_number[] = {arg_string, arg_number}; static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any}; static argcheck_T arg2_string_or_list_bool[] = {arg_string_or_list_any, arg_bool}; + static argcheck_T arg2_string_or_list_number[] = {arg_string_or_list_any, arg_number}; static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr}; static argcheck_T arg3_any_list_dict[] = {NULL, arg_list_any, arg_dict_any}; static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum}; *************** *** 1774,1780 **** ret_number, f_char2nr}, {"charclass", 1, 1, FEARG_1, arg1_string, ret_number, f_charclass}, ! {"charcol", 1, 1, FEARG_1, arg1_string_or_list_any, ret_number, f_charcol}, {"charidx", 2, 3, FEARG_1, arg3_string_number_bool, ret_number, f_charidx}, --- 1775,1781 ---- ret_number, f_char2nr}, {"charclass", 1, 1, FEARG_1, arg1_string, ret_number, f_charclass}, ! {"charcol", 1, 2, FEARG_1, arg2_string_or_list_number, ret_number, f_charcol}, {"charidx", 2, 3, FEARG_1, arg3_string_number_bool, ret_number, f_charidx}, *************** *** 1784,1790 **** ret_number, f_cindent}, {"clearmatches", 0, 1, FEARG_1, arg1_number, ret_void, f_clearmatches}, ! {"col", 1, 1, FEARG_1, arg1_string_or_list_any, ret_number, f_col}, {"complete", 2, 2, FEARG_2, arg2_number_list, ret_void, f_complete}, --- 1785,1791 ---- ret_number, f_cindent}, {"clearmatches", 0, 1, FEARG_1, arg1_number, ret_void, f_clearmatches}, ! {"col", 1, 2, FEARG_1, arg2_string_or_list_number, ret_number, f_col}, {"complete", 2, 2, FEARG_2, arg2_number_list, ret_void, f_complete}, *************** *** 3389,3400 **** { colnr_T col = 0; pos_T *fp; ! int fnum = curbuf->b_fnum; ! if (in_vim9script() ! && check_for_string_or_list_arg(argvars, 0) == FAIL) return; fp = var2fpos(&argvars[0], FALSE, &fnum, charcol); if (fp != NULL && fnum == curbuf->b_fnum) { --- 3390,3420 ---- { colnr_T col = 0; pos_T *fp; ! switchwin_T switchwin; ! int winchanged = FALSE; ! if (check_for_string_or_list_arg(argvars, 0) == FAIL ! || check_for_opt_number_arg(argvars, 1) == FAIL) return; + if (argvars[1].v_type != VAR_UNKNOWN) + { + tabpage_T *tp; + win_T *wp; + + // use the window specified in the second argument + wp = win_id2wp_tp((int)tv_get_number(&argvars[1]), &tp); + if (wp == NULL || tp == NULL) + return; + + if (switch_win_noblock(&switchwin, wp, tp, TRUE) != OK) + return; + + check_cursor(); + winchanged = TRUE; + } + + int fnum = curbuf->b_fnum; fp = var2fpos(&argvars[0], FALSE, &fnum, charcol); if (fp != NULL && fnum == curbuf->b_fnum) { *************** *** 3427,3432 **** --- 3447,3455 ---- } } rettv->vval.v_number = col; + + if (winchanged) + restore_win_noblock(&switchwin, TRUE); } /* *** ../vim-9.0.0862/src/testdir/test_cursor_func.vim 2022-10-10 12:42:52.476239815 +0100 --- src/testdir/test_cursor_func.vim 2022-11-12 15:58:35.545348935 +0000 *************** *** 287,294 **** " Test for the charcol() function func Test_charcol() ! call assert_fails('call charcol({})', 'E731:') ! call assert_equal(0, charcol(0)) new call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678']) --- 287,295 ---- " Test for the charcol() function func Test_charcol() ! call assert_fails('call charcol({})', 'E1222:') ! call assert_fails('call charcol(".", [])', 'E1210:') ! call assert_fails('call charcol(0)', 'E1222:') new call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678']) *************** *** 344,349 **** --- 345,369 ---- call assert_equal([1, 10, 2, 10, 7], g:InsertCurrentCol) iunmap + " Test for getting the column number in another window. + let winid = win_getid() + new + call win_execute(winid, 'normal 1G') + call assert_equal(1, charcol('.', winid)) + call assert_equal(1, charcol('$', winid)) + call win_execute(winid, 'normal 2G6l') + call assert_equal(7, charcol('.', winid)) + call assert_equal(10, charcol('$', winid)) + + " calling from another tab page also works + tabnew + call assert_equal(7, charcol('.', winid)) + call assert_equal(10, charcol('$', winid)) + tabclose + + " unknown window ID + call assert_equal(0, charcol('.', 10001)) + %bw! endfunc *** ../vim-9.0.0862/src/testdir/test_functions.vim 2022-11-05 23:46:30.720146269 +0000 --- src/testdir/test_functions.vim 2022-11-12 15:53:44.613076920 +0000 *************** *** 1484,1490 **** call assert_equal(0, col([1, 100])) call assert_equal(0, col([1])) call assert_equal(0, col(test_null_list())) ! call assert_fails('let c = col({})', 'E731:') " test for getting the visual start column func T() --- 1484,1491 ---- call assert_equal(0, col([1, 100])) call assert_equal(0, col([1])) call assert_equal(0, col(test_null_list())) ! call assert_fails('let c = col({})', 'E1222:') ! call assert_fails('let c = col(".", [])', 'E1210:') " test for getting the visual start column func T() *************** *** 1514,1519 **** --- 1515,1529 ---- call assert_equal(4, col('.')) set virtualedit& + " Test for getting the column number in another window + let winid = win_getid() + new + call win_execute(winid, 'normal 1G$') + call assert_equal(3, col('.', winid)) + call win_execute(winid, 'normal 2G') + call assert_equal(8, col('$', winid)) + call assert_equal(0, col('.', 5001)) + bw! endfunc *** ../vim-9.0.0862/src/testdir/test_vim9_builtin.vim 2022-11-05 23:46:30.720146269 +0000 --- src/testdir/test_vim9_builtin.vim 2022-11-12 15:53:44.617076922 +0000 *************** *** 687,692 **** --- 687,693 ---- def Test_charcol() v9.CheckDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict', 'E1222: String or List required for argument 1']) + v9.CheckDefAndScriptFailure(['charcol(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list', 'E1210: Number required for argument 2']) v9.CheckDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number') new setline(1, ['abcdefgh']) *************** *** 734,739 **** --- 735,741 ---- v9.CheckDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1']) + v9.CheckDefAndScriptFailure(['col(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list', 'E1210: Number required for argument 2']) v9.CheckDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number') bw! enddef *** ../vim-9.0.0862/src/testdir/test_vim9_expr.vim 2022-11-06 18:27:09.363922860 +0000 --- src/testdir/test_vim9_expr.vim 2022-11-12 15:53:44.617076922 +0000 *************** *** 53,59 **** assert_equal(function('len'), Res) var RetOne: func(string): number = function('len') ! var RetTwo: func(string): number = function('charcol') var RetThat: func = g:atrue ? RetOne : RetTwo assert_equal(function('len'), RetThat) --- 53,59 ---- assert_equal(function('len'), Res) var RetOne: func(string): number = function('len') ! var RetTwo: func(string): number = function('strlen') var RetThat: func = g:atrue ? RetOne : RetTwo assert_equal(function('len'), RetThat) *** ../vim-9.0.0862/src/version.c 2022-11-12 11:54:19.209571526 +0000 --- src/version.c 2022-11-12 15:55:37.201132670 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 863, /**/ -- hundred-and-one symptoms of being an internet addict: 43. You tell the kids they can't use the computer because "Daddy's got work to do" and you don't even have a job. /// Bram Moolenaar -- Bram@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 ///