Patch 8.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.
Files: src/option.c, src/option.h, src/os_unix.c, src/proto/os_unix.pro,
src/feature.h, src/misc2.c, src/keymap.h, src/edit.c,
src/ex_getln.c, src/message.c, src/misc1.c, src/normal.c,
src/terminal.c, src/getchar.c, src/ex_cmds2.c, src/gui_beval.c,
src/proto/gui_beval.pro, src/evalfunc.c, src/popupmnu.c,
src/proto/popupmnu.pro, src/version.c, src/globals.h, src/gui.c,
runtime/doc/options.txt, src/term.c,
runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
*** ../vim-8.0.1308/src/option.c 2017-11-11 18:16:44.093617922 +0100
--- src/option.c 2017-11-18 17:06:39.075582598 +0100
***************
*** 642,647 ****
--- 642,656 ----
{(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,8434 ****
#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);
}
#endif
#ifdef FEAT_AUTOCHDIR
else if ((int *)varp == &p_acd)
--- 8432,8452 ----
#ifdef FEAT_BEVAL
else if ((int *)varp == &p_beval)
{
! 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)
*** ../vim-8.0.1308/src/option.h 2017-11-09 18:33:22.408374709 +0100
--- src/option.h 2017-11-17 21:05:25.842764748 +0100
***************
*** 382,387 ****
--- 382,390 ----
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
*** ../vim-8.0.1308/src/os_unix.c 2017-11-16 17:03:41.948727893 +0100
--- src/os_unix.c 2017-11-17 21:57:36.715786036 +0100
***************
*** 3564,3579 ****
#endif /* VMS */
#if defined(FEAT_MOUSE_TTY) || defined(PROTO)
/*
* Set mouse clicks on or off.
*/
void
mch_setmouse(int on)
{
! static int ison = FALSE;
int xterm_mouse_vers;
! if (on == ison) /* return quickly if nothing to do */
return;
xterm_mouse_vers = use_xterm_mouse();
--- 3564,3588 ----
#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)
{
! # ifdef FEAT_BEVALTERM
! static int bevalterm_ison = FALSE;
! # endif
int xterm_mouse_vers;
! 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,3602 ****
(on
? IF_EB("\033[?1015h", ESC_STR "[?1015h")
: IF_EB("\033[?1015l", ESC_STR "[?1015l")));
! ison = on;
}
# endif
# ifdef FEAT_MOUSE_SGR
if (ttym_flags == TTYM_SGR)
{
out_str_nf((char_u *)
(on
? IF_EB("\033[?1006h", ESC_STR "[?1006h")
: IF_EB("\033[?1006l", ESC_STR "[?1006l")));
! ison = on;
}
# endif
--- 3594,3623 ----
(on
? IF_EB("\033[?1015h", ESC_STR "[?1015h")
: IF_EB("\033[?1015l", ESC_STR "[?1015l")));
! 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")));
! 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,3618 ****
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")
: 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;
}
# ifdef FEAT_MOUSE_DEC
--- 3626,3644 ----
if (on) /* enable mouse events, use mouse tracking if available */
out_str_nf((char_u *)
(xterm_mouse_vers > 1
! ? (
! # 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")));
! mouse_ison = on;
}
# ifdef FEAT_MOUSE_DEC
***************
*** 3622,3628 ****
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;
}
# endif
--- 3648,3654 ----
out_str_nf((char_u *)"\033[1;2'z\033[1;3'{");
else /* disable mouse events */
out_str_nf((char_u *)"\033['z");
! mouse_ison = on;
}
# endif
***************
*** 3632,3643 ****
if (on)
{
if (gpm_open())
! ison = TRUE;
}
else
{
gpm_close();
! ison = FALSE;
}
}
# endif
--- 3658,3669 ----
if (on)
{
if (gpm_open())
! mouse_ison = TRUE;
}
else
{
gpm_close();
! mouse_ison = FALSE;
}
}
# endif
***************
*** 3648,3659 ****
if (on)
{
if (sysmouse_open() == OK)
! ison = TRUE;
}
else
{
sysmouse_close();
! ison = FALSE;
}
}
# endif
--- 3674,3685 ----
if (on)
{
if (sysmouse_open() == OK)
! mouse_ison = TRUE;
}
else
{
sysmouse_close();
! mouse_ison = FALSE;
}
}
# endif
***************
*** 3686,3698 ****
out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK+1Q\033\\",
ESC_STR "[0~ZwLMRK+1Q" ESC_STR "\\"));
# endif
! ison = TRUE;
}
else
{
out_str_nf((char_u *)IF_EB("\033[0~ZwQ\033\\",
ESC_STR "[0~ZwQ" ESC_STR "\\"));
! ison = FALSE;
}
}
# endif
--- 3712,3724 ----
out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK+1Q\033\\",
ESC_STR "[0~ZwLMRK+1Q" ESC_STR "\\"));
# endif
! mouse_ison = TRUE;
}
else
{
out_str_nf((char_u *)IF_EB("\033[0~ZwQ\033\\",
ESC_STR "[0~ZwQ" ESC_STR "\\"));
! mouse_ison = FALSE;
}
}
# endif
***************
*** 3704,3714 ****
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;
}
# endif
}
/*
* Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
*/
--- 3730,3751 ----
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");
! 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.
*/
*** ../vim-8.0.1308/src/proto/os_unix.pro 2017-11-16 17:03:41.948727893
+0100
--- src/proto/os_unix.pro 2017-11-17 21:14:09.294791793 +0100
***************
*** 53,58 ****
--- 53,59 ----
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);
*** ../vim-8.0.1308/src/feature.h 2017-11-13 22:08:00.650177110 +0100
--- src/feature.h 2017-11-17 22:31:34.921605663 +0100
***************
*** 1328,1333 ****
--- 1328,1340 ----
# 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
*** ../vim-8.0.1308/src/misc2.c 2017-11-09 13:21:53.328924049 +0100
--- src/misc2.c 2017-11-17 22:24:54.379632706 +0100
***************
*** 2453,2458 ****
--- 2453,2459 ----
{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,2521 ****
{(int)KE_X2DRAG, MOUSE_X2, FALSE, TRUE},
{(int)KE_X2RELEASE, MOUSE_X2, FALSE, FALSE},
/* DRAG without CLICK */
! {(int)KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE},
/* RELEASE without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE},
{0, 0, 0, 0},
--- 2516,2522 ----
{(int)KE_X2DRAG, MOUSE_X2, FALSE, TRUE},
{(int)KE_X2RELEASE, MOUSE_X2, FALSE, FALSE},
/* DRAG without CLICK */
! {(int)KE_MOUSEMOVE, MOUSE_RELEASE, FALSE, TRUE},
/* RELEASE without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE},
{0, 0, 0, 0},
*** ../vim-8.0.1308/src/keymap.h 2017-10-28 21:08:38.983456981 +0200
--- src/keymap.h 2017-11-17 22:10:59.444064985 +0100
***************
*** 269,274 ****
--- 269,275 ----
, 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,442 ****
--- 438,444 ----
#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)
*** ../vim-8.0.1308/src/edit.c 2017-10-28 21:08:38.975457036 +0200
--- src/edit.c 2017-11-18 17:42:13.367985521 +0100
***************
*** 1177,1182 ****
--- 1177,1183 ----
case K_LEFTDRAG:
case K_LEFTRELEASE:
case K_LEFTRELEASE_NM:
+ case K_MOUSEMOVE:
case K_MIDDLEMOUSE:
case K_MIDDLEDRAG:
case K_MIDDLERELEASE:
*** ../vim-8.0.1308/src/ex_getln.c 2017-11-16 22:20:35.024615088 +0100
--- src/ex_getln.c 2017-11-17 22:13:21.201962257 +0100
***************
*** 1452,1457 ****
--- 1452,1458 ----
case K_X2MOUSE:
case K_X2DRAG:
case K_X2RELEASE:
+ case K_MOUSEMOVE:
goto cmdline_not_changed;
#endif /* FEAT_MOUSE */
*** ../vim-8.0.1308/src/message.c 2017-10-28 21:08:38.987456954 +0200
--- src/message.c 2017-11-17 22:14:20.825076447 +0100
***************
*** 1179,1184 ****
--- 1179,1185 ----
|| 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
*** ../vim-8.0.1308/src/misc1.c 2017-10-28 21:08:38.987456954 +0200
--- src/misc1.c 2017-11-17 22:14:39.340801214 +0100
***************
*** 3345,3350 ****
--- 3345,3351 ----
|| c == K_LEFTDRAG
|| c == K_LEFTRELEASE
|| c == K_LEFTRELEASE_NM
+ || c == K_MOUSEMOVE
|| c == K_MIDDLEMOUSE
|| c == K_MIDDLEDRAG
|| c == K_MIDDLERELEASE
*** ../vim-8.0.1308/src/normal.c 2017-10-24 21:49:32.230837763 +0200
--- src/normal.c 2017-11-18 17:19:27.628256894 +0100
***************
*** 358,363 ****
--- 358,364 ----
{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,2401 ****
--- 2397,2416 ----
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,3849 ****
K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
# endif
K_IGNORE, K_PS,
! K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
--- 3858,3864 ----
K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
# endif
K_IGNORE, K_PS,
! 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,8363 ****
--- 8373,8379 ----
case K_LEFTMOUSE:
case K_LEFTDRAG:
case K_LEFTRELEASE:
+ case K_MOUSEMOVE:
case K_RIGHTMOUSE:
case K_RIGHTDRAG:
case K_RIGHTRELEASE:
*** ../vim-8.0.1308/src/terminal.c 2017-11-16 13:07:59.886081407 +0100
--- src/terminal.c 2017-11-17 22:21:54.714314889 +0100
***************
*** 52,57 ****
--- 52,58 ----
* - 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,723 ****
vterm_mouse_move(vterm, mouse_row - W_WINROW(curwin),
mouse_col - curwin->w_wincol, mod);
! vterm_mouse_button(vterm, button, pressed, mod);
return TRUE;
}
--- 718,725 ----
vterm_mouse_move(vterm, mouse_row - W_WINROW(curwin),
mouse_col - curwin->w_wincol, mod);
! if (button != 0)
! vterm_mouse_button(vterm, button, pressed, mod);
return TRUE;
}
***************
*** 818,823 ****
--- 820,826 ----
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,1289 ****
--- 1287,1293 ----
case K_LEFTMOUSE_NM:
case K_LEFTRELEASE:
case K_LEFTRELEASE_NM:
+ case K_MOUSEMOVE:
case K_MIDDLEMOUSE:
case K_MIDDLERELEASE:
case K_RIGHTMOUSE:
*** ../vim-8.0.1308/src/getchar.c 2017-10-28 21:08:38.979457009 +0200
--- src/getchar.c 2017-11-18 18:13:09.495454349 +0100
***************
*** 1792,1797 ****
--- 1792,1805 ----
*/
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;
}
*** ../vim-8.0.1308/src/ex_cmds2.c 2017-10-26 14:28:25.944144974 +0200
--- src/ex_cmds2.c 2017-11-18 17:12:48.094186277 +0100
***************
*** 1093,1113 ****
static long last_timer_id = 0;
static long
! timer_time_left(timer_T *timer, proftime_T *now)
{
# ifdef WIN3264
LARGE_INTEGER fr;
! if (now->QuadPart > timer->tr_due.QuadPart)
return 0;
QueryPerformanceFrequency(&fr);
! return (long)(((double)(timer->tr_due.QuadPart - now->QuadPart)
/ (double)fr.QuadPart) * 1000);
# else
! if (now->tv_sec > timer->tr_due.tv_sec)
return 0;
! return (timer->tr_due.tv_sec - now->tv_sec) * 1000
! + (timer->tr_due.tv_usec - now->tv_usec) / 1000;
# endif
}
--- 1093,1113 ----
static long last_timer_id = 0;
static long
! proftime_time_left(proftime_T *due, proftime_T *now)
{
# ifdef WIN3264
LARGE_INTEGER fr;
! if (now->QuadPart > due->QuadPart)
return 0;
QueryPerformanceFrequency(&fr);
! return (long)(((double)(due->QuadPart - now->QuadPart)
/ (double)fr.QuadPart) * 1000);
# else
! if (now->tv_sec > due->tv_sec)
return 0;
! return (due->tv_sec - now->tv_sec) * 1000
! + (due->tv_usec - now->tv_usec) / 1000;
# endif
}
***************
*** 1219,1225 ****
if (timer->tr_id == -1 || timer->tr_firing || timer->tr_paused)
continue;
! this_due = timer_time_left(timer, &now);
if (this_due <= 1)
{
int save_timer_busy = timer_busy;
--- 1219,1225 ----
if (timer->tr_id == -1 || timer->tr_firing || timer->tr_paused)
continue;
! this_due = proftime_time_left(&timer->tr_due, &now);
if (this_due <= 1)
{
int save_timer_busy = timer_busy;
***************
*** 1271,1277 ****
&& timer->tr_emsg_count < 3)
{
profile_setlimit(timer->tr_interval, &timer->tr_due);
! this_due = timer_time_left(timer, &now);
if (this_due < 1)
this_due = 1;
if (timer->tr_repeat > 0)
--- 1271,1277 ----
&& timer->tr_emsg_count < 3)
{
profile_setlimit(timer->tr_interval, &timer->tr_due);
! this_due = proftime_time_left(&timer->tr_due, &now);
if (this_due < 1)
this_due = 1;
if (timer->tr_repeat > 0)
***************
*** 1291,1296 ****
--- 1291,1317 ----
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,1364 ****
dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL);
profile_start(&now);
! remaining = timer_time_left(timer, &now);
dict_add_nr_str(dict, "remaining", (long)remaining, NULL);
dict_add_nr_str(dict, "repeat",
--- 1379,1385 ----
dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL);
profile_start(&now);
! remaining = proftime_time_left(&timer->tr_due, &now);
dict_add_nr_str(dict, "remaining", (long)remaining, NULL);
dict_add_nr_str(dict, "repeat",
*** ../vim-8.0.1308/src/gui_beval.c 2017-09-22 15:20:27.736148641 +0200
--- src/gui_beval.c 2017-11-18 18:43:26.928614044 +0100
***************
*** 35,41 ****
/* 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)
return;
/* Don't do this recursively. Happens when the expression evaluation
--- 35,45 ----
/* Don't do anything when 'ballooneval' is off, messages scrolled the
* windows up or we have no beval area. */
! 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,51 ****
recursive = TRUE;
#ifdef FEAT_EVAL
! if (get_beval_info(balloonEval, TRUE, &wp, &lnum, &text, &col) == OK)
{
bexpr = (*wp->w_buffer->b_p_bexpr == NUL) ? p_bexpr
: wp->w_buffer->b_p_bexpr;
--- 49,55 ----
recursive = TRUE;
#ifdef FEAT_EVAL
! 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,102 ****
set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
if (result != NULL && result[0] != NUL)
{
! gui_mch_post_balloon(beval, result);
recursive = FALSE;
return;
}
--- 100,106 ----
set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
if (result != NULL && result[0] != NUL)
{
! post_balloon(beval, result);
recursive = FALSE;
return;
}
***************
*** 335,342 ****
linenr_T lnum;
*textp = NULL;
! 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)
{
--- 339,356 ----
linenr_T lnum;
*textp = NULL;
! # 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,426 ****
--- 435,454 ----
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,460 ****
#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)
{
--- 479,484 ----
*** ../vim-8.0.1308/src/proto/gui_beval.pro 2016-09-12 13:04:23.000000000
+0200
--- src/proto/gui_beval.pro 2017-11-18 15:48:46.516644383 +0100
***************
*** 6,11 ****
--- 6,12 ----
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 : */
*** ../vim-8.0.1308/src/evalfunc.c 2017-11-16 23:03:43.240816180 +0100
--- src/evalfunc.c 2017-11-18 15:57:59.072589712 +0100
***************
*** 1410,1416 ****
f_balloon_show(typval_T *argvars, typval_T *rettv UNUSED)
{
if (balloonEval != NULL)
! gui_mch_post_balloon(balloonEval, get_tv_string_chk(&argvars[0]));
}
#endif
--- 1410,1416 ----
f_balloon_show(typval_T *argvars, typval_T *rettv UNUSED)
{
if (balloonEval != NULL)
! post_balloon(balloonEval, get_tv_string_chk(&argvars[0]));
}
#endif
***************
*** 5589,5594 ****
--- 5589,5597 ----
"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
*** ../vim-8.0.1308/src/popupmnu.c 2017-10-26 22:04:00.186638048 +0200
--- src/popupmnu.c 2017-11-18 18:26:03.567881281 +0100
***************
*** 23,28 ****
--- 23,29 ----
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,40 ****
--- 36,71 ----
#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,59 ****
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;
--- 79,86 ----
***************
*** 67,75 ****
do
{
def_width = PUM_DEF_WIDTH;
- max_width = 0;
- kind_width = 0;
- extra_width = 0;
above_row = 0;
below_row = cmdline_row;
--- 94,99 ----
***************
*** 107,113 ****
/* 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)
{
/* pum above "row" */
--- 131,137 ----
/* 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)
{
/* pum above "row" */
***************
*** 167,193 ****
}
#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;
/* Calculate column */
#ifdef FEAT_RIGHTLEFT
--- 191,200 ----
}
#endif
! pum_array = array;
! pum_size = size;
! pum_compute_size();
! max_width = pum_base_width;
/* Calculate column */
#ifdef FEAT_RIGHTLEFT
***************
*** 226,235 ****
#endif
pum_width = Columns - pum_col - pum_scrollbar;
! if (pum_width > max_width + kind_width + extra_width + 1
! && pum_width >
PUM_DEF_WIDTH)
{
! pum_width = max_width + kind_width + extra_width + 1;
if (pum_width < PUM_DEF_WIDTH)
pum_width = PUM_DEF_WIDTH;
}
--- 233,242 ----
#endif
pum_width = Columns - pum_col - pum_scrollbar;
! if (pum_width > max_width + pum_kind_width + pum_extra_width + 1
! && pum_width > PUM_DEF_WIDTH)
{
! pum_width = max_width + pum_kind_width + pum_extra_width + 1;
if (pum_width < PUM_DEF_WIDTH)
pum_width = PUM_DEF_WIDTH;
}
***************
*** 258,266 ****
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. */
--- 265,270 ----
***************
*** 756,759 ****
--- 760,856 ----
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
*** ../vim-8.0.1308/src/proto/popupmnu.pro 2016-09-12 13:04:16.000000000
+0200
--- src/proto/popupmnu.pro 2017-11-18 18:15:05.801699540 +0100
***************
*** 5,8 ****
--- 5,11 ----
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 : */
*** ../vim-8.0.1308/src/version.c 2017-11-18 14:55:19.315803253 +0100
--- src/version.c 2017-11-18 18:33:55.089046103 +0100
***************
*** 93,98 ****
--- 93,103 ----
#else
"-balloon_eval",
#endif
+ #ifdef FEAT_BEVALTERM
+ "+balloon_eval_term",
+ #else
+ "-balloon_eval_term",
+ #endif
#ifdef FEAT_BROWSE
"+browse",
#else
*** ../vim-8.0.1308/src/globals.h 2017-11-16 23:03:43.244816117 +0100
--- src/globals.h 2017-11-18 17:03:17.826514499 +0100
***************
*** 1231,1236 ****
--- 1231,1237 ----
#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,1653 ****
--- 1649,1659 ----
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);
*** ../vim-8.0.1308/src/gui.c 2017-11-13 21:09:59.547760060 +0100
--- src/gui.c 2017-11-18 17:04:47.369211283 +0100
***************
*** 740,746 ****
#ifdef FEAT_BEVAL
/* Always create the Balloon Evaluation area, but disable it when
! * 'ballooneval' is off */
# ifdef FEAT_GUI_GTK
balloonEval = gui_mch_create_beval_area(gui.drawarea, NULL,
&general_beval_cb, NULL);
--- 740,749 ----
#ifdef FEAT_BEVAL
/* Always create the Balloon Evaluation area, but disable it when
! * '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);
*** ../vim-8.0.1308/runtime/doc/options.txt 2017-11-11 18:16:44.089617980
+0100
--- runtime/doc/options.txt 2017-11-18 18:48:16.040326522 +0100
***************
*** 1091,1097 ****
{not in Vi}
{only available when compiled with the |+balloon_eval|
feature}
! Switch on the |balloon-eval| functionality.
*'balloonexpr'* *'bexpr'*
'balloonexpr' 'bexpr' string (default "")
--- 1127,1142 ----
{not in Vi}
{only available when compiled with the |+balloon_eval|
feature}
! Switch on the |balloon-eval| functionality for the GUI.
!
! *'balloonevalterm'* *'bevalterm'* *'noballoonevalterm'*
! *'nobevalterm'*
! 'balloonevalterm' 'bevalterm' boolean (default off)
! global
! {not in Vi}
! {only available when compiled with the
! |+balloon_eval_term| feature}
! Switch on the |balloon-eval| functionality for the terminal.
*'balloonexpr'* *'bexpr'*
'balloonexpr' 'bexpr' string (default "")
***************
*** 1120,1125 ****
--- 1165,1173 ----
set bexpr=MyBalloonExpr()
set ballooneval
<
+ Also see |balloon_show()|, can be used if the content of the balloon
+ is to be fetched asynchronously.
+
NOTE: The balloon is displayed only if the cursor is on a text
character. If the result of evaluating 'balloonexpr' is not empty,
Vim does not try to send a message to an external debugger (Netbeans
*** ../vim-8.0.1308/src/term.c 2017-11-16 22:07:09.217057471 +0100
--- src/term.c 2017-11-18 16:04:15.319073671 +0100
***************
*** 5625,5630 ****
--- 5625,5631 ----
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,
*** ../vim-8.0.1308/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
2017-11-12 18:00:36.412643584 +0100
--- runtime/pack/dist/opt/termdebug/plugin/termdebug.vim 2017-11-18
18:13:41.850965883 +0100
***************
*** 69,74 ****
--- 69,79 ----
endif
let pty = job_info(term_getjob(s:ptybuf))['tty_out']
let s:ptywin = win_getid(winnr())
+ if vertical
+ " Assuming the source code window will get a signcolumn, use two more
+ " columns for that, thus one less for the terminal window.
+ exe (&columns / 2 - 1) . "wincmd |"
+ endif
" Create a hidden terminal window to communicate with gdb
let s:commbuf = term_start('NONE', {
***************
*** 121,126 ****
--- 126,140 ----
call s:InstallCommands()
call win_gotoid(s:gdbwin)
+ " Enable showing a balloon with eval info
+ if has("balloon_eval")
+ set ballooneval
+ set balloonexpr=TermDebugBalloonExpr()
+ if has("balloon_eval_term")
+ set balloonevalterm
+ endif
+ endif
+
let s:breakpoints = {}
augroup TermDebug
***************
*** 144,149 ****
--- 158,171 ----
let &columns = s:save_columns
endif
+ if has("balloon_eval")
+ set noballooneval
+ set balloonexpr=
+ if has("balloon_eval_term")
+ set noballoonevalterm
+ endif
+ endif
+
au! TermDebug
endfunc
***************
*** 279,284 ****
--- 301,311 ----
call s:SendCommand('-exec-run')
endfunc
+ func s:SendEval(expr)
+ call s:SendCommand('-data-evaluate-expression "' . a:expr . '"')
+ let s:evalexpr = a:expr
+ endfunc
+
" :Evaluate - evaluate what is under the cursor
func s:Evaluate(range, arg)
if a:arg != ''
***************
*** 294,318 ****
else
let expr = expand('<cexpr>')
endif
! call s:SendCommand('-data-evaluate-expression "' . expr . '"')
! let s:evalexpr = expr
endfunc
" Handle the result of data-evaluate-expression
func s:HandleEvaluate(msg)
let value = substitute(a:msg, '.*value="\(.*\)"', '\1', '')
let value = substitute(value, '\\"', '"', 'g')
! echomsg '"' . s:evalexpr . '": ' . value
if s:evalexpr[0] != '*' && value =~ '^0x' && value != '0x0' && value !~ '"$'
" Looks like a pointer, also display what it points to.
! let s:evalexpr = '*' . s:evalexpr
! call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . s:evalexpr
. "\"\r")
endif
endfunc
" Handle an error.
func s:HandleError(msg)
echoerr substitute(a:msg, '.*msg="\(.*\)"', '\1', '')
endfunc
--- 321,374 ----
else
let expr = expand('<cexpr>')
endif
! call s:SendEval(expr)
endfunc
+ let s:evalFromBalloonExpr = 0
+
" Handle the result of data-evaluate-expression
func s:HandleEvaluate(msg)
let value = substitute(a:msg, '.*value="\(.*\)"', '\1', '')
let value = substitute(value, '\\"', '"', 'g')
! if s:evalFromBalloonExpr
! if s:evalFromBalloonExprResult == ''
! let s:evalFromBalloonExprResult = s:evalexpr . ': ' . value
! else
! let s:evalFromBalloonExprResult .= ' = ' . value
! endif
! call balloon_show(s:evalFromBalloonExprResult)
! else
! echomsg '"' . s:evalexpr . '": ' . value
! endif
if s:evalexpr[0] != '*' && value =~ '^0x' && value != '0x0' && value !~ '"$'
" Looks like a pointer, also display what it points to.
! call s:SendEval('*' . s:evalexpr)
! else
! let s:evalFromBalloonExpr = 0
! endif
! endfunc
!
! " Show a balloon with information of the variable under the mouse pointer,
! " if there is any.
! func TermDebugBalloonExpr()
! if v:beval_winid != s:startwin
! return
endif
+ call s:SendEval(v:beval_text)
+ let s:evalFromBalloonExpr = 1
+ let s:evalFromBalloonExprResult = ''
+ return ''
endfunc
" Handle an error.
func s:HandleError(msg)
+ if a:msg =~ 'No symbol .* in current context'
+ \ || a:msg =~ 'Cannot access memory at address '
+ \ || a:msg =~ 'Attempt to use a type name as an expression'
+ " Result of s:SendEval() failed, ignore.
+ return
+ endif
echoerr substitute(a:msg, '.*msg="\(.*\)"', '\1', '')
endfunc
*** ../vim-8.0.1308/src/version.c 2017-11-18 14:55:19.315803253 +0100
--- src/version.c 2017-11-18 18:33:55.089046103 +0100
***************
*** 768,769 ****
--- 773,776 ----
{ /* Add new patch number below this line */
+ /**/
+ 1309,
/**/
--
A)bort, R)etry, D)o it right this time
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.