]> granicus.if.org Git - vim/commitdiff
patch 8.0.1309: cannot use 'balloonexpr' in a terminal v8.0.1309
authorBram Moolenaar <Bram@vim.org>
Sat, 18 Nov 2017 17:52:04 +0000 (18:52 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 18 Nov 2017 17:52:04 +0000 (18:52 +0100)
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.

26 files changed:
runtime/doc/options.txt
runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
src/edit.c
src/evalfunc.c
src/ex_cmds2.c
src/ex_getln.c
src/feature.h
src/getchar.c
src/globals.h
src/gui.c
src/gui_beval.c
src/keymap.h
src/message.c
src/misc1.c
src/misc2.c
src/normal.c
src/option.c
src/option.h
src/os_unix.c
src/popupmnu.c
src/proto/gui_beval.pro
src/proto/os_unix.pro
src/proto/popupmnu.pro
src/term.c
src/terminal.c
src/version.c

index b9e82d73a8f6c18eae2c197efc4099d1d2a8595b..f9acff8186304a155ccd40006c73918d12e1fff4 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 8.0.  Last change: 2017 Nov 11
+*options.txt*  For Vim version 8.0.  Last change: 2017 Nov 18
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1127,7 +1127,16 @@ A jump table for the options with a short description can be found at |Q_op|.
                        {not in Vi}
                        {only available when compiled with the |+balloon_eval|
                        feature}
-       Switch on the |balloon-eval| functionality.
+       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 "")
@@ -3521,6 +3530,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        systems without an fsync() implementation, this variable is always
        off.
        Also see 'swapsync' for controlling fsync() on swap files.
+       'fsync' also applies to |writefile()|, unless a flag is used to
+       overrule it.
 
                                   *'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
 'gdefault' 'gd'                boolean (default off)
@@ -3944,7 +3955,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                toolbar, tabline, etc.  Instead, the behavior is similar to
                when the window is maximized and will adjust 'lines' and
                'columns' to fit to the window.  Without the 'k' flag Vim will
-               try to keep 'lines' and 'columns the same when adding and
+               try to keep 'lines' and 'columns' the same when adding and
                removing GUI components.
 
                                                *'guipty'* *'noguipty'*
@@ -8221,7 +8232,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        number, more intelligent detection process runs.
        The "xterm2" value will be set if the xterm version is reported to be
        from 95 to 276.  The "sgr" value will be set if the xterm version is
-       277 or highter.
+       277 or highter and when Vim detects Mac Terminal.app or Iterm2.
        If you do not want 'ttymouse' to be set to "xterm2" or "sgr"
        automatically, set t_RV to an empty string: >
                :set t_RV=
index 635bf93f239e63941286de203e629b17b5e1fb3f..1c3c9df9a7a8152b3d0ef067b0d7b90e0b458721 100644 (file)
@@ -69,6 +69,11 @@ func s:StartDebug(cmd)
   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,6 +126,15 @@ func s:StartDebug(cmd)
   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,6 +158,14 @@ func s:EndDebug(job, status)
     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,6 +301,11 @@ func s:Run(args)
   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,25 +321,54 @@ func s:Evaluate(range, arg)
   else
     let expr = expand('<cexpr>')
   endif
-  call s:SendCommand('-data-evaluate-expression "' . expr . '"')
-  let s:evalexpr = expr
+  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')
-  echomsg '"' . s:evalexpr . '": ' . value
+  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.
-    let s:evalexpr = '*' . s:evalexpr
-    call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . s:evalexpr . "\"\r")
+    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
 
