Merge remote-tracking branch 'vim/master'

This commit is contained in:
Yee Cheng Chin
2019-07-11 02:37:24 -07:00
34 changed files with 788 additions and 167 deletions
+19
View File
@@ -2535,6 +2535,7 @@ or({expr}, {expr}) Number bitwise OR
pathshorten({expr}) String shorten directory names in a path
perleval({expr}) any evaluate |Perl| expression
popup_atcursor({what}, {options}) Number create popup window near the cursor
popup_beval({what}, {options}) Number create popup window for 'ballooneval'
popup_clear() none close all popup windows
popup_close({id} [, {result}]) none close popup window {id}
popup_create({what}, {options}) Number create a popup window
@@ -2613,6 +2614,7 @@ screenattr({row}, {col}) Number attribute at screen position
screenchar({row}, {col}) Number character at screen position
screenchars({row}, {col}) List List of characters at screen position
screencol() Number current cursor column
screenpos({winid}, {lnum}, {col}) Dict screen row and col of a text character
screenrow() Number current cursor row
screenstring({row}, {col}) String characters at screen position
search({pattern} [, {flags} [, {stopline} [, {timeout}]]])
@@ -7907,6 +7909,23 @@ screencol() *screencol()*
nnoremap <expr> GG ":echom ".screencol()."\n"
nnoremap <silent> GG :echom screencol()<CR>
<
screenpos({winid}, {lnum}, {col}) *screenpos()*
The result is a Dict with the screen position of the text
character in window {winid} at buffer line {lnum} and column
{col}. {col} is a one-based byte index.
The Dict has these members:
row screen row
col first screen column
endcol last screen column
curscol cursor screen column
If the specified position is not visible, all values are zero.
The "endcol" value differs from "col" when the character
occupies more than one screen cell. E.g. for a Tab "col" can
be 1 and "endcol" can be 8.
The "curscol" value is where the cursor would be placed. For
a Tab it would be the same as "endcol", while for a double
width character it would be the same as "col".
screenrow() *screenrow()*
The result is a Number, which is the current screen row of the
cursor. The top line has number one.
+73 -2
View File
@@ -146,6 +146,8 @@ Creating a popup window:
|popup_create()| centered in the screen
|popup_atcursor()| just above the cursor position, closes when
the cursor moves away
|popup_beval()| at the position indicated by v:beval_
variables, closes when the mouse moves away
|popup_notification()| show a notification for three seconds
|popup_dialog()| centered with padding and border
|popup_menu()| prompt for selecting an item from a list
@@ -184,6 +186,20 @@ popup_atcursor({what}, {options}) *popup_atcursor()*
< Use {options} to change the properties.
popup_beval({what}, {options}) *popup_beval()*
Show the {what} above the position from 'ballooneval' and
close it when the mouse moves. This works like: >
let pos = screenpos(v:beval_winnr, v:beval_lnum, v:beval_col)
call popup_create({what}, {
\ 'pos': 'botleft',
\ 'line': pos.row - 1,
\ 'col': pos.col,
\ 'mousemoved': 'WORD',
\ })
< Use {options} to change the properties.
See |popup_beval_example| for an example use.
*popup_clear()*
popup_clear() Emergency solution to a misbehaving plugin: close all popup
windows for the current tab and global popups.
@@ -276,8 +292,11 @@ popup_getoptions({id}) *popup_getoptions()*
A zero value means the option was not set. For "zindex" the
default value is returned, not zero.
The "moved" entry is a list with minimum and maximum column,
[0, 0] when not set.
The "moved" entry is a list with line number, minimum and
maximum column, [0, 0, 0] when not set.
The "mousemoved" entry is a list with screen row, minimum and
maximum screen column, [0, 0, 0] when not set.
"border" and "padding" are not included when all values are
zero. When all values are one then an empty list is included.
@@ -566,6 +585,7 @@ The second argument of |popup_create()| is a dictionary with options:
- "any": if the cursor moved at all
- "word": if the cursor moved outside |<cword>|
- "WORD": if the cursor moved outside |<cWORD>|
- "expr": if the cursor moved outside |<cexpr>|
- [{start}, {end}]: if the cursor moved before column
{start} or after {end}
The popup also closes if the cursor moves to another
@@ -736,5 +756,56 @@ Extend popup_filter_menu() with shortcut keys: >
return popup_filter_menu(a:id, a:key)
endfunc
<
*popup_beval_example*
Example for using a popup window for 'ballooneval': >
set ballooneval balloonevalterm
set balloonexpr=BalloonExpr()
let s:winid = 0
let s:last_text = ''
func BalloonExpr()
if s:winid && popup_getpos(s:winid) != {}
" previous popup window still shows
if v:beval_text == s:last_text
" Still the same text, keep the existing popup
return ''
endif
call popup_close(s:winid)
endif
let s:winid = popup_beval(v:beval_text, {'mousemoved': 'word'})
let s:last_text = v:beval_text
return ''
endfunc
<
If the text has to be obtained asynchronously return an empty string from the
expression function and call popup_beval() once the text is available. In
this example simulated with a timer callback: >
set ballooneval balloonevalterm
set balloonexpr=BalloonExpr()
let s:winid = 0
let s:balloonText = ''
func BalloonExpr()
if s:winid && popup_getpos(s:winid) != {}
" previous popup window still shows
if v:beval_text == s:balloonText
" Still the same text, keep the existing popup
return ''
endif
call popup_close(s:winid)
let s:winid = 0
endif
" simulate an asynchronous loopup for the text to display
let s:balloonText = v:beval_text
call timer_start(100, 'ShowPopup')
return ''
endfunc
func ShowPopup(id)
let s:winid = popup_beval(s:balloonText, {'mousemoved': 'word'})
endfunc
<
vim:tw=78:ts=8:noet:ft=help:norl:
+3
View File
@@ -720,6 +720,7 @@ Cursor and mark position: *cursor-functions* *mark-functions*
cursor() position the cursor at a line/column
screencol() get screen column of the cursor
screenrow() get screen row of the cursor
screenpos() screen row and col of a text character
getcurpos() get position of the cursor
getpos() get position of cursor, mark, etc.
setpos() set position of cursor, mark, etc.
@@ -1046,6 +1047,8 @@ Popup window: *popup-window-functions*
popup_create() create popup centered in the screen
popup_atcursor() create popup just above the cursor position,
closes when the cursor moves away
popup_beval() at the position indicated by v:beval_
variables, closes when the mouse moves away
popup_notification() show a notification for three seconds
popup_dialog() create popup centered with padding and border
popup_menu() prompt for selecting an item from a list
+95 -56
View File
@@ -10,61 +10,50 @@
#include "vim.h"
#if defined(FEAT_BEVAL) || defined(PROTO)
#if defined(FEAT_BEVAL) || defined(FEAT_TEXT_PROP) || defined(PROT)
/*
* Get the text and position to be evaluated for "beval".
* If "getword" is true the returned text is not the whole line but the
* relevant word in allocated memory.
* Returns OK or FAIL.
* Find text under the mouse position "row" / "col".
* If "getword" is TRUE the returned text in "*textp" is not the whole line but
* the relevant word in allocated memory.
* Return OK if found.
* Return FAIL if not found, no text at the mouse position.
*/
int
get_beval_info(
BalloonEval *beval,
int getword,
win_T **winp,
linenr_T *lnump,
char_u **textp,
int *colp)
find_word_under_cursor(
int mouserow,
int mousecol,
int getword,
int flags, // flags for find_ident_at_pos()
win_T **winp, // can be NULL
linenr_T *lnump, // can be NULL
char_u **textp,
int *colp, // column where mouse hovers, can be NULL
int *startcolp) // column where text starts, can be NULL
{
int row = mouserow;
int col = mousecol;
int scol;
win_T *wp;
int row, col;
char_u *lbuf;
linenr_T lnum;
*textp = NULL;
# ifdef FEAT_BEVAL_TERM
# ifdef FEAT_GUI
if (!gui.in_use)
# endif
{
row = mouse_row;
col = mouse_col;
}
# endif
# ifdef FEAT_GUI
if (gui.in_use)
{
row = Y_2_ROW(beval->y);
col = X_2_COL(beval->x);
}
#endif
wp = mouse_find_win(&row, &col, FAIL_POPUP);
if (wp != NULL && row >= 0 && row < wp->w_height && col < wp->w_width)
{
/* Found a window and the cursor is in the text. Now find the line
* number. */
// Found a window and the cursor is in the text. Now find the line
// number.
if (!mouse_comp_pos(wp, &row, &col, &lnum))
{
/* Not past end of the file. */
// Not past end of the file.
lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL))
{
/* Not past end of line. */
// Not past end of line.
if (getword)
{
/* For Netbeans we get the relevant part of the line
* instead of the whole line. */
// For Netbeans we get the relevant part of the line
// instead of the whole line.
int len;
pos_T *spos = NULL, *epos = NULL;
@@ -93,9 +82,9 @@ get_beval_info(
? col <= (int)epos->col
: lnum < epos->lnum))
{
/* Visual mode and pointing to the line with the
* Visual selection: return selected text, with a
* maximum of one line. */
// Visual mode and pointing to the line with the
// Visual selection: return selected text, with a
// maximum of one line.
if (spos->lnum != epos->lnum || spos->col == epos->col)
return FAIL;
@@ -109,10 +98,10 @@ get_beval_info(
}
else
{
/* Find the word under the cursor. */
// Find the word under the cursor.
++emsg_off;
len = find_ident_at_pos(wp, lnum, (colnr_T)col, &lbuf,
FIND_IDENT + FIND_STRING + FIND_EVAL);
len = find_ident_at_pos(wp, lnum, (colnr_T)col,
&lbuf, &scol, flags);
--emsg_off;
if (len == 0)
return FAIL;
@@ -120,21 +109,67 @@ get_beval_info(
}
}
*winp = wp;
*lnump = lnum;
if (winp != NULL)
*winp = wp;
if (lnump != NULL)
*lnump = lnum;
*textp = lbuf;
*colp = col;
#ifdef FEAT_VARTABS
vim_free(beval->vts);
beval->vts = tabstop_copy(wp->w_buffer->b_p_vts_array);
if (wp->w_buffer->b_p_vts_array != NULL && beval->vts == NULL)
return FAIL;
#endif
beval->ts = wp->w_buffer->b_p_ts;
if (colp != NULL)
*colp = col;
if (startcolp != NULL)
*startcolp = scol;
return OK;
}
}
}
return FAIL;
}
#endif
#if defined(FEAT_BEVAL) || defined(PROTO)
/*
* Get the text and position to be evaluated for "beval".
* If "getword" is TRUE the returned text is not the whole line but the
* relevant word in allocated memory.
* Returns OK or FAIL.
*/
int
get_beval_info(
BalloonEval *beval,
int getword,
win_T **winp,
linenr_T *lnump,
char_u **textp,
int *colp)
{
int row = mouse_row;
int col = mouse_col;
# ifdef FEAT_GUI
if (gui.in_use)
{
row = Y_2_ROW(beval->y);
col = X_2_COL(beval->x);
}
#endif
if (find_word_under_cursor(row, col, getword,
FIND_IDENT + FIND_STRING + FIND_EVAL,
winp, lnump, textp, colp, NULL) == OK)
{
#ifdef FEAT_VARTABS
vim_free(beval->vts);
beval->vts = tabstop_copy((*winp)->w_buffer->b_p_vts_array);
if ((*winp)->w_buffer->b_p_vts_array != NULL && beval->vts == NULL)
{
if (getword)
vim_free(*textp);
return FAIL;
}
#endif
beval->ts = (*winp)->w_buffer->b_p_ts;
return OK;
}
return FAIL;
}
@@ -264,11 +299,15 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
if (result != NULL && result[0] != NUL)
{
post_balloon(beval, result, NULL);
recursive = FALSE;
return;
}
// The 'balloonexpr' evaluation may show something on the screen
// that requires a screen update.
if (must_redraw)
redraw_after_callback(FALSE);
recursive = FALSE;
return;
}
}
#endif
+2 -2
View File
@@ -4032,7 +4032,7 @@ channel_send(
writeq_T *last = wq->wq_prev;
/* append to the last entry */
if (ga_grow(&last->wq_ga, len) == OK)
if (len > 0 && ga_grow(&last->wq_ga, len) == OK)
{
mch_memmove((char *)last->wq_ga.ga_data
+ last->wq_ga.ga_len,
@@ -4054,7 +4054,7 @@ channel_send(
wq->wq_prev->wq_next = last;
wq->wq_prev = last;
ga_init2(&last->wq_ga, 1, 1000);
if (ga_grow(&last->wq_ga, len) == OK)
if (len > 0 && ga_grow(&last->wq_ga, len) == OK)
{
mch_memmove(last->wq_ga.ga_data, buf, len);
last->wq_ga.ga_len = len;
+6 -1
View File
@@ -9910,10 +9910,14 @@ assert_fails(typval_T *argvars)
char_u *cmd = tv_get_string_chk(&argvars[0]);
garray_T ga;
int ret = 0;
int save_trylevel = trylevel;
// trylevel must be zero for a ":throw" command to be considered failed
trylevel = 0;
called_emsg = FALSE;
suppress_errthrow = TRUE;
emsg_silent = TRUE;
do_cmdline_cmd(cmd);
if (!called_emsg)
{
@@ -9939,10 +9943,11 @@ assert_fails(typval_T *argvars)
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
ret = 1;
ret = 1;
}
}
trylevel = save_trylevel;
called_emsg = FALSE;
suppress_errthrow = FALSE;
emsg_silent = FALSE;
+2
View File
@@ -771,6 +771,7 @@ static struct fst
#endif
#ifdef FEAT_TEXT_PROP
{"popup_atcursor", 2, 2, f_popup_atcursor},
{"popup_beval", 2, 2, f_popup_beval},
{"popup_clear", 0, 0, f_popup_clear},
{"popup_close", 1, 2, f_popup_close},
{"popup_create", 2, 2, f_popup_create},
@@ -849,6 +850,7 @@ static struct fst
{"screenchar", 2, 2, f_screenchar},
{"screenchars", 2, 2, f_screenchars},
{"screencol", 0, 0, f_screencol},
{"screenpos", 3, 3, f_screenpos},
{"screenrow", 0, 0, f_screenrow},
{"screenstring", 2, 2, f_screenstring},
{"search", 1, 4, f_search},
+5 -7
View File
@@ -603,6 +603,11 @@ EXTERN int aucmd_win_used INIT(= FALSE); /* aucmd_win is being used */
#ifdef FEAT_TEXT_PROP
EXTERN win_T *first_popupwin; // first global popup window
EXTERN win_T *popup_dragwin INIT(= NULL); // popup window being dragged
// Set to TRUE if there is any visible popup.
EXTERN int popup_visible INIT(= FALSE);
EXTERN int text_prop_frozen INIT(= 0);
#endif
/*
@@ -1685,10 +1690,3 @@ typedef int HINSTANCE;
EXTERN int ctrl_break_was_pressed INIT(= FALSE);
EXTERN HINSTANCE g_hinst INIT(= NULL);
#endif
#ifdef FEAT_TEXT_PROP
EXTERN int text_prop_frozen INIT(= 0);
// Set to TRUE if there is any visible popup.
EXTERN int popup_visible INIT(= FALSE);
#endif
+27 -9
View File
@@ -2285,7 +2285,7 @@ gui_outstr_nowrap(
int col = gui.col;
#ifdef FEAT_SIGN_ICONS
int draw_sign = FALSE;
int signcol = 0;
int signcol = col;
char_u extra[18];
# ifdef FEAT_NETBEANS_INTG
int multi_sign = FALSE;
@@ -2321,7 +2321,7 @@ gui_outstr_nowrap(
--col;
len = (int)STRLEN(s);
if (len > 2)
signcol = len - 3; // Right align sign icon in the number column
signcol = col + len - 3; // Right align sign icon in the number column
draw_sign = TRUE;
highlight_mask = 0;
}
@@ -4864,18 +4864,15 @@ gui_focus_change(int in_focus)
}
/*
* Called when the mouse moved (but not when dragging).
* When mouse moved: apply 'mousefocus'.
* Also updates the mouse pointer shape.
*/
void
gui_mouse_moved(int x, int y)
static void
gui_mouse_focus(int x, int y)
{
win_T *wp;
char_u st[8];
/* Ignore this while still starting up. */
if (!gui.in_use || gui.starting)
return;
#ifdef FEAT_MOUSESHAPE
/* Get window pointer, and update mouse shape as well. */
wp = xy2win(x, y);
@@ -4934,6 +4931,27 @@ gui_mouse_moved(int x, int y)
}
}
/*
* Called when the mouse moved (but not when dragging).
*/
void
gui_mouse_moved(int x, int y)
{
// Ignore this while still starting up.
if (!gui.in_use || gui.starting)
return;
// apply 'mousefocus' and pointer shape
gui_mouse_focus(x, y);
#ifdef FEAT_TEXT_PROP
if (popup_visible)
// Generate a mouse-moved event, so that the popup can perhaps be
// closed, just like in the terminal.
gui_send_mouse_event(MOUSE_DRAG, x, y, FALSE, 0);
#endif
}
/*
* Called when mouse should be moved to window with focus.
*/
+2
View File
@@ -404,11 +404,13 @@ hangul_input_state_set(int state)
hangul_input_clear();
}
#if (!defined(FEAT_XIM) && !defined(FEAT_GUI_GTK)) || defined(PROTO)
int
im_get_status(void)
{
return hangul_input_state_get();
}
#endif
void
hangul_input_state_toggle(void)
+12 -3
View File
@@ -4266,14 +4266,18 @@ mb_lefthalve(int row, int col)
int
mb_fix_col(int col, int row)
{
int off;
col = check_col(col);
row = check_row(row);
off = LineOffset[row] + col;
if (has_mbyte && ScreenLines != NULL && col > 0
&& ((enc_dbcs
&& ScreenLines[LineOffset[row] + col] != NUL
&& ScreenLines[off] != NUL
&& dbcs_screen_head_off(ScreenLines + LineOffset[row],
ScreenLines + LineOffset[row] + col))
|| (enc_utf8 && ScreenLines[LineOffset[row] + col] == 0)))
ScreenLines + off))
|| (enc_utf8 && ScreenLines[off] == 0
&& ScreenLinesUC[off] == 0)))
return col - 1;
return col;
}
@@ -5931,6 +5935,11 @@ xim_queue_key_press_event(GdkEventKey *event, int down)
int
im_get_status(void)
{
# ifdef FEAT_HANGULIN
if (hangul_input_state_get())
return TRUE;
# endif
# ifdef FEAT_EVAL
if (USE_IMSTATUSFUNC)
return call_imstatusfunc();
+9
View File
@@ -4451,12 +4451,19 @@ parse_queued_messages(void)
{
win_T *old_curwin = curwin;
int i;
int save_may_garbage_collect = may_garbage_collect;
// Do not handle messages while redrawing, because it may cause buffers to
// change or be wiped while they are being redrawn.
if (updating_screen)
return;
// may_garbage_collect is set in main_loop() to do garbage collection when
// blocking to wait on a character. We don't want that while parsing
// messages, a callback may invoke vgetc() while lists and dicts are in use
// in the call stack.
may_garbage_collect = FALSE;
// Loop when a job ended, but don't keep looping forever.
for (i = 0; i < MAX_REPEAT_PARSE; ++i)
{
@@ -4497,6 +4504,8 @@ parse_queued_messages(void)
break;
}
may_garbage_collect = save_may_garbage_collect;
// If the current window changed we need to bail out of the waiting loop.
// E.g. when a job exit callback closes the terminal window.
if (curwin != old_curwin)
+90
View File
@@ -1218,6 +1218,96 @@ curs_columns(
curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
}
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Compute the screen position of text character at "pos" in window "wp"
* The resulting values are one-based, zero when character is not visible.
*/
static void
textpos2screenpos(
win_T *wp,
pos_T *pos,
int *rowp, // screen row
int *scolp, // start screen column
int *ccolp, // cursor screen column
int *ecolp) // end screen column
{
colnr_T scol = 0, ccol = 0, ecol = 0;
int row = 0;
int rowoff = 0;
colnr_T coloff = 0;
if (pos->lnum >= wp->w_topline && pos->lnum < wp->w_botline)
{
colnr_T off;
colnr_T col;
int width;
row = plines_m_win(wp, wp->w_topline, pos->lnum - 1) + 1;
getvcol(wp, pos, &scol, &ccol, &ecol);
// similar to what is done in validate_cursor_col()
col = scol;
off = win_col_off(wp);
col += off;
width = wp->w_width - off + win_col_off2(wp);
/* long line wrapping, adjust row */
if (wp->w_p_wrap
&& col >= (colnr_T)wp->w_width
&& width > 0)
{
/* use same formula as what is used in curs_columns() */
rowoff = ((col - wp->w_width) / width + 1);
col -= rowoff * width;
}
col -= wp->w_leftcol;
if (col >= width)
col = -1;
if (col >= 0)
coloff = col - scol + wp->w_wincol + 1;
else
// character is left or right of the window
row = scol = ccol = ecol = 0;
}
*rowp = wp->w_winrow + row + rowoff;
*scolp = scol + coloff;
*ccolp = ccol + coloff;
*ecolp = ecol + coloff;
}
/*
* "screenpos({winid}, {lnum}, {col})" function
*/
void
f_screenpos(typval_T *argvars UNUSED, typval_T *rettv)
{
dict_T *dict;
win_T *wp;
pos_T pos;
int row = 0;
int scol = 0, ccol = 0, ecol = 0;
if (rettv_dict_alloc(rettv) != OK)
return;
dict = rettv->vval.v_dict;
wp = find_win_by_nr_or_id(&argvars[0]);
if (wp == NULL)
return;
pos.lnum = tv_get_number(&argvars[1]);
pos.col = tv_get_number(&argvars[2]) - 1;
pos.coladd = 0;
textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol);
dict_add_number(dict, "row", row);
dict_add_number(dict, "col", scol);
dict_add_number(dict, "curscol", ccol);
dict_add_number(dict, "endcol", ecol);
}
#endif
/*
* Scroll the current window down by "line_count" logical lines. "CTRL-Y"
*/
+32 -26
View File
@@ -2328,6 +2328,9 @@ do_mouse(
profile_setlimit(p_bdlay, &bevalexpr_due);
bevalexpr_due_set = TRUE;
}
#endif
#ifdef FEAT_TEXT_PROP
popup_handle_mouse_moved();
#endif
return FALSE;
}
@@ -3325,28 +3328,28 @@ find_is_eval_item(
* Find the identifier under or to the right of the cursor.
* "find_type" can have one of three values:
* FIND_IDENT: find an identifier (keyword)
* FIND_STRING: find any non-white string
* FIND_IDENT + FIND_STRING: find any non-white string, identifier preferred.
* FIND_STRING: find any non-white text
* FIND_IDENT + FIND_STRING: find any non-white text, identifier preferred.
* FIND_EVAL: find text useful for C program debugging
*
* There are three steps:
* 1. Search forward for the start of an identifier/string. Doesn't move if
* 1. Search forward for the start of an identifier/text. Doesn't move if
* already on one.
* 2. Search backward for the start of this identifier/string.
* 2. Search backward for the start of this identifier/text.
* This doesn't match the real Vi but I like it a little better and it
* shouldn't bother anyone.
* 3. Search forward to the end of this identifier/string.
* 3. Search forward to the end of this identifier/text.
* When FIND_IDENT isn't defined, we backup until a blank.
*
* Returns the length of the string, or zero if no string is found.
* If a string is found, a pointer to the string is put in "*string". This
* string is not always NUL terminated.
* Returns the length of the text, or zero if no text is found.
* If text is found, a pointer to the text is put in "*text". This
* points into the current buffer line and is not always NUL terminated.
*/
int
find_ident_under_cursor(char_u **string, int find_type)
find_ident_under_cursor(char_u **text, int find_type)
{
return find_ident_at_pos(curwin, curwin->w_cursor.lnum,
curwin->w_cursor.col, string, find_type);
curwin->w_cursor.col, text, NULL, find_type);
}
/*
@@ -3358,33 +3361,34 @@ find_ident_at_pos(
win_T *wp,
linenr_T lnum,
colnr_T startcol,
char_u **string,
char_u **text,
int *textcol, // column where "text" starts, can be NULL
int find_type)
{
char_u *ptr;
int col = 0; /* init to shut up GCC */
int col = 0; // init to shut up GCC
int i;
int this_class = 0;
int prev_class;
int prevcol;
int bn = 0; /* bracket nesting */
int bn = 0; // bracket nesting
/*
* if i == 0: try to find an identifier
* if i == 1: try to find any non-white string
* if i == 1: try to find any non-white text
*/
ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; ++i)
{
/*
* 1. skip to start of identifier/string
* 1. skip to start of identifier/text
*/
col = startcol;
if (has_mbyte)
{
while (ptr[col] != NUL)
{
/* Stop at a ']' to evaluate "a[x]". */
// Stop at a ']' to evaluate "a[x]".
if ((find_type & FIND_EVAL) && ptr[col] == ']')
break;
this_class = mb_get_class(ptr + col);
@@ -3400,11 +3404,11 @@ find_ident_at_pos(
)
++col;
/* When starting on a ']' count it, so that we include the '['. */
// When starting on a ']' count it, so that we include the '['.
bn = ptr[col] == ']';
/*
* 2. Back up to start of identifier/string.
* 2. Back up to start of identifier/text.
*/
if (has_mbyte)
{
@@ -3430,8 +3434,8 @@ find_ident_at_pos(
col = prevcol;
}
/* If we don't want just any old string, or we've found an
* identifier, stop searching. */
// If we don't want just any old text, or we've found an
// identifier, stop searching.
if (this_class > 2)
this_class = 2;
if (!(find_type & FIND_STRING) || this_class == 2)
@@ -3452,8 +3456,8 @@ find_ident_at_pos(
))
--col;
/* If we don't want just any old string, or we've found an
* identifier, stop searching. */
// If we don't want just any old text, or we've found an
// identifier, stop searching.
if (!(find_type & FIND_STRING) || vim_iswordc(ptr[col]))
break;
}
@@ -3462,7 +3466,7 @@ find_ident_at_pos(
if (ptr[col] == NUL || (i == 0
&& (has_mbyte ? this_class != 2 : !vim_iswordc(ptr[col]))))
{
// didn't find an identifier or string
// didn't find an identifier or text
if ((find_type & FIND_NOERROR) == 0)
{
if (find_type & FIND_STRING)
@@ -3473,17 +3477,19 @@ find_ident_at_pos(
return 0;
}
ptr += col;
*string = ptr;
*text = ptr;
if (textcol != NULL)
*textcol = col;
/*
* 3. Find the end if the identifier/string.
* 3. Find the end if the identifier/text.
*/
bn = 0;
startcol -= col;
col = 0;
if (has_mbyte)
{
/* Search for point of changing multibyte character class. */
// Search for point of changing multibyte character class.
this_class = mb_get_class(ptr);
while (ptr[col] != NUL
&& ((i == 0 ? mb_get_class(ptr + col) == this_class
+3 -4
View File
@@ -992,8 +992,6 @@ pum_position_at_mouse(int min_width)
# if defined(FEAT_BEVAL_TERM) || defined(PROTO)
static pumitem_T *balloon_array = NULL;
static int balloon_arraysize;
static int balloon_mouse_row = 0;
static int balloon_mouse_col = 0;
#define BALLOON_MIN_WIDTH 50
#define BALLOON_MIN_HEIGHT 10
@@ -1209,8 +1207,9 @@ ui_post_balloon(char_u *mesg, list_T *list)
void
ui_may_remove_balloon(void)
{
if (mouse_row != balloon_mouse_row || mouse_col != balloon_mouse_col)
ui_remove_balloon();
// For now: remove the balloon whenever the mouse moves to another screen
// cell.
ui_remove_balloon();
}
# endif
+183 -28
View File
@@ -167,6 +167,45 @@ set_moved_columns(win_T *wp, int flags)
}
}
/*
* Used when popup options contain "mousemoved": set default moved values.
*/
static void
set_mousemoved_values(win_T *wp)
{
wp->w_popup_mouse_row = mouse_row;
wp->w_popup_mouse_mincol = mouse_col;
wp->w_popup_mouse_maxcol = mouse_col;
}
/*
* Used when popup options contain "moved" with "word" or "WORD".
*/
static void
set_mousemoved_columns(win_T *wp, int flags)
{
win_T *textwp;
char_u *text;
int col;
pos_T pos;
colnr_T mcol;
if (find_word_under_cursor(mouse_row, mouse_col, TRUE, flags,
&textwp, &pos.lnum, &text, NULL, &col) == OK)
{
// convert text column to mouse column
pos.col = col;
pos.coladd = 0;
getvcol(textwp, &pos, &mcol, NULL, NULL);
wp->w_popup_mouse_mincol = mcol;
pos.col = col + STRLEN(text) - 1;
getvcol(textwp, &pos, NULL, NULL, &mcol);
wp->w_popup_mouse_maxcol = mcol;
vim_free(text);
}
}
/*
* Return TRUE if "row"/"col" is on the border of the popup.
* The values are relative to the top-left corner.
@@ -335,6 +374,53 @@ apply_move_options(win_T *wp, dict_T *d)
get_pos_options(wp, d);
}
static void
handle_moved_argument(win_T *wp, dictitem_T *di, int mousemoved)
{
if (di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
{
char_u *s = di->di_tv.vval.v_string;
int flags = 0;
if (STRCMP(s, "word") == 0)
flags = FIND_IDENT | FIND_STRING;
else if (STRCMP(s, "WORD") == 0)
flags = FIND_STRING;
else if (STRCMP(s, "expr") == 0)
flags = FIND_IDENT | FIND_STRING | FIND_EVAL;
else if (STRCMP(s, "any") != 0)
semsg(_(e_invarg2), s);
if (flags != 0)
{
if (mousemoved)
set_mousemoved_columns(wp, flags);
else
set_moved_columns(wp, flags);
}
}
else if (di->di_tv.v_type == VAR_LIST
&& di->di_tv.vval.v_list != NULL
&& di->di_tv.vval.v_list->lv_len == 2)
{
list_T *l = di->di_tv.vval.v_list;
int mincol = tv_get_number(&l->lv_first->li_tv);
int maxcol = tv_get_number(&l->lv_first->li_next->li_tv);
if (mousemoved)
{
wp->w_popup_mouse_mincol = mincol;
wp->w_popup_mouse_maxcol = maxcol;
}
else
{
wp->w_popup_mincol = mincol;
wp->w_popup_maxcol = maxcol;
}
}
else
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
}
static void
check_highlight(dict_T *dict, char *name, char_u **pval)
{
@@ -541,31 +627,14 @@ apply_general_options(win_T *wp, dict_T *dict)
if (di != NULL)
{
set_moved_values(wp);
if (di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
{
char_u *s = di->di_tv.vval.v_string;
int flags = 0;
handle_moved_argument(wp, di, FALSE);
}
if (STRCMP(s, "word") == 0)
flags = FIND_IDENT | FIND_STRING;
else if (STRCMP(s, "WORD") == 0)
flags = FIND_STRING;
else if (STRCMP(s, "any") != 0)
semsg(_(e_invarg2), s);
if (flags != 0)
set_moved_columns(wp, flags);
}
else if (di->di_tv.v_type == VAR_LIST
&& di->di_tv.vval.v_list != NULL
&& di->di_tv.vval.v_list->lv_len == 2)
{
list_T *l = di->di_tv.vval.v_list;
wp->w_popup_mincol = tv_get_number(&l->lv_first->li_tv);
wp->w_popup_maxcol = tv_get_number(&l->lv_first->li_next->li_tv);
}
else
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
di = dict_find(dict, (char_u *)"mousemoved", -1);
if (di != NULL)
{
set_mousemoved_values(wp);
handle_moved_argument(wp, di, TRUE);
}
di = dict_find(dict, (char_u *)"filter", -1);
@@ -821,7 +890,9 @@ popup_adjust_position(win_T *wp)
wp->w_width = 1;
for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
{
int len = vim_strsize(ml_get_buf(wp->w_buffer, lnum, FALSE));
// count Tabs for what they are worth
int len = win_linetabsize(wp, ml_get_buf(wp->w_buffer, lnum, FALSE),
(colnr_T)MAXCOL);
if (wp->w_p_wrap)
{
@@ -956,6 +1027,7 @@ typedef enum
{
TYPE_NORMAL,
TYPE_ATCURSOR,
TYPE_BEVAL,
TYPE_NOTIFICATION,
TYPE_DIALOG,
TYPE_MENU
@@ -1137,17 +1209,33 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
{
wp->w_popup_pos = POPPOS_BOTLEFT;
setcursor_mayforce(TRUE);
wp->w_wantline = screen_screenrow();
wp->w_wantline = curwin->w_winrow + curwin->w_wrow;
if (wp->w_wantline == 0) // cursor in first line
{
wp->w_wantline = 2;
wp->w_popup_pos = POPPOS_TOPLEFT;
}
wp->w_wantcol = screen_screencol() + 1;
wp->w_wantcol = curwin->w_wincol + curwin->w_wcol + 1;
set_moved_values(wp);
set_moved_columns(wp, FIND_STRING);
}
if (type == TYPE_BEVAL)
{
wp->w_popup_pos = POPPOS_BOTLEFT;
// by default use the mouse position
wp->w_wantline = mouse_row;
if (wp->w_wantline <= 0) // mouse on first line
{
wp->w_wantline = 2;
wp->w_popup_pos = POPPOS_TOPLEFT;
}
wp->w_wantcol = mouse_col + 1;
set_mousemoved_values(wp);
set_mousemoved_columns(wp, FIND_IDENT + FIND_STRING + FIND_EVAL);
}
// set default values
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
wp->w_popup_close = POPCLOSE_NONE;
@@ -1275,6 +1363,15 @@ f_popup_atcursor(typval_T *argvars, typval_T *rettv)
popup_create(argvars, rettv, TYPE_ATCURSOR);
}
/*
* popup_beval({text}, {options})
*/
void
f_popup_beval(typval_T *argvars, typval_T *rettv)
{
popup_create(argvars, rettv, TYPE_BEVAL);
}
/*
* Invoke the close callback for window "wp" with value "result".
* Careful: The callback may make "wp" invalid!
@@ -1334,6 +1431,55 @@ popup_close_for_mouse_click(win_T *wp)
popup_close_and_callback(wp, &res);
}
static void
check_mouse_moved(win_T *wp, win_T *mouse_wp)
{
// Close the popup when all if these are true:
// - the mouse is not on this popup
// - "mousemoved" was used
// - the mouse is no longer on the same screen row or the mouse column is
// outside of the relevant text
if (wp != mouse_wp
&& wp->w_popup_mouse_row != 0
&& (wp->w_popup_mouse_row != mouse_row
|| mouse_col < wp->w_popup_mouse_mincol
|| mouse_col > wp->w_popup_mouse_maxcol))
{
typval_T res;
res.v_type = VAR_NUMBER;
res.vval.v_number = -2;
// Careful: this makes "wp" invalid.
popup_close_and_callback(wp, &res);
}
}
/*
* Called when the mouse moved: may close a popup with "mousemoved".
*/
void
popup_handle_mouse_moved(void)
{
win_T *wp, *nextwp;
win_T *mouse_wp;
int row = mouse_row;
int col = mouse_col;
// find the window where the mouse is in
mouse_wp = mouse_find_win(&row, &col, FIND_POPUP);
for (wp = first_popupwin; wp != NULL; wp = nextwp)
{
nextwp = wp->w_next;
check_mouse_moved(wp, mouse_wp);
}
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = nextwp)
{
nextwp = wp->w_next;
check_mouse_moved(wp, mouse_wp);
}
}
/*
* In a filter: check if the typed key is a mouse event that is used for
* dragging the popup.
@@ -1821,7 +1967,7 @@ get_borderchars(dict_T *dict, win_T *wp)
}
/*
* For popup_getoptions(): add a "moved" entry to "dict".
* For popup_getoptions(): add a "moved" and "mousemoved" entry to "dict".
*/
static void
get_moved_list(dict_T *dict, win_T *wp)
@@ -1832,9 +1978,18 @@ get_moved_list(dict_T *dict, win_T *wp)
if (list != NULL)
{
dict_add_list(dict, "moved", list);
list_append_number(list, wp->w_popup_lnum);
list_append_number(list, wp->w_popup_mincol);
list_append_number(list, wp->w_popup_maxcol);
}
list = list_alloc();
if (list != NULL)
{
dict_add_list(dict, "mousemoved", list);
list_append_number(list, wp->w_popup_mouse_row);
list_append_number(list, wp->w_popup_mouse_mincol);
list_append_number(list, wp->w_popup_mouse_maxcol);
}
}
/*
+6 -5
View File
@@ -230,13 +230,14 @@ void qsort(void *base, size_t elm_count, size_t elm_size, int (*cmp)(const void
# include "if_ruby.pro"
# endif
/* Ugly solution for "BalloonEval" not being defined while it's used in some
* .pro files. */
# ifdef FEAT_BEVAL
# include "beval.pro"
# else
// Ugly solution for "BalloonEval" not being defined while it's used in some
// .pro files.
# ifndef FEAT_BEVAL
# define BalloonEval int
# endif
# if defined(FEAT_BEVAL) || defined(FEAT_TEXT_PROP)
# include "beval.pro"
# endif
# ifdef FEAT_NETBEANS_INTG
# include "netbeans.pro"
+1
View File
@@ -1,4 +1,5 @@
/* beval.c */
int find_word_under_cursor(int mouserow, int mousecol, int getword, int flags, win_T **winp, linenr_T *lnump, char_u **textp, int *colp, int *startcolp);
int get_beval_info(BalloonEval *beval, int getword, win_T **winp, linenr_T *lnump, char_u **textp, int *colp);
void post_balloon(BalloonEval *beval, char_u *mesg, list_T *list);
int can_use_beval(void);
+1
View File
@@ -27,6 +27,7 @@ int curwin_col_off(void);
int win_col_off2(win_T *wp);
int curwin_col_off2(void);
void curs_columns(int may_scroll);
void f_screenpos(typval_T *argvars, typval_T *rettv);
void scrolldown(long line_count, int byfold);
void scrollup(long line_count, int byfold);
void check_topfill(win_T *wp, int down);
+2 -2
View File
@@ -7,8 +7,8 @@ void check_visual_highlight(void);
void end_visual_mode(void);
void reset_VIsual_and_resel(void);
void reset_VIsual(void);
int find_ident_under_cursor(char_u **string, int find_type);
int find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char_u **string, int find_type);
int find_ident_under_cursor(char_u **text, int find_type);
int find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char_u **text, int *textcol, int find_type);
void clear_showcmd(void);
int add_to_showcmd(int c);
void add_to_showcmd_c(int c);
+2
View File
@@ -11,7 +11,9 @@ void popup_adjust_position(win_T *wp);
void f_popup_clear(typval_T *argvars, typval_T *rettv);
void f_popup_create(typval_T *argvars, typval_T *rettv);
void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
void f_popup_beval(typval_T *argvars, typval_T *rettv);
void popup_close_for_mouse_click(win_T *wp);
void popup_handle_mouse_moved(void);
void f_popup_filter_menu(typval_T *argvars, typval_T *rettv);
void f_popup_filter_yesno(typval_T *argvars, typval_T *rettv);
void f_popup_dialog(typval_T *argvars, typval_T *rettv);
+14 -12
View File
@@ -611,6 +611,7 @@ update_screen(int type_arg)
curwin->w_lines_valid = 0; /* don't use w_lines[].wl_size now */
return FAIL;
}
updating_screen = TRUE;
#ifdef FEAT_TEXT_PROP
// Update popup_mask if needed. This may set w_redraw_top and w_redraw_bot
@@ -618,7 +619,6 @@ update_screen(int type_arg)
may_update_popup_mask(type);
#endif
updating_screen = TRUE;
#ifdef FEAT_SYN_HL
++display_tick; /* let syntax code know we're in a next round of
* display updating */
@@ -3193,9 +3193,10 @@ win_line(
int n_skip = 0; /* nr of chars to skip for 'nowrap' */
int fromcol, tocol; /* start/end of inverting */
int fromcol_prev = -2; /* start of inverting after cursor */
int noinvcur = FALSE; /* don't invert the cursor */
int fromcol = -10; // start of inverting
int tocol = MAXCOL; // end of inverting
int fromcol_prev = -2; // start of inverting after cursor
int noinvcur = FALSE; // don't invert the cursor
pos_T *top, *bot;
int lnum_in_visual_area = FALSE;
pos_T pos;
@@ -3455,39 +3456,40 @@ win_line(
#endif
/*
* handle visual active in this window
* handle Visual active in this window
*/
fromcol = -10;
tocol = MAXCOL;
if (VIsual_active && wp->w_buffer == curwin->w_buffer)
{
/* Visual is after curwin->w_cursor */
if (LTOREQ_POS(curwin->w_cursor, VIsual))
{
// Visual is after curwin->w_cursor
top = &curwin->w_cursor;
bot = &VIsual;
}
else /* Visual is before curwin->w_cursor */
else
{
// Visual is before curwin->w_cursor
top = &VIsual;
bot = &curwin->w_cursor;
}
lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
if (VIsual_mode == Ctrl_V) /* block mode */
if (VIsual_mode == Ctrl_V)
{
// block mode
if (lnum_in_visual_area)
{
fromcol = wp->w_old_cursor_fcol;
tocol = wp->w_old_cursor_lcol;
}
}
else /* non-block mode */
else
{
// non-block mode
if (lnum > top->lnum && lnum <= bot->lnum)
fromcol = 0;
else if (lnum == top->lnum)
{
if (VIsual_mode == 'V') /* linewise */
if (VIsual_mode == 'V') // linewise
fromcol = 0;
else
{
+3
View File
@@ -2953,6 +2953,9 @@ struct window_S
linenr_T w_popup_lnum; // close popup if cursor not on this line
colnr_T w_popup_mincol; // close popup if cursor before this col
colnr_T w_popup_maxcol; // close popup if cursor after this col
int w_popup_mouse_row; // close popup if mouse moves away
int w_popup_mouse_mincol; // close popup if mouse moves away
int w_popup_mouse_maxcol; // close popup if mouse moves away
int w_popup_drag; // allow moving the popup with the mouse
popclose_T w_popup_close; // allow closing the popup with the mouse
+5 -5
View File
@@ -1,10 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @18|#+0#e000e06#e0e0e08|i|n|c|l|u|d|e| |<+0#e000002&|s|t|d|i|o|.|h|>| +0#0000000#ffffff0@36
|4| @18|i+0#00e0003#e0e0e08|n|t| +0#0000000&|m|a|i|n|(|v+0#00e0003&|o|i|d|)+0#0000000&| @3| +0&#ffffff0@36
|5| @18|{+0&#e0e0e08| @16| +0&#ffffff0@36
|6| @18| +0&#e0e0e08@3|p|r|i|n|t|f|(|5+0#e000002&|6|7|)+0#0000000&|;| @1| +0&#ffffff0@36
|7| @18|}+0&#e0e0e08| @16| +0&#ffffff0@36
|3| @18|#+0#e000e06#e0e0e08|i|n|c|l|u|d|e| |<+0#e000002&|s|t|d|i|o|.|h|>| +0#0000000&@1| +0&#ffffff0@34
|4| @18|i+0#00e0003#e0e0e08|n|t| +0#0000000&|m|a|i|n|(|v+0#00e0003&|o|i|d|)+0#0000000&| @5| +0&#ffffff0@34
|5| @18|{+0&#e0e0e08| @18| +0&#ffffff0@34
|6| @18| +0&#e0e0e08@7|p|r|i|n|t|f|(|5+0#e000002&|6|7|)+0#0000000&|;| +0&#ffffff0@34
|7| @18|}+0&#e0e0e08| @18| +0&#ffffff0@34
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|
+12
View File
@@ -0,0 +1,12 @@
>1+0&#ffffff0| @73
|2| |╔+0&#5fd7ff255|═@11|╗| +0&#ffffff0@5|╔+0&#dadada255|═@11|╗+0&#8a8a8a255| +0&#ffffff0@5|x+0&#5fd7ff255@13| +0&#ffffff0@2|#+0&#5fd7ff255|x@11|#| +0&#ffffff0@1
|3| |║+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|║+0#0000000#5fd7ff255| +0&#ffffff0@5|║+0&#a8a8a8255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|║+0#0000000#8a8a8a255| +0&#ffffff0@5|x+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|x+0#0000000#5fd7ff255| +0&#ffffff0@2|x+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|x+0#0000000#5fd7ff255| +0&#ffffff0@1
|4| |╚+0&#5fd7ff255|═@11|╝| +0&#ffffff0@5|║+0&#a8a8a8255|a+0#0000001#ffd7ff255|n|d| |m|o|r|e| @3|║+0#0000000#8a8a8a255| +0&#ffffff0@5|x+0&#5fd7ff255|l+0#0000001#ffd7ff255|i|n|e|s| |o|n|l|y| @1|x+0#0000000#5fd7ff255| +0&#ffffff0@2|x+0&#5fd7ff255|w+0#0000001#ffd7ff255|i|t|h| |c|o|r|n|e|r|s|x+0#0000000#5fd7ff255| +0&#ffffff0@1
|5| @20|╚+0&#585858255|═@11|╝| +0&#ffffff0@5|x+0&#5fd7ff255@13| +0&#ffffff0@2|#+0&#5fd7ff255|x@11|#| +0&#ffffff0@1
|6| |e+0&#5fd7ff255|a@11|f| +0&#ffffff0@58
|7| |d+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|b+0#0000000#5fd7ff255| +0&#ffffff0@5| +0&#5fd7ff255@13| +0&#ffffff0@38
|8| |d+0&#5fd7ff255|w+0#0000001#ffd7ff255|i|t|h| |n|u|m|b|e|r|s|b+0#0000000#5fd7ff255| +0&#ffffff0@5| +0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r| +0#0000000#5fd7ff255| +0&#ffffff0@5|┌+0#0000001#ffd7ff255|─@4|┐| +0#0000000#ffffff0@25
|9| |h+0&#5fd7ff255|c@11|g| +0&#ffffff0@5| +0&#5fd7ff255|j+0#0000001#ffd7ff255|u|s|t| |b|l|a|n|k|s| | +0#0000000#5fd7ff255| +0&#ffffff0@5|│+0#0000001#ffd7ff255|h|e|l@1|o|│| +0#0000000#ffffff0@25
|1|0| @19| +0&#5fd7ff255@13| +0&#ffffff0@5|└+0#0000001#ffd7ff255|─@4|┘| +0#0000000#ffffff0@25
|1@1| @72
|:|c|a|l@1| |M|u|l|t|i|B|y|t|e|(|)| @39|1|,|1| @10|T|o|p|
@@ -0,0 +1,10 @@
|1+0&#ffffff0| @73
>2| @73
|3| @73
|4| @12|t+0#0000001#ffd7ff255|e|x|t| +0#0000000#ffffff0@56
|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
|6| @73
|7| @73
|8| @73
|9| @73
|:|c|a|l@1| |H|o|v|e|r|(|)| @43|2|,|1| @10|T|o|p|
@@ -0,0 +1,10 @@
|1+0&#ffffff0| @73
>2| @73
|3| @73
|4| @12|t+0#0000001#ffd7ff255|e|x|t| +0#0000000#ffffff0@56
|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
|6| @73
|7| @73
|8| @73
|9| @73
|:|c|a|l@1| |M|o|v|e|O|n|t|o|P|o|p|u|p|(|)| @35|2|,|1| @10|T|o|p|
@@ -0,0 +1,10 @@
|1+0&#ffffff0| @73
>2| @73
|3| @73
|4| @73
|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
|6| @73
|7| @73
|8| @73
|9| @73
|:|c|a|l@1| |M|o|v|e|A|w|a|y|(|)| @40|2|,|1| @10|T|o|p|
+6
View File
@@ -166,6 +166,12 @@ func Test_assert_fail_fails()
call remove(v:errors, 0)
endfunc
func Test_assert_fails_in_try_block()
try
call assert_equal(0, assert_fails('throw "error"'))
endtry
endfunc
func Test_assert_beeps()
new
call assert_equal(0, assert_beeps('normal h'))
+28
View File
@@ -72,3 +72,31 @@ func Test_curswant_with_cursorline()
call assert_equal(6, winsaveview().curswant)
quit!
endfunc
func Test_screenpos()
rightbelow new
rightbelow 20vsplit
call setline(1, ["\tsome text", "long wrapping line here", "next line"])
redraw
let winid = win_getid()
let [winrow, wincol] = win_screenpos(winid)
call assert_equal({'row': winrow,
\ 'col': wincol + 0,
\ 'curscol': wincol + 7,
\ 'endcol': wincol + 7}, screenpos(winid, 1, 1))
call assert_equal({'row': winrow,
\ 'col': wincol + 13,
\ 'curscol': wincol + 13,
\ 'endcol': wincol + 13}, screenpos(winid, 1, 7))
call assert_equal({'row': winrow + 2,
\ '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))
close
bwipe!
endfunc
+11
View File
@@ -252,3 +252,14 @@ func Test_numberwidth_adjusted()
call s:compare_lines(expect, lines)
call s:close_windows()
endfunc
" This was causing a memcheck error
func Test_relativenumber_uninitialised()
new
set rnu
call setline(1, ["a", "b"])
redraw
call feedkeys("j", 'xt')
redraw
bwipe!
endfunc
+61 -5
View File
@@ -113,6 +113,9 @@ func Test_popup_with_border_and_padding()
call popup_create(['hello border', 'with corners'], {'line': 2, 'col': 60, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['x', '#']})
let winid = popup_create(['hello border', 'with numbers'], {'line': 6, 'col': 3, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['0', '1', '2', '3', '4', '5', '6', '7']})
call popup_create(['hello border', 'just blanks'], {'line': 7, 'col': 23, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': [' ']})
func MultiByte()
call popup_create(['hello'], {'line': 8, 'col': 43, 'border': [], 'borderchars': ['─', '│', '─', '│', '┌', '┐', '┘', '└']})
endfunc
END
call writefile(lines, 'XtestPopupBorder')
let buf = RunVimInTerminal('-S XtestPopupBorder', {'rows': 12})
@@ -122,6 +125,12 @@ func Test_popup_with_border_and_padding()
call term_sendkeys(buf, ":call popup_setoptions(winid, {'borderchars': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']})\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_23', {})
" check multi-byte border only with 'ambiwidth' single
if &ambiwidth == 'single'
call term_sendkeys(buf, ":call MultiByte()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_24', {})
endif
call StopVimInTerminal(buf)
call delete('XtestPopupBorder')
@@ -216,7 +225,7 @@ func Test_popup_with_syntax_setbufvar()
\ '#include <stdio.h>',
\ 'int main(void)',
\ '{',
\ ' printf(567);',
\ "\tprintf(567);",
\ '}',
\], {'line': 3, 'col': 21, 'highlight': 'PopupColor'})
call setbufvar(winbufnr(winid), '&syntax', 'cpp')
@@ -1005,6 +1014,53 @@ func Test_popup_atcursor()
bwipe!
endfunc
func Test_popup_beval()
if !CanRunVimInTerminal()
throw 'Skipped: cannot make screendumps'
endif
let lines =<< trim END
call setline(1, range(1, 20))
call setline(5, 'here is some text to hover over')
set balloonevalterm
set balloonexpr=BalloonExpr()
set balloondelay=100
func BalloonExpr()
let s:winid = popup_beval([v:beval_text], {})
return ''
endfunc
func Hover()
call test_setmouse(5, 15)
call feedkeys("\<MouseMove>\<Ignore>", "xt")
sleep 100m
endfunc
func MoveOntoPopup()
call test_setmouse(4, 17)
call feedkeys("\<F4>\<MouseMove>\<Ignore>", "xt")
endfunc
func MoveAway()
call test_setmouse(5, 13)
call feedkeys("\<F5>\<MouseMove>\<Ignore>", "xt")
endfunc
END
call writefile(lines, 'XtestPopupBeval')
let buf = RunVimInTerminal('-S XtestPopupBeval', {'rows': 10})
call term_wait(buf, 100)
call term_sendkeys(buf, 'j')
call term_sendkeys(buf, ":call Hover()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_beval_1', {})
call term_sendkeys(buf, ":call MoveOntoPopup()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_beval_2', {})
call term_sendkeys(buf, ":call MoveAway()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_beval_3', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopupBeval')
endfunc
func Test_popup_filter()
new
call setline(1, 'some text')
@@ -1413,7 +1469,7 @@ func Test_popup_moved()
let winid = popup_atcursor('text', {'moved': 'any'})
redraw
call assert_equal(1, popup_getpos(winid).visible)
call assert_equal([4, 4], popup_getoptions(winid).moved)
call assert_equal([1, 4, 4], popup_getoptions(winid).moved)
" trigger the check for last_cursormoved by going into insert mode
call feedkeys("li\<Esc>", 'xt')
call assert_equal({}, popup_getpos(winid))
@@ -1423,7 +1479,7 @@ func Test_popup_moved()
let winid = popup_atcursor('text', {'moved': 'word'})
redraw
call assert_equal(1, popup_getpos(winid).visible)
call assert_equal([4, 7], popup_getoptions(winid).moved)
call assert_equal([1, 4, 7], popup_getoptions(winid).moved)
call feedkeys("hi\<Esc>", 'xt')
call assert_equal({}, popup_getpos(winid))
call popup_clear()
@@ -1432,7 +1488,7 @@ func Test_popup_moved()
let winid = popup_atcursor('text', {'moved': 'word'})
redraw
call assert_equal(1, popup_getpos(winid).visible)
call assert_equal([4, 7], popup_getoptions(winid).moved)
call assert_equal([1, 4, 7], popup_getoptions(winid).moved)
call feedkeys("li\<Esc>", 'xt')
call assert_equal(1, popup_getpos(winid).visible)
call feedkeys("ei\<Esc>", 'xt')
@@ -1446,7 +1502,7 @@ func Test_popup_moved()
let winid = popup_atcursor('text', {})
redraw
call assert_equal(1, popup_getpos(winid).visible)
call assert_equal([2, 15], popup_getoptions(winid).moved)
call assert_equal([2, 2, 15], popup_getoptions(winid).moved)
call feedkeys("eli\<Esc>", 'xt')
call assert_equal(1, popup_getpos(winid).visible)
call feedkeys("wi\<Esc>", 'xt')
+1
View File
@@ -54,6 +54,7 @@ func Test_suspend()
" Quit gracefully to dump coverage information.
call term_sendkeys(buf, ":qall!\<CR>")
call term_wait(buf)
" Wait until Vim actually exited and shell shows a prompt
call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
call StopShellInTerminal(buf)
+42
View File
@@ -792,6 +792,48 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1661,
/**/
1660,
/**/
1659,
/**/
1658,
/**/
1657,
/**/
1656,
/**/
1655,
/**/
1654,
/**/
1653,
/**/
1652,
/**/
1651,
/**/
1650,
/**/
1649,
/**/
1648,
/**/
1647,
/**/
1646,
/**/
1645,
/**/
1644,
/**/
1643,
/**/
1642,
/**/
1641,
/**/
1640,
/**/