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 }