Merge pull request #21302 from zeertzjq/vim-8.2.3193

vim-patch:8.2.{3193,4204,4389},9.0.{1011,1016}: screenpos() fixes
This commit is contained in:
zeertzjq
2022-12-06 08:39:57 +08:00
committed by GitHub
4 changed files with 92 additions and 24 deletions

View File

@@ -1023,6 +1023,8 @@ EXTERN char e_highlight_group_name_invalid_char[] INIT(= N_("E5248: Invalid char
EXTERN char e_highlight_group_name_too_long[] INIT(= N_("E1249: Highlight group name too long"));
EXTERN char e_invalid_line_number_nr[] INIT(= N_("E966: Invalid line number: %ld"));
EXTERN char e_undobang_cannot_redo_or_move_branch[]
INIT(= N_("E5767: Cannot use :undo! to redo or move to a different undo branch"));

View File

@@ -920,11 +920,16 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp,
int rowoff = 0;
colnr_T coloff = 0;
bool visible_row = false;
bool is_folded = false;
if (pos->lnum >= wp->w_topline && pos->lnum < wp->w_botline) {
row = plines_m_win(wp, wp->w_topline, pos->lnum - 1) + 1;
if (pos->lnum >= wp->w_topline && pos->lnum <= wp->w_botline) {
linenr_T lnum = pos->lnum;
is_folded = hasFoldingWin(wp, lnum, &lnum, NULL, true, NULL);
row = plines_m_win(wp, wp->w_topline, lnum - 1) + 1;
// Add filler lines above this buffer line.
row += win_get_fill(wp, lnum);
visible_row = true;
} else if (pos->lnum < wp->w_topline) {
} else if (!local || pos->lnum < wp->w_topline) {
row = 0;
} else {
row = wp->w_height_inner;
@@ -933,7 +938,10 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp,
bool existing_row = (pos->lnum > 0
&& pos->lnum <= wp->w_buffer->b_ml.ml_line_count);
if ((local && existing_row) || visible_row) {
if (is_folded) {
row += local ? 0 : wp->w_winrow + wp->w_winrow_off;
coloff = (local ? 0 : wp->w_wincol + wp->w_wincol_off) + 1;
} else if ((local || visible_row) && existing_row) {
colnr_T off;
colnr_T col;
int width;
@@ -955,19 +963,20 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp,
col -= wp->w_leftcol;
if (col >= 0 && col < wp->w_width) {
if (col >= 0 && col < wp->w_width && row + rowoff <= wp->w_height) {
coloff = col - scol + (local ? 0 : wp->w_wincol + wp->w_wincol_off) + 1;
row += local ? 0 : wp->w_winrow + wp->w_winrow_off;
} else {
// character is left, right or below of the window
scol = ccol = ecol = 0;
// character is left or right of the window
if (local) {
coloff = col < 0 ? -1 : wp->w_width_inner + 1;
} else {
row = 0;
row = rowoff = 0;
}
}
}
*rowp = (local ? 0 : wp->w_winrow + wp->w_winrow_off) + row + rowoff;
*rowp = row + rowoff;
*scolp = scol + coloff;
*ccolp = ccol + coloff;
*ecolp = ecol + coloff;
@@ -989,6 +998,10 @@ void f_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
.col = (colnr_T)tv_get_number(&argvars[2]) - 1,
.coladd = 0
};
if (pos.lnum > wp->w_buffer->b_ml.ml_line_count) {
semsg(_(e_invalid_line_number_nr), pos.lnum);
return;
}
int row = 0;
int scol = 0, ccol = 0, ecol = 0;
textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol, false);

View File

@@ -1,7 +1,10 @@
" Tests for cursor() and other functions that get/set the cursor position
source check.vim
func Test_wrong_arguments()
call assert_fails('call cursor(1. 3)', 'E474:')
call assert_fails('call cursor(v:_null_list)', 'E474:')
endfunc
func Test_move_cursor()
@@ -82,34 +85,81 @@ func Test_screenpos()
let winid = win_getid()
let [winrow, wincol] = win_screenpos(winid)
call assert_equal({'row': winrow,
\ 'col': wincol + 0,
\ 'curscol': wincol + 7,
\ 'endcol': wincol + 7}, winid->screenpos(1, 1))
\ 'col': wincol + 0,
\ 'curscol': wincol + 7,
\ 'endcol': wincol + 7}, winid->screenpos(1, 1))
call assert_equal({'row': winrow,
\ 'col': wincol + 13,
\ 'curscol': wincol + 13,
\ 'endcol': wincol + 13}, winid->screenpos(1, 7))
\ 'col': wincol + 13,
\ 'curscol': wincol + 13,
\ 'endcol': wincol + 13}, winid->screenpos(1, 7))
call assert_equal({'row': winrow + 2,
\ 'col': wincol + 1,
\ 'curscol': wincol + 1,
\ 'endcol': wincol + 1}, screenpos(winid, 2, 22))
\ 'col': wincol + 1,
\ 'curscol': wincol + 1,
\ 'endcol': wincol + 1}, screenpos(winid, 2, 22))
setlocal number
call assert_equal({'row': winrow + 3,
\ 'col': wincol + 9,
\ 'curscol': wincol + 9,
\ 'endcol': wincol + 9}, screenpos(winid, 2, 22))
\ 'col': wincol + 9,
\ 'curscol': wincol + 9,
\ 'endcol': wincol + 9}, screenpos(winid, 2, 22))
let wininfo = getwininfo(winid)[0]
call setline(3, ['x']->repeat(wininfo.height))
call setline(line('$') + 1, 'x'->repeat(wininfo.width * 3))
setlocal nonumber display=lastline so=0
exe "normal G\<C-Y>\<C-Y>"
redraw
call assert_equal({'row': winrow + wininfo.height - 1,
\ 'col': wincol + 7,
\ 'curscol': wincol + 7,
\ 'endcol': wincol + 7}, winid->screenpos(line('$'), 8))
call assert_equal({'row': 0, 'col': 0, 'curscol': 0, 'endcol': 0},
\ winid->screenpos(line('$'), 22))
close
call assert_equal({}, screenpos(999, 1, 1))
bwipe!
call assert_equal({'col': 1, 'row': 1, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1))
bwipe!
set display&
call assert_equal(#{col: 1, row: 1, endcol: 1, curscol: 1}, screenpos(win_getid(), 1, 1))
" nmenu WinBar.TEST :
setlocal winbar=TEST
call assert_equal({'col': 1, 'row': 2, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1))
call assert_equal(#{col: 1, row: 2, endcol: 1, curscol: 1}, screenpos(win_getid(), 1, 1))
" nunmenu WinBar.TEST
setlocal winbar&
endfunc
func Test_screenpos_fold()
CheckFeature folding
enew!
call setline(1, range(10))
3,5fold
redraw
call assert_equal(2, screenpos(1, 2, 1).row)
call assert_equal(#{col: 1, row: 3, endcol: 1, curscol: 1}, screenpos(1, 3, 1))
call assert_equal(3, screenpos(1, 4, 1).row)
call assert_equal(3, screenpos(1, 5, 1).row)
call assert_equal(4, screenpos(1, 6, 1).row)
bwipe!
endfunc
func Test_screenpos_diff()
CheckFeature diff
enew!
call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
vnew
call setline(1, ['a', 'b', 'c', 'g', 'h', 'i'])
windo diffthis
wincmd w
call assert_equal(#{col: 3, row: 7, endcol: 3, curscol: 3}, screenpos(0, 4, 1))
windo diffoff
bwipe!
bwipe!
endfunc
func Test_screenpos_number()
rightbelow new
rightbelow 73vsplit
@@ -121,6 +171,9 @@ func Test_screenpos_number()
let pos = screenpos(winid, 1, 66)
call assert_equal(winrow, pos.row)
call assert_equal(wincol + 66 + 3, pos.col)
call assert_fails('echo screenpos(0, 2, 1)', 'E966:')
close
bwipe!
endfunc

View File

@@ -849,7 +849,7 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
pos_T pos = { wp->w_float_config.bufpos.lnum + 1,
wp->w_float_config.bufpos.col, 0 };
int trow, tcol, tcolc, tcole;
textpos2screenpos(wp, &pos, &trow, &tcol, &tcolc, &tcole, true);
textpos2screenpos(parent, &pos, &trow, &tcol, &tcolc, &tcole, true);
row += trow - 1;
col += tcol - 1;
}