index 435e1ed8124cc4c2b0d03e78489e7e70ef1d97c3..65c53f52f69f96852b4762127ef0867f09b53506 100644 (file)
@@ -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:
index 25b28bb3a2500710abec1f2f80639b2cce74964d..bd5cf8dec577240bf9daa76b90a26388bc4940b0 100644 (file)
@@ -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
index 2eef050eea9884ba9a98224ed1a08574fdc78ecd..c6a6dbe14db8b7279046030ad322502e68d9b53b 100644 (file)
@@ -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",
index 7c0db89a87d7a6b26cd90235978df8fe98aa1deb..f8a193d1d018d5fccbea5d2b5181ea4bbcd6863c 100644 (file)
@@ -1452,6 +1452,7 @@ getcmdline(
        case K_X2MOUSE:
        case K_X2DRAG:
        case K_X2RELEASE:
+       case K_MOUSEMOVE:
                goto cmdline_not_changed;
 
 #endif /* FEAT_MOUSE */
index a6a159997798cf8eff4678ea3b7a6d098b07862d..f17a5c1674bbe6e9a523c7b8d7d85b1c952989ad 100644 (file)
 # 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
index 455c0138841ae453f9763d5e65e33fc432899436..2e91c24c1a0021b8a3a4557953a55e5a7af8e3c4 100644 (file)
@@ -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;
 }
index ae62710d5781b0ca1bb9ed8ac5cfb7ee8b6c577f..c19866497ce36eb766263241c7ece05e03e6efee 100644 (file)
@@ -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);
 
index 7ef1c95341d60f3141e428c4d9407d9b72c2b9a8..926750cb2b6affacd8b9c9815ec2d0e42b5867cc 100644 (file)
--- 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);
index 1c01ecc84ac9a4db38568a0c6244d9a6b884a93d..ada048c62ce373bc4dce4610eccd0f0847357717 100644 (file)
@@ -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)
 {
index 7cb5c69bcc358c0cd78af6b8265bec3baf62f81d..8a34f0e296799aeb78686ea9db815465a73f9322 100644 (file)
@@ -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)
index 221e3d8012b132a7ab9af4cb5bb5b15f4394c53f..c40b6cf15b06a5382ad7c62e12461dda893390d4 100644 (file)
@@ -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
index f33fd3b9e6d2a6c46d9e13289ac4b9ac89cff4a9..4c691bb258c7f1485db70d173c6a804d38ff2507 100644 (file)
@@ -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
index 63d9e81d69c1fd1a0d90b979e6b6c1d2f696d973..87b79fae1eb82272253e337d681ab8a90b7c4734 100644 (file)
@@ -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},
index e781cd70e23fc40e0cc2c33300b5d87217b0703f..81bedfdba1f00bd72621380eb4dfbc8896c7a11a 100644 (file)
@@ -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:
index 4f25c1ff4480e2d019b0fc7f3a9397d15519f4b4..495a89dddb084c270061707fd36523671c701b87 100644 (file)
@@ -640,6 +640,15 @@ static struct vimoption options[] =
 #else
                            (char_u *)NULL, PV_NONE,
                            {(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,
@@ -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)
index f9972f21acde1198092c6ab6fc3b4a44efed8d93..2084517d558e8310b5297cb849b11a05a7244239 100644 (file)
@@ -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
index d2f080529e523241fcb01ba655ed15c477b7c819..1c2a902761fd05e534da07c701487177122f46e0 100644 (file)
@@ -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.
  */
index ec75281e776745e4974983585b7b60ca778004fe..dc66e75944ad25cb15288d424061daeb46ada2c6 100644 (file)
@@ -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
index b0067a00a48394765dbad1e7052c341a3dd78531..aa0553fa006c9f1aef6ccbe3a89a16ce0cd17674 100644 (file)
@@ -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 : */
index d3a00b5a24811074630f252d965517861c271b8b..fbdad1570922f007b2f50a9a104616f83d5319a8 100644 (file)
@@ -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);
index 423076c3eff2b1a4acb57a95163f35b3f87ad7c5..57795338b0c5adf568a0299952e0df41230791fc 100644 (file)
@@ -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 : */
index 83b54e18ce9e907ee9403f2859a0a484084efc5f..359c17100d9f5ba27ebb438691966fbe382ec5d8 100644 (file)
@@ -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,
index b416e20f483b386a08d84ae8b5077c82239b2baf..6cbe3433ff4804c96f112f9f7b17382dc6181663 100644 (file)
@@ -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:
index c81d7a39b611aec1626a6a468e4ed559aeaf4f5f..3d0b5cd54b782b49bc3b9cd75d7004afb820313a 100644 (file)
@@ -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
@@ -766,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1309,
 /**/
     1308,
 /**/