Mercurial > hg > RemoteEditor > vim7
comparison src/ex_docmd.c @ 8:f21b6f345e69 v7_2
*** empty log message ***
author | axmo |
---|---|
date | Wed, 13 Aug 2008 17:54:25 +0900 |
parents | beaeafecd1cd |
children | 13f0cd4d1b23 |
comparison
equal
deleted
inserted
replaced
7:95054589743a | 8:f21b6f345e69 |
---|---|
10 /* | 10 /* |
11 * ex_docmd.c: functions for executing an Ex command line. | 11 * ex_docmd.c: functions for executing an Ex command line. |
12 */ | 12 */ |
13 | 13 |
14 #include "vim.h" | 14 #include "vim.h" |
15 #include "reditor.h" /* REP: for Remote Editor */ | |
16 | |
17 #ifdef HAVE_FCNTL_H | |
18 # include <fcntl.h> /* for chdir() */ | |
19 #endif | |
20 | 15 |
21 static int quitmore = 0; | 16 static int quitmore = 0; |
22 static int ex_pressedreturn = FALSE; | 17 static int ex_pressedreturn = FALSE; |
23 #ifndef FEAT_PRINTER | 18 #ifndef FEAT_PRINTER |
24 # define ex_hardcopy ex_ni | 19 # define ex_hardcopy ex_ni |
371 # define ex_return ex_ni | 366 # define ex_return ex_ni |
372 #endif | 367 #endif |
373 static char_u *arg_all __ARGS((void)); | 368 static char_u *arg_all __ARGS((void)); |
374 #ifdef FEAT_SESSION | 369 #ifdef FEAT_SESSION |
375 static int makeopens __ARGS((FILE *fd, char_u *dirnow)); | 370 static int makeopens __ARGS((FILE *fd, char_u *dirnow)); |
376 static int put_view __ARGS((FILE *fd, win_T *wp, int add_edit, unsigned *flagp)); | 371 static int put_view __ARGS((FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx)); |
377 static void ex_loadview __ARGS((exarg_T *eap)); | 372 static void ex_loadview __ARGS((exarg_T *eap)); |
378 static char_u *get_view_file __ARGS((int c)); | 373 static char_u *get_view_file __ARGS((int c)); |
379 static int did_lcd; /* whether ":lcd" was produced for a session */ | 374 static int did_lcd; /* whether ":lcd" was produced for a session */ |
380 #else | 375 #else |
381 # define ex_loadview ex_ni | 376 # define ex_loadview ex_ni |
461 #endif | 456 #endif |
462 | 457 |
463 #ifndef FEAT_PROFILE | 458 #ifndef FEAT_PROFILE |
464 # define ex_profile ex_ni | 459 # define ex_profile ex_ni |
465 #endif | 460 #endif |
466 | |
467 /* | |
468 * REP: commands for Remote Editor | |
469 */ | |
470 static void ex_repstart __ARGS((exarg_T *eap)); | |
471 static void ex_repend __ARGS((exarg_T *eap)); | |
472 | 461 |
473 /* | 462 /* |
474 * Declare cmdnames[]. | 463 * Declare cmdnames[]. |
475 */ | 464 */ |
476 #define DO_DECLARE_EXCMD | 465 #define DO_DECLARE_EXCMD |
671 else | 660 else |
672 { | 661 { |
673 if (ex_pressedreturn) | 662 if (ex_pressedreturn) |
674 { | 663 { |
675 /* go up one line, to overwrite the ":<CR>" line, so the | 664 /* go up one line, to overwrite the ":<CR>" line, so the |
676 * output doensn't contain empty lines. */ | 665 * output doesn't contain empty lines. */ |
677 msg_row = prev_msg_row; | 666 msg_row = prev_msg_row; |
678 if (prev_msg_row == Rows - 1) | 667 if (prev_msg_row == Rows - 1) |
679 msg_row--; | 668 msg_row--; |
680 } | 669 } |
681 msg_col = 0; | 670 msg_col = 0; |
1137 } | 1126 } |
1138 else | 1127 else |
1139 { | 1128 { |
1140 /* need to copy the command after the '|' to cmdline_copy, for the | 1129 /* need to copy the command after the '|' to cmdline_copy, for the |
1141 * next do_one_cmd() */ | 1130 * next do_one_cmd() */ |
1142 mch_memmove(cmdline_copy, next_cmdline, STRLEN(next_cmdline) + 1); | 1131 STRMOVE(cmdline_copy, next_cmdline); |
1143 next_cmdline = cmdline_copy; | 1132 next_cmdline = cmdline_copy; |
1144 } | 1133 } |
1145 | 1134 |
1146 | 1135 |
1147 #ifdef FEAT_EVAL | 1136 #ifdef FEAT_EVAL |
1746 ea.cmd = (char_u *)"+"; | 1735 ea.cmd = (char_u *)"+"; |
1747 ex_pressedreturn = TRUE; | 1736 ex_pressedreturn = TRUE; |
1748 } | 1737 } |
1749 | 1738 |
1750 /* ignore comment and empty lines */ | 1739 /* ignore comment and empty lines */ |
1751 if (*ea.cmd == '"' || *ea.cmd == NUL) | 1740 if (*ea.cmd == '"') |
1741 goto doend; | |
1742 if (*ea.cmd == NUL) | |
1752 { | 1743 { |
1753 ex_pressedreturn = TRUE; | 1744 ex_pressedreturn = TRUE; |
1754 goto doend; | 1745 goto doend; |
1755 } | 1746 } |
1756 | 1747 |
2145 goto doend; | 2136 goto doend; |
2146 } | 2137 } |
2147 | 2138 |
2148 #endif | 2139 #endif |
2149 | 2140 |
2150 if (*p == '!' && ea.cmdidx != CMD_substitute) /* forced commands */ | 2141 /* forced commands */ |
2142 if (*p == '!' && ea.cmdidx != CMD_substitute | |
2143 && ea.cmdidx != CMD_smagic && ea.cmdidx != CMD_snomagic) | |
2151 { | 2144 { |
2152 ++p; | 2145 ++p; |
2153 ea.forceit = TRUE; | 2146 ea.forceit = TRUE; |
2154 } | 2147 } |
2155 else | 2148 else |
2376 * with a backslash. This makes it impossible to end a shell | 2369 * with a backslash. This makes it impossible to end a shell |
2377 * command in a backslash, but that doesn't appear useful. | 2370 * command in a backslash, but that doesn't appear useful. |
2378 * Halving the number of backslashes is incompatible with previous | 2371 * Halving the number of backslashes is incompatible with previous |
2379 * versions. */ | 2372 * versions. */ |
2380 if (*p == '\\' && p[1] == '\n') | 2373 if (*p == '\\' && p[1] == '\n') |
2381 mch_memmove(p, p + 1, STRLEN(p)); | 2374 STRMOVE(p, p + 1); |
2382 else if (*p == '\n') | 2375 else if (*p == '\n') |
2383 { | 2376 { |
2384 ea.nextcmd = p + 1; | 2377 ea.nextcmd = p + 1; |
2385 *p = NUL; | 2378 *p = NUL; |
2386 break; | 2379 break; |
2663 { | 2656 { |
2664 STRCPY(IObuff, errormsg); | 2657 STRCPY(IObuff, errormsg); |
2665 errormsg = IObuff; | 2658 errormsg = IObuff; |
2666 } | 2659 } |
2667 STRCAT(errormsg, ": "); | 2660 STRCAT(errormsg, ": "); |
2668 STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff)); | 2661 STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff) - 1); |
2669 } | 2662 } |
2670 emsg(errormsg); | 2663 emsg(errormsg); |
2671 } | 2664 } |
2672 #ifdef FEAT_EVAL | 2665 #ifdef FEAT_EVAL |
2673 do_errthrow(cstack, | 2666 do_errthrow(cstack, |
2765 char_u *p; | 2758 char_u *p; |
2766 int i; | 2759 int i; |
2767 | 2760 |
2768 /* | 2761 /* |
2769 * Isolate the command and search for it in the command table. | 2762 * Isolate the command and search for it in the command table. |
2770 * Exeptions: | 2763 * Exceptions: |
2771 * - the 'k' command can directly be followed by any character. | 2764 * - the 'k' command can directly be followed by any character. |
2772 * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r' | 2765 * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r' |
2773 * but :sre[wind] is another command, as are :scrip[tnames], | 2766 * but :sre[wind] is another command, as are :scrip[tnames], |
2774 * :scs[cope], :sim[alt], :sig[ns] and :sil[ent]. | 2767 * :scs[cope], :sim[alt], :sig[ns] and :sil[ent]. |
2775 * - the "d" command can directly be followed by 'l' or 'p' flag. | 2768 * - the "d" command can directly be followed by 'l' or 'p' flag. |
2966 return p; | 2959 return p; |
2967 } | 2960 } |
2968 #endif | 2961 #endif |
2969 | 2962 |
2970 #if defined(FEAT_EVAL) || defined(PROTO) | 2963 #if defined(FEAT_EVAL) || defined(PROTO) |
2964 static struct cmdmod | |
2965 { | |
2966 char *name; | |
2967 int minlen; | |
2968 int has_count; /* :123verbose :3tab */ | |
2969 } cmdmods[] = { | |
2970 {"aboveleft", 3, FALSE}, | |
2971 {"belowright", 3, FALSE}, | |
2972 {"botright", 2, FALSE}, | |
2973 {"browse", 3, FALSE}, | |
2974 {"confirm", 4, FALSE}, | |
2975 {"hide", 3, FALSE}, | |
2976 {"keepalt", 5, FALSE}, | |
2977 {"keepjumps", 5, FALSE}, | |
2978 {"keepmarks", 3, FALSE}, | |
2979 {"leftabove", 5, FALSE}, | |
2980 {"lockmarks", 3, FALSE}, | |
2981 {"rightbelow", 6, FALSE}, | |
2982 {"sandbox", 3, FALSE}, | |
2983 {"silent", 3, FALSE}, | |
2984 {"tab", 3, TRUE}, | |
2985 {"topleft", 2, FALSE}, | |
2986 {"verbose", 4, TRUE}, | |
2987 {"vertical", 4, FALSE}, | |
2988 }; | |
2989 | |
2990 /* | |
2991 * Return length of a command modifier (including optional count). | |
2992 * Return zero when it's not a modifier. | |
2993 */ | |
2994 int | |
2995 modifier_len(cmd) | |
2996 char_u *cmd; | |
2997 { | |
2998 int i, j; | |
2999 char_u *p = cmd; | |
3000 | |
3001 if (VIM_ISDIGIT(*cmd)) | |
3002 p = skipwhite(skipdigits(cmd)); | |
3003 for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i) | |
3004 { | |
3005 for (j = 0; p[j] != NUL; ++j) | |
3006 if (p[j] != cmdmods[i].name[j]) | |
3007 break; | |
3008 if (!isalpha(p[j]) && j >= cmdmods[i].minlen | |
3009 && (p == cmd || cmdmods[i].has_count)) | |
3010 return j + (int)(p - cmd); | |
3011 } | |
3012 return 0; | |
3013 } | |
3014 | |
2971 /* | 3015 /* |
2972 * Return > 0 if an Ex command "name" exists. | 3016 * Return > 0 if an Ex command "name" exists. |
2973 * Return 2 if there is an exact match. | 3017 * Return 2 if there is an exact match. |
2974 * Return 3 if there is an ambiguous match. | 3018 * Return 3 if there is an ambiguous match. |
2975 */ | 3019 */ |
2980 exarg_T ea; | 3024 exarg_T ea; |
2981 int full = FALSE; | 3025 int full = FALSE; |
2982 int i; | 3026 int i; |
2983 int j; | 3027 int j; |
2984 char_u *p; | 3028 char_u *p; |
2985 static struct cmdmod | |
2986 { | |
2987 char *name; | |
2988 int minlen; | |
2989 } cmdmods[] = { | |
2990 {"aboveleft", 3}, | |
2991 {"belowright", 3}, | |
2992 {"botright", 2}, | |
2993 {"browse", 3}, | |
2994 {"confirm", 4}, | |
2995 {"hide", 3}, | |
2996 {"keepalt", 5}, | |
2997 {"keepjumps", 5}, | |
2998 {"keepmarks", 3}, | |
2999 {"leftabove", 5}, | |
3000 {"lockmarks", 3}, | |
3001 {"rightbelow", 6}, | |
3002 {"sandbox", 3}, | |
3003 {"silent", 3}, | |
3004 {"tab", 3}, | |
3005 {"topleft", 2}, | |
3006 {"verbose", 4}, | |
3007 {"vertical", 4}, | |
3008 }; | |
3009 | 3029 |
3010 /* Check command modifiers. */ | 3030 /* Check command modifiers. */ |
3011 for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i) | 3031 for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i) |
3012 { | 3032 { |
3013 for (j = 0; name[j] != NUL; ++j) | 3033 for (j = 0; name[j] != NUL; ++j) |
3314 xp->xp_pattern = p; | 3334 xp->xp_pattern = p; |
3315 bow = p + 1; | 3335 bow = p + 1; |
3316 } | 3336 } |
3317 in_quote = !in_quote; | 3337 in_quote = !in_quote; |
3318 } | 3338 } |
3339 /* An argument can contain just about everything, except | |
3340 * characters that end the command and white space. */ | |
3341 else if (c == '|' || c == '\n' || c == '"' || (vim_iswhite(c) | |
3319 #ifdef SPACE_IN_FILENAME | 3342 #ifdef SPACE_IN_FILENAME |
3320 else if (!vim_isfilec_or_wc(c) | 3343 && (!(ea.argt & NOSPC) || usefilter) |
3321 && (!(ea.argt & NOSPC) || usefilter)) | 3344 #endif |
3322 #else | 3345 )) |
3323 else if (!vim_isfilec_or_wc(c)) | |
3324 #endif | |
3325 { | 3346 { |
3347 len = 0; /* avoid getting stuck when space is in 'isfname' */ | |
3326 while (*p != NUL) | 3348 while (*p != NUL) |
3327 { | 3349 { |
3328 #ifdef FEAT_MBYTE | 3350 #ifdef FEAT_MBYTE |
3329 if (has_mbyte) | 3351 if (has_mbyte) |
3330 c = mb_ptr2char(p); | 3352 c = mb_ptr2char(p); |
3434 case CMD_tab: | 3456 case CMD_tab: |
3435 case CMD_topleft: | 3457 case CMD_topleft: |
3436 case CMD_verbose: | 3458 case CMD_verbose: |
3437 case CMD_vertical: | 3459 case CMD_vertical: |
3438 case CMD_windo: | 3460 case CMD_windo: |
3439 /* REP: for Remote Editor */ | |
3440 case CMD_repstart: | |
3441 case CMD_repend: | |
3442 return arg; | 3461 return arg; |
3443 | 3462 |
3444 #ifdef FEAT_CMDL_COMPL | 3463 #ifdef FEAT_CMDL_COMPL |
3445 # ifdef FEAT_SEARCH_EXTRA | 3464 # ifdef FEAT_SEARCH_EXTRA |
3446 case CMD_match: | 3465 case CMD_match: |
3909 curwin->w_cursor.col = MAXCOL; | 3928 curwin->w_cursor.col = MAXCOL; |
3910 else | 3929 else |
3911 curwin->w_cursor.col = 0; | 3930 curwin->w_cursor.col = 0; |
3912 searchcmdlen = 0; | 3931 searchcmdlen = 0; |
3913 if (!do_search(NULL, c, cmd, 1L, | 3932 if (!do_search(NULL, c, cmd, 1L, |
3914 SEARCH_HIS + SEARCH_MSG + SEARCH_START)) | 3933 SEARCH_HIS | SEARCH_MSG, NULL)) |
3915 { | 3934 { |
3916 curwin->w_cursor = pos; | 3935 curwin->w_cursor = pos; |
3917 cmd = NULL; | 3936 cmd = NULL; |
3918 goto error; | 3937 goto error; |
3919 } | 3938 } |
3956 pos.col = MAXCOL; | 3975 pos.col = MAXCOL; |
3957 else | 3976 else |
3958 pos.col = 0; | 3977 pos.col = 0; |
3959 if (searchit(curwin, curbuf, &pos, | 3978 if (searchit(curwin, curbuf, &pos, |
3960 *cmd == '?' ? BACKWARD : FORWARD, | 3979 *cmd == '?' ? BACKWARD : FORWARD, |
3961 (char_u *)"", 1L, | 3980 (char_u *)"", 1L, SEARCH_MSG, |
3962 SEARCH_MSG + SEARCH_START, | 3981 i, (linenr_T)0, NULL) != FAIL) |
3963 i, (linenr_T)0) != FAIL) | |
3964 lnum = pos.lnum; | 3982 lnum = pos.lnum; |
3965 else | 3983 else |
3966 { | 3984 { |
3967 cmd = NULL; | 3985 cmd = NULL; |
3968 goto error; | 3986 goto error; |
4527 { | 4545 { |
4528 if (eap->argt & (USECTRLV | XFILE)) | 4546 if (eap->argt & (USECTRLV | XFILE)) |
4529 ++p; /* skip CTRL-V and next char */ | 4547 ++p; /* skip CTRL-V and next char */ |
4530 else | 4548 else |
4531 /* remove CTRL-V and skip next char */ | 4549 /* remove CTRL-V and skip next char */ |
4532 mch_memmove(p, p + 1, STRLEN(p)); | 4550 STRMOVE(p, p + 1); |
4533 if (*p == NUL) /* stop at NUL after CTRL-V */ | 4551 if (*p == NUL) /* stop at NUL after CTRL-V */ |
4534 break; | 4552 break; |
4535 } | 4553 } |
4536 | 4554 |
4537 #ifdef FEAT_EVAL | 4555 #ifdef FEAT_EVAL |
4558 * AND 'b' is present in 'cpoptions'. | 4576 * AND 'b' is present in 'cpoptions'. |
4559 */ | 4577 */ |
4560 if ((vim_strchr(p_cpo, CPO_BAR) == NULL | 4578 if ((vim_strchr(p_cpo, CPO_BAR) == NULL |
4561 || !(eap->argt & USECTRLV)) && *(p - 1) == '\\') | 4579 || !(eap->argt & USECTRLV)) && *(p - 1) == '\\') |
4562 { | 4580 { |
4563 mch_memmove(p - 1, p, STRLEN(p) + 1); /* remove the '\' */ | 4581 STRMOVE(p - 1, p); /* remove the '\' */ |
4564 --p; | 4582 --p; |
4565 } | 4583 } |
4566 else | 4584 else |
4567 { | 4585 { |
4568 eap->nextcmd = check_nextcmd(p); | 4586 eap->nextcmd = check_nextcmd(p); |
4616 while (*p && !vim_isspace(*p)) | 4634 while (*p && !vim_isspace(*p)) |
4617 { | 4635 { |
4618 if (*p == '\\' && p[1] != NUL) | 4636 if (*p == '\\' && p[1] != NUL) |
4619 { | 4637 { |
4620 if (rembs) | 4638 if (rembs) |
4621 mch_memmove(p, p + 1, STRLEN(p)); | 4639 STRMOVE(p, p + 1); |
4622 else | 4640 else |
4623 ++p; | 4641 ++p; |
4624 } | 4642 } |
4625 mb_ptr_adv(p); | 4643 mb_ptr_adv(p); |
4626 } | 4644 } |
6685 * functions in this file. | 6703 * functions in this file. |
6686 * | 6704 * |
6687 * The list should be allocated using alloc(), as should each item in the | 6705 * The list should be allocated using alloc(), as should each item in the |
6688 * list. This function takes over responsibility for freeing the list. | 6706 * list. This function takes over responsibility for freeing the list. |
6689 * | 6707 * |
6690 * XXX The list is made into the arggument list. This is freed using | 6708 * XXX The list is made into the argument list. This is freed using |
6691 * FreeWild(), which does a series of vim_free() calls, unless the two defines | 6709 * FreeWild(), which does a series of vim_free() calls, unless the two defines |
6692 * __EMX__ and __ALWAYS_HAS_TRAILING_NUL_POINTER are set. In this case, a | 6710 * __EMX__ and __ALWAYS_HAS_TRAILING_NUL_POINTER are set. In this case, a |
6693 * routine _fnexplodefree() is used. This may cause problems, but as the drop | 6711 * routine _fnexplodefree() is used. This may cause problems, but as the drop |
6694 * file functionality is (currently) not in EMX this is not presently a | 6712 * file functionality is (currently) not in EMX this is not presently a |
6695 * problem. | 6713 * problem. |
6708 return; | 6726 return; |
6709 #ifdef FEAT_AUTOCMD | 6727 #ifdef FEAT_AUTOCMD |
6710 if (curbuf_locked()) | 6728 if (curbuf_locked()) |
6711 return; | 6729 return; |
6712 #endif | 6730 #endif |
6731 /* When the screen is being updated we should not change buffers and | |
6732 * windows structures, it may cause freed memory to be used. */ | |
6733 if (updating_screen) | |
6734 return; | |
6713 | 6735 |
6714 /* Check whether the current buffer is changed. If so, we will need | 6736 /* Check whether the current buffer is changed. If so, we will need |
6715 * to split the current window or data could be lost. | 6737 * to split the current window or data could be lost. |
6716 * We don't need to check if the 'hidden' option is set, as in this | 6738 * We don't need to check if the 'hidden' option is set, as in this |
6717 * case the buffer won't be lost. | 6739 * case the buffer won't be lost. |
7039 need_mouse_correct = TRUE; | 7061 need_mouse_correct = TRUE; |
7040 # endif | 7062 # endif |
7041 | 7063 |
7042 # ifdef FEAT_QUICKFIX | 7064 # ifdef FEAT_QUICKFIX |
7043 /* A ":split" in the quickfix window works like ":new". Don't want two | 7065 /* A ":split" in the quickfix window works like ":new". Don't want two |
7044 * quickfix windows. */ | 7066 * quickfix windows. But it's OK when doing ":tab split". */ |
7045 if (bt_quickfix(curbuf)) | 7067 if (bt_quickfix(curbuf) && cmdmod.tab == 0) |
7046 { | 7068 { |
7047 if (eap->cmdidx == CMD_split) | 7069 if (eap->cmdidx == CMD_split) |
7048 eap->cmdidx = CMD_new; | 7070 eap->cmdidx = CMD_new; |
7049 # ifdef FEAT_VERTSPLIT | 7071 # ifdef FEAT_VERTSPLIT |
7050 if (eap->cmdidx == CMD_vsplit) | 7072 if (eap->cmdidx == CMD_vsplit) |
7071 # ifdef FEAT_VERTSPLIT | 7093 # ifdef FEAT_VERTSPLIT |
7072 && eap->cmdidx != CMD_vnew | 7094 && eap->cmdidx != CMD_vnew |
7073 # endif | 7095 # endif |
7074 && eap->cmdidx != CMD_new) | 7096 && eap->cmdidx != CMD_new) |
7075 { | 7097 { |
7098 # ifdef FEAT_AUTOCMD | |
7076 if ( | 7099 if ( |
7077 # ifdef FEAT_GUI | 7100 # ifdef FEAT_GUI |
7078 !gui.in_use && | 7101 !gui.in_use && |
7079 # endif | 7102 # endif |
7080 au_has_group((char_u *)"FileExplorer")) | 7103 au_has_group((char_u *)"FileExplorer")) |
7081 { | 7104 { |
7082 /* No browsing supported but we do have the file explorer: | 7105 /* No browsing supported but we do have the file explorer: |
7083 * Edit the directory. */ | 7106 * Edit the directory. */ |
7084 if (*eap->arg == NUL || !mch_isdir(eap->arg)) | 7107 if (*eap->arg == NUL || !mch_isdir(eap->arg)) |
7085 eap->arg = (char_u *)"."; | 7108 eap->arg = (char_u *)"."; |
7086 } | 7109 } |
7087 else | 7110 else |
7111 # endif | |
7088 { | 7112 { |
7089 fname = do_browse(0, (char_u *)_("Edit File in new window"), | 7113 fname = do_browse(0, (char_u *)_("Edit File in new window"), |
7090 eap->arg, NULL, NULL, NULL, curbuf); | 7114 eap->arg, NULL, NULL, NULL, curbuf); |
7091 if (fname == NULL) | 7115 if (fname == NULL) |
7092 goto theend; | 7116 goto theend; |
7105 { | 7129 { |
7106 if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab | 7130 if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab |
7107 : eap->addr_count == 0 ? 0 | 7131 : eap->addr_count == 0 ? 0 |
7108 : (int)eap->line2 + 1) != FAIL) | 7132 : (int)eap->line2 + 1) != FAIL) |
7109 { | 7133 { |
7110 do_exedit(eap, NULL); | 7134 do_exedit(eap, old_curwin); |
7111 | 7135 |
7112 /* set the alternate buffer for the window we came from */ | 7136 /* set the alternate buffer for the window we came from */ |
7113 if (curwin != old_curwin | 7137 if (curwin != old_curwin |
7114 && win_valid(old_curwin) | 7138 && win_valid(old_curwin) |
7115 && old_curwin->w_buffer != curbuf | 7139 && old_curwin->w_buffer != curbuf |
7143 theend: | 7167 theend: |
7144 vim_free(fname); | 7168 vim_free(fname); |
7145 # endif | 7169 # endif |
7146 } | 7170 } |
7147 | 7171 |
7148 #if defined(FEAT_MOUSE) || defined(PROTO) | |
7149 /* | 7172 /* |
7150 * Open a new tab page. | 7173 * Open a new tab page. |
7151 */ | 7174 */ |
7152 void | 7175 void |
7153 tabpage_new() | 7176 tabpage_new() |
7158 ea.cmdidx = CMD_tabnew; | 7181 ea.cmdidx = CMD_tabnew; |
7159 ea.cmd = (char_u *)"tabn"; | 7182 ea.cmd = (char_u *)"tabn"; |
7160 ea.arg = (char_u *)""; | 7183 ea.arg = (char_u *)""; |
7161 ex_splitview(&ea); | 7184 ex_splitview(&ea); |
7162 } | 7185 } |
7163 #endif | |
7164 | 7186 |
7165 /* | 7187 /* |
7166 * :tabnext command | 7188 * :tabnext command |
7167 */ | 7189 */ |
7168 static void | 7190 static void |
7778 #if defined(EXITFREE) || defined(PROTO) | 7800 #if defined(EXITFREE) || defined(PROTO) |
7779 void | 7801 void |
7780 free_cd_dir() | 7802 free_cd_dir() |
7781 { | 7803 { |
7782 vim_free(prev_dir); | 7804 vim_free(prev_dir); |
7805 prev_dir = NULL; | |
7783 } | 7806 } |
7784 #endif | 7807 #endif |
7785 | 7808 |
7786 | 7809 |
7787 /* | 7810 /* |
7803 #endif | 7826 #endif |
7804 { | 7827 { |
7805 if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged() | 7828 if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged() |
7806 && !eap->forceit) | 7829 && !eap->forceit) |
7807 { | 7830 { |
7808 EMSG(_("E747: Cannot change directory, buffer is modifed (add ! to override)")); | 7831 EMSG(_("E747: Cannot change directory, buffer is modified (add ! to override)")); |
7809 return; | 7832 return; |
7810 } | 7833 } |
7811 | 7834 |
7812 /* ":cd -": Change to previous directory */ | 7835 /* ":cd -": Change to previous directory */ |
7813 if (STRCMP(new_dir, "-") == 0) | 7836 if (STRCMP(new_dir, "-") == 0) |
8741 shorten_fnames(TRUE); | 8764 shorten_fnames(TRUE); |
8742 } | 8765 } |
8743 } | 8766 } |
8744 else | 8767 else |
8745 { | 8768 { |
8746 failed |= (put_view(fd, curwin, !using_vdir, flagp) == FAIL); | 8769 failed |= (put_view(fd, curwin, !using_vdir, flagp, |
8770 -1) == FAIL); | |
8747 } | 8771 } |
8748 if (put_line(fd, "let &so = s:so_save | let &siso = s:siso_save") | 8772 if (put_line(fd, "let &so = s:so_save | let &siso = s:siso_save") |
8749 == FAIL) | 8773 == FAIL) |
8750 failed = TRUE; | 8774 failed = TRUE; |
8751 if (put_line(fd, "doautoall SessionLoadPost") == FAIL) | 8775 if (put_line(fd, "doautoall SessionLoadPost") == FAIL) |
8887 int save_msg_didout = msg_didout; | 8911 int save_msg_didout = msg_didout; |
8888 int save_State = State; | 8912 int save_State = State; |
8889 tasave_T tabuf; | 8913 tasave_T tabuf; |
8890 int save_insertmode = p_im; | 8914 int save_insertmode = p_im; |
8891 int save_finish_op = finish_op; | 8915 int save_finish_op = finish_op; |
8916 int save_opcount = opcount; | |
8892 #ifdef FEAT_MBYTE | 8917 #ifdef FEAT_MBYTE |
8893 char_u *arg = NULL; | 8918 char_u *arg = NULL; |
8894 int l; | 8919 int l; |
8895 char_u *p; | 8920 char_u *p; |
8896 #endif | 8921 #endif |
9014 --ex_normal_busy; | 9039 --ex_normal_busy; |
9015 msg_scroll = save_msg_scroll; | 9040 msg_scroll = save_msg_scroll; |
9016 restart_edit = save_restart_edit; | 9041 restart_edit = save_restart_edit; |
9017 p_im = save_insertmode; | 9042 p_im = save_insertmode; |
9018 finish_op = save_finish_op; | 9043 finish_op = save_finish_op; |
9044 opcount = save_opcount; | |
9019 msg_didout |= save_msg_didout; /* don't reset msg_didout now */ | 9045 msg_didout |= save_msg_didout; /* don't reset msg_didout now */ |
9020 | 9046 |
9021 /* Restore the state (needed when called from a function executed for | 9047 /* Restore the state (needed when called from a function executed for |
9022 * 'indentexpr'). */ | 9048 * 'indentexpr'). */ |
9023 State = save_State; | 9049 State = save_State; |
9276 break; | 9302 break; |
9277 case 'l': cmd = DT_LAST; /* ":tlast" */ | 9303 case 'l': cmd = DT_LAST; /* ":tlast" */ |
9278 break; | 9304 break; |
9279 default: /* ":tag" */ | 9305 default: /* ":tag" */ |
9280 #ifdef FEAT_CSCOPE | 9306 #ifdef FEAT_CSCOPE |
9281 if (p_cst) | 9307 if (p_cst && *eap->arg != NUL) |
9282 { | 9308 { |
9283 do_cstag(eap); | 9309 do_cstag(eap); |
9284 return; | 9310 return; |
9285 } | 9311 } |
9286 #endif | 9312 #endif |
9301 do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1, | 9327 do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1, |
9302 eap->forceit, TRUE); | 9328 eap->forceit, TRUE); |
9303 } | 9329 } |
9304 | 9330 |
9305 /* | 9331 /* |
9306 * Evaluate cmdline variables. | 9332 * Check "str" for starting with a special cmdline variable. |
9307 * | 9333 * If found return one of the SPEC_ values and set "*usedlen" to the length of |
9308 * change '%' to curbuf->b_ffname | 9334 * the variable. Otherwise return -1 and "*usedlen" is unchanged. |
9309 * '#' to curwin->w_altfile | 9335 */ |
9310 * '<cword>' to word under the cursor | 9336 int |
9311 * '<cWORD>' to WORD under the cursor | 9337 find_cmdline_var(src, usedlen) |
9312 * '<cfile>' to path name under the cursor | 9338 char_u *src; |
9313 * '<sfile>' to sourced file name | 9339 int *usedlen; |
9314 * '<afile>' to file name for autocommand | 9340 { |
9315 * '<abuf>' to buffer number for autocommand | 9341 int len; |
9316 * '<amatch>' to matching name for autocommand | |
9317 * | |
9318 * When an error is detected, "errormsg" is set to a non-NULL pointer (may be | |
9319 * "" for error without a message) and NULL is returned. | |
9320 * Returns an allocated string if a valid match was found. | |
9321 * Returns NULL if no match was found. "usedlen" then still contains the | |
9322 * number of characters to skip. | |
9323 */ | |
9324 char_u * | |
9325 eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped) | |
9326 char_u *src; /* pointer into commandline */ | |
9327 char_u *srcstart; /* beginning of valid memory for src */ | |
9328 int *usedlen; /* characters after src that are used */ | |
9329 linenr_T *lnump; /* line number for :e command, or NULL */ | |
9330 char_u **errormsg; /* pointer to error message */ | |
9331 int *escaped; /* return value has escaped white space (can | |
9332 * be NULL) */ | |
9333 { | |
9334 int i; | 9342 int i; |
9335 char_u *s; | 9343 static char *(spec_str[]) = { |
9336 char_u *result; | |
9337 char_u *resultbuf = NULL; | |
9338 int resultlen; | |
9339 buf_T *buf; | |
9340 int valid = VALID_HEAD + VALID_PATH; /* assume valid result */ | |
9341 int spec_idx; | |
9342 #ifdef FEAT_MODIFY_FNAME | |
9343 int skip_mod = FALSE; | |
9344 #endif | |
9345 static char *(spec_str[]) = | |
9346 { | |
9347 "%", | 9344 "%", |
9348 #define SPEC_PERC 0 | 9345 #define SPEC_PERC 0 |
9349 "#", | 9346 "#", |
9350 #define SPEC_HASH 1 | 9347 #define SPEC_HASH 1 |
9351 "<cword>", /* cursor word */ | 9348 "<cword>", /* cursor word */ |
9366 #endif | 9363 #endif |
9367 #ifdef FEAT_CLIENTSERVER | 9364 #ifdef FEAT_CLIENTSERVER |
9368 "<client>" | 9365 "<client>" |
9369 # define SPEC_CLIENT 9 | 9366 # define SPEC_CLIENT 9 |
9370 #endif | 9367 #endif |
9371 }; | 9368 }; |
9372 #define SPEC_COUNT (sizeof(spec_str) / sizeof(char *)) | 9369 #define SPEC_COUNT (sizeof(spec_str) / sizeof(char *)) |
9370 | |
9371 for (i = 0; i < SPEC_COUNT; ++i) | |
9372 { | |
9373 len = (int)STRLEN(spec_str[i]); | |
9374 if (STRNCMP(src, spec_str[i], len) == 0) | |
9375 { | |
9376 *usedlen = len; | |
9377 return i; | |
9378 } | |
9379 } | |
9380 return -1; | |
9381 } | |
9382 | |
9383 /* | |
9384 * Evaluate cmdline variables. | |
9385 * | |
9386 * change '%' to curbuf->b_ffname | |
9387 * '#' to curwin->w_altfile | |
9388 * '<cword>' to word under the cursor | |
9389 * '<cWORD>' to WORD under the cursor | |
9390 * '<cfile>' to path name under the cursor | |
9391 * '<sfile>' to sourced file name | |
9392 * '<afile>' to file name for autocommand | |
9393 * '<abuf>' to buffer number for autocommand | |
9394 * '<amatch>' to matching name for autocommand | |
9395 * | |
9396 * When an error is detected, "errormsg" is set to a non-NULL pointer (may be | |
9397 * "" for error without a message) and NULL is returned. | |
9398 * Returns an allocated string if a valid match was found. | |
9399 * Returns NULL if no match was found. "usedlen" then still contains the | |
9400 * number of characters to skip. | |
9401 */ | |
9402 char_u * | |
9403 eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped) | |
9404 char_u *src; /* pointer into commandline */ | |
9405 char_u *srcstart; /* beginning of valid memory for src */ | |
9406 int *usedlen; /* characters after src that are used */ | |
9407 linenr_T *lnump; /* line number for :e command, or NULL */ | |
9408 char_u **errormsg; /* pointer to error message */ | |
9409 int *escaped; /* return value has escaped white space (can | |
9410 * be NULL) */ | |
9411 { | |
9412 int i; | |
9413 char_u *s; | |
9414 char_u *result; | |
9415 char_u *resultbuf = NULL; | |
9416 int resultlen; | |
9417 buf_T *buf; | |
9418 int valid = VALID_HEAD + VALID_PATH; /* assume valid result */ | |
9419 int spec_idx; | |
9420 #ifdef FEAT_MODIFY_FNAME | |
9421 int skip_mod = FALSE; | |
9422 #endif | |
9373 | 9423 |
9374 #if defined(FEAT_AUTOCMD) || defined(FEAT_CLIENTSERVER) | 9424 #if defined(FEAT_AUTOCMD) || defined(FEAT_CLIENTSERVER) |
9375 char_u strbuf[30]; | 9425 char_u strbuf[30]; |
9376 #endif | 9426 #endif |
9377 | 9427 |
9380 *escaped = FALSE; | 9430 *escaped = FALSE; |
9381 | 9431 |
9382 /* | 9432 /* |
9383 * Check if there is something to do. | 9433 * Check if there is something to do. |
9384 */ | 9434 */ |
9385 for (spec_idx = 0; spec_idx < SPEC_COUNT; ++spec_idx) | 9435 spec_idx = find_cmdline_var(src, usedlen); |
9386 { | 9436 if (spec_idx < 0) /* no match */ |
9387 *usedlen = (int)STRLEN(spec_str[spec_idx]); | |
9388 if (STRNCMP(src, spec_str[spec_idx], *usedlen) == 0) | |
9389 break; | |
9390 } | |
9391 if (spec_idx == SPEC_COUNT) /* no match */ | |
9392 { | 9437 { |
9393 *usedlen = 1; | 9438 *usedlen = 1; |
9394 return NULL; | 9439 return NULL; |
9395 } | 9440 } |
9396 | 9441 |
9399 * Note: In "\\%" the % is also not recognized! | 9444 * Note: In "\\%" the % is also not recognized! |
9400 */ | 9445 */ |
9401 if (src > srcstart && src[-1] == '\\') | 9446 if (src > srcstart && src[-1] == '\\') |
9402 { | 9447 { |
9403 *usedlen = 0; | 9448 *usedlen = 0; |
9404 STRCPY(src - 1, src); /* remove backslash */ | 9449 STRMOVE(src - 1, src); /* remove backslash */ |
9405 return NULL; | 9450 return NULL; |
9406 } | 9451 } |
9407 | 9452 |
9408 /* | 9453 /* |
9409 * word or WORD under cursor | 9454 * word or WORD under cursor |
9499 if (result == NULL) | 9544 if (result == NULL) |
9500 { | 9545 { |
9501 *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\""); | 9546 *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\""); |
9502 return NULL; | 9547 return NULL; |
9503 } | 9548 } |
9549 result = shorten_fname1(result); | |
9504 break; | 9550 break; |
9505 | 9551 |
9506 case SPEC_ABUF: /* buffer number for autocommand */ | 9552 case SPEC_ABUF: /* buffer number for autocommand */ |
9507 if (autocmd_bufnr <= 0) | 9553 if (autocmd_bufnr <= 0) |
9508 { | 9554 { |
9740 char_u *sname; | 9786 char_u *sname; |
9741 win_T *edited_win = NULL; | 9787 win_T *edited_win = NULL; |
9742 int tabnr; | 9788 int tabnr; |
9743 win_T *tab_firstwin; | 9789 win_T *tab_firstwin; |
9744 frame_T *tab_topframe; | 9790 frame_T *tab_topframe; |
9791 int cur_arg_idx = 0; | |
9792 int next_arg_idx = 0; | |
9745 | 9793 |
9746 if (ssop_flags & SSOP_BUFFERS) | 9794 if (ssop_flags & SSOP_BUFFERS) |
9747 only_save_windows = FALSE; /* Save ALL buffers */ | 9795 only_save_windows = FALSE; /* Save ALL buffers */ |
9748 | 9796 |
9749 /* | 9797 /* |
9955 */ | 10003 */ |
9956 for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) | 10004 for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) |
9957 { | 10005 { |
9958 if (!ses_do_win(wp)) | 10006 if (!ses_do_win(wp)) |
9959 continue; | 10007 continue; |
9960 if (put_view(fd, wp, wp != edited_win, &ssop_flags) == FAIL) | 10008 if (put_view(fd, wp, wp != edited_win, &ssop_flags, |
10009 cur_arg_idx) == FAIL) | |
9961 return FAIL; | 10010 return FAIL; |
9962 if (nr > 1 && put_line(fd, "wincmd w") == FAIL) | 10011 if (nr > 1 && put_line(fd, "wincmd w") == FAIL) |
9963 return FAIL; | 10012 return FAIL; |
9964 } | 10013 next_arg_idx = wp->w_arg_idx; |
10014 } | |
10015 | |
10016 /* The argument index in the first tab page is zero, need to set it in | |
10017 * each window. For further tab pages it's the window where we do | |
10018 * "tabedit". */ | |
10019 cur_arg_idx = next_arg_idx; | |
9965 | 10020 |
9966 /* | 10021 /* |
9967 * Restore cursor to the current window if it's not the first one. | 10022 * Restore cursor to the current window if it's not the first one. |
9968 */ | 10023 */ |
9969 if (cnr > 1 && (fprintf(fd, "%dwincmd w", cnr) < 0 | 10024 if (cnr > 1 && (fprintf(fd, "%dwincmd w", cnr) < 0 |
10169 /* | 10224 /* |
10170 * Write commands to "fd" to restore the view of a window. | 10225 * Write commands to "fd" to restore the view of a window. |
10171 * Caller must make sure 'scrolloff' is zero. | 10226 * Caller must make sure 'scrolloff' is zero. |
10172 */ | 10227 */ |
10173 static int | 10228 static int |
10174 put_view(fd, wp, add_edit, flagp) | 10229 put_view(fd, wp, add_edit, flagp, current_arg_idx) |
10175 FILE *fd; | 10230 FILE *fd; |
10176 win_T *wp; | 10231 win_T *wp; |
10177 int add_edit; /* add ":edit" command to view */ | 10232 int add_edit; /* add ":edit" command to view */ |
10178 unsigned *flagp; /* vop_flags or ssop_flags */ | 10233 unsigned *flagp; /* vop_flags or ssop_flags */ |
10234 int current_arg_idx; /* current argument index of the window, use | |
10235 * -1 if unknown */ | |
10179 { | 10236 { |
10180 win_T *save_curwin; | 10237 win_T *save_curwin; |
10181 int f; | 10238 int f; |
10182 int do_cursor; | 10239 int do_cursor; |
10183 int did_next = FALSE; | 10240 int did_next = FALSE; |
10203 return FAIL; | 10260 return FAIL; |
10204 } | 10261 } |
10205 | 10262 |
10206 /* Only when part of a session: restore the argument index. Some | 10263 /* Only when part of a session: restore the argument index. Some |
10207 * arguments may have been deleted, check if the index is valid. */ | 10264 * arguments may have been deleted, check if the index is valid. */ |
10208 if (wp->w_arg_idx != 0 && wp->w_arg_idx <= WARGCOUNT(wp) | 10265 if (wp->w_arg_idx != current_arg_idx && wp->w_arg_idx <= WARGCOUNT(wp) |
10209 && flagp == &ssop_flags) | 10266 && flagp == &ssop_flags) |
10210 { | 10267 { |
10211 if (fprintf(fd, "%ldnext", (long)wp->w_arg_idx) < 0 | 10268 if (fprintf(fd, "%ldargu", (long)wp->w_arg_idx + 1) < 0 |
10212 || put_eol(fd) == FAIL) | 10269 || put_eol(fd) == FAIL) |
10213 return FAIL; | 10270 return FAIL; |
10214 did_next = TRUE; | 10271 did_next = TRUE; |
10215 } | 10272 } |
10216 | 10273 |
10952 /* Execute the command on the marked lines. */ | 11009 /* Execute the command on the marked lines. */ |
10953 global_exe(eap->arg); | 11010 global_exe(eap->arg); |
10954 ml_clearmarked(); /* clear rest of the marks */ | 11011 ml_clearmarked(); /* clear rest of the marks */ |
10955 } | 11012 } |
10956 #endif | 11013 #endif |
10957 | |
10958 | |
10959 /* | |
10960 * REP: Remote Editor's Ex commands | |
10961 */ | |
10962 /* start REP mode */ | |
10963 static void | |
10964 ex_repstart(eap) | |
10965 exarg_T *eap; | |
10966 { | |
10967 if (curbuf->b_sfname == NULL) { | |
10968 MSG(_("[REP MODE] start without file")); | |
10969 if (rep_join() == FALSE) { | |
10970 rep_end(); | |
10971 } | |
10972 } else { | |
10973 MSG(_("[REP MODE] start with file")); | |
10974 if (rep_put(curbuf->b_sfname) == FALSE) { | |
10975 rep_end(); | |
10976 } | |
10977 } | |
10978 } | |
10979 | |
10980 /* end REP mode */ | |
10981 static void | |
10982 ex_repend(eap) | |
10983 exarg_T *eap; | |
10984 { | |
10985 MSG(_("[REP MODE] end")); | |
10986 rep_end(); | |
10987 } |