mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
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:
@@ -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"));
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user