Mercurial > vim
comparison src/ex_getln.c @ 22075:eb878f85967e v8.2.1587
patch 8.2.1587: loop for handling keys for the command line is too long
Commit: https://github.com/vim/vim/commit/eadee486c70946ad0e1746d77898d6f4f4acc817
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Sep 4 15:37:31 2020 +0200
patch 8.2.1587: loop for handling keys for the command line is too long
Problem: Loop for handling keys for the command line is too long.
Solution: Move wild menu handling to separate functions. (Yegappan
Lakshmanan, closes #6856)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 04 Sep 2020 15:45:03 +0200 |
parents | d6120c97f57c |
children | e6fb7f627448 |
comparison
equal
deleted
inserted
replaced
22074:923f618adb59 | 22075:eb878f85967e |
---|---|
42 static void alloc_cmdbuff(int len); | 42 static void alloc_cmdbuff(int len); |
43 static void draw_cmdline(int start, int len); | 43 static void draw_cmdline(int start, int len); |
44 static void save_cmdline(cmdline_info_T *ccp); | 44 static void save_cmdline(cmdline_info_T *ccp); |
45 static void restore_cmdline(cmdline_info_T *ccp); | 45 static void restore_cmdline(cmdline_info_T *ccp); |
46 static int cmdline_paste(int regname, int literally, int remcr); | 46 static int cmdline_paste(int regname, int literally, int remcr); |
47 #ifdef FEAT_WILDMENU | |
48 static void cmdline_del(int from); | |
49 #endif | |
50 static void redrawcmdprompt(void); | 47 static void redrawcmdprompt(void); |
51 static int ccheck_abbr(int); | 48 static int ccheck_abbr(int); |
52 | 49 |
53 #ifdef FEAT_CMDWIN | 50 #ifdef FEAT_CMDWIN |
54 static int open_cmdwin(void); | 51 static int open_cmdwin(void); |
1062 */ | 1059 */ |
1063 if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0) | 1060 if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0) |
1064 c = Ctrl_P; | 1061 c = Ctrl_P; |
1065 | 1062 |
1066 #ifdef FEAT_WILDMENU | 1063 #ifdef FEAT_WILDMENU |
1067 // Special translations for 'wildmenu' | 1064 c = wildmenu_translate_key(&ccline, c, &xpc, did_wild_list); |
1068 if (did_wild_list && p_wmnu) | |
1069 { | |
1070 if (c == K_LEFT) | |
1071 c = Ctrl_P; | |
1072 else if (c == K_RIGHT) | |
1073 c = Ctrl_N; | |
1074 } | |
1075 // Hitting CR after "emenu Name.": complete submenu | |
1076 if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu | |
1077 && ccline.cmdpos > 1 | |
1078 && ccline.cmdbuff[ccline.cmdpos - 1] == '.' | |
1079 && ccline.cmdbuff[ccline.cmdpos - 2] != '\\' | |
1080 && (c == '\n' || c == '\r' || c == K_KENTER)) | |
1081 c = K_DOWN; | |
1082 #endif | 1065 #endif |
1083 | 1066 |
1084 // free expanded names when finished walking through matches | 1067 // free expanded names when finished walking through matches |
1085 if (xpc.xp_numfiles != -1 | 1068 if (xpc.xp_numfiles != -1 |
1086 && !(c == p_wc && KeyTyped) && c != p_wcm | 1069 && !(c == p_wc && KeyTyped) && c != p_wcm |
1093 if (!p_wmnu || (c != K_UP && c != K_DOWN)) | 1076 if (!p_wmnu || (c != K_UP && c != K_DOWN)) |
1094 #endif | 1077 #endif |
1095 xpc.xp_context = EXPAND_NOTHING; | 1078 xpc.xp_context = EXPAND_NOTHING; |
1096 wim_index = 0; | 1079 wim_index = 0; |
1097 #ifdef FEAT_WILDMENU | 1080 #ifdef FEAT_WILDMENU |
1098 if (p_wmnu && wild_menu_showing != 0) | 1081 wildmenu_cleanup(&ccline); |
1099 { | |
1100 int skt = KeyTyped; | |
1101 int old_RedrawingDisabled = RedrawingDisabled; | |
1102 | |
1103 if (ccline.input_fn) | |
1104 RedrawingDisabled = 0; | |
1105 | |
1106 if (wild_menu_showing == WM_SCROLLED) | |
1107 { | |
1108 // Entered command line, move it up | |
1109 cmdline_row--; | |
1110 redrawcmd(); | |
1111 } | |
1112 else if (save_p_ls != -1) | |
1113 { | |
1114 // restore 'laststatus' and 'winminheight' | |
1115 p_ls = save_p_ls; | |
1116 p_wmh = save_p_wmh; | |
1117 last_status(FALSE); | |
1118 update_screen(VALID); // redraw the screen NOW | |
1119 redrawcmd(); | |
1120 save_p_ls = -1; | |
1121 } | |
1122 else | |
1123 { | |
1124 win_redraw_last_status(topframe); | |
1125 redraw_statuslines(); | |
1126 } | |
1127 KeyTyped = skt; | |
1128 wild_menu_showing = 0; | |
1129 if (ccline.input_fn) | |
1130 RedrawingDisabled = old_RedrawingDisabled; | |
1131 } | |
1132 #endif | 1082 #endif |
1133 } | 1083 } |
1134 | 1084 |
1135 #ifdef FEAT_WILDMENU | 1085 #ifdef FEAT_WILDMENU |
1136 // Special translations for 'wildmenu' | 1086 c = wildmenu_process_key(&ccline, c, &xpc); |
1137 if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu) | 1087 #endif |
1138 { | |
1139 // Hitting <Down> after "emenu Name.": complete submenu | |
1140 if (c == K_DOWN && ccline.cmdpos > 0 | |
1141 && ccline.cmdbuff[ccline.cmdpos - 1] == '.') | |
1142 c = p_wc; | |
1143 else if (c == K_UP) | |
1144 { | |
1145 // Hitting <Up>: Remove one submenu name in front of the | |
1146 // cursor | |
1147 int found = FALSE; | |
1148 | |
1149 j = (int)(xpc.xp_pattern - ccline.cmdbuff); | |
1150 i = 0; | |
1151 while (--j > 0) | |
1152 { | |
1153 // check for start of menu name | |
1154 if (ccline.cmdbuff[j] == ' ' | |
1155 && ccline.cmdbuff[j - 1] != '\\') | |
1156 { | |
1157 i = j + 1; | |
1158 break; | |
1159 } | |
1160 // check for start of submenu name | |
1161 if (ccline.cmdbuff[j] == '.' | |
1162 && ccline.cmdbuff[j - 1] != '\\') | |
1163 { | |
1164 if (found) | |
1165 { | |
1166 i = j + 1; | |
1167 break; | |
1168 } | |
1169 else | |
1170 found = TRUE; | |
1171 } | |
1172 } | |
1173 if (i > 0) | |
1174 cmdline_del(i); | |
1175 c = p_wc; | |
1176 xpc.xp_context = EXPAND_NOTHING; | |
1177 } | |
1178 } | |
1179 if ((xpc.xp_context == EXPAND_FILES | |
1180 || xpc.xp_context == EXPAND_DIRECTORIES | |
1181 || xpc.xp_context == EXPAND_SHELLCMD) && p_wmnu) | |
1182 { | |
1183 char_u upseg[5]; | |
1184 | |
1185 upseg[0] = PATHSEP; | |
1186 upseg[1] = '.'; | |
1187 upseg[2] = '.'; | |
1188 upseg[3] = PATHSEP; | |
1189 upseg[4] = NUL; | |
1190 | |
1191 if (c == K_DOWN | |
1192 && ccline.cmdpos > 0 | |
1193 && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP | |
1194 && (ccline.cmdpos < 3 | |
1195 || ccline.cmdbuff[ccline.cmdpos - 2] != '.' | |
1196 || ccline.cmdbuff[ccline.cmdpos - 3] != '.')) | |
1197 { | |
1198 // go down a directory | |
1199 c = p_wc; | |
1200 } | |
1201 else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN) | |
1202 { | |
1203 // If in a direct ancestor, strip off one ../ to go down | |
1204 int found = FALSE; | |
1205 | |
1206 j = ccline.cmdpos; | |
1207 i = (int)(xpc.xp_pattern - ccline.cmdbuff); | |
1208 while (--j > i) | |
1209 { | |
1210 if (has_mbyte) | |
1211 j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j); | |
1212 if (vim_ispathsep(ccline.cmdbuff[j])) | |
1213 { | |
1214 found = TRUE; | |
1215 break; | |
1216 } | |
1217 } | |
1218 if (found | |
1219 && ccline.cmdbuff[j - 1] == '.' | |
1220 && ccline.cmdbuff[j - 2] == '.' | |
1221 && (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2)) | |
1222 { | |
1223 cmdline_del(j - 2); | |
1224 c = p_wc; | |
1225 } | |
1226 } | |
1227 else if (c == K_UP) | |
1228 { | |
1229 // go up a directory | |
1230 int found = FALSE; | |
1231 | |
1232 j = ccline.cmdpos - 1; | |
1233 i = (int)(xpc.xp_pattern - ccline.cmdbuff); | |
1234 while (--j > i) | |
1235 { | |
1236 if (has_mbyte) | |
1237 j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j); | |
1238 if (vim_ispathsep(ccline.cmdbuff[j]) | |
1239 # ifdef BACKSLASH_IN_FILENAME | |
1240 && vim_strchr((char_u *)" *?[{`$%#", | |
1241 ccline.cmdbuff[j + 1]) == NULL | |
1242 # endif | |
1243 ) | |
1244 { | |
1245 if (found) | |
1246 { | |
1247 i = j + 1; | |
1248 break; | |
1249 } | |
1250 else | |
1251 found = TRUE; | |
1252 } | |
1253 } | |
1254 | |
1255 if (!found) | |
1256 j = i; | |
1257 else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0) | |
1258 j += 4; | |
1259 else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0 | |
1260 && j == i) | |
1261 j += 3; | |
1262 else | |
1263 j = 0; | |
1264 if (j > 0) | |
1265 { | |
1266 // TODO this is only for DOS/UNIX systems - need to put in | |
1267 // machine-specific stuff here and in upseg init | |
1268 cmdline_del(j); | |
1269 put_on_cmdline(upseg + 1, 3, FALSE); | |
1270 } | |
1271 else if (ccline.cmdpos > i) | |
1272 cmdline_del(i); | |
1273 | |
1274 // Now complete in the new directory. Set KeyTyped in case the | |
1275 // Up key came from a mapping. | |
1276 c = p_wc; | |
1277 KeyTyped = TRUE; | |
1278 } | |
1279 } | |
1280 | |
1281 #endif // FEAT_WILDMENU | |
1282 | 1088 |
1283 // CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert | 1089 // CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert |
1284 // mode when 'insertmode' is set, CTRL-\ e prompts for an expression. | 1090 // mode when 'insertmode' is set, CTRL-\ e prompts for an expression. |
1285 if (c == Ctrl_BSL) | 1091 if (c == Ctrl_BSL) |
1286 { | 1092 { |
3658 stuffcharReadbuff(Ctrl_V); | 3464 stuffcharReadbuff(Ctrl_V); |
3659 stuffcharReadbuff(c); | 3465 stuffcharReadbuff(c); |
3660 } | 3466 } |
3661 } | 3467 } |
3662 | 3468 |
3663 #ifdef FEAT_WILDMENU | |
3664 /* | |
3665 * Delete characters on the command line, from "from" to the current | |
3666 * position. | |
3667 */ | |
3668 static void | |
3669 cmdline_del(int from) | |
3670 { | |
3671 mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos, | |
3672 (size_t)(ccline.cmdlen - ccline.cmdpos + 1)); | |
3673 ccline.cmdlen -= ccline.cmdpos - from; | |
3674 ccline.cmdpos = from; | |
3675 } | |
3676 #endif | |
3677 | |
3678 /* | 3469 /* |
3679 * This function is called when the screen size changes and with incremental | 3470 * This function is called when the screen size changes and with incremental |
3680 * search and in other situations where the command line may have been | 3471 * search and in other situations where the command line may have been |
3681 * overwritten. | 3472 * overwritten. |
3682 */ | 3473 */ |