Mercurial > vim
comparison src/popupmnu.c @ 13369:244ff1b6d2ad v8.0.1558
patch 8.0.1558: no right-click menu in a terminal
commit https://github.com/vim/vim/commit/aef8c3da2ba59285b7cfde559ae21cdce6ba6919
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 3 18:59:16 2018 +0100
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.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 03 Mar 2018 19:00:06 +0100 |
parents | 1ba4f926247c |
children | d5347779fb20 |
comparison
equal
deleted
inserted
replaced
13368:a68814ee7449 | 13369:244ff1b6d2ad |
---|---|
420 /* Display the text that fits or comes before a Tab. | 420 /* Display the text that fits or comes before a Tab. |
421 * First convert it to printable characters. */ | 421 * First convert it to printable characters. */ |
422 char_u *st; | 422 char_u *st; |
423 int saved = *p; | 423 int saved = *p; |
424 | 424 |
425 *p = NUL; | 425 if (saved != NUL) |
426 *p = NUL; | |
426 st = transstr(s); | 427 st = transstr(s); |
427 *p = saved; | 428 if (saved != NUL) |
429 *p = saved; | |
428 #ifdef FEAT_RIGHTLEFT | 430 #ifdef FEAT_RIGHTLEFT |
429 if (curwin->w_p_rl) | 431 if (curwin->w_p_rl) |
430 { | 432 { |
431 if (st != NULL) | 433 if (st != NULL) |
432 { | 434 { |
828 pum_get_height(void) | 830 pum_get_height(void) |
829 { | 831 { |
830 return pum_height; | 832 return pum_height; |
831 } | 833 } |
832 | 834 |
835 # if defined(FEAT_BEVAL_TERM) || defined(FEAT_TERM_POPUP_MENU) || defined(PROTO) | |
836 static void | |
837 pum_position_at_mouse(int min_width) | |
838 { | |
839 if (Rows - mouse_row > pum_size) | |
840 { | |
841 /* Enough space below the mouse row. */ | |
842 pum_row = mouse_row + 1; | |
843 if (pum_height > Rows - pum_row) | |
844 pum_height = Rows - pum_row; | |
845 } | |
846 else | |
847 { | |
848 /* Show above the mouse row, reduce height if it does not fit. */ | |
849 pum_row = mouse_row - pum_size; | |
850 if (pum_row < 0) | |
851 { | |
852 pum_height += pum_row; | |
853 pum_row = 0; | |
854 } | |
855 } | |
856 if (Columns - mouse_col >= pum_base_width | |
857 || Columns - mouse_col > min_width) | |
858 /* Enough space to show at mouse column. */ | |
859 pum_col = mouse_col; | |
860 else | |
861 /* Not enough space, right align with window. */ | |
862 pum_col = Columns - (pum_base_width > min_width | |
863 ? min_width : pum_base_width); | |
864 | |
865 pum_width = Columns - pum_col; | |
866 if (pum_width > pum_base_width + 1) | |
867 pum_width = pum_base_width + 1; | |
868 } | |
869 | |
870 # endif | |
871 | |
833 # if defined(FEAT_BEVAL_TERM) || defined(PROTO) | 872 # if defined(FEAT_BEVAL_TERM) || defined(PROTO) |
834 static pumitem_T *balloon_array = NULL; | 873 static pumitem_T *balloon_array = NULL; |
835 static int balloon_arraysize; | 874 static int balloon_arraysize; |
836 static int balloon_mouse_row = 0; | 875 static int balloon_mouse_row = 0; |
837 static int balloon_mouse_col = 0; | 876 static int balloon_mouse_col = 0; |
1026 pum_size = balloon_arraysize; | 1065 pum_size = balloon_arraysize; |
1027 pum_compute_size(); | 1066 pum_compute_size(); |
1028 pum_scrollbar = 0; | 1067 pum_scrollbar = 0; |
1029 pum_height = balloon_arraysize; | 1068 pum_height = balloon_arraysize; |
1030 | 1069 |
1031 if (Rows - mouse_row > pum_size) | 1070 pum_position_at_mouse(BALLOON_MIN_WIDTH); |
1032 { | |
1033 /* Enough space below the mouse row. */ | |
1034 pum_row = mouse_row + 1; | |
1035 if (pum_height > Rows - pum_row) | |
1036 pum_height = Rows - pum_row; | |
1037 } | |
1038 else | |
1039 { | |
1040 /* Show above the mouse row, reduce height if it does not fit. */ | |
1041 pum_row = mouse_row - pum_size; | |
1042 if (pum_row < 0) | |
1043 { | |
1044 pum_height += pum_row; | |
1045 pum_row = 0; | |
1046 } | |
1047 } | |
1048 if (Columns - mouse_col >= pum_base_width | |
1049 || Columns - mouse_col > BALLOON_MIN_WIDTH) | |
1050 /* Enough space to show at mouse column. */ | |
1051 pum_col = mouse_col; | |
1052 else | |
1053 /* Not enough space, right align with window. */ | |
1054 pum_col = Columns - (pum_base_width > BALLOON_MIN_WIDTH | |
1055 ? BALLOON_MIN_WIDTH : pum_base_width); | |
1056 | |
1057 pum_width = Columns - pum_col; | |
1058 if (pum_width > pum_base_width + 1) | |
1059 pum_width = pum_base_width + 1; | |
1060 | |
1061 pum_selected = -1; | 1071 pum_selected = -1; |
1062 pum_first = 0; | 1072 pum_first = 0; |
1063 pum_redraw(); | 1073 pum_redraw(); |
1064 } | 1074 } |
1065 } | 1075 } |
1073 if (mouse_row != balloon_mouse_row || mouse_col != balloon_mouse_col) | 1083 if (mouse_row != balloon_mouse_row || mouse_col != balloon_mouse_col) |
1074 ui_remove_balloon(); | 1084 ui_remove_balloon(); |
1075 } | 1085 } |
1076 # endif | 1086 # endif |
1077 | 1087 |
1078 #endif | 1088 # if defined(FEAT_TERM_POPUP_MENU) || defined(PROTO) |
1089 /* | |
1090 * Select the pum entry at the mouse position. | |
1091 */ | |
1092 static void | |
1093 pum_select_mouse_pos(void) | |
1094 { | |
1095 int idx = mouse_row - pum_row; | |
1096 | |
1097 if (idx < 0 || idx >= pum_size) | |
1098 pum_selected = -1; | |
1099 else if (*pum_array[idx].pum_text != NUL) | |
1100 pum_selected = idx; | |
1101 } | |
1102 | |
1103 /* | |
1104 * Execute the currently selected popup menu item. | |
1105 */ | |
1106 static void | |
1107 pum_execute_menu(vimmenu_T *menu) | |
1108 { | |
1109 vimmenu_T *mp; | |
1110 int idx = 0; | |
1111 exarg_T ea; | |
1112 | |
1113 for (mp = menu->children; mp != NULL; mp = mp->next) | |
1114 if (idx++ == pum_selected) | |
1115 { | |
1116 vim_memset(&ea, 0, sizeof(ea)); | |
1117 execute_menu(&ea, mp); | |
1118 break; | |
1119 } | |
1120 } | |
1121 | |
1122 /* | |
1123 * Open the terminal version of the popup menu and don't return until it is | |
1124 * closed. | |
1125 */ | |
1126 void | |
1127 pum_show_popupmenu(vimmenu_T *menu) | |
1128 { | |
1129 vimmenu_T *mp; | |
1130 int idx = 0; | |
1131 pumitem_T *array; | |
1132 #ifdef FEAT_BEVAL_TERM | |
1133 int save_bevalterm = p_bevalterm; | |
1134 #endif | |
1135 | |
1136 pum_undisplay(); | |
1137 pum_size = 0; | |
1138 | |
1139 for (mp = menu->children; mp != NULL; mp = mp->next) | |
1140 ++pum_size; | |
1141 | |
1142 array = (pumitem_T *)alloc_clear((unsigned)sizeof(pumitem_T) * pum_size); | |
1143 if (array == NULL) | |
1144 return; | |
1145 | |
1146 for (mp = menu->children; mp != NULL; mp = mp->next) | |
1147 if (menu_is_separator(mp->dname)) | |
1148 array[idx++].pum_text = (char_u *)""; | |
1149 else | |
1150 array[idx++].pum_text = mp->dname; | |
1151 | |
1152 pum_array = array; | |
1153 pum_compute_size(); | |
1154 pum_scrollbar = 0; | |
1155 pum_height = pum_size; | |
1156 pum_position_at_mouse(20); | |
1157 | |
1158 pum_selected = -1; | |
1159 pum_first = 0; | |
1160 # ifdef FEAT_BEVAL_TERM | |
1161 p_bevalterm = TRUE; /* track mouse movement */ | |
1162 mch_setmouse(TRUE); | |
1163 # endif | |
1164 | |
1165 for (;;) | |
1166 { | |
1167 int c; | |
1168 | |
1169 pum_redraw(); | |
1170 setcursor(); | |
1171 out_flush(); | |
1172 | |
1173 c = vgetc(); | |
1174 if (c == ESC) | |
1175 break; | |
1176 else if (c == CAR || c == NL) | |
1177 { | |
1178 /* enter: select current item, if any, and close */ | |
1179 pum_execute_menu(menu); | |
1180 break; | |
1181 } | |
1182 else if (c == 'k' || c == K_UP || c == K_MOUSEUP) | |
1183 { | |
1184 /* cursor up: select previous item */ | |
1185 while (pum_selected > 0) | |
1186 { | |
1187 --pum_selected; | |
1188 if (*array[pum_selected].pum_text != NUL) | |
1189 break; | |
1190 } | |
1191 } | |
1192 else if (c == 'j' || c == K_DOWN || c == K_MOUSEDOWN) | |
1193 { | |
1194 /* cursor down: select next item */ | |
1195 while (pum_selected < pum_size - 1) | |
1196 { | |
1197 ++pum_selected; | |
1198 if (*array[pum_selected].pum_text != NUL) | |
1199 break; | |
1200 } | |
1201 } | |
1202 else if (c == K_RIGHTMOUSE) | |
1203 { | |
1204 /* Right mouse down: reposition the menu. */ | |
1205 vungetc(c); | |
1206 break; | |
1207 } | |
1208 else if (c == K_LEFTDRAG || c == K_RIGHTDRAG || c == K_MOUSEMOVE) | |
1209 { | |
1210 /* mouse moved: selec item in the mouse row */ | |
1211 pum_select_mouse_pos(); | |
1212 } | |
1213 else if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM || c == K_RIGHTRELEASE) | |
1214 { | |
1215 /* left mouse click: select clicked item, if any, and close; | |
1216 * right mouse release: select clicked item, close if any */ | |
1217 pum_select_mouse_pos(); | |
1218 if (pum_selected >= 0) | |
1219 { | |
1220 pum_execute_menu(menu); | |
1221 break; | |
1222 } | |
1223 if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM) | |
1224 break; | |
1225 } | |
1226 } | |
1227 | |
1228 vim_free(array); | |
1229 pum_undisplay(); | |
1230 # ifdef FEAT_BEVAL_TERM | |
1231 p_bevalterm = save_bevalterm; | |
1232 mch_setmouse(TRUE); | |
1233 # endif | |
1234 } | |
1235 # endif | |
1236 | |
1237 #endif |