comparison src/cmdexpand.c @ 17835:fd6c8dc33152 v8.1.1914

patch 8.1.1914: command line expansion code is spread out Commit: https://github.com/vim/vim/commit/d019039ccd7cbeae8923db20383a241d7fc77e2c Author: Bram Moolenaar <Bram@vim.org> Date: Fri Aug 23 21:17:35 2019 +0200 patch 8.1.1914: command line expansion code is spread out Problem: Command line expansion code is spread out. Solution: Move set_one_cmd_context(). (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/4855)
author Bram Moolenaar <Bram@vim.org>
date Fri, 23 Aug 2019 21:30:04 +0200
parents 6582dda76821
children 0a5c615cd949
comparison
equal deleted inserted replaced
17834:6170a2c5faaf 17835:fd6c8dc33152
957 return; 957 return;
958 } 958 }
959 set_cmd_context(xp, ccline->cmdbuff, ccline->cmdlen, ccline->cmdpos, TRUE); 959 set_cmd_context(xp, ccline->cmdbuff, ccline->cmdlen, ccline->cmdpos, TRUE);
960 } 960 }
961 961
962 /*
963 * This is all pretty much copied from do_one_cmd(), with all the extra stuff
964 * we don't need/want deleted. Maybe this could be done better if we didn't
965 * repeat all this stuff. The only problem is that they may not stay
966 * perfectly compatible with each other, but then the command line syntax
967 * probably won't change that much -- webb.
968 */
969 static char_u *
970 set_one_cmd_context(
971 expand_T *xp,
972 char_u *buff) // buffer for command string
973 {
974 char_u *p;
975 char_u *cmd, *arg;
976 int len = 0;
977 exarg_T ea;
978 int compl = EXPAND_NOTHING;
979 int delim;
980 int forceit = FALSE;
981 int usefilter = FALSE; // filter instead of file name
982
983 ExpandInit(xp);
984 xp->xp_pattern = buff;
985 xp->xp_context = EXPAND_COMMANDS; // Default until we get past command
986 ea.argt = 0;
987
988 // 1. skip comment lines and leading space, colons or bars
989 for (cmd = buff; vim_strchr((char_u *)" \t:|", *cmd) != NULL; cmd++)
990 ;
991 xp->xp_pattern = cmd;
992
993 if (*cmd == NUL)
994 return NULL;
995 if (*cmd == '"') // ignore comment lines
996 {
997 xp->xp_context = EXPAND_NOTHING;
998 return NULL;
999 }
1000
1001 // 3. Skip over the range to find the command.
1002 cmd = skip_range(cmd, &xp->xp_context);
1003 xp->xp_pattern = cmd;
1004 if (*cmd == NUL)
1005 return NULL;
1006 if (*cmd == '"')
1007 {
1008 xp->xp_context = EXPAND_NOTHING;
1009 return NULL;
1010 }
1011
1012 if (*cmd == '|' || *cmd == '\n')
1013 return cmd + 1; // There's another command
1014
1015 // Isolate the command and search for it in the command table.
1016 // Exceptions:
1017 // - the 'k' command can directly be followed by any character, but
1018 // do accept "keepmarks", "keepalt" and "keepjumps".
1019 // - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
1020 if (*cmd == 'k' && cmd[1] != 'e')
1021 {
1022 ea.cmdidx = CMD_k;
1023 p = cmd + 1;
1024 }
1025 else
1026 {
1027 p = cmd;
1028 while (ASCII_ISALPHA(*p) || *p == '*') // Allow * wild card
1029 ++p;
1030 // a user command may contain digits
1031 if (ASCII_ISUPPER(cmd[0]))
1032 while (ASCII_ISALNUM(*p) || *p == '*')
1033 ++p;
1034 // for python 3.x: ":py3*" commands completion
1035 if (cmd[0] == 'p' && cmd[1] == 'y' && p == cmd + 2 && *p == '3')
1036 {
1037 ++p;
1038 while (ASCII_ISALPHA(*p) || *p == '*')
1039 ++p;
1040 }
1041 // check for non-alpha command
1042 if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
1043 ++p;
1044 len = (int)(p - cmd);
1045
1046 if (len == 0)
1047 {
1048 xp->xp_context = EXPAND_UNSUCCESSFUL;
1049 return NULL;
1050 }
1051
1052 ea.cmdidx = excmd_get_cmdidx(cmd, len);
1053
1054 if (cmd[0] >= 'A' && cmd[0] <= 'Z')
1055 while (ASCII_ISALNUM(*p) || *p == '*') // Allow * wild card
1056 ++p;
1057 }
1058
1059 // If the cursor is touching the command, and it ends in an alpha-numeric
1060 // character, complete the command name.
1061 if (*p == NUL && ASCII_ISALNUM(p[-1]))
1062 return NULL;
1063
1064 if (ea.cmdidx == CMD_SIZE)
1065 {
1066 if (*cmd == 's' && vim_strchr((char_u *)"cgriI", cmd[1]) != NULL)
1067 {
1068 ea.cmdidx = CMD_substitute;
1069 p = cmd + 1;
1070 }
1071 else if (cmd[0] >= 'A' && cmd[0] <= 'Z')
1072 {
1073 ea.cmd = cmd;
1074 p = find_ucmd(&ea, p, NULL, xp, &compl);
1075 if (p == NULL)
1076 ea.cmdidx = CMD_SIZE; // ambiguous user command
1077 }
1078 }
1079 if (ea.cmdidx == CMD_SIZE)
1080 {
1081 // Not still touching the command and it was an illegal one
1082 xp->xp_context = EXPAND_UNSUCCESSFUL;
1083 return NULL;
1084 }
1085
1086 xp->xp_context = EXPAND_NOTHING; // Default now that we're past command
1087
1088 if (*p == '!') // forced commands
1089 {
1090 forceit = TRUE;
1091 ++p;
1092 }
1093
1094 // 6. parse arguments
1095 if (!IS_USER_CMDIDX(ea.cmdidx))
1096 ea.argt = excmd_get_argt(ea.cmdidx);
1097
1098 arg = skipwhite(p);
1099
1100 if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update)
1101 {
1102 if (*arg == '>') // append
1103 {
1104 if (*++arg == '>')
1105 ++arg;
1106 arg = skipwhite(arg);
1107 }
1108 else if (*arg == '!' && ea.cmdidx == CMD_write) // :w !filter
1109 {
1110 ++arg;
1111 usefilter = TRUE;
1112 }
1113 }
1114
1115 if (ea.cmdidx == CMD_read)
1116 {
1117 usefilter = forceit; // :r! filter if forced
1118 if (*arg == '!') // :r !filter
1119 {
1120 ++arg;
1121 usefilter = TRUE;
1122 }
1123 }
1124
1125 if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift)
1126 {
1127 while (*arg == *cmd) // allow any number of '>' or '<'
1128 ++arg;
1129 arg = skipwhite(arg);
1130 }
1131
1132 // Does command allow "+command"?
1133 if ((ea.argt & EX_CMDARG) && !usefilter && *arg == '+')
1134 {
1135 // Check if we're in the +command
1136 p = arg + 1;
1137 arg = skip_cmd_arg(arg, FALSE);
1138
1139 // Still touching the command after '+'?
1140 if (*arg == NUL)
1141 return p;
1142
1143 // Skip space(s) after +command to get to the real argument
1144 arg = skipwhite(arg);
1145 }
1146
1147 // Check for '|' to separate commands and '"' to start comments.
1148 // Don't do this for ":read !cmd" and ":write !cmd".
1149 if ((ea.argt & EX_TRLBAR) && !usefilter)
1150 {
1151 p = arg;
1152 // ":redir @" is not the start of a comment
1153 if (ea.cmdidx == CMD_redir && p[0] == '@' && p[1] == '"')
1154 p += 2;
1155 while (*p)
1156 {
1157 if (*p == Ctrl_V)
1158 {
1159 if (p[1] != NUL)
1160 ++p;
1161 }
1162 else if ( (*p == '"' && !(ea.argt & EX_NOTRLCOM))
1163 || *p == '|' || *p == '\n')
1164 {
1165 if (*(p - 1) != '\\')
1166 {
1167 if (*p == '|' || *p == '\n')
1168 return p + 1;
1169 return NULL; // It's a comment
1170 }
1171 }
1172 MB_PTR_ADV(p);
1173 }
1174 }
1175
1176 if (!(ea.argt & EX_EXTRA) && *arg != NUL
1177 && vim_strchr((char_u *)"|\"", *arg) == NULL)
1178 // no arguments allowed but there is something
1179 return NULL;
1180
1181 // Find start of last argument (argument just before cursor):
1182 p = buff;
1183 xp->xp_pattern = p;
1184 len = (int)STRLEN(buff);
1185 while (*p && p < buff + len)
1186 {
1187 if (*p == ' ' || *p == TAB)
1188 {
1189 // argument starts after a space
1190 xp->xp_pattern = ++p;
1191 }
1192 else
1193 {
1194 if (*p == '\\' && *(p + 1) != NUL)
1195 ++p; // skip over escaped character
1196 MB_PTR_ADV(p);
1197 }
1198 }
1199
1200 if (ea.argt & EX_XFILE)
1201 {
1202 int c;
1203 int in_quote = FALSE;
1204 char_u *bow = NULL; // Beginning of word
1205
1206 // Allow spaces within back-quotes to count as part of the argument
1207 // being expanded.
1208 xp->xp_pattern = skipwhite(arg);
1209 p = xp->xp_pattern;
1210 while (*p != NUL)
1211 {
1212 if (has_mbyte)
1213 c = mb_ptr2char(p);
1214 else
1215 c = *p;
1216 if (c == '\\' && p[1] != NUL)
1217 ++p;
1218 else if (c == '`')
1219 {
1220 if (!in_quote)
1221 {
1222 xp->xp_pattern = p;
1223 bow = p + 1;
1224 }
1225 in_quote = !in_quote;
1226 }
1227 // An argument can contain just about everything, except
1228 // characters that end the command and white space.
1229 else if (c == '|' || c == '\n' || c == '"' || (VIM_ISWHITE(c)
1230 #ifdef SPACE_IN_FILENAME
1231 && (!(ea.argt & EX_NOSPC) || usefilter)
1232 #endif
1233 ))
1234 {
1235 len = 0; // avoid getting stuck when space is in 'isfname'
1236 while (*p != NUL)
1237 {
1238 if (has_mbyte)
1239 c = mb_ptr2char(p);
1240 else
1241 c = *p;
1242 if (c == '`' || vim_isfilec_or_wc(c))
1243 break;
1244 if (has_mbyte)
1245 len = (*mb_ptr2len)(p);
1246 else
1247 len = 1;
1248 MB_PTR_ADV(p);
1249 }
1250 if (in_quote)
1251 bow = p;
1252 else
1253 xp->xp_pattern = p;
1254 p -= len;
1255 }
1256 MB_PTR_ADV(p);
1257 }
1258
1259 // If we are still inside the quotes, and we passed a space, just
1260 // expand from there.
1261 if (bow != NULL && in_quote)
1262 xp->xp_pattern = bow;
1263 xp->xp_context = EXPAND_FILES;
1264
1265 // For a shell command more chars need to be escaped.
1266 if (usefilter || ea.cmdidx == CMD_bang || ea.cmdidx == CMD_terminal)
1267 {
1268 #ifndef BACKSLASH_IN_FILENAME
1269 xp->xp_shell = TRUE;
1270 #endif
1271 // When still after the command name expand executables.
1272 if (xp->xp_pattern == skipwhite(arg))
1273 xp->xp_context = EXPAND_SHELLCMD;
1274 }
1275
1276 // Check for environment variable
1277 if (*xp->xp_pattern == '$'
1278 #if defined(MSWIN)
1279 || *xp->xp_pattern == '%'
1280 #endif
1281 )
1282 {
1283 for (p = xp->xp_pattern + 1; *p != NUL; ++p)
1284 if (!vim_isIDc(*p))
1285 break;
1286 if (*p == NUL)
1287 {
1288 xp->xp_context = EXPAND_ENV_VARS;
1289 ++xp->xp_pattern;
1290 // Avoid that the assignment uses EXPAND_FILES again.
1291 if (compl != EXPAND_USER_DEFINED && compl != EXPAND_USER_LIST)
1292 compl = EXPAND_ENV_VARS;
1293 }
1294 }
1295 // Check for user names
1296 if (*xp->xp_pattern == '~')
1297 {
1298 for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; ++p)
1299 ;
1300 // Complete ~user only if it partially matches a user name.
1301 // A full match ~user<Tab> will be replaced by user's home
1302 // directory i.e. something like ~user<Tab> -> /home/user/
1303 if (*p == NUL && p > xp->xp_pattern + 1
1304 && match_user(xp->xp_pattern + 1) >= 1)
1305 {
1306 xp->xp_context = EXPAND_USER;
1307 ++xp->xp_pattern;
1308 }
1309 }
1310 }
1311
1312 // 6. Switch on command name.
1313 switch (ea.cmdidx)
1314 {
1315 case CMD_find:
1316 case CMD_sfind:
1317 case CMD_tabfind:
1318 if (xp->xp_context == EXPAND_FILES)
1319 xp->xp_context = EXPAND_FILES_IN_PATH;
1320 break;
1321 case CMD_cd:
1322 case CMD_chdir:
1323 case CMD_tcd:
1324 case CMD_tchdir:
1325 case CMD_lcd:
1326 case CMD_lchdir:
1327 if (xp->xp_context == EXPAND_FILES)
1328 xp->xp_context = EXPAND_DIRECTORIES;
1329 break;
1330 case CMD_help:
1331 xp->xp_context = EXPAND_HELP;
1332 xp->xp_pattern = arg;
1333 break;
1334
1335 // Command modifiers: return the argument.
1336 // Also for commands with an argument that is a command.
1337 case CMD_aboveleft:
1338 case CMD_argdo:
1339 case CMD_belowright:
1340 case CMD_botright:
1341 case CMD_browse:
1342 case CMD_bufdo:
1343 case CMD_cdo:
1344 case CMD_cfdo:
1345 case CMD_confirm:
1346 case CMD_debug:
1347 case CMD_folddoclosed:
1348 case CMD_folddoopen:
1349 case CMD_hide:
1350 case CMD_keepalt:
1351 case CMD_keepjumps:
1352 case CMD_keepmarks:
1353 case CMD_keeppatterns:
1354 case CMD_ldo:
1355 case CMD_leftabove:
1356 case CMD_lfdo:
1357 case CMD_lockmarks:
1358 case CMD_noautocmd:
1359 case CMD_noswapfile:
1360 case CMD_rightbelow:
1361 case CMD_sandbox:
1362 case CMD_silent:
1363 case CMD_tab:
1364 case CMD_tabdo:
1365 case CMD_topleft:
1366 case CMD_verbose:
1367 case CMD_vertical:
1368 case CMD_windo:
1369 return arg;
1370
1371 case CMD_filter:
1372 if (*arg != NUL)
1373 arg = skip_vimgrep_pat(arg, NULL, NULL);
1374 if (arg == NULL || *arg == NUL)
1375 {
1376 xp->xp_context = EXPAND_NOTHING;
1377 return NULL;
1378 }
1379 return skipwhite(arg);
1380
1381 #ifdef FEAT_SEARCH_EXTRA
1382 case CMD_match:
1383 if (*arg == NUL || !ends_excmd(*arg))
1384 {
1385 // also complete "None"
1386 set_context_in_echohl_cmd(xp, arg);
1387 arg = skipwhite(skiptowhite(arg));
1388 if (*arg != NUL)
1389 {
1390 xp->xp_context = EXPAND_NOTHING;
1391 arg = skip_regexp(arg + 1, *arg, p_magic, NULL);
1392 }
1393 }
1394 return find_nextcmd(arg);
1395 #endif
1396
1397 // All completion for the +cmdline_compl feature goes here.
1398
1399 case CMD_command:
1400 return set_context_in_user_cmd(xp, arg);
1401
1402 case CMD_delcommand:
1403 xp->xp_context = EXPAND_USER_COMMANDS;
1404 xp->xp_pattern = arg;
1405 break;
1406
1407 case CMD_global:
1408 case CMD_vglobal:
1409 delim = *arg; // get the delimiter
1410 if (delim)
1411 ++arg; // skip delimiter if there is one
1412
1413 while (arg[0] != NUL && arg[0] != delim)
1414 {
1415 if (arg[0] == '\\' && arg[1] != NUL)
1416 ++arg;
1417 ++arg;
1418 }
1419 if (arg[0] != NUL)
1420 return arg + 1;
1421 break;
1422 case CMD_and:
1423 case CMD_substitute:
1424 delim = *arg;
1425 if (delim)
1426 {
1427 // skip "from" part
1428 ++arg;
1429 arg = skip_regexp(arg, delim, p_magic, NULL);
1430 }
1431 // skip "to" part
1432 while (arg[0] != NUL && arg[0] != delim)
1433 {
1434 if (arg[0] == '\\' && arg[1] != NUL)
1435 ++arg;
1436 ++arg;
1437 }
1438 if (arg[0] != NUL) // skip delimiter
1439 ++arg;
1440 while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
1441 ++arg;
1442 if (arg[0] != NUL)
1443 return arg;
1444 break;
1445 case CMD_isearch:
1446 case CMD_dsearch:
1447 case CMD_ilist:
1448 case CMD_dlist:
1449 case CMD_ijump:
1450 case CMD_psearch:
1451 case CMD_djump:
1452 case CMD_isplit:
1453 case CMD_dsplit:
1454 arg = skipwhite(skipdigits(arg)); // skip count
1455 if (*arg == '/') // Match regexp, not just whole words
1456 {
1457 for (++arg; *arg && *arg != '/'; arg++)
1458 if (*arg == '\\' && arg[1] != NUL)
1459 arg++;
1460 if (*arg)
1461 {
1462 arg = skipwhite(arg + 1);
1463
1464 // Check for trailing illegal characters
1465 if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL)
1466 xp->xp_context = EXPAND_NOTHING;
1467 else
1468 return arg;
1469 }
1470 }
1471 break;
1472
1473 case CMD_autocmd:
1474 return set_context_in_autocmd(xp, arg, FALSE);
1475 case CMD_doautocmd:
1476 case CMD_doautoall:
1477 return set_context_in_autocmd(xp, arg, TRUE);
1478 case CMD_set:
1479 set_context_in_set_cmd(xp, arg, 0);
1480 break;
1481 case CMD_setglobal:
1482 set_context_in_set_cmd(xp, arg, OPT_GLOBAL);
1483 break;
1484 case CMD_setlocal:
1485 set_context_in_set_cmd(xp, arg, OPT_LOCAL);
1486 break;
1487 case CMD_tag:
1488 case CMD_stag:
1489 case CMD_ptag:
1490 case CMD_ltag:
1491 case CMD_tselect:
1492 case CMD_stselect:
1493 case CMD_ptselect:
1494 case CMD_tjump:
1495 case CMD_stjump:
1496 case CMD_ptjump:
1497 if (*p_wop != NUL)
1498 xp->xp_context = EXPAND_TAGS_LISTFILES;
1499 else
1500 xp->xp_context = EXPAND_TAGS;
1501 xp->xp_pattern = arg;
1502 break;
1503 case CMD_augroup:
1504 xp->xp_context = EXPAND_AUGROUP;
1505 xp->xp_pattern = arg;
1506 break;
1507 #ifdef FEAT_SYN_HL
1508 case CMD_syntax:
1509 set_context_in_syntax_cmd(xp, arg);
1510 break;
1511 #endif
1512 #ifdef FEAT_EVAL
1513 case CMD_let:
1514 case CMD_if:
1515 case CMD_elseif:
1516 case CMD_while:
1517 case CMD_for:
1518 case CMD_echo:
1519 case CMD_echon:
1520 case CMD_execute:
1521 case CMD_echomsg:
1522 case CMD_echoerr:
1523 case CMD_call:
1524 case CMD_return:
1525 case CMD_cexpr:
1526 case CMD_caddexpr:
1527 case CMD_cgetexpr:
1528 case CMD_lexpr:
1529 case CMD_laddexpr:
1530 case CMD_lgetexpr:
1531 set_context_for_expression(xp, arg, ea.cmdidx);
1532 break;
1533
1534 case CMD_unlet:
1535 while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
1536 arg = xp->xp_pattern + 1;
1537
1538 xp->xp_context = EXPAND_USER_VARS;
1539 xp->xp_pattern = arg;
1540
1541 if (*xp->xp_pattern == '$')
1542 {
1543 xp->xp_context = EXPAND_ENV_VARS;
1544 ++xp->xp_pattern;
1545 }
1546
1547 break;
1548
1549 case CMD_function:
1550 case CMD_delfunction:
1551 xp->xp_context = EXPAND_USER_FUNC;
1552 xp->xp_pattern = arg;
1553 break;
1554
1555 case CMD_echohl:
1556 set_context_in_echohl_cmd(xp, arg);
1557 break;
1558 #endif
1559 case CMD_highlight:
1560 set_context_in_highlight_cmd(xp, arg);
1561 break;
1562 #ifdef FEAT_CSCOPE
1563 case CMD_cscope:
1564 case CMD_lcscope:
1565 case CMD_scscope:
1566 set_context_in_cscope_cmd(xp, arg, ea.cmdidx);
1567 break;
1568 #endif
1569 #ifdef FEAT_SIGNS
1570 case CMD_sign:
1571 set_context_in_sign_cmd(xp, arg);
1572 break;
1573 #endif
1574 case CMD_bdelete:
1575 case CMD_bwipeout:
1576 case CMD_bunload:
1577 while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
1578 arg = xp->xp_pattern + 1;
1579 // FALLTHROUGH
1580 case CMD_buffer:
1581 case CMD_sbuffer:
1582 case CMD_checktime:
1583 xp->xp_context = EXPAND_BUFFERS;
1584 xp->xp_pattern = arg;
1585 break;
1586
1587 case CMD_USER:
1588 case CMD_USER_BUF:
1589 if (compl != EXPAND_NOTHING)
1590 {
1591 // EX_XFILE: file names are handled above
1592 if (!(ea.argt & EX_XFILE))
1593 {
1594 #ifdef FEAT_MENU
1595 if (compl == EXPAND_MENUS)
1596 return set_context_in_menu_cmd(xp, cmd, arg, forceit);
1597 #endif
1598 if (compl == EXPAND_COMMANDS)
1599 return arg;
1600 if (compl == EXPAND_MAPPINGS)
1601 return set_context_in_map_cmd(xp, (char_u *)"map",
1602 arg, forceit, FALSE, FALSE, CMD_map);
1603 // Find start of last argument.
1604 p = arg;
1605 while (*p)
1606 {
1607 if (*p == ' ')
1608 // argument starts after a space
1609 arg = p + 1;
1610 else if (*p == '\\' && *(p + 1) != NUL)
1611 ++p; // skip over escaped character
1612 MB_PTR_ADV(p);
1613 }
1614 xp->xp_pattern = arg;
1615 }
1616 xp->xp_context = compl;
1617 }
1618 break;
1619
1620 case CMD_map: case CMD_noremap:
1621 case CMD_nmap: case CMD_nnoremap:
1622 case CMD_vmap: case CMD_vnoremap:
1623 case CMD_omap: case CMD_onoremap:
1624 case CMD_imap: case CMD_inoremap:
1625 case CMD_cmap: case CMD_cnoremap:
1626 case CMD_lmap: case CMD_lnoremap:
1627 case CMD_smap: case CMD_snoremap:
1628 case CMD_tmap: case CMD_tnoremap:
1629 case CMD_xmap: case CMD_xnoremap:
1630 return set_context_in_map_cmd(xp, cmd, arg, forceit,
1631 FALSE, FALSE, ea.cmdidx);
1632 case CMD_unmap:
1633 case CMD_nunmap:
1634 case CMD_vunmap:
1635 case CMD_ounmap:
1636 case CMD_iunmap:
1637 case CMD_cunmap:
1638 case CMD_lunmap:
1639 case CMD_sunmap:
1640 case CMD_tunmap:
1641 case CMD_xunmap:
1642 return set_context_in_map_cmd(xp, cmd, arg, forceit,
1643 FALSE, TRUE, ea.cmdidx);
1644 case CMD_mapclear:
1645 case CMD_nmapclear:
1646 case CMD_vmapclear:
1647 case CMD_omapclear:
1648 case CMD_imapclear:
1649 case CMD_cmapclear:
1650 case CMD_lmapclear:
1651 case CMD_smapclear:
1652 case CMD_tmapclear:
1653 case CMD_xmapclear:
1654 xp->xp_context = EXPAND_MAPCLEAR;
1655 xp->xp_pattern = arg;
1656 break;
1657
1658 case CMD_abbreviate: case CMD_noreabbrev:
1659 case CMD_cabbrev: case CMD_cnoreabbrev:
1660 case CMD_iabbrev: case CMD_inoreabbrev:
1661 return set_context_in_map_cmd(xp, cmd, arg, forceit,
1662 TRUE, FALSE, ea.cmdidx);
1663 case CMD_unabbreviate:
1664 case CMD_cunabbrev:
1665 case CMD_iunabbrev:
1666 return set_context_in_map_cmd(xp, cmd, arg, forceit,
1667 TRUE, TRUE, ea.cmdidx);
1668 #ifdef FEAT_MENU
1669 case CMD_menu: case CMD_noremenu: case CMD_unmenu:
1670 case CMD_amenu: case CMD_anoremenu: case CMD_aunmenu:
1671 case CMD_nmenu: case CMD_nnoremenu: case CMD_nunmenu:
1672 case CMD_vmenu: case CMD_vnoremenu: case CMD_vunmenu:
1673 case CMD_omenu: case CMD_onoremenu: case CMD_ounmenu:
1674 case CMD_imenu: case CMD_inoremenu: case CMD_iunmenu:
1675 case CMD_cmenu: case CMD_cnoremenu: case CMD_cunmenu:
1676 case CMD_tlmenu: case CMD_tlnoremenu: case CMD_tlunmenu:
1677 case CMD_tmenu: case CMD_tunmenu:
1678 case CMD_popup: case CMD_tearoff: case CMD_emenu:
1679 return set_context_in_menu_cmd(xp, cmd, arg, forceit);
1680 #endif
1681
1682 case CMD_colorscheme:
1683 xp->xp_context = EXPAND_COLORS;
1684 xp->xp_pattern = arg;
1685 break;
1686
1687 case CMD_compiler:
1688 xp->xp_context = EXPAND_COMPILER;
1689 xp->xp_pattern = arg;
1690 break;
1691
1692 case CMD_ownsyntax:
1693 xp->xp_context = EXPAND_OWNSYNTAX;
1694 xp->xp_pattern = arg;
1695 break;
1696
1697 case CMD_setfiletype:
1698 xp->xp_context = EXPAND_FILETYPE;
1699 xp->xp_pattern = arg;
1700 break;
1701
1702 case CMD_packadd:
1703 xp->xp_context = EXPAND_PACKADD;
1704 xp->xp_pattern = arg;
1705 break;
1706
1707 #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
1708 case CMD_language:
1709 p = skiptowhite(arg);
1710 if (*p == NUL)
1711 {
1712 xp->xp_context = EXPAND_LANGUAGE;
1713 xp->xp_pattern = arg;
1714 }
1715 else
1716 {
1717 if ( STRNCMP(arg, "messages", p - arg) == 0
1718 || STRNCMP(arg, "ctype", p - arg) == 0
1719 || STRNCMP(arg, "time", p - arg) == 0)
1720 {
1721 xp->xp_context = EXPAND_LOCALES;
1722 xp->xp_pattern = skipwhite(p);
1723 }
1724 else
1725 xp->xp_context = EXPAND_NOTHING;
1726 }
1727 break;
1728 #endif
1729 #if defined(FEAT_PROFILE)
1730 case CMD_profile:
1731 set_context_in_profile_cmd(xp, arg);
1732 break;
1733 #endif
1734 case CMD_behave:
1735 xp->xp_context = EXPAND_BEHAVE;
1736 xp->xp_pattern = arg;
1737 break;
1738
1739 case CMD_messages:
1740 xp->xp_context = EXPAND_MESSAGES;
1741 xp->xp_pattern = arg;
1742 break;
1743
1744 case CMD_history:
1745 xp->xp_context = EXPAND_HISTORY;
1746 xp->xp_pattern = arg;
1747 break;
1748 #if defined(FEAT_PROFILE)
1749 case CMD_syntime:
1750 xp->xp_context = EXPAND_SYNTIME;
1751 xp->xp_pattern = arg;
1752 break;
1753 #endif
1754
1755 case CMD_argdelete:
1756 while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
1757 arg = xp->xp_pattern + 1;
1758 xp->xp_context = EXPAND_ARGLIST;
1759 xp->xp_pattern = arg;
1760 break;
1761
1762 default:
1763 break;
1764 }
1765 return NULL;
1766 }
1767
962 void 1768 void
963 set_cmd_context( 1769 set_cmd_context(
964 expand_T *xp, 1770 expand_T *xp,
965 char_u *str, // start of command line 1771 char_u *str, // start of command line
966 int len, // length of command line (excl. NUL) 1772 int len, // length of command line (excl. NUL)
1111 file[i][len] = NUL; 1917 file[i][len] = NUL;
1112 } 1918 }
1113 } 1919 }
1114 } 1920 }
1115 #endif 1921 #endif
1922
1923 /*
1924 * Function given to ExpandGeneric() to obtain the possible arguments of the
1925 * ":behave {mswin,xterm}" command.
1926 */
1927 static char_u *
1928 get_behave_arg(expand_T *xp UNUSED, int idx)
1929 {
1930 if (idx == 0)
1931 return (char_u *)"mswin";
1932 if (idx == 1)
1933 return (char_u *)"xterm";
1934 return NULL;
1935 }
1936
1937 /*
1938 * Function given to ExpandGeneric() to obtain the possible arguments of the
1939 * ":messages {clear}" command.
1940 */
1941 static char_u *
1942 get_messages_arg(expand_T *xp UNUSED, int idx)
1943 {
1944 if (idx == 0)
1945 return (char_u *)"clear";
1946 return NULL;
1947 }
1948
1949 static char_u *
1950 get_mapclear_arg(expand_T *xp UNUSED, int idx)
1951 {
1952 if (idx == 0)
1953 return (char_u *)"<buffer>";
1954 return NULL;
1955 }
1116 1956
1117 /* 1957 /*
1118 * Do the expansion based on xp->xp_context and "pat". 1958 * Do the expansion based on xp->xp_context and "pat".
1119 */ 1959 */
1120 static int 1960 static int