Mercurial > vim
comparison src/ex_cmds2.c @ 17744:4a3dca734d36 v8.1.1869
patch 8.1.1869: code for the argument list is spread out
commit https://github.com/vim/vim/commit/4ad62155a1015751a6645aaecd94b02c94c8934b
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Aug 17 14:38:55 2019 +0200
patch 8.1.1869: code for the argument list is spread out
Problem: Code for the argument list is spread out.
Solution: Put argument list code in arglist.c. (Yegappan Lakshmanan,
closes #4819)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 17 Aug 2019 14:45:04 +0200 |
parents | ff097edaae89 |
children | 04245f071792 |
comparison
equal
deleted
inserted
replaced
17743:4ca7a477f326 | 17744:4a3dca734d36 |
---|---|
818 { | 818 { |
819 msg_source(HL_ATTR(HLF_W)); | 819 msg_source(HL_ATTR(HLF_W)); |
820 msg(_("Warning: Entered other buffer unexpectedly (check autocommands)")); | 820 msg(_("Warning: Entered other buffer unexpectedly (check autocommands)")); |
821 } | 821 } |
822 return retval; | 822 return retval; |
823 } | |
824 | |
825 /* | |
826 * Code to handle the argument list. | |
827 */ | |
828 | |
829 static int do_arglist(char_u *str, int what, int after, int will_edit); | |
830 static void alist_check_arg_idx(void); | |
831 static void alist_add_list(int count, char_u **files, int after, int will_edit); | |
832 #define AL_SET 1 | |
833 #define AL_ADD 2 | |
834 #define AL_DEL 3 | |
835 | |
836 /* | |
837 * Isolate one argument, taking backticks. | |
838 * Changes the argument in-place, puts a NUL after it. Backticks remain. | |
839 * Return a pointer to the start of the next argument. | |
840 */ | |
841 static char_u * | |
842 do_one_arg(char_u *str) | |
843 { | |
844 char_u *p; | |
845 int inbacktick; | |
846 | |
847 inbacktick = FALSE; | |
848 for (p = str; *str; ++str) | |
849 { | |
850 /* When the backslash is used for escaping the special meaning of a | |
851 * character we need to keep it until wildcard expansion. */ | |
852 if (rem_backslash(str)) | |
853 { | |
854 *p++ = *str++; | |
855 *p++ = *str; | |
856 } | |
857 else | |
858 { | |
859 /* An item ends at a space not in backticks */ | |
860 if (!inbacktick && vim_isspace(*str)) | |
861 break; | |
862 if (*str == '`') | |
863 inbacktick ^= TRUE; | |
864 *p++ = *str; | |
865 } | |
866 } | |
867 str = skipwhite(str); | |
868 *p = NUL; | |
869 | |
870 return str; | |
871 } | |
872 | |
873 /* | |
874 * Separate the arguments in "str" and return a list of pointers in the | |
875 * growarray "gap". | |
876 */ | |
877 static int | |
878 get_arglist(garray_T *gap, char_u *str, int escaped) | |
879 { | |
880 ga_init2(gap, (int)sizeof(char_u *), 20); | |
881 while (*str != NUL) | |
882 { | |
883 if (ga_grow(gap, 1) == FAIL) | |
884 { | |
885 ga_clear(gap); | |
886 return FAIL; | |
887 } | |
888 ((char_u **)gap->ga_data)[gap->ga_len++] = str; | |
889 | |
890 /* If str is escaped, don't handle backslashes or spaces */ | |
891 if (!escaped) | |
892 return OK; | |
893 | |
894 /* Isolate one argument, change it in-place, put a NUL after it. */ | |
895 str = do_one_arg(str); | |
896 } | |
897 return OK; | |
898 } | |
899 | |
900 #if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO) | |
901 /* | |
902 * Parse a list of arguments (file names), expand them and return in | |
903 * "fnames[fcountp]". When "wig" is TRUE, removes files matching 'wildignore'. | |
904 * Return FAIL or OK. | |
905 */ | |
906 int | |
907 get_arglist_exp( | |
908 char_u *str, | |
909 int *fcountp, | |
910 char_u ***fnamesp, | |
911 int wig) | |
912 { | |
913 garray_T ga; | |
914 int i; | |
915 | |
916 if (get_arglist(&ga, str, TRUE) == FAIL) | |
917 return FAIL; | |
918 if (wig == TRUE) | |
919 i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data, | |
920 fcountp, fnamesp, EW_FILE|EW_NOTFOUND); | |
921 else | |
922 i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data, | |
923 fcountp, fnamesp, EW_FILE|EW_NOTFOUND); | |
924 | |
925 ga_clear(&ga); | |
926 return i; | |
927 } | |
928 #endif | |
929 | |
930 /* | |
931 * Redefine the argument list. | |
932 */ | |
933 void | |
934 set_arglist(char_u *str) | |
935 { | |
936 do_arglist(str, AL_SET, 0, FALSE); | |
937 } | |
938 | |
939 /* | |
940 * "what" == AL_SET: Redefine the argument list to 'str'. | |
941 * "what" == AL_ADD: add files in 'str' to the argument list after "after". | |
942 * "what" == AL_DEL: remove files in 'str' from the argument list. | |
943 * | |
944 * Return FAIL for failure, OK otherwise. | |
945 */ | |
946 static int | |
947 do_arglist( | |
948 char_u *str, | |
949 int what, | |
950 int after UNUSED, // 0 means before first one | |
951 int will_edit) // will edit added argument | |
952 { | |
953 garray_T new_ga; | |
954 int exp_count; | |
955 char_u **exp_files; | |
956 int i; | |
957 char_u *p; | |
958 int match; | |
959 int arg_escaped = TRUE; | |
960 | |
961 /* | |
962 * Set default argument for ":argadd" command. | |
963 */ | |
964 if (what == AL_ADD && *str == NUL) | |
965 { | |
966 if (curbuf->b_ffname == NULL) | |
967 return FAIL; | |
968 str = curbuf->b_fname; | |
969 arg_escaped = FALSE; | |
970 } | |
971 | |
972 /* | |
973 * Collect all file name arguments in "new_ga". | |
974 */ | |
975 if (get_arglist(&new_ga, str, arg_escaped) == FAIL) | |
976 return FAIL; | |
977 | |
978 if (what == AL_DEL) | |
979 { | |
980 regmatch_T regmatch; | |
981 int didone; | |
982 | |
983 /* | |
984 * Delete the items: use each item as a regexp and find a match in the | |
985 * argument list. | |
986 */ | |
987 regmatch.rm_ic = p_fic; /* ignore case when 'fileignorecase' is set */ | |
988 for (i = 0; i < new_ga.ga_len && !got_int; ++i) | |
989 { | |
990 p = ((char_u **)new_ga.ga_data)[i]; | |
991 p = file_pat_to_reg_pat(p, NULL, NULL, FALSE); | |
992 if (p == NULL) | |
993 break; | |
994 regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0); | |
995 if (regmatch.regprog == NULL) | |
996 { | |
997 vim_free(p); | |
998 break; | |
999 } | |
1000 | |
1001 didone = FALSE; | |
1002 for (match = 0; match < ARGCOUNT; ++match) | |
1003 if (vim_regexec(®match, alist_name(&ARGLIST[match]), | |
1004 (colnr_T)0)) | |
1005 { | |
1006 didone = TRUE; | |
1007 vim_free(ARGLIST[match].ae_fname); | |
1008 mch_memmove(ARGLIST + match, ARGLIST + match + 1, | |
1009 (ARGCOUNT - match - 1) * sizeof(aentry_T)); | |
1010 --ALIST(curwin)->al_ga.ga_len; | |
1011 if (curwin->w_arg_idx > match) | |
1012 --curwin->w_arg_idx; | |
1013 --match; | |
1014 } | |
1015 | |
1016 vim_regfree(regmatch.regprog); | |
1017 vim_free(p); | |
1018 if (!didone) | |
1019 semsg(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]); | |
1020 } | |
1021 ga_clear(&new_ga); | |
1022 } | |
1023 else | |
1024 { | |
1025 i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data, | |
1026 &exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND); | |
1027 ga_clear(&new_ga); | |
1028 if (i == FAIL || exp_count == 0) | |
1029 { | |
1030 emsg(_(e_nomatch)); | |
1031 return FAIL; | |
1032 } | |
1033 | |
1034 if (what == AL_ADD) | |
1035 { | |
1036 alist_add_list(exp_count, exp_files, after, will_edit); | |
1037 vim_free(exp_files); | |
1038 } | |
1039 else /* what == AL_SET */ | |
1040 alist_set(ALIST(curwin), exp_count, exp_files, will_edit, NULL, 0); | |
1041 } | |
1042 | |
1043 alist_check_arg_idx(); | |
1044 | |
1045 return OK; | |
1046 } | |
1047 | |
1048 /* | |
1049 * Check the validity of the arg_idx for each other window. | |
1050 */ | |
1051 static void | |
1052 alist_check_arg_idx(void) | |
1053 { | |
1054 win_T *win; | |
1055 tabpage_T *tp; | |
1056 | |
1057 FOR_ALL_TAB_WINDOWS(tp, win) | |
1058 if (win->w_alist == curwin->w_alist) | |
1059 check_arg_idx(win); | |
1060 } | |
1061 | |
1062 /* | |
1063 * Return TRUE if window "win" is editing the file at the current argument | |
1064 * index. | |
1065 */ | |
1066 static int | |
1067 editing_arg_idx(win_T *win) | |
1068 { | |
1069 return !(win->w_arg_idx >= WARGCOUNT(win) | |
1070 || (win->w_buffer->b_fnum | |
1071 != WARGLIST(win)[win->w_arg_idx].ae_fnum | |
1072 && (win->w_buffer->b_ffname == NULL | |
1073 || !(fullpathcmp( | |
1074 alist_name(&WARGLIST(win)[win->w_arg_idx]), | |
1075 win->w_buffer->b_ffname, TRUE, TRUE) & FPC_SAME)))); | |
1076 } | |
1077 | |
1078 /* | |
1079 * Check if window "win" is editing the w_arg_idx file in its argument list. | |
1080 */ | |
1081 void | |
1082 check_arg_idx(win_T *win) | |
1083 { | |
1084 if (WARGCOUNT(win) > 1 && !editing_arg_idx(win)) | |
1085 { | |
1086 /* We are not editing the current entry in the argument list. | |
1087 * Set "arg_had_last" if we are editing the last one. */ | |
1088 win->w_arg_idx_invalid = TRUE; | |
1089 if (win->w_arg_idx != WARGCOUNT(win) - 1 | |
1090 && arg_had_last == FALSE | |
1091 && ALIST(win) == &global_alist | |
1092 && GARGCOUNT > 0 | |
1093 && win->w_arg_idx < GARGCOUNT | |
1094 && (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum | |
1095 || (win->w_buffer->b_ffname != NULL | |
1096 && (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]), | |
1097 win->w_buffer->b_ffname, TRUE, TRUE) & FPC_SAME)))) | |
1098 arg_had_last = TRUE; | |
1099 } | |
1100 else | |
1101 { | |
1102 /* We are editing the current entry in the argument list. | |
1103 * Set "arg_had_last" if it's also the last one */ | |
1104 win->w_arg_idx_invalid = FALSE; | |
1105 if (win->w_arg_idx == WARGCOUNT(win) - 1 | |
1106 && win->w_alist == &global_alist) | |
1107 arg_had_last = TRUE; | |
1108 } | |
1109 } | |
1110 | |
1111 /* | |
1112 * ":args", ":argslocal" and ":argsglobal". | |
1113 */ | |
1114 void | |
1115 ex_args(exarg_T *eap) | |
1116 { | |
1117 int i; | |
1118 | |
1119 if (eap->cmdidx != CMD_args) | |
1120 { | |
1121 alist_unlink(ALIST(curwin)); | |
1122 if (eap->cmdidx == CMD_argglobal) | |
1123 ALIST(curwin) = &global_alist; | |
1124 else /* eap->cmdidx == CMD_arglocal */ | |
1125 alist_new(); | |
1126 } | |
1127 | |
1128 if (*eap->arg != NUL) | |
1129 { | |
1130 /* | |
1131 * ":args file ..": define new argument list, handle like ":next" | |
1132 * Also for ":argslocal file .." and ":argsglobal file ..". | |
1133 */ | |
1134 ex_next(eap); | |
1135 } | |
1136 else if (eap->cmdidx == CMD_args) | |
1137 { | |
1138 /* | |
1139 * ":args": list arguments. | |
1140 */ | |
1141 if (ARGCOUNT > 0) | |
1142 { | |
1143 char_u **items = ALLOC_MULT(char_u *, ARGCOUNT); | |
1144 | |
1145 if (items != NULL) | |
1146 { | |
1147 /* Overwrite the command, for a short list there is no | |
1148 * scrolling required and no wait_return(). */ | |
1149 gotocmdline(TRUE); | |
1150 | |
1151 for (i = 0; i < ARGCOUNT; ++i) | |
1152 items[i] = alist_name(&ARGLIST[i]); | |
1153 list_in_columns(items, ARGCOUNT, curwin->w_arg_idx); | |
1154 vim_free(items); | |
1155 } | |
1156 } | |
1157 } | |
1158 else if (eap->cmdidx == CMD_arglocal) | |
1159 { | |
1160 garray_T *gap = &curwin->w_alist->al_ga; | |
1161 | |
1162 /* | |
1163 * ":argslocal": make a local copy of the global argument list. | |
1164 */ | |
1165 if (ga_grow(gap, GARGCOUNT) == OK) | |
1166 for (i = 0; i < GARGCOUNT; ++i) | |
1167 if (GARGLIST[i].ae_fname != NULL) | |
1168 { | |
1169 AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname = | |
1170 vim_strsave(GARGLIST[i].ae_fname); | |
1171 AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum = | |
1172 GARGLIST[i].ae_fnum; | |
1173 ++gap->ga_len; | |
1174 } | |
1175 } | |
1176 } | |
1177 | |
1178 /* | |
1179 * ":previous", ":sprevious", ":Next" and ":sNext". | |
1180 */ | |
1181 void | |
1182 ex_previous(exarg_T *eap) | |
1183 { | |
1184 /* If past the last one already, go to the last one. */ | |
1185 if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT) | |
1186 do_argfile(eap, ARGCOUNT - 1); | |
1187 else | |
1188 do_argfile(eap, curwin->w_arg_idx - (int)eap->line2); | |
1189 } | |
1190 | |
1191 /* | |
1192 * ":rewind", ":first", ":sfirst" and ":srewind". | |
1193 */ | |
1194 void | |
1195 ex_rewind(exarg_T *eap) | |
1196 { | |
1197 do_argfile(eap, 0); | |
1198 } | |
1199 | |
1200 /* | |
1201 * ":last" and ":slast". | |
1202 */ | |
1203 void | |
1204 ex_last(exarg_T *eap) | |
1205 { | |
1206 do_argfile(eap, ARGCOUNT - 1); | |
1207 } | |
1208 | |
1209 /* | |
1210 * ":argument" and ":sargument". | |
1211 */ | |
1212 void | |
1213 ex_argument(exarg_T *eap) | |
1214 { | |
1215 int i; | |
1216 | |
1217 if (eap->addr_count > 0) | |
1218 i = eap->line2 - 1; | |
1219 else | |
1220 i = curwin->w_arg_idx; | |
1221 do_argfile(eap, i); | |
1222 } | |
1223 | |
1224 /* | |
1225 * Edit file "argn" of the argument lists. | |
1226 */ | |
1227 void | |
1228 do_argfile(exarg_T *eap, int argn) | |
1229 { | |
1230 int other; | |
1231 char_u *p; | |
1232 int old_arg_idx = curwin->w_arg_idx; | |
1233 | |
1234 if (ERROR_IF_POPUP_WINDOW) | |
1235 return; | |
1236 if (argn < 0 || argn >= ARGCOUNT) | |
1237 { | |
1238 if (ARGCOUNT <= 1) | |
1239 emsg(_("E163: There is only one file to edit")); | |
1240 else if (argn < 0) | |
1241 emsg(_("E164: Cannot go before first file")); | |
1242 else | |
1243 emsg(_("E165: Cannot go beyond last file")); | |
1244 } | |
1245 else | |
1246 { | |
1247 setpcmark(); | |
1248 #ifdef FEAT_GUI | |
1249 need_mouse_correct = TRUE; | |
1250 #endif | |
1251 | |
1252 /* split window or create new tab page first */ | |
1253 if (*eap->cmd == 's' || cmdmod.tab != 0) | |
1254 { | |
1255 if (win_split(0, 0) == FAIL) | |
1256 return; | |
1257 RESET_BINDING(curwin); | |
1258 } | |
1259 else | |
1260 { | |
1261 /* | |
1262 * if 'hidden' set, only check for changed file when re-editing | |
1263 * the same buffer | |
1264 */ | |
1265 other = TRUE; | |
1266 if (buf_hide(curbuf)) | |
1267 { | |
1268 p = fix_fname(alist_name(&ARGLIST[argn])); | |
1269 other = otherfile(p); | |
1270 vim_free(p); | |
1271 } | |
1272 if ((!buf_hide(curbuf) || !other) | |
1273 && check_changed(curbuf, CCGD_AW | |
1274 | (other ? 0 : CCGD_MULTWIN) | |
1275 | (eap->forceit ? CCGD_FORCEIT : 0) | |
1276 | CCGD_EXCMD)) | |
1277 return; | |
1278 } | |
1279 | |
1280 curwin->w_arg_idx = argn; | |
1281 if (argn == ARGCOUNT - 1 && curwin->w_alist == &global_alist) | |
1282 arg_had_last = TRUE; | |
1283 | |
1284 /* Edit the file; always use the last known line number. | |
1285 * When it fails (e.g. Abort for already edited file) restore the | |
1286 * argument index. */ | |
1287 if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL, | |
1288 eap, ECMD_LAST, | |
1289 (buf_hide(curwin->w_buffer) ? ECMD_HIDE : 0) | |
1290 + (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) | |
1291 curwin->w_arg_idx = old_arg_idx; | |
1292 /* like Vi: set the mark where the cursor is in the file. */ | |
1293 else if (eap->cmdidx != CMD_argdo) | |
1294 setmark('\''); | |
1295 } | |
1296 } | |
1297 | |
1298 /* | |
1299 * ":next", and commands that behave like it. | |
1300 */ | |
1301 void | |
1302 ex_next(exarg_T *eap) | |
1303 { | |
1304 int i; | |
1305 | |
1306 /* | |
1307 * check for changed buffer now, if this fails the argument list is not | |
1308 * redefined. | |
1309 */ | |
1310 if ( buf_hide(curbuf) | |
1311 || eap->cmdidx == CMD_snext | |
1312 || !check_changed(curbuf, CCGD_AW | |
1313 | (eap->forceit ? CCGD_FORCEIT : 0) | |
1314 | CCGD_EXCMD)) | |
1315 { | |
1316 if (*eap->arg != NUL) /* redefine file list */ | |
1317 { | |
1318 if (do_arglist(eap->arg, AL_SET, 0, TRUE) == FAIL) | |
1319 return; | |
1320 i = 0; | |
1321 } | |
1322 else | |
1323 i = curwin->w_arg_idx + (int)eap->line2; | |
1324 do_argfile(eap, i); | |
1325 } | |
1326 } | |
1327 | |
1328 /* | |
1329 * ":argedit" | |
1330 */ | |
1331 void | |
1332 ex_argedit(exarg_T *eap) | |
1333 { | |
1334 int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1; | |
1335 // Whether curbuf will be reused, curbuf->b_ffname will be set. | |
1336 int curbuf_is_reusable = curbuf_reusable(); | |
1337 | |
1338 if (do_arglist(eap->arg, AL_ADD, i, TRUE) == FAIL) | |
1339 return; | |
1340 #ifdef FEAT_TITLE | |
1341 maketitle(); | |
1342 #endif | |
1343 | |
1344 if (curwin->w_arg_idx == 0 | |
1345 && (curbuf->b_ml.ml_flags & ML_EMPTY) | |
1346 && (curbuf->b_ffname == NULL || curbuf_is_reusable)) | |
1347 i = 0; | |
1348 /* Edit the argument. */ | |
1349 if (i < ARGCOUNT) | |
1350 do_argfile(eap, i); | |
1351 } | |
1352 | |
1353 /* | |
1354 * ":argadd" | |
1355 */ | |
1356 void | |
1357 ex_argadd(exarg_T *eap) | |
1358 { | |
1359 do_arglist(eap->arg, AL_ADD, | |
1360 eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1, | |
1361 FALSE); | |
1362 #ifdef FEAT_TITLE | |
1363 maketitle(); | |
1364 #endif | |
1365 } | |
1366 | |
1367 /* | |
1368 * ":argdelete" | |
1369 */ | |
1370 void | |
1371 ex_argdelete(exarg_T *eap) | |
1372 { | |
1373 int i; | |
1374 int n; | |
1375 | |
1376 if (eap->addr_count > 0) | |
1377 { | |
1378 /* ":1,4argdel": Delete all arguments in the range. */ | |
1379 if (eap->line2 > ARGCOUNT) | |
1380 eap->line2 = ARGCOUNT; | |
1381 n = eap->line2 - eap->line1 + 1; | |
1382 if (*eap->arg != NUL) | |
1383 /* Can't have both a range and an argument. */ | |
1384 emsg(_(e_invarg)); | |
1385 else if (n <= 0) | |
1386 { | |
1387 /* Don't give an error for ":%argdel" if the list is empty. */ | |
1388 if (eap->line1 != 1 || eap->line2 != 0) | |
1389 emsg(_(e_invrange)); | |
1390 } | |
1391 else | |
1392 { | |
1393 for (i = eap->line1; i <= eap->line2; ++i) | |
1394 vim_free(ARGLIST[i - 1].ae_fname); | |
1395 mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2, | |
1396 (size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T))); | |
1397 ALIST(curwin)->al_ga.ga_len -= n; | |
1398 if (curwin->w_arg_idx >= eap->line2) | |
1399 curwin->w_arg_idx -= n; | |
1400 else if (curwin->w_arg_idx > eap->line1) | |
1401 curwin->w_arg_idx = eap->line1; | |
1402 if (ARGCOUNT == 0) | |
1403 curwin->w_arg_idx = 0; | |
1404 else if (curwin->w_arg_idx >= ARGCOUNT) | |
1405 curwin->w_arg_idx = ARGCOUNT - 1; | |
1406 } | |
1407 } | |
1408 else if (*eap->arg == NUL) | |
1409 emsg(_(e_argreq)); | |
1410 else | |
1411 do_arglist(eap->arg, AL_DEL, 0, FALSE); | |
1412 #ifdef FEAT_TITLE | |
1413 maketitle(); | |
1414 #endif | |
1415 } | 823 } |
1416 | 824 |
1417 /* | 825 /* |
1418 * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo" | 826 * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo" |
1419 */ | 827 */ |
1679 #ifdef FEAT_CLIPBOARD | 1087 #ifdef FEAT_CLIPBOARD |
1680 end_global_changes(); | 1088 end_global_changes(); |
1681 #endif | 1089 #endif |
1682 } | 1090 } |
1683 | 1091 |
1684 /* | |
1685 * Add files[count] to the arglist of the current window after arg "after". | |
1686 * The file names in files[count] must have been allocated and are taken over. | |
1687 * Files[] itself is not taken over. | |
1688 */ | |
1689 static void | |
1690 alist_add_list( | |
1691 int count, | |
1692 char_u **files, | |
1693 int after, // where to add: 0 = before first one | |
1694 int will_edit) // will edit adding argument | |
1695 { | |
1696 int i; | |
1697 int old_argcount = ARGCOUNT; | |
1698 | |
1699 if (ga_grow(&ALIST(curwin)->al_ga, count) == OK) | |
1700 { | |
1701 if (after < 0) | |
1702 after = 0; | |
1703 if (after > ARGCOUNT) | |
1704 after = ARGCOUNT; | |
1705 if (after < ARGCOUNT) | |
1706 mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]), | |
1707 (ARGCOUNT - after) * sizeof(aentry_T)); | |
1708 for (i = 0; i < count; ++i) | |
1709 { | |
1710 int flags = BLN_LISTED | (will_edit ? BLN_CURBUF : 0); | |
1711 | |
1712 ARGLIST[after + i].ae_fname = files[i]; | |
1713 ARGLIST[after + i].ae_fnum = buflist_add(files[i], flags); | |
1714 } | |
1715 ALIST(curwin)->al_ga.ga_len += count; | |
1716 if (old_argcount > 0 && curwin->w_arg_idx >= after) | |
1717 curwin->w_arg_idx += count; | |
1718 return; | |
1719 } | |
1720 | |
1721 for (i = 0; i < count; ++i) | |
1722 vim_free(files[i]); | |
1723 } | |
1724 | |
1725 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) | |
1726 /* | |
1727 * Function given to ExpandGeneric() to obtain the possible arguments of the | |
1728 * argedit and argdelete commands. | |
1729 */ | |
1730 char_u * | |
1731 get_arglist_name(expand_T *xp UNUSED, int idx) | |
1732 { | |
1733 if (idx >= ARGCOUNT) | |
1734 return NULL; | |
1735 | |
1736 return alist_name(&ARGLIST[idx]); | |
1737 } | |
1738 #endif | |
1739 | |
1740 | |
1741 #ifdef FEAT_EVAL | 1092 #ifdef FEAT_EVAL |
1742 /* | 1093 /* |
1743 * ":compiler[!] {name}" | 1094 * ":compiler[!] {name}" |
1744 */ | 1095 */ |
1745 void | 1096 void |