comparison src/ex_docmd.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 316ae5631c1d
children a4e488a6655c
comparison
equal deleted inserted replaced
17743:4ca7a477f326 17744:4a3dca734d36
302 # define ex_try ex_ni 302 # define ex_try ex_ni
303 # define ex_unlet ex_ni 303 # define ex_unlet ex_ni
304 # define ex_unlockvar ex_ni 304 # define ex_unlockvar ex_ni
305 # define ex_while ex_ni 305 # define ex_while ex_ni
306 #endif 306 #endif
307 static char_u *arg_all(void);
308 #ifndef FEAT_SESSION 307 #ifndef FEAT_SESSION
309 # define ex_loadview ex_ni 308 # define ex_loadview ex_ni
310 #endif 309 #endif
311 #ifndef FEAT_VIMINFO 310 #ifndef FEAT_VIMINFO
312 # define ex_viminfo ex_ni 311 # define ex_viminfo ex_ni
6135 win_goto(wp); 6134 win_goto(wp);
6136 } 6135 }
6137 close_others(TRUE, eap->forceit); 6136 close_others(TRUE, eap->forceit);
6138 } 6137 }
6139 6138
6140 /*
6141 * ":all" and ":sall".
6142 * Also used for ":tab drop file ..." after setting the argument list.
6143 */
6144 void
6145 ex_all(exarg_T *eap)
6146 {
6147 if (eap->addr_count == 0)
6148 eap->line2 = 9999;
6149 do_arg_all((int)eap->line2, eap->forceit, eap->cmdidx == CMD_drop);
6150 }
6151
6152 static void 6139 static void
6153 ex_hide(exarg_T *eap UNUSED) 6140 ex_hide(exarg_T *eap UNUSED)
6154 { 6141 {
6155 /* ":hide" or ":hide | cmd": hide current window */ 6142 /* ":hide" or ":hide | cmd": hide current window */
6156 if (!eap->skip) 6143 if (!eap->skip)
6439 handle_any_postponed_drop(void) 6426 handle_any_postponed_drop(void)
6440 { 6427 {
6441 if (!drop_busy && drop_filev != NULL 6428 if (!drop_busy && drop_filev != NULL
6442 && !text_locked() && !curbuf_locked() && !updating_screen) 6429 && !text_locked() && !curbuf_locked() && !updating_screen)
6443 handle_drop_internal(); 6430 handle_drop_internal();
6444 }
6445 #endif
6446
6447 /*
6448 * Clear an argument list: free all file names and reset it to zero entries.
6449 */
6450 void
6451 alist_clear(alist_T *al)
6452 {
6453 while (--al->al_ga.ga_len >= 0)
6454 vim_free(AARGLIST(al)[al->al_ga.ga_len].ae_fname);
6455 ga_clear(&al->al_ga);
6456 }
6457
6458 /*
6459 * Init an argument list.
6460 */
6461 void
6462 alist_init(alist_T *al)
6463 {
6464 ga_init2(&al->al_ga, (int)sizeof(aentry_T), 5);
6465 }
6466
6467 /*
6468 * Remove a reference from an argument list.
6469 * Ignored when the argument list is the global one.
6470 * If the argument list is no longer used by any window, free it.
6471 */
6472 void
6473 alist_unlink(alist_T *al)
6474 {
6475 if (al != &global_alist && --al->al_refcount <= 0)
6476 {
6477 alist_clear(al);
6478 vim_free(al);
6479 }
6480 }
6481
6482 /*
6483 * Create a new argument list and use it for the current window.
6484 */
6485 void
6486 alist_new(void)
6487 {
6488 curwin->w_alist = ALLOC_ONE(alist_T);
6489 if (curwin->w_alist == NULL)
6490 {
6491 curwin->w_alist = &global_alist;
6492 ++global_alist.al_refcount;
6493 }
6494 else
6495 {
6496 curwin->w_alist->al_refcount = 1;
6497 curwin->w_alist->id = ++max_alist_id;
6498 alist_init(curwin->w_alist);
6499 }
6500 }
6501
6502 #if !defined(UNIX) || defined(PROTO)
6503 /*
6504 * Expand the file names in the global argument list.
6505 * If "fnum_list" is not NULL, use "fnum_list[fnum_len]" as a list of buffer
6506 * numbers to be re-used.
6507 */
6508 void
6509 alist_expand(int *fnum_list, int fnum_len)
6510 {
6511 char_u **old_arg_files;
6512 int old_arg_count;
6513 char_u **new_arg_files;
6514 int new_arg_file_count;
6515 char_u *save_p_su = p_su;
6516 int i;
6517
6518 /* Don't use 'suffixes' here. This should work like the shell did the
6519 * expansion. Also, the vimrc file isn't read yet, thus the user
6520 * can't set the options. */
6521 p_su = empty_option;
6522 old_arg_files = ALLOC_MULT(char_u *, GARGCOUNT);
6523 if (old_arg_files != NULL)
6524 {
6525 for (i = 0; i < GARGCOUNT; ++i)
6526 old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
6527 old_arg_count = GARGCOUNT;
6528 if (expand_wildcards(old_arg_count, old_arg_files,
6529 &new_arg_file_count, &new_arg_files,
6530 EW_FILE|EW_NOTFOUND|EW_ADDSLASH|EW_NOERROR) == OK
6531 && new_arg_file_count > 0)
6532 {
6533 alist_set(&global_alist, new_arg_file_count, new_arg_files,
6534 TRUE, fnum_list, fnum_len);
6535 FreeWild(old_arg_count, old_arg_files);
6536 }
6537 }
6538 p_su = save_p_su;
6539 }
6540 #endif
6541
6542 /*
6543 * Set the argument list for the current window.
6544 * Takes over the allocated files[] and the allocated fnames in it.
6545 */
6546 void
6547 alist_set(
6548 alist_T *al,
6549 int count,
6550 char_u **files,
6551 int use_curbuf,
6552 int *fnum_list,
6553 int fnum_len)
6554 {
6555 int i;
6556 static int recursive = 0;
6557
6558 if (recursive)
6559 {
6560 emsg(_(e_au_recursive));
6561 return;
6562 }
6563 ++recursive;
6564
6565 alist_clear(al);
6566 if (ga_grow(&al->al_ga, count) == OK)
6567 {
6568 for (i = 0; i < count; ++i)
6569 {
6570 if (got_int)
6571 {
6572 /* When adding many buffers this can take a long time. Allow
6573 * interrupting here. */
6574 while (i < count)
6575 vim_free(files[i++]);
6576 break;
6577 }
6578
6579 /* May set buffer name of a buffer previously used for the
6580 * argument list, so that it's re-used by alist_add. */
6581 if (fnum_list != NULL && i < fnum_len)
6582 buf_set_name(fnum_list[i], files[i]);
6583
6584 alist_add(al, files[i], use_curbuf ? 2 : 1);
6585 ui_breakcheck();
6586 }
6587 vim_free(files);
6588 }
6589 else
6590 FreeWild(count, files);
6591 if (al == &global_alist)
6592 arg_had_last = FALSE;
6593
6594 --recursive;
6595 }
6596
6597 /*
6598 * Add file "fname" to argument list "al".
6599 * "fname" must have been allocated and "al" must have been checked for room.
6600 */
6601 void
6602 alist_add(
6603 alist_T *al,
6604 char_u *fname,
6605 int set_fnum) /* 1: set buffer number; 2: re-use curbuf */
6606 {
6607 if (fname == NULL) /* don't add NULL file names */
6608 return;
6609 #ifdef BACKSLASH_IN_FILENAME
6610 slash_adjust(fname);
6611 #endif
6612 AARGLIST(al)[al->al_ga.ga_len].ae_fname = fname;
6613 if (set_fnum > 0)
6614 AARGLIST(al)[al->al_ga.ga_len].ae_fnum =
6615 buflist_add(fname, BLN_LISTED | (set_fnum == 2 ? BLN_CURBUF : 0));
6616 ++al->al_ga.ga_len;
6617 }
6618
6619 #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
6620 /*
6621 * Adjust slashes in file names. Called after 'shellslash' was set.
6622 */
6623 void
6624 alist_slash_adjust(void)
6625 {
6626 int i;
6627 win_T *wp;
6628 tabpage_T *tp;
6629
6630 for (i = 0; i < GARGCOUNT; ++i)
6631 if (GARGLIST[i].ae_fname != NULL)
6632 slash_adjust(GARGLIST[i].ae_fname);
6633 FOR_ALL_TAB_WINDOWS(tp, wp)
6634 if (wp->w_alist != &global_alist)
6635 for (i = 0; i < WARGCOUNT(wp); ++i)
6636 if (WARGLIST(wp)[i].ae_fname != NULL)
6637 slash_adjust(WARGLIST(wp)[i].ae_fname);
6638 } 6431 }
6639 #endif 6432 #endif
6640 6433
6641 /* 6434 /*
6642 * ":preserve". 6435 * ":preserve".
9283 vim_free(resultbuf); 9076 vim_free(resultbuf);
9284 return result; 9077 return result;
9285 } 9078 }
9286 9079
9287 /* 9080 /*
9288 * Concatenate all files in the argument list, separated by spaces, and return
9289 * it in one allocated string.
9290 * Spaces and backslashes in the file names are escaped with a backslash.
9291 * Returns NULL when out of memory.
9292 */
9293 static char_u *
9294 arg_all(void)
9295 {
9296 int len;
9297 int idx;
9298 char_u *retval = NULL;
9299 char_u *p;
9300
9301 /*
9302 * Do this loop two times:
9303 * first time: compute the total length
9304 * second time: concatenate the names
9305 */
9306 for (;;)
9307 {
9308 len = 0;
9309 for (idx = 0; idx < ARGCOUNT; ++idx)
9310 {
9311 p = alist_name(&ARGLIST[idx]);
9312 if (p != NULL)
9313 {
9314 if (len > 0)
9315 {
9316 /* insert a space in between names */
9317 if (retval != NULL)
9318 retval[len] = ' ';
9319 ++len;
9320 }
9321 for ( ; *p != NUL; ++p)
9322 {
9323 if (*p == ' '
9324 #ifndef BACKSLASH_IN_FILENAME
9325 || *p == '\\'
9326 #endif
9327 || *p == '`')
9328 {
9329 /* insert a backslash */
9330 if (retval != NULL)
9331 retval[len] = '\\';
9332 ++len;
9333 }
9334 if (retval != NULL)
9335 retval[len] = *p;
9336 ++len;
9337 }
9338 }
9339 }
9340
9341 /* second time: break here */
9342 if (retval != NULL)
9343 {
9344 retval[len] = NUL;
9345 break;
9346 }
9347
9348 /* allocate memory */
9349 retval = alloc(len + 1);
9350 if (retval == NULL)
9351 break;
9352 }
9353
9354 return retval;
9355 }
9356
9357 /*
9358 * Expand the <sfile> string in "arg". 9081 * Expand the <sfile> string in "arg".
9359 * 9082 *
9360 * Returns an allocated string, or NULL for any error. 9083 * Returns an allocated string, or NULL for any error.
9361 */ 9084 */
9362 char_u * 9085 char_u *