summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-11-18 18:52:04 +0100
committerBram Moolenaar <Bram@vim.org>2017-11-18 18:52:04 +0100
commit51b0f3701ecb440aa72ab6017c1df6940c0e0f6f (patch)
tree9cfd3546d8e52be2b1425dcc65095f8e650eadde /src
parent234d16286a2733adedef56784c17415ae169b9ad (diff)
downloadvim-git-51b0f3701ecb440aa72ab6017c1df6940c0e0f6f.tar.gz
patch 8.0.1309: cannot use 'balloonexpr' in a terminalv8.0.1309
Problem: Cannot use 'balloonexpr' in a terminal. Solution: Add 'balloonevalterm' and add code to handle mouse movements in a terminal. Initial implementation for Unix with GUI.
Diffstat (limited to 'src')
-rw-r--r--src/edit.c1
-rw-r--r--src/evalfunc.c5
-rw-r--r--src/ex_cmds2.c39
-rw-r--r--src/ex_getln.c1
-rw-r--r--src/feature.h7
-rw-r--r--src/getchar.c8
-rw-r--r--src/globals.h6
-rw-r--r--src/gui.c5
-rw-r--r--src/gui_beval.c42
-rw-r--r--src/keymap.h2
-rw-r--r--src/message.c1
-rw-r--r--src/misc1.c1
-rw-r--r--src/misc2.c3
-rw-r--r--src/normal.c18
-rw-r--r--src/option.c26
-rw-r--r--src/option.h3
-rw-r--r--src/os_unix.c65
-rw-r--r--src/popupmnu.c167
-rw-r--r--src/proto/gui_beval.pro1
-rw-r--r--src/proto/os_unix.pro1
-rw-r--r--src/proto/popupmnu.pro3
-rw-r--r--src/term.c1
-rw-r--r--src/terminal.c6
-rw-r--r--src/version.c7
24 files changed, 343 insertions, 76 deletions
diff --git a/src/edit.c b/src/edit.c
index 435e1ed81..65c53f52f 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1177,6 +1177,7 @@ doESCkey:
case K_LEFTDRAG:
case K_LEFTRELEASE:
case K_LEFTRELEASE_NM:
+ case K_MOUSEMOVE:
case K_MIDDLEMOUSE:
case K_MIDDLEDRAG:
case K_MIDDLERELEASE:
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 25b28bb3a..bd5cf8dec 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1410,7 +1410,7 @@ f_atan2(typval_T *argvars, typval_T *rettv)
f_balloon_show(typval_T *argvars, typval_T *rettv UNUSED)
{
if (balloonEval != NULL)
- gui_mch_post_balloon(balloonEval, get_tv_string_chk(&argvars[0]));
+ post_balloon(balloonEval, get_tv_string_chk(&argvars[0]));
}
#endif
@@ -5589,6 +5589,9 @@ f_has(typval_T *argvars, typval_T *rettv)
"balloon_multiline",
# endif
#endif
+#ifdef FEAT_BEVALTERM
+ "balloon_eval_term",
+#endif
#if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
"builtin_terms",
# ifdef ALL_BUILTIN_TCAPS
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 2eef050ee..c6a6dbe14 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1093,21 +1093,21 @@ static timer_T *first_timer = NULL;
static long last_timer_id = 0;
static long
-timer_time_left(timer_T *timer, proftime_T *now)
+proftime_time_left(proftime_T *due, proftime_T *now)
{
# ifdef WIN3264
LARGE_INTEGER fr;
- if (now->QuadPart > timer->tr_due.QuadPart)
+ if (now->QuadPart > due->QuadPart)
return 0;
QueryPerformanceFrequency(&fr);
- return (long)(((double)(timer->tr_due.QuadPart - now->QuadPart)
+ return (long)(((double)(due->QuadPart - now->QuadPart)
/ (double)fr.QuadPart) * 1000);
# else
- if (now->tv_sec > timer->tr_due.tv_sec)
+ if (now->tv_sec > due->tv_sec)
return 0;
- return (timer->tr_due.tv_sec - now->tv_sec) * 1000
- + (timer->tr_due.tv_usec - now->tv_usec) / 1000;
+ return (due->tv_sec - now->tv_sec) * 1000
+ + (due->tv_usec - now->tv_usec) / 1000;
# endif
}
@@ -1219,7 +1219,7 @@ check_due_timer(void)
if (timer->tr_id == -1 || timer->tr_firing || timer->tr_paused)
continue;
- this_due = timer_time_left(timer, &now);
+ this_due = proftime_time_left(&timer->tr_due, &now);
if (this_due <= 1)
{
int save_timer_busy = timer_busy;
@@ -1271,7 +1271,7 @@ check_due_timer(void)
&& timer->tr_emsg_count < 3)
{
profile_setlimit(timer->tr_interval, &timer->tr_due);
- this_due = timer_time_left(timer, &now);
+ this_due = proftime_time_left(&timer->tr_due, &now);
if (this_due < 1)
this_due = 1;
if (timer->tr_repeat > 0)
@@ -1291,6 +1291,27 @@ check_due_timer(void)
if (did_one)
redraw_after_callback(need_update_screen);
+#ifdef FEAT_BEVALTERM
+ if (bevalexpr_due_set)
+ {
+ this_due = proftime_time_left(&bevalexpr_due, &now);
+ if (this_due <= 1)
+ {
+ bevalexpr_due_set = FALSE;
+
+ if (balloonEval == NULL)
+ {
+ balloonEval = (BalloonEval *)alloc(sizeof(BalloonEval));
+ balloonEvalForTerm = TRUE;
+ }
+ if (balloonEval != NULL)
+ general_beval_cb(balloonEval, 0);
+ }
+ else if (this_due > 0 && (next_due == -1 || next_due > this_due))
+ next_due = this_due;
+ }
+#endif
+
return current_id != last_timer_id ? 1 : next_due;
}
@@ -1358,7 +1379,7 @@ add_timer_info(typval_T *rettv, timer_T *timer)
dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL);
profile_start(&now);
- remaining = timer_time_left(timer, &now);
+ remaining = proftime_time_left(&timer->tr_due, &now);
dict_add_nr_str(dict, "remaining", (long)remaining, NULL);
dict_add_nr_str(dict, "repeat",
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 7c0db89a8..f8a193d1d 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1452,6 +1452,7 @@ getcmdline(
case K_X2MOUSE:
case K_X2DRAG:
case K_X2RELEASE:
+ case K_MOUSEMOVE:
goto cmdline_not_changed;
#endif /* FEAT_MOUSE */
diff --git a/src/feature.h b/src/feature.h
index a6a159997..f17a5c167 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -1328,6 +1328,13 @@
# define FEAT_BEVAL_TIP /* balloon eval used for toolbar tooltip */
#endif
+/*
+ * +balloon_eval_term Allow balloon expression evaluation in the terminal.
+ */
+#if defined(FEAT_BEVAL) && defined(UNIX) && defined(FEAT_TIMERS)
+# define FEAT_BEVALTERM
+#endif
+
/* both Motif and Athena are X11 and share some code */
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
# define FEAT_GUI_X11
diff --git a/src/getchar.c b/src/getchar.c
index 455c01388..2e91c24c1 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1792,6 +1792,14 @@ vgetc(void)
*/
may_garbage_collect = FALSE;
#endif
+#ifdef FEAT_BEVALTERM
+ if (c != K_MOUSEMOVE && c != K_IGNORE)
+ {
+ /* Don't trigger 'balloonexpr' unless only the mouse was moved. */
+ bevalexpr_due_set = FALSE;
+ ui_remove_balloon();
+ }
+#endif
return c;
}
diff --git a/src/globals.h b/src/globals.h
index ae62710d5..c19866497 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1231,6 +1231,7 @@ EXTERN int no_hlsearch INIT(= FALSE);
#if defined(FEAT_BEVAL) && !defined(NO_X11_INCLUDES)
EXTERN BalloonEval *balloonEval INIT(= NULL);
+EXTERN int balloonEvalForTerm INIT(= FALSE);
# if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP)
EXTERN int bevalServers INIT(= 0);
# define BEVAL_NETBEANS 0x01
@@ -1648,6 +1649,11 @@ EXTERN int did_add_timer INIT(= FALSE);
EXTERN int timer_busy INIT(= 0); /* when timer is inside vgetc() then > 0 */
#endif
+#ifdef FEAT_BEVALTERM
+EXTERN int bevalexpr_due_set INIT(= FALSE);
+EXTERN proftime_T bevalexpr_due;
+#endif
+
#ifdef FEAT_EVAL
EXTERN time_T time_for_testing INIT(= 0);
diff --git a/src/gui.c b/src/gui.c
index 7ef1c9534..926750cb2 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -740,7 +740,10 @@ gui_init(void)
#ifdef FEAT_BEVAL
/* Always create the Balloon Evaluation area, but disable it when
- * 'ballooneval' is off */
+ * 'ballooneval' is off. */
+ if (balloonEval != NULL)
+ vim_free(balloonEval);
+ balloonEvalForTerm = FALSE;
# ifdef FEAT_GUI_GTK
balloonEval = gui_mch_create_beval_area(gui.drawarea, NULL,
&general_beval_cb, NULL);
diff --git a/src/gui_beval.c b/src/gui_beval.c
index 1c01ecc84..ada048c62 100644
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -35,7 +35,11 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
/* Don't do anything when 'ballooneval' is off, messages scrolled the
* windows up or we have no beval area. */
- if (!p_beval || balloonEval == NULL || msg_scrolled > 0)
+ if (!((gui.in_use && p_beval)
+# ifdef FEAT_BEVALTERM
+ || (!gui.in_use && p_bevalterm)
+# endif
+ ) || beval == NULL || msg_scrolled > 0)
return;
/* Don't do this recursively. Happens when the expression evaluation
@@ -45,7 +49,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
recursive = TRUE;
#ifdef FEAT_EVAL
- if (get_beval_info(balloonEval, TRUE, &wp, &lnum, &text, &col) == OK)
+ if (get_beval_info(beval, TRUE, &wp, &lnum, &text, &col) == OK)
{
bexpr = (*wp->w_buffer->b_p_bexpr == NUL) ? p_bexpr
: wp->w_buffer->b_p_bexpr;
@@ -96,7 +100,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
if (result != NULL && result[0] != NUL)
{
- gui_mch_post_balloon(beval, result);
+ post_balloon(beval, result);
recursive = FALSE;
return;
}
@@ -335,8 +339,18 @@ get_beval_info(
linenr_T lnum;
*textp = NULL;
- row = Y_2_ROW(beval->y);
- col = X_2_COL(beval->x);
+# ifdef FEAT_BEVALTERM
+ if (!gui.in_use)
+ {
+ row = mouse_row;
+ col = mouse_col;
+ }
+ else
+# endif
+ {
+ row = Y_2_ROW(beval->y);
+ col = X_2_COL(beval->x);
+ }
wp = mouse_find_win(&row, &col);
if (wp != NULL && row < wp->w_height && col < wp->w_width)
{
@@ -421,6 +435,20 @@ get_beval_info(
return FAIL;
}
+/*
+ * Show a balloon with "mesg".
+ */
+ void
+post_balloon(BalloonEval *beval, char_u *mesg)
+{
+# ifdef FEAT_BEVALTERM
+ if (!gui.in_use)
+ ui_post_balloon(mesg);
+ else
+# endif
+ gui_mch_post_balloon(beval, mesg);
+}
+
# if !defined(FEAT_GUI_W32) || defined(PROTO)
/*
@@ -451,10 +479,6 @@ gui_mch_unpost_balloon(BalloonEval *beval)
#endif
#ifdef FEAT_GUI_GTK
-/*
- * We can unconditionally use ANSI-style prototypes here since
- * GTK+ requires an ANSI C compiler anyway.
- */
static void
addEventHandler(GtkWidget *target, BalloonEval *beval)
{
diff --git a/src/keymap.h b/src/keymap.h
index 7cb5c69bc..8a34f0e29 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -269,6 +269,7 @@ enum key_extra
, KE_NOP = 97 /* doesn't do something */
, KE_FOCUSGAINED = 98 /* focus gained */
, KE_FOCUSLOST = 99 /* focus lost */
+ , KE_MOUSEMOVE = 100 /* mouse moved with no button down */
};
/*
@@ -437,6 +438,7 @@ enum key_extra
#define K_LEFTDRAG TERMCAP2KEY(KS_EXTRA, KE_LEFTDRAG)
#define K_LEFTRELEASE TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE)
#define K_LEFTRELEASE_NM TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE_NM)
+#define K_MOUSEMOVE TERMCAP2KEY(KS_EXTRA, KE_MOUSEMOVE)
#define K_MIDDLEMOUSE TERMCAP2KEY(KS_EXTRA, KE_MIDDLEMOUSE)
#define K_MIDDLEDRAG TERMCAP2KEY(KS_EXTRA, KE_MIDDLEDRAG)
#define K_MIDDLERELEASE TERMCAP2KEY(KS_EXTRA, KE_MIDDLERELEASE)
diff --git a/src/message.c b/src/message.c
index 221e3d801..c40b6cf15 100644
--- a/src/message.c
+++ b/src/message.c
@@ -1179,6 +1179,7 @@ wait_return(int redraw)
|| c == K_RIGHTDRAG || c == K_RIGHTRELEASE
|| c == K_MOUSELEFT || c == K_MOUSERIGHT
|| c == K_MOUSEDOWN || c == K_MOUSEUP
+ || c == K_MOUSEMOVE
|| (!mouse_has(MOUSE_RETURN)
&& mouse_row < msg_row
&& (c == K_LEFTMOUSE
diff --git a/src/misc1.c b/src/misc1.c
index f33fd3b9e..4c691bb25 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3345,6 +3345,7 @@ is_mouse_key(int c)
|| c == K_LEFTDRAG
|| c == K_LEFTRELEASE
|| c == K_LEFTRELEASE_NM
+ || c == K_MOUSEMOVE
|| c == K_MIDDLEMOUSE
|| c == K_MIDDLEDRAG
|| c == K_MIDDLERELEASE
diff --git a/src/misc2.c b/src/misc2.c
index 63d9e81d6..87b79fae1 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2453,6 +2453,7 @@ static struct key_name_entry
{K_LEFTDRAG, (char_u *)"LeftDrag"},
{K_LEFTRELEASE, (char_u *)"LeftRelease"},
{K_LEFTRELEASE_NM, (char_u *)"LeftReleaseNM"},
+ {K_MOUSEMOVE, (char_u *)"MouseMove"},
{K_MIDDLEMOUSE, (char_u *)"MiddleMouse"},
{K_MIDDLEDRAG, (char_u *)"MiddleDrag"},
{K_MIDDLERELEASE, (char_u *)"MiddleRelease"},
@@ -2515,7 +2516,7 @@ static struct mousetable
{(int)KE_X2DRAG, MOUSE_X2, FALSE, TRUE},
{(int)KE_X2RELEASE, MOUSE_X2, FALSE, FALSE},
/* DRAG without CLICK */
- {(int)KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE},
+ {(int)KE_MOUSEMOVE, MOUSE_RELEASE, FALSE, TRUE},
/* RELEASE without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE},
{0, 0, 0, 0},
diff --git a/src/normal.c b/src/normal.c
index e781cd70e..81bedfdba 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -358,6 +358,7 @@ static const struct nv_cmd
{K_LEFTDRAG, nv_mouse, 0, 0},
{K_LEFTRELEASE, nv_mouse, 0, 0},
{K_LEFTRELEASE_NM, nv_mouse, 0, 0},
+ {K_MOUSEMOVE, nv_mouse, 0, 0},
{K_MIDDLEMOUSE, nv_mouse, 0, 0},
{K_MIDDLEDRAG, nv_mouse, 0, 0},
{K_MIDDLERELEASE, nv_mouse, 0, 0},
@@ -2396,6 +2397,20 @@ do_mouse(
break;
}
+ if (c == K_MOUSEMOVE)
+ {
+ /* Mouse moved without a button pressed. */
+#ifdef FEAT_BEVALTERM
+ ui_may_remove_balloon();
+ if (p_bevalterm && !VIsual_active)
+ {
+ profile_setlimit(p_bdlay, &bevalexpr_due);
+ bevalexpr_due_set = TRUE;
+ }
+#endif
+ return FALSE;
+ }
+
#ifdef FEAT_MOUSESHAPE
/* May have stopped dragging the status or separator line. The pointer is
* most likely still on the status or separator line. */
@@ -3843,7 +3858,7 @@ add_to_showcmd(int c)
K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
# endif
K_IGNORE, K_PS,
- K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
+ K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE, K_MOUSEMOVE,
K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
@@ -8358,6 +8373,7 @@ nv_g_cmd(cmdarg_T *cap)
case K_LEFTMOUSE:
case K_LEFTDRAG:
case K_LEFTRELEASE:
+ case K_MOUSEMOVE:
case K_RIGHTMOUSE:
case K_RIGHTDRAG:
case K_RIGHTRELEASE:
diff --git a/src/option.c b/src/option.c
index 4f25c1ff4..495a89ddd 100644
--- a/src/option.c
+++ b/src/option.c
@@ -642,6 +642,15 @@ static struct vimoption options[] =
{(char_u *)0L, (char_u *)0L}
#endif
SCRIPTID_INIT},
+ {"balloonevalterm", "bevalterm",P_BOOL|P_VI_DEF|P_NO_MKRC,
+#ifdef FEAT_BEVALTERM
+ (char_u *)&p_bevalterm, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
{"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
(char_u *)&p_bexpr, PV_BEXPR,
@@ -8423,12 +8432,21 @@ set_bool_option(
#ifdef FEAT_BEVAL
else if ((int *)varp == &p_beval)
{
- if (p_beval && !old_value)
- gui_mch_enable_beval_area(balloonEval);
- else if (!p_beval && old_value)
- gui_mch_disable_beval_area(balloonEval);
+ if (!balloonEvalForTerm)
+ {
+ if (p_beval && !old_value)
+ gui_mch_enable_beval_area(balloonEval);
+ else if (!p_beval && old_value)
+ gui_mch_disable_beval_area(balloonEval);
+ }
}
#endif
+# ifdef FEAT_BEVALTERM
+ else if ((int *)varp == &p_bevalterm)
+ {
+ mch_bevalterm_changed();
+ }
+# endif
#ifdef FEAT_AUTOCHDIR
else if ((int *)varp == &p_acd)
diff --git a/src/option.h b/src/option.h
index f9972f21a..2084517d5 100644
--- a/src/option.h
+++ b/src/option.h
@@ -382,6 +382,9 @@ EXTERN int p_beval; /* 'ballooneval' */
EXTERN char_u *p_bexpr;
# endif
#endif
+# ifdef FEAT_BEVALTERM
+EXTERN int p_bevalterm; /* 'balloonevalterm' */
+# endif
#ifdef FEAT_BROWSE
EXTERN char_u *p_bsdir; /* 'browsedir' */
#endif
diff --git a/src/os_unix.c b/src/os_unix.c
index d2f080529..1c2a90276 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3564,16 +3564,25 @@ get_tty_info(int fd, ttyinfo_T *info)
#endif /* VMS */
#if defined(FEAT_MOUSE_TTY) || defined(PROTO)
+static int mouse_ison = FALSE;
+
/*
* Set mouse clicks on or off.
*/
void
mch_setmouse(int on)
{
- static int ison = FALSE;
+# ifdef FEAT_BEVALTERM
+ static int bevalterm_ison = FALSE;
+# endif
int xterm_mouse_vers;
- if (on == ison) /* return quickly if nothing to do */
+ if (on == mouse_ison
+# ifdef FEAT_BEVALTERM
+ && p_bevalterm == bevalterm_ison
+# endif
+ )
+ /* return quickly if nothing to do */
return;
xterm_mouse_vers = use_xterm_mouse();
@@ -3585,18 +3594,30 @@ mch_setmouse(int on)
(on
? IF_EB("\033[?1015h", ESC_STR "[?1015h")
: IF_EB("\033[?1015l", ESC_STR "[?1015l")));
- ison = on;
+ mouse_ison = on;
}
# endif
# ifdef FEAT_MOUSE_SGR
if (ttym_flags == TTYM_SGR)
{
+ /* SGR mode supports columns above 223 */
out_str_nf((char_u *)
(on
? IF_EB("\033[?1006h", ESC_STR "[?1006h")
: IF_EB("\033[?1006l", ESC_STR "[?1006l")));
- ison = on;
+ mouse_ison = on;
+ }
+# endif
+
+# ifdef FEAT_BEVALTERM
+ if (bevalterm_ison != (p_bevalterm && on))
+ {
+ bevalterm_ison = (p_bevalterm && on);
+ if (xterm_mouse_vers > 1 && !bevalterm_ison)
+ /* disable mouse movement events, enabling is below */
+ out_str_nf((char_u *)
+ (IF_EB("\033[?1003l", ESC_STR "[?1003l")));
}
# endif
@@ -3605,14 +3626,19 @@ mch_setmouse(int on)
if (on) /* enable mouse events, use mouse tracking if available */
out_str_nf((char_u *)
(xterm_mouse_vers > 1
- ? IF_EB("\033[?1002h", ESC_STR "[?1002h")
+ ? (
+# ifdef FEAT_BEVALTERM
+ bevalterm_ison
+ ? IF_EB("\033[?1003h", ESC_STR "[?1003h") :
+# endif
+ IF_EB("\033[?1002h", ESC_STR "[?1002h"))
: IF_EB("\033[?1000h", ESC_STR "[?1000h")));
else /* disable mouse events, could probably always send the same */
out_str_nf((char_u *)
(xterm_mouse_vers > 1
? IF_EB("\033[?1002l", ESC_STR "[?1002l")
: IF_EB("\033[?1000l", ESC_STR "[?1000l")));
- ison = on;
+ mouse_ison = on;
}
# ifdef FEAT_MOUSE_DEC
@@ -3622,7 +3648,7 @@ mch_setmouse(int on)
out_str_nf((char_u *)"\033[1;2'z\033[1;3'{");
else /* disable mouse events */
out_str_nf((char_u *)"\033['z");
- ison = on;
+ mouse_ison = on;
}
# endif
@@ -3632,12 +3658,12 @@ mch_setmouse(int on)
if (on)
{
if (gpm_open())
- ison = TRUE;
+ mouse_ison = TRUE;
}
else
{
gpm_close();
- ison = FALSE;
+ mouse_ison = FALSE;
}
}
# endif
@@ -3648,12 +3674,12 @@ mch_setmouse(int on)
if (on)
{
if (sysmouse_open() == OK)
- ison = TRUE;
+ mouse_ison = TRUE;
}
else
{
sysmouse_close();
- ison = FALSE;
+ mouse_ison = FALSE;
}
}
# endif
@@ -3686,13 +3712,13 @@ mch_setmouse(int on)
out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK+1Q\033\\",
ESC_STR "[0~ZwLMRK+1Q" ESC_STR "\\"));
# endif
- ison = TRUE;
+ mouse_ison = TRUE;
}
else
{
out_str_nf((char_u *)IF_EB("\033[0~ZwQ\033\\",
ESC_STR "[0~ZwQ" ESC_STR "\\"));
- ison = FALSE;
+ mouse_ison = FALSE;
}
}
# endif
@@ -3704,11 +3730,22 @@ mch_setmouse(int on)
out_str_nf("\033[>1h\033[>6h\033[>7h\033[>1h\033[>9l");
else
out_str_nf("\033[>1l\033[>6l\033[>7l\033[>1l\033[>9h");
- ison = on;
+ mouse_ison = on;
}
# endif
}
+#if defined(FEAT_BEVALTERM) || defined(PROTO)
+/*
+ * Called when 'balloonevalterm' changed.
+ */
+ void
+mch_bevalterm_changed(void)
+{
+ mch_setmouse(mouse_ison);
+}
+#endif
+
/*
* Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
*/
diff --git a/src/popupmnu.c b/src/popupmnu.c
index ec75281e7..dc66e7594 100644
--- a/src/popupmnu.c
+++ b/src/popupmnu.c
@@ -23,6 +23,7 @@ static int pum_height; /* nr of displayed pum items */
static int pum_width; /* width of displayed pum items */
static int pum_base_width; /* width of pum items base */
static int pum_kind_width; /* width of pum items kind column */
+static int pum_extra_width; /* width of extra stuff */
static int pum_scrollbar; /* TRUE when scrollbar present */
static int pum_row; /* top row of pum */
@@ -35,6 +36,36 @@ static int pum_set_selected(int n, int repeat);
#define PUM_DEF_HEIGHT 10
#define PUM_DEF_WIDTH 15
+ static void
+pum_compute_size(void)
+{
+ int i;
+ int w;
+
+ /* Compute the width of the widest match and the widest extra. */
+ pum_base_width = 0;
+ pum_kind_width = 0;
+ pum_extra_width = 0;
+ for (i = 0; i < pum_size; ++i)
+ {
+ w = vim_strsize(pum_array[i].pum_text);
+ if (pum_base_width < w)
+ pum_base_width = w;
+ if (pum_array[i].pum_kind != NULL)
+ {
+ w = vim_strsize(pum_array[i].pum_kind) + 1;
+ if (pum_kind_width < w)
+ pum_kind_width = w;
+ }
+ if (pum_array[i].pum_extra != NULL)
+ {
+ w = vim_strsize(pum_array[i].pum_extra) + 1;
+ if (pum_extra_width < w)
+ pum_extra_width = w;
+ }
+ }
+}
+
/*
* Show the popup menu with items "array[size]".
* "array" must remain valid until pum_undisplay() is called!
@@ -48,12 +79,8 @@ pum_display(
int selected) /* index of initially selected item, none if
out of range */
{
- int w;
int def_width;
int max_width;
- int kind_width;
- int extra_width;
- int i;
int row;
int context_lines;
int col;
@@ -67,9 +94,6 @@ pum_display(
do
{
def_width = PUM_DEF_WIDTH;
- max_width = 0;
- kind_width = 0;
- extra_width = 0;
above_row = 0;
below_row = cmdline_row;
@@ -107,7 +131,7 @@ pum_display(
/* Put the pum below "row" if possible. If there are few lines decide
* on where there is more room. */
if (row + 2 >= below_row - pum_height
- && row - above_row > (below_row - above_row) / 2)
+ && row - above_row > (below_row - above_row) / 2)
{
/* pum above "row" */
@@ -167,27 +191,10 @@ pum_display(
}
#endif
- /* Compute the width of the widest match and the widest extra. */
- for (i = 0; i < size; ++i)
- {
- w = vim_strsize(array[i].pum_text);
- if (max_width < w)
- max_width = w;
- if (array[i].pum_kind != NULL)
- {
- w = vim_strsize(array[i].pum_kind) + 1;
- if (kind_width < w)
- kind_width = w;
- }
- if (array[i].pum_extra != NULL)
- {
- w = vim_strsize(array[i].pum_extra) + 1;
- if (extra_width < w)
- extra_width = w;
- }
- }
- pum_base_width = max_width;
- pum_kind_width = kind_width;
+ pum_array = array;
+ pum_size = size;
+ pum_compute_size();
+ max_width = pum_base_width;
/* Calculate column */
#ifdef FEAT_RIGHTLEFT
@@ -226,10 +233,10 @@ pum_display(
#endif
pum_width = Columns - pum_col - pum_scrollbar;
- if (pum_width > max_width + kind_width + extra_width + 1
- && pum_width > PUM_DEF_WIDTH)
+ if (pum_width > max_width + pum_kind_width + pum_extra_width + 1
+ && pum_width > PUM_DEF_WIDTH)
{
- pum_width = max_width + kind_width + extra_width + 1;
+ pum_width = max_width + pum_kind_width + pum_extra_width + 1;
if (pum_width < PUM_DEF_WIDTH)
pum_width = PUM_DEF_WIDTH;
}
@@ -258,9 +265,6 @@ pum_display(
pum_width = max_width - pum_scrollbar;
}
- pum_array = array;
- pum_size = size;
-
/* Set selected item and redraw. If the window size changed need to
* redo the positioning. Limit this to two times, when there is not
* much room the window size will keep changing. */
@@ -756,4 +760,97 @@ pum_get_height(void)
return pum_height;
}
+# if defined(FEAT_BEVALTERM) || 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 40
+#define BALLOON_MIN_HEIGHT 10
+
+ void
+ui_remove_balloon(void)
+{
+ if (balloon_array != NULL)
+ {
+ pum_undisplay();
+ while (balloon_arraysize > 0)
+ vim_free(balloon_array[--balloon_arraysize].pum_text);
+ vim_free(balloon_array);
+ balloon_array = NULL;
+ }
+}
+
+/*
+ * Terminal version of a balloon, uses the popup menu code.
+ */
+ void
+ui_post_balloon(char_u *mesg)
+{
+ ui_remove_balloon();
+
+ /* TODO: split the text in multiple lines. */
+ balloon_arraysize = 3;
+ balloon_array = (pumitem_T *)alloc_clear(
+ (unsigned)sizeof(pumitem_T) * balloon_arraysize);
+ if (balloon_array != NULL)
+ {
+ /* Add an empty line above and below, looks better. */
+ balloon_array[0].pum_text = vim_strsave((char_u *)"");
+ balloon_array[1].pum_text = vim_strsave(mesg);
+ balloon_array[2].pum_text = vim_strsave((char_u *)"");
+
+ pum_array = balloon_array;
+ pum_size = balloon_arraysize;
+ pum_compute_size();
+ pum_scrollbar = 0;
+ pum_height = balloon_arraysize;
+
+ if (Rows - mouse_row > BALLOON_MIN_HEIGHT)
+ {
+ /* Enough space below the mouse row. */
+ pum_row = mouse_row + 1;
+ if (pum_height > Rows - pum_row)
+ pum_height = Rows - pum_row;
+ }
+ else
+ {
+ /* Show above the mouse row, reduce height if it does not fit. */
+ pum_row = mouse_row - 1 - pum_size;
+ if (pum_row < 0)
+ {
+ pum_height += pum_row;
+ pum_row = 0;
+ }
+ }
+ if (Columns - mouse_col >= pum_base_width
+ || Columns - mouse_col > BALLOON_MIN_WIDTH)
+ /* Enough space to show at mouse column. */
+ pum_col = mouse_col;
+ else
+ /* Not enough space, right align with window. */
+ pum_col = Columns - (pum_base_width > BALLOON_MIN_WIDTH
+ ? BALLOON_MIN_WIDTH : pum_base_width);
+
+ pum_width = Columns - pum_col;
+ if (pum_width > pum_base_width + 1)
+ pum_width = pum_base_width + 1;
+
+ pum_selected = -1;
+ pum_first = 0;
+ pum_redraw();
+ }
+}
+
+/*
+ * Called when the mouse moved, may remove any displayed balloon.
+ */
+ void
+ui_may_remove_balloon(void)
+{
+ if (mouse_row != balloon_mouse_row || mouse_col != balloon_mouse_col)
+ ui_remove_balloon();
+}
+# endif
#endif
diff --git a/src/proto/gui_beval.pro b/src/proto/gui_beval.pro
index b0067a00a..aa0553fa0 100644
--- a/src/proto/gui_beval.pro
+++ b/src/proto/gui_beval.pro
@@ -6,6 +6,7 @@ void gui_mch_enable_beval_area(BalloonEval *beval);
void gui_mch_disable_beval_area(BalloonEval *beval);
BalloonEval *gui_mch_currently_showing_beval(void);
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);
void gui_mch_post_balloon(BalloonEval *beval, char_u *mesg);
void gui_mch_unpost_balloon(BalloonEval *beval);
/* vim: set ft=c : */
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
index d3a00b5a2..fbdad1570 100644
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -53,6 +53,7 @@ void mch_settmode(int tmode);
void get_stty(void);
int get_tty_info(int fd, ttyinfo_T *info);
void mch_setmouse(int on);
+void mch_bevalterm_changed(void);
void check_mouse_termcode(void);
int mch_screenmode(char_u *arg);
int mch_get_shellsize(void);
diff --git a/src/proto/popupmnu.pro b/src/proto/popupmnu.pro
index 423076c3e..57795338b 100644
--- a/src/proto/popupmnu.pro
+++ b/src/proto/popupmnu.pro
@@ -5,4 +5,7 @@ void pum_undisplay(void);
void pum_clear(void);
int pum_visible(void);
int pum_get_height(void);
+void ui_remove_balloon(void);
+void ui_post_balloon(char_u *mesg);
+void ui_may_remove_balloon(void);
/* vim: set ft=c : */
diff --git a/src/term.c b/src/term.c
index 83b54e18c..359c17100 100644
--- a/src/term.c
+++ b/src/term.c
@@ -5625,6 +5625,7 @@ check_termcode(
modifiers |= MOD_MASK_ALT;
key_name[1] = (wheel_code & 1)
? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
+ held_button = MOUSE_RELEASE;
}
else
key_name[1] = get_pseudo_mouse_code(current_button,
diff --git a/src/terminal.c b/src/terminal.c
index b416e20f4..6cbe3433f 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -52,6 +52,7 @@
* - Termdebug does not work when Vim build with mzscheme. gdb hangs.
* - MS-Windows GUI: WinBar has tearoff item
* - MS-Windows GUI: still need to type a key after shell exits? #1924
+ * - After executing a shell command the status line isn't redraw.
* - What to store in a session file? Shell at the prompt would be OK to
* restore, but others may not. Open the window and let the user start the
* command?
@@ -717,7 +718,8 @@ term_send_mouse(VTerm *vterm, int button, int pressed)
vterm_mouse_move(vterm, mouse_row - W_WINROW(curwin),
mouse_col - curwin->w_wincol, mod);
- vterm_mouse_button(vterm, button, pressed, mod);
+ if (button != 0)
+ vterm_mouse_button(vterm, button, pressed, mod);
return TRUE;
}
@@ -818,6 +820,7 @@ term_convert_key(term_T *term, int c, char *buf)
case K_LEFTDRAG: other = term_send_mouse(vterm, 1, 1); break;
case K_LEFTRELEASE:
case K_LEFTRELEASE_NM: other = term_send_mouse(vterm, 1, 0); break;
+ case K_MOUSEMOVE: other = term_send_mouse(vterm, 0, 0); break;
case K_MIDDLEMOUSE: other = term_send_mouse(vterm, 2, 1); break;
case K_MIDDLEDRAG: other = term_send_mouse(vterm, 2, 1); break;
case K_MIDDLERELEASE: other = term_send_mouse(vterm, 2, 0); break;
@@ -1284,6 +1287,7 @@ send_keys_to_term(term_T *term, int c, int typed)
case K_LEFTMOUSE_NM:
case K_LEFTRELEASE:
case K_LEFTRELEASE_NM:
+ case K_MOUSEMOVE:
case K_MIDDLEMOUSE:
case K_MIDDLERELEASE:
case K_RIGHTMOUSE:
diff --git a/src/version.c b/src/version.c
index c81d7a39b..3d0b5cd54 100644
--- a/src/version.c
+++ b/src/version.c
@@ -93,6 +93,11 @@ static char *(features[]) =
#else
"-balloon_eval",
#endif
+#ifdef FEAT_BEVALTERM
+ "+balloon_eval_term",
+#else
+ "-balloon_eval_term",
+#endif
#ifdef FEAT_BROWSE
"+browse",
#else
@@ -767,6 +772,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1309,
+/**/
1308,
/**/
1307,