Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2018-03-03 21:54:41 -08:00
16 changed files with 561 additions and 238 deletions
+13 -4
View File
@@ -2192,8 +2192,9 @@ gettabvar({nr}, {varname} [, {def}])
gettabwinvar({tabnr}, {winnr}, {name} [, {def}])
any {name} in {winnr} in tab page {tabnr}
getwininfo([{winid}]) List list of windows
getwinposx() Number X coord in pixels of GUI Vim window
getwinposy() Number Y coord in pixels of GUI Vim window
getwinpos([{tmeout}]) List X and Y coord in pixels of the Vim window
getwinposx() Number X coord in pixels of the Vim window
getwinposy() Number Y coord in pixels of the Vim window
getwinvar({nr}, {varname} [, {def}])
any variable {varname} in window {nr}
glob({expr} [, {nosuf} [, {list} [, {alllinks}]]])
@@ -4878,16 +4879,24 @@ gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
:let list_is_on = gettabwinvar(1, 2, '&list')
:echo "myvar = " . gettabwinvar(3, 1, 'myvar')
<
getwinpos([{timeout}]) *getwinpos()*
The result is a list with two numbers, the result of
getwinposx() and getwinposy() combined:
[x-pos, y-pos]
{timeout} can be used to specify how long to wait in msec for
a response from the terminal. When omitted 100 msec is used.
*getwinposx()*
getwinposx() The result is a Number, which is the X coordinate in pixels of
the left hand side of the GUI Vim window. Also works for an
xterm.
xterm (uses a timeout of 100 msec).
The result will be -1 if the information is not available.
The value can be used with `:winpos`.
*getwinposy()*
getwinposy() The result is a Number, which is the Y coordinate in pixels of
the top of the GUI Vim window. Also works for an xterm.
the top of the GUI Vim window. Also works for an xterm (uses
a timeout of 100 msec).
The result will be -1 if the information is not available.
The value can be used with `:winpos`.
+49 -27
View File
@@ -7,8 +7,6 @@
Terminal window support *terminal*
WARNING: THIS IS ONLY PARTLY IMPLEMENTED, ANYTHING CAN STILL CHANGE
The terminal feature is optional, use this to check if your Vim has it: >
echo has('terminal')
If the result is "1" you have it.
@@ -40,7 +38,6 @@ If the result is "1" you have it.
{Vi does not have any of these commands}
{only available when compiled with the |+terminal| feature}
The terminal feature requires the |+multi_byte|, |+job| and |+channel| features.
==============================================================================
@@ -481,7 +478,7 @@ program window A terminal window for the executed program. When "run" is
The current window is used to show the source code. When gdb pauses the
source file location will be displayed, if possible. A sign is used to
highlight the current position (using highlight group debugPC).
highlight the current position, using highlight group debugPC.
If the buffer in the current window is modified, another window will be opened
to display the current gdb position.
@@ -506,6 +503,7 @@ You should now have three windows:
source - where you started, has a window toolbar with buttons
gdb - you can type gdb commands here
program - the executed program will use this window
You can use CTRL-W CTRL-W or the mouse to move focus between windows.
Put focus on the gdb window and type: >
break ex_help
@@ -526,6 +524,8 @@ displayed:
This way you can inspect the value of local variables. You can also focus the
gdb window and use a "print" command, e.g.: >
print *eap
If mouse pointer movements are working, Vim will also show a balloon when the
mouse rests on text that can be evaluated by gdb.
Now go back to the source window and put the cursor on the first line after
the for loop, then type: >
@@ -561,38 +561,42 @@ Put focus on the gdb window to type commands there. Some common ones are:
- frame N go to the Nth stack frame
- continue continue execution
In the window showing the source code these commands can used to control gdb:
:Run [args] run the program with [args] or the previous arguments
:Arguments {args} set arguments for the next :Run
In the window showing the source code these commands can be used to control gdb:
`:Run` [args] run the program with [args] or the previous arguments
`:Arguments` {args} set arguments for the next `:Run`
:Break set a breakpoint at the current line; a sign will be displayed
:Delete delete a breakpoint at the current line
`:Break` set a breakpoint at the current line; a sign will be displayed
`:Clear` delete the breakpoint at the current line
:Step execute the gdb "step" command
:Over execute the gdb "next" command (:Next is a Vim command)
:Finish execute the gdb "finish" command
:Continue execute the gdb "continue" command
:Stop interrupt the program
`:Step` execute the gdb "step" command
`:Over` execute the gdb "next" command (`:Next` is a Vim command)
`:Finish` execute the gdb "finish" command
`:Continue` execute the gdb "continue" command
`:Stop` interrupt the program
If 'mouse' is set the plugin adds a window toolbar with these entries:
Step :Step
Next :Over
Finish :Finish
Cont :Continue
Stop :Stop
Eval :Evaluate
Step `:Step`
Next `:Over`
Finish `:Finish`
Cont `:Continue`
Stop `:Stop`
Eval `:Evaluate`
This way you can use the mouse to perform the most common commands. You need
to have the 'mouse' option set to enable mouse clicks.
You can add the window toolbar in other windows you open with: >
:Winbar
Inspecting variables ~
*termdebug-variables*
:Evaluate evaluate the expression under the cursor
K same
:Evaluate {expr} evaluate {expr}
:'<,'>Evaluate evaluate the Visually selected text
`:Evaluate` evaluate the expression under the cursor
`K` same
`:Evaluate` {expr} evaluate {expr}
`:'<,'>Evaluate` evaluate the Visually selected text
This is similar to using "print" in the gdb window.
You can usually shorten `:Evaluate` to `:Ev`.
Other commands ~
@@ -609,17 +613,21 @@ will break the debugger.
Customizing ~
*termdebug-customizing*
GDB command *termdebug-customizing*
To change the name of the gdb command, set the "termdebugger" variable before
invoking `:Termdebug`: >
let termdebugger = "mygdb"
< *gdb-version*
< *gdb-version*
Only debuggers fully compatible with gdb will work. Vim uses the GDB/MI
interface. This probably requires gdb version 7.12. if you get this error:
Undefined command: "new-ui". Try "help".~
Then your gdb is too old.
*hl-debugPC* *hl-debugBreakpoint*
Colors *hl-debugPC* *hl-debugBreakpoint*
The color of the signs can be adjusted with these highlight groups:
- debugPC the current position
- debugBreakpoint a breakpoint
@@ -632,6 +640,20 @@ When 'background' is "dark":
hi debugPC term=reverse ctermbg=darkblue guibg=darkblue
hi debugBreakpoint term=reverse ctermbg=red guibg=red
Popup menu *termdebug_popup*
By default the Termdebug plugin sets 'mousemodel' to "popup_setpos" and adds
these entries to the popup menu:
Set breakpoint `:Break`
Clear breakpoint `:Clear`
Evaluate `:Evaluate`
If you don't want this then disable it with: >
let g:termdebug_popup = 0
Vim window width *termdebug_wide*
To change the width of the Vim window when debugging starts, and use a
vertical split: >
let g:termdebug_wide = 163
+52 -16
View File
@@ -201,7 +201,7 @@ endfunc
" Install commands in the current window to control the debugger.
func s:InstallCommands()
command Break call s:SetBreakpoint()
command Delete call s:DeleteBreakpoint()
command Clear call s:ClearBreakpoint()
command Step call s:SendCommand('-exec-step')
command Over call s:SendCommand('-exec-next')
command Finish call s:SendCommand('-exec-finish')
@@ -212,24 +212,42 @@ func s:InstallCommands()
command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
command Gdb call win_gotoid(s:gdbwin)
command Program call win_gotoid(s:ptywin)
command Winbar call s:InstallWinbar()
" TODO: can the K mapping be restored?
nnoremap K :Evaluate<CR>
if has('menu') && &mouse != ''
nnoremenu WinBar.Step :Step<CR>
nnoremenu WinBar.Next :Over<CR>
nnoremenu WinBar.Finish :Finish<CR>
nnoremenu WinBar.Cont :Continue<CR>
nnoremenu WinBar.Stop :Stop<CR>
nnoremenu WinBar.Eval :Evaluate<CR>
call s:InstallWinbar()
if !exists('g:termdebug_popup') || g:termdebug_popup != 0
let s:saved_mousemodel = &mousemodel
let &mousemodel = 'popup_setpos'
an 1.200 PopUp.-SEP3- <Nop>
an 1.210 PopUp.Set\ breakpoint :Break<CR>
an 1.220 PopUp.Clear\ breakpoint :Clear<CR>
an 1.230 PopUp.Evaluate :Evaluate<CR>
endif
endif
endfunc
let s:winbar_winids = []
" Install the window toolbar in the current window.
func s:InstallWinbar()
nnoremenu WinBar.Step :Step<CR>
nnoremenu WinBar.Next :Over<CR>
nnoremenu WinBar.Finish :Finish<CR>
nnoremenu WinBar.Cont :Continue<CR>
nnoremenu WinBar.Stop :Stop<CR>
nnoremenu WinBar.Eval :Evaluate<CR>
call add(s:winbar_winids, win_getid(winnr()))
endfunc
" Delete installed debugger commands in the current window.
func s:DeleteCommands()
delcommand Break
delcommand Delete
delcommand Clear
delcommand Step
delcommand Over
delcommand Finish
@@ -240,16 +258,34 @@ func s:DeleteCommands()
delcommand Evaluate
delcommand Gdb
delcommand Program
delcommand Winbar
nunmap K
if has('menu')
aunmenu WinBar.Step
aunmenu WinBar.Next
aunmenu WinBar.Finish
aunmenu WinBar.Cont
aunmenu WinBar.Stop
aunmenu WinBar.Eval
" Remove the WinBar entries from all windows where it was added.
let curwinid = win_getid(winnr())
for winid in s:winbar_winids
if win_gotoid(winid)
aunmenu WinBar.Step
aunmenu WinBar.Next
aunmenu WinBar.Finish
aunmenu WinBar.Cont
aunmenu WinBar.Stop
aunmenu WinBar.Eval
endif
endfor
call win_gotoid(curwinid)
let s:winbar_winids = []
if exists('s:saved_mousemodel')
let &mousemodel = s:saved_mousemodel
unlet s:saved_mousemodel
aunmenu PopUp.-SEP3-
aunmenu PopUp.Set\ breakpoint
aunmenu PopUp.Clear\ breakpoint
aunmenu PopUp.Evaluate
endif
endif
exe 'sign unplace ' . s:pc_id
@@ -278,8 +314,8 @@ func s:SetBreakpoint()
endif
endfunc
" :Delete - Delete a breakpoint at the cursor position.
func s:DeleteBreakpoint()
" :Clear - Delete a breakpoint at the cursor position.
func s:ClearBreakpoint()
let fname = fnameescape(expand('%:p'))
let lnum = line('.')
for [key, val] in items(s:breakpoints)
+37 -3
View File
@@ -197,6 +197,7 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv);
static void f_gettabvar(typval_T *argvars, typval_T *rettv);
static void f_gettabwinvar(typval_T *argvars, typval_T *rettv);
static void f_getwininfo(typval_T *argvars, typval_T *rettv);
static void f_getwinpos(typval_T *argvars, typval_T *rettv);
static void f_getwinposx(typval_T *argvars, typval_T *rettv);
static void f_getwinposy(typval_T *argvars, typval_T *rettv);
static void f_getwinvar(typval_T *argvars, typval_T *rettv);
@@ -641,6 +642,7 @@ static struct fst
{"gettabvar", 2, 3, f_gettabvar},
{"gettabwinvar", 3, 4, f_gettabwinvar},
{"getwininfo", 0, 1, f_getwininfo},
{"getwinpos", 0, 1, f_getwinpos},
{"getwinposx", 0, 0, f_getwinposx},
{"getwinposy", 0, 0, f_getwinposy},
{"getwinvar", 2, 3, f_getwinvar},
@@ -738,7 +740,7 @@ static struct fst
{"pow", 2, 2, f_pow},
#endif
{"prevnonblank", 1, 1, f_prevnonblank},
{"printf", 2, 19, f_printf},
{"printf", 1, 19, f_printf},
{"pumvisible", 0, 0, f_pumvisible},
#ifdef FEAT_PYTHON3
{"py3eval", 1, 1, f_py3eval},
@@ -5533,6 +5535,38 @@ f_win_screenpos(typval_T *argvars, typval_T *rettv)
list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
}
/*
* "getwinpos({timeout})" function
*/
static void
f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv)
{
int x = -1;
int y = -1;
if (rettv_list_alloc(rettv) == FAIL)
return;
#ifdef FEAT_GUI
if (gui.in_use)
gui_mch_get_winpos(&x, &y);
# if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
else
# endif
#endif
#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
{
varnumber_T timeout = 100;
if (argvars[0].v_type != VAR_UNKNOWN)
timeout = get_tv_number(&argvars[0]);
term_get_winpos(&x, &y, timeout);
}
#endif
list_append_number(rettv->vval.v_list, (varnumber_T)x);
list_append_number(rettv->vval.v_list, (varnumber_T)y);
}
/*
* "getwinposx()" function
*/
@@ -5554,7 +5588,7 @@ f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
{
int x, y;
if (term_get_winpos(&x, &y) == OK)
if (term_get_winpos(&x, &y, (varnumber_T)100) == OK)
rettv->vval.v_number = x;
}
#endif
@@ -5581,7 +5615,7 @@ f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
{
int x, y;
if (term_get_winpos(&x, &y) == OK)
if (term_get_winpos(&x, &y, (varnumber_T)100) == OK)
rettv->vval.v_number = y;
}
#endif
+7
View File
@@ -730,6 +730,13 @@
# endif
#endif
/*
* popup menu in a terminal
*/
#if defined(FEAT_MENU) && !defined(ALWAYS_USE_GUI) && defined(FEAT_INS_EXPAND)
# define FEAT_TERM_POPUP_MENU
#endif
/* There are two ways to use XPM. */
#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
|| defined(HAVE_X11_XPM_H)
+67 -57
View File
@@ -34,10 +34,6 @@ static int menu_namecmp(char_u *name, char_u *mname);
static int get_menu_cmd_modes(char_u *, int, int *, int *);
static char_u *popup_mode_name(char_u *name, int idx);
static char_u *menu_text(char_u *text, int *mnemonic, char_u **actext);
#ifdef FEAT_GUI
static int get_menu_mode(void);
static void gui_update_menus_recurse(vimmenu_T *, int);
#endif
#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
static void gui_create_tearoffs_recurse(vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx);
@@ -1877,7 +1873,7 @@ menu_is_tearoff(char_u *name UNUSED)
}
#endif
#ifdef FEAT_GUI
#if defined(FEAT_GUI) || defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
static int
get_menu_mode(void)
@@ -1901,6 +1897,60 @@ get_menu_mode(void)
return MENU_INDEX_INVALID;
}
/*
* Display the Special "PopUp" menu as a pop-up at the current mouse
* position. The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode,
* etc.
*/
void
show_popupmenu(void)
{
vimmenu_T *menu;
int mode;
mode = get_menu_mode();
if (mode == MENU_INDEX_INVALID)
return;
mode = menu_mode_chars[mode];
# ifdef FEAT_AUTOCMD
{
char_u ename[2];
ename[0] = mode;
ename[1] = NUL;
apply_autocmds(EVENT_MENUPOPUP, ename, NULL, FALSE, curbuf);
}
# endif
for (menu = root_menu; menu != NULL; menu = menu->next)
if (STRNCMP("PopUp", menu->name, 5) == 0 && menu->name[5] == mode)
break;
/* Only show a popup when it is defined and has entries */
if (menu != NULL && menu->children != NULL)
{
# if defined(FEAT_GUI)
if (gui.in_use)
{
/* Update the menus now, in case the MenuPopup autocommand did
* anything. */
gui_update_menus(0);
gui_mch_show_popupmenu(menu);
}
# endif
# if defined(FEAT_GUI) && defined(FEAT_TERM_POPUP_MENU)
else
# endif
# if defined(FEAT_TERM_POPUP_MENU)
pum_show_popupmenu(menu);
# endif
}
}
#endif
#if defined(FEAT_GUI) || defined(PROTO)
/*
* Check that a pointer appears in the menu tree. Used to protect from using
* a menu that was deleted after it was selected but before the event was
@@ -1961,28 +2011,28 @@ gui_update_menus_recurse(vimmenu_T *menu, int mode)
while (menu)
{
if ((menu->modes & menu->enabled & mode)
#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
# if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
|| menu_is_tearoff(menu->dname)
#endif
# endif
)
grey = FALSE;
else
grey = TRUE;
#ifdef FEAT_GUI_ATHENA
# ifdef FEAT_GUI_ATHENA
/* Hiding menus doesn't work for Athena, it can cause a crash. */
gui_mch_menu_grey(menu, grey);
#else
# else
/* Never hide a toplevel menu, it may make the menubar resize or
* disappear. Same problem for ToolBar items. */
if (vim_strchr(p_go, GO_GREY) != NULL || menu->parent == NULL
# ifdef FEAT_TOOLBAR
# ifdef FEAT_TOOLBAR
|| menu_is_toolbar(menu->parent->name)
# endif
# endif
)
gui_mch_menu_grey(menu, grey);
else
gui_mch_menu_hidden(menu, grey);
#endif
# endif
gui_update_menus_recurse(menu->children, mode);
menu = menu->next;
}
@@ -2016,15 +2066,15 @@ gui_update_menus(int modes)
gui_mch_draw_menubar();
prev_mode = mode;
force_menu_update = FALSE;
#ifdef FEAT_GUI_W32
# ifdef FEAT_GUI_W32
/* This can leave a tearoff as active window - make sure we
* have the focus <negri>*/
gui_mch_activate_window();
#endif
# endif
}
}
#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \
# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \
|| defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(PROTO)
/*
* Check if a key is used as a mnemonic for a toplevel menu.
@@ -2043,47 +2093,7 @@ gui_is_menu_shortcut(int key)
return TRUE;
return FALSE;
}
#endif
/*
* Display the Special "PopUp" menu as a pop-up at the current mouse
* position. The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode,
* etc.
*/
void
gui_show_popupmenu(void)
{
vimmenu_T *menu;
int mode;
mode = get_menu_mode();
if (mode == MENU_INDEX_INVALID)
return;
mode = menu_mode_chars[mode];
#ifdef FEAT_AUTOCMD
{
char_u ename[2];
ename[0] = mode;
ename[1] = NUL;
apply_autocmds(EVENT_MENUPOPUP, ename, NULL, FALSE, curbuf);
}
#endif
for (menu = root_menu; menu != NULL; menu = menu->next)
if (STRNCMP("PopUp", menu->name, 5) == 0 && menu->name[5] == mode)
break;
/* Only show a popup when it is defined and has entries */
if (menu != NULL && menu->children != NULL)
{
/* Update the menus now, in case the MenuPopup autocommand did
* anything. */
gui_update_menus(0);
gui_mch_show_popupmenu(menu);
}
}
# endif
#endif /* FEAT_GUI */
#if (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)) || defined(PROTO)
@@ -2244,7 +2254,7 @@ gui_destroy_tearoffs_recurse(vimmenu_T *menu)
* Execute "menu". Use by ":emenu" and the window toolbar.
* "eap" is NULL for the window toolbar.
*/
static void
void
execute_menu(exarg_T *eap, vimmenu_T *menu)
{
char_u *mode;
+78 -67
View File
@@ -2286,12 +2286,12 @@ op_function(oparg_T *oap UNUSED)
* Do the appropriate action for the current mouse click in the current mode.
* Not used for Command-line mode.
*
* Normal Mode:
* Normal and Visual Mode:
* event modi- position visual change action
* fier cursor window
* left press - yes end yes
* left press C yes end yes "^]" (2)
* left press S yes end yes "*" (2)
* left press S yes end (popup: extend) yes "*" (2)
* left drag - yes start if moved no
* left relse - yes start if moved no
* middle press - yes if not active no put register
@@ -2670,84 +2670,95 @@ do_mouse(
if (which_button == MOUSE_RIGHT
&& !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
{
/*
* NOTE: Ignore right button down and drag mouse events.
* Windows only shows the popup menu on the button up event.
*/
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) \
|| defined(FEAT_GUI_MACVIM)
if (!is_click)
return FALSE;
#endif
#if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN)
if (is_click || is_drag)
return FALSE;
#endif
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
|| defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON) \
|| defined(FEAT_TERM_POPUP_MENU) \
|| defined(FEAT_GUI_MACVIM)
# ifdef FEAT_GUI
if (gui.in_use)
{
jump_flags = 0;
if (STRCMP(p_mousem, "popup_setpos") == 0)
{
/* First set the cursor position before showing the popup
* menu. */
if (VIsual_active)
{
pos_T m_pos;
# if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
if (!is_click)
/* Ignore right button release events, only shows the popup
* menu on the button down event. */
return FALSE;
# endif
# if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN)
if (is_click || is_drag)
/* Ignore right button down and drag mouse events. Windows
* only shows the popup menu on the button up event. */
return FALSE;
# endif
}
# endif
# if defined(FEAT_GUI) && defined(FEAT_TERM_POPUP_MENU)
else
# endif
# if defined(FEAT_TERM_POPUP_MENU)
if (!is_click)
/* Ignore right button release events, only shows the popup
* menu on the button down event. */
return FALSE;
#endif
/*
* set MOUSE_MAY_STOP_VIS if we are outside the
* selection or the current window (might have false
* negative here)
*/
if (mouse_row < curwin->w_winrow
|| mouse_row
> (curwin->w_winrow + curwin->w_height))
jump_flags = MOUSE_MAY_STOP_VIS;
else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER)
jump_flags = MOUSE_MAY_STOP_VIS;
else
jump_flags = 0;
if (STRCMP(p_mousem, "popup_setpos") == 0)
{
/* First set the cursor position before showing the popup
* menu. */
if (VIsual_active)
{
pos_T m_pos;
/*
* set MOUSE_MAY_STOP_VIS if we are outside the
* selection or the current window (might have false
* negative here)
*/
if (mouse_row < curwin->w_winrow
|| mouse_row
> (curwin->w_winrow + curwin->w_height))
jump_flags = MOUSE_MAY_STOP_VIS;
else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER)
jump_flags = MOUSE_MAY_STOP_VIS;
else
{
if ((LT_POS(curwin->w_cursor, VIsual)
&& (LT_POS(m_pos, curwin->w_cursor)
|| LT_POS(VIsual, m_pos)))
|| (LT_POS(VIsual, curwin->w_cursor)
&& (LT_POS(m_pos, VIsual)
|| LT_POS(curwin->w_cursor, m_pos))))
{
if ((LT_POS(curwin->w_cursor, VIsual)
&& (LT_POS(m_pos, curwin->w_cursor)
|| LT_POS(VIsual, m_pos)))
|| (LT_POS(VIsual, curwin->w_cursor)
&& (LT_POS(m_pos, VIsual)
|| LT_POS(curwin->w_cursor, m_pos))))
{
jump_flags = MOUSE_MAY_STOP_VIS;
}
else if (VIsual_mode == Ctrl_V)
{
getvcols(curwin, &curwin->w_cursor, &VIsual,
&leftcol, &rightcol);
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
if (m_pos.col < leftcol || m_pos.col > rightcol)
jump_flags = MOUSE_MAY_STOP_VIS;
}
else if (VIsual_mode == Ctrl_V)
{
getvcols(curwin, &curwin->w_cursor, &VIsual,
&leftcol, &rightcol);
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
if (m_pos.col < leftcol || m_pos.col > rightcol)
jump_flags = MOUSE_MAY_STOP_VIS;
}
}
}
else
jump_flags = MOUSE_MAY_STOP_VIS;
}
if (jump_flags)
{
jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
update_curbuf(VIsual_active ? INVERTED : VALID);
setcursor();
out_flush(); /* Update before showing popup menu */
}
# ifdef FEAT_MENU
gui_show_popupmenu();
# endif
return (jump_flags & CURSOR_MOVED) != 0;
else
jump_flags = MOUSE_MAY_STOP_VIS;
}
else
return FALSE;
if (jump_flags)
{
jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
update_curbuf(VIsual_active ? INVERTED : VALID);
setcursor();
out_flush(); /* Update before showing popup menu */
}
# ifdef FEAT_MENU
show_popupmenu();
got_click = FALSE; /* ignore release events */
# endif
return (jump_flags & CURSOR_MOVED) != 0;
#else
return FALSE;
#endif
+191 -32
View File
@@ -422,9 +422,11 @@ pum_redraw(void)
char_u *st;
int saved = *p;
*p = NUL;
if (saved != NUL)
*p = NUL;
st = transstr(s);
*p = saved;
if (saved != NUL)
*p = saved;
#ifdef FEAT_RIGHTLEFT
if (curwin->w_p_rl)
{
@@ -830,6 +832,43 @@ pum_get_height(void)
return pum_height;
}
# if defined(FEAT_BEVAL_TERM) || defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
static void
pum_position_at_mouse(int min_width)
{
if (Rows - mouse_row > pum_size)
{
/* 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 - pum_size;
if (pum_row < 0)
{
pum_height += pum_row;
pum_row = 0;
}
}
if (Columns - mouse_col >= pum_base_width
|| Columns - mouse_col > 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 > min_width
? min_width : pum_base_width);
pum_width = Columns - pum_col;
if (pum_width > pum_base_width + 1)
pum_width = pum_base_width + 1;
}
# endif
# if defined(FEAT_BEVAL_TERM) || defined(PROTO)
static pumitem_T *balloon_array = NULL;
static int balloon_arraysize;
@@ -1028,36 +1067,7 @@ ui_post_balloon(char_u *mesg, list_T *list)
pum_scrollbar = 0;
pum_height = balloon_arraysize;
if (Rows - mouse_row > pum_size)
{
/* 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 - 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_position_at_mouse(BALLOON_MIN_WIDTH);
pum_selected = -1;
pum_first = 0;
pum_redraw();
@@ -1075,4 +1085,153 @@ ui_may_remove_balloon(void)
}
# endif
# if defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
/*
* Select the pum entry at the mouse position.
*/
static void
pum_select_mouse_pos(void)
{
int idx = mouse_row - pum_row;
if (idx < 0 || idx >= pum_size)
pum_selected = -1;
else if (*pum_array[idx].pum_text != NUL)
pum_selected = idx;
}
/*
* Execute the currently selected popup menu item.
*/
static void
pum_execute_menu(vimmenu_T *menu)
{
vimmenu_T *mp;
int idx = 0;
exarg_T ea;
for (mp = menu->children; mp != NULL; mp = mp->next)
if (idx++ == pum_selected)
{
vim_memset(&ea, 0, sizeof(ea));
execute_menu(&ea, mp);
break;
}
}
/*
* Open the terminal version of the popup menu and don't return until it is
* closed.
*/
void
pum_show_popupmenu(vimmenu_T *menu)
{
vimmenu_T *mp;
int idx = 0;
pumitem_T *array;
#ifdef FEAT_BEVAL_TERM
int save_bevalterm = p_bevalterm;
#endif
pum_undisplay();
pum_size = 0;
for (mp = menu->children; mp != NULL; mp = mp->next)
++pum_size;
array = (pumitem_T *)alloc_clear((unsigned)sizeof(pumitem_T) * pum_size);
if (array == NULL)
return;
for (mp = menu->children; mp != NULL; mp = mp->next)
if (menu_is_separator(mp->dname))
array[idx++].pum_text = (char_u *)"";
else
array[idx++].pum_text = mp->dname;
pum_array = array;
pum_compute_size();
pum_scrollbar = 0;
pum_height = pum_size;
pum_position_at_mouse(20);
pum_selected = -1;
pum_first = 0;
# ifdef FEAT_BEVAL_TERM
p_bevalterm = TRUE; /* track mouse movement */
mch_setmouse(TRUE);
# endif
for (;;)
{
int c;
pum_redraw();
setcursor();
out_flush();
c = vgetc();
if (c == ESC)
break;
else if (c == CAR || c == NL)
{
/* enter: select current item, if any, and close */
pum_execute_menu(menu);
break;
}
else if (c == 'k' || c == K_UP || c == K_MOUSEUP)
{
/* cursor up: select previous item */
while (pum_selected > 0)
{
--pum_selected;
if (*array[pum_selected].pum_text != NUL)
break;
}
}
else if (c == 'j' || c == K_DOWN || c == K_MOUSEDOWN)
{
/* cursor down: select next item */
while (pum_selected < pum_size - 1)
{
++pum_selected;
if (*array[pum_selected].pum_text != NUL)
break;
}
}
else if (c == K_RIGHTMOUSE)
{
/* Right mouse down: reposition the menu. */
vungetc(c);
break;
}
else if (c == K_LEFTDRAG || c == K_RIGHTDRAG || c == K_MOUSEMOVE)
{
/* mouse moved: selec item in the mouse row */
pum_select_mouse_pos();
}
else if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM || c == K_RIGHTRELEASE)
{
/* left mouse click: select clicked item, if any, and close;
* right mouse release: select clicked item, close if any */
pum_select_mouse_pos();
if (pum_selected >= 0)
{
pum_execute_menu(menu);
break;
}
if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM)
break;
}
}
vim_free(array);
pum_undisplay();
# ifdef FEAT_BEVAL_TERM
p_bevalterm = save_bevalterm;
mch_setmouse(TRUE);
# endif
}
# endif
#endif
+2 -1
View File
@@ -12,12 +12,13 @@ int menu_is_popup(char_u *name);
int menu_is_child_of_popup(vimmenu_T *menu);
int menu_is_toolbar(char_u *name);
int menu_is_separator(char_u *name);
void show_popupmenu(void);
int check_menu_pointer(vimmenu_T *root, vimmenu_T *menu_to_check);
void gui_create_initial_menus(vimmenu_T *menu);
void gui_update_menus(int modes);
int gui_is_menu_shortcut(int key);
void gui_show_popupmenu(void);
void gui_mch_toggle_tearoffs(int enable);
void execute_menu(exarg_T *eap, vimmenu_T *menu);
void ex_emenu(exarg_T *eap);
void winbar_click(win_T *wp, int col);
vimmenu_T *gui_find_menu(char_u *path_name);
+1
View File
@@ -9,4 +9,5 @@ int split_message(char_u *mesg, pumitem_T **array);
void ui_remove_balloon(void);
void ui_post_balloon(char_u *mesg, list_T *list);
void ui_may_remove_balloon(void);
void pum_show_popupmenu(vimmenu_T *menu);
/* vim: set ft=c : */
+1 -1
View File
@@ -24,7 +24,7 @@ void term_cursor_right(int i);
void term_append_lines(int line_count);
void term_delete_lines(int line_count);
void term_set_winpos(int x, int y);
int term_get_winpos(int *x, int *y);
int term_get_winpos(int *x, int *y, varnumber_T timeout);
void term_set_winsize(int height, int width);
void term_fg_color(int n);
void term_bg_color(int n);
+2 -1
View File
@@ -2470,7 +2470,8 @@ syn_current_attr(
/* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */
if (current_next_list != NULL
&& syn_getcurline()[current_col + 1] == NUL
&& (line = syn_getcurline())[current_col] != NUL
&& line[current_col + 1] == NUL
&& !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)))
current_next_list = NULL;
+37 -26
View File
@@ -2795,7 +2795,7 @@ static int waiting_for_winpos = FALSE;
* Returns OK or FAIL.
*/
int
term_get_winpos(int *x, int *y)
term_get_winpos(int *x, int *y, varnumber_T timeout)
{
int count = 0;
@@ -2807,8 +2807,8 @@ term_get_winpos(int *x, int *y)
OUT_STR(T_CGP);
out_flush();
/* Try reading the result for 100 msec. */
while (count++ < 10)
/* Try reading the result for "timeout" msec. */
while (count++ < timeout / 10)
{
(void)vpeekc_nomap();
if (winpos_x >= 0 && winpos_y >= 0)
@@ -4872,7 +4872,7 @@ check_termcode(
* {tail} can be Esc>\ or STERM
*
* Check for cursor shape response from xterm:
* {lead}1$r<number> q{tail}
* {lead}1$r<digit> q{tail}
*
* {lead} can be <Esc>P or DCS
* {tail} can be Esc>\ or STERM
@@ -4903,35 +4903,46 @@ check_termcode(
break;
}
}
else if ((len >= j + 6 && isdigit(argp[3]))
&& argp[4] == ' '
&& argp[5] == 'q')
else
{
/* cursor shape response */
i = j + 6;
if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
|| tp[i] == STERM)
/* Probably the cursor shape response. Make sure that "i"
* is equal to "len" when there are not sufficient
* characters. */
for (i = j + 3; i < len; ++i)
{
int number = argp[3] - '0';
if (i - j == 3 && !isdigit(tp[i]))
break;
if (i - j == 4 && tp[i] != ' ')
break;
if (i - j == 5 && tp[i] != 'q')
break;
if (i - j == 6 && tp[i] != ESC && tp[i] != STERM)
break;
if ((i - j == 6 && tp[i] == STERM)
|| (i - j == 7 && tp[i] == '\\'))
{
int number = argp[3] - '0';
/* 0, 1 = block blink, 2 = block
* 3 = underline blink, 4 = underline
* 5 = vertical bar blink, 6 = vertical bar */
number = number == 0 ? 1 : number;
initial_cursor_shape = (number + 1) / 2;
/* The blink flag is actually inverted, compared to
* the value set with T_SH. */
initial_cursor_shape_blink =
/* 0, 1 = block blink, 2 = block
* 3 = underline blink, 4 = underline
* 5 = vertical bar blink, 6 = vertical bar */
number = number == 0 ? 1 : number;
initial_cursor_shape = (number + 1) / 2;
/* The blink flag is actually inverted, compared to
* the value set with T_SH. */
initial_cursor_shape_blink =
(number & 1) ? FALSE : TRUE;
rcs_status = STATUS_GOT;
LOG_TR("Received cursor shape response");
rcs_status = STATUS_GOT;
LOG_TR("Received cursor shape response");
key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE;
slen = i + 1 + (tp[i] == ESC);
key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE;
slen = i + 1;
# ifdef FEAT_EVAL
set_vim_var_string(VV_TERMSTYLERESP, tp, slen);
set_vim_var_string(VV_TERMSTYLERESP, tp, slen);
# endif
break;
}
}
}
+3
View File
@@ -131,6 +131,9 @@ func Test_option_value()
endfunc
function Test_printf_misc()
call assert_equal('123', printf('123'))
call assert_fails("call printf('123', 3)", "E767:")
call assert_equal('123', printf('%d', 123))
call assert_equal('123', printf('%i', 123))
call assert_equal('123', printf('%D', 123))
+5 -3
View File
@@ -3219,8 +3219,9 @@ mouse_find_win(int *rowp, int *colp UNUSED)
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \
|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
|| defined(FEAT_GUI_PHOTON) || defined(PROTO) \
|| defined(FEAT_GUI_MACVIM)
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_TERM_POPUP_MENU) \
|| defined(FEAT_GUI_MACVIM) \
|| defined(PROTO)
/*
* Translate window coordinates to buffer position without any side effects
*/
@@ -3266,7 +3267,8 @@ get_fpos_of_mouse(pos_T *mpos)
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \
|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_BEVAL) || defined(PROTO)
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_BEVAL) \
|| defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
/*
* Convert a virtual (screen) column to a character column.
* The first column is one.
+16
View File
@@ -793,6 +793,22 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1563,
/**/
1562,
/**/
1561,
/**/
1560,
/**/
1559,
/**/
1558,
/**/
1557,
/**/
1556,
/**/
1555,
/**/