diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-11-18 18:52:04 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-11-18 18:52:04 +0100 |
commit | 51b0f3701ecb440aa72ab6017c1df6940c0e0f6f (patch) | |
tree | 9cfd3546d8e52be2b1425dcc65095f8e650eadde | |
parent | 234d16286a2733adedef56784c17415ae169b9ad (diff) |
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.
-rw-r--r-- | runtime/doc/options.txt | 19 | ||||
-rw-r--r-- | runtime/pack/dist/opt/termdebug/plugin/termdebug.vim | 66 | ||||
-rw-r--r-- | src/edit.c | 1 | ||||
-rw-r--r-- | src/evalfunc.c | 5 | ||||
-rw-r--r-- | src/ex_cmds2.c | 39 | ||||
-rw-r--r-- | src/ex_getln.c | 1 | ||||
-rw-r--r-- | src/feature.h | 7 | ||||
-rw-r--r-- | src/getchar.c | 8 | ||||
-rw-r--r-- | src/globals.h | 6 | ||||
-rw-r--r-- | src/gui.c | 5 | ||||
-rw-r--r-- | src/gui_beval.c | 42 | ||||
-rw-r--r-- | src/keymap.h | 2 | ||||
-rw-r--r-- | src/message.c | 1 | ||||
-rw-r--r-- | src/misc1.c | 1 | ||||
-rw-r--r-- | src/misc2.c | 3 | ||||
-rw-r--r-- | src/normal.c | 18 | ||||
-rw-r--r-- | src/option.c | 26 | ||||
-rw-r--r-- | src/option.h | 3 | ||||
-rw-r--r-- | src/os_unix.c | 65 | ||||
-rw-r--r-- | src/popupmnu.c | 167 | ||||
-rw-r--r-- | src/proto/gui_beval.pro | 1 | ||||
-rw-r--r-- | src/proto/os_unix.pro | 1 | ||||
-rw-r--r-- | src/proto/popupmnu.pro | 3 | ||||
-rw-r--r-- | src/term.c | 1 | ||||
-rw-r--r-- | src/terminal.c | 6 | ||||
-rw-r--r-- | src/version.c | 7 |
26 files changed, 419 insertions, 85 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index b9e82d73a8..f9acff8186 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -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= diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 635bf93f23..1c3c9df9a7 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -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 diff --git a/src/edit.c b/src/edit.c index 435e1ed812..65c53f52f6 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 25b28bb3a2..bd5cf8dec5 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 2eef050eea..c6a6dbe14d 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 7c0db89a87..f8a193d1d0 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 a6a1599977..f17a5c1674 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 455c013884..2e91c24c1a 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 ae62710d57..c19866497c 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); @@ -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 1c01ecc84a..ada048c62c 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 7cb5c69bcc..8a34f0e296 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 221e3d8012..c40b6cf15b 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 f33fd3b9e6..4c691bb258 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 63d9e81d69..87b79fae1e 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 e781cd70e2..81bedfdba1 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 4f25c1ff44..495a89dddb 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 f9972f21ac..2084517d55 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 d2f080529e..1c2a902761 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 ec75281e77..dc66e75944 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_heig |