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 */