mirror of
				https://github.com/vim/vim.git
				synced 2025-10-30 09:47:20 -04:00 
			
		
		
		
	patch 8.0.1558: no right-click menu in a terminal
Problem: No right-click menu in a terminal. Solution: Implement the right click menu for the terminal.
This commit is contained in:
		| @@ -726,6 +726,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) | ||||
|   | ||||
							
								
								
									
										124
									
								
								src/menu.c
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								src/menu.c
									
									
									
									
									
								
							| @@ -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); | ||||
| @@ -1871,7 +1867,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) | ||||
| @@ -1895,6 +1891,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 | ||||
| @@ -1955,28 +2005,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; | ||||
|     } | ||||
| @@ -2010,15 +2060,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. | ||||
| @@ -2037,47 +2087,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) | ||||
| @@ -2238,7 +2248,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; | ||||
|   | ||||
							
								
								
									
										146
									
								
								src/normal.c
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								src/normal.c
									
									
									
									
									
								
							| @@ -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,82 +2670,94 @@ 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) | ||||
| 	    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_GUI_MAC) || defined(FEAT_GUI_PHOTON) \ | ||||
| 	    || defined(FEAT_TERM_POPUP_MENU) | ||||
| # 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 | ||||
|   | ||||
							
								
								
									
										223
									
								
								src/popupmnu.c
									
									
									
									
									
								
							
							
						
						
									
										223
									
								
								src/popupmnu.c
									
									
									
									
									
								
							| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 : */ | ||||
|   | ||||
| @@ -778,6 +778,8 @@ static char *(features[]) = | ||||
|  | ||||
| static int included_patches[] = | ||||
| {   /* Add new patch number below this line */ | ||||
| /**/ | ||||
|     1558, | ||||
| /**/ | ||||
|     1557, | ||||
| /**/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user