comparison src/ex_cmds.c @ 170:8c60f65311fa v7.0052

updated for version 7.0052
author vimboss
date Sat, 26 Feb 2005 23:04:13 +0000
parents 0e902b8f511f
children 906b37d2f9c3
comparison
equal deleted inserted replaced
169:0e902b8f511f 170:8c60f65311fa
28 static int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int other)); 28 static int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int other));
29 static int check_readonly __ARGS((int *forceit, buf_T *buf)); 29 static int check_readonly __ARGS((int *forceit, buf_T *buf));
30 #ifdef FEAT_AUTOCMD 30 #ifdef FEAT_AUTOCMD
31 static void delbuf_msg __ARGS((char_u *name)); 31 static void delbuf_msg __ARGS((char_u *name));
32 #endif 32 #endif
33 static int do_sub_msg __ARGS((void)); 33 static int do_sub_msg __ARGS((int count_only));
34 static int 34 static int
35 #ifdef __BORLANDC__ 35 #ifdef __BORLANDC__
36 _RTLENTRYF 36 _RTLENTRYF
37 #endif 37 #endif
38 help_compare __ARGS((const void *s1, const void *s2)); 38 help_compare __ARGS((const void *s1, const void *s2));
3659 linenr_T lnum; 3659 linenr_T lnum;
3660 long i = 0; 3660 long i = 0;
3661 regmmatch_T regmatch; 3661 regmmatch_T regmatch;
3662 static int do_all = FALSE; /* do multiple substitutions per line */ 3662 static int do_all = FALSE; /* do multiple substitutions per line */
3663 static int do_ask = FALSE; /* ask for confirmation */ 3663 static int do_ask = FALSE; /* ask for confirmation */
3664 static int do_count = FALSE; /* count only */
3664 static int do_error = TRUE; /* if false, ignore errors */ 3665 static int do_error = TRUE; /* if false, ignore errors */
3665 static int do_print = FALSE; /* print last line with subs. */ 3666 static int do_print = FALSE; /* print last line with subs. */
3666 static int do_list = FALSE; /* list last line with subs. */ 3667 static int do_list = FALSE; /* list last line with subs. */
3667 static int do_number = FALSE; /* list last line with line nr*/ 3668 static int do_number = FALSE; /* list last line with line nr*/
3668 static int do_ic = 0; /* ignore case flag */ 3669 static int do_ic = 0; /* ignore case flag */
3682 linenr_T line2; 3683 linenr_T line2;
3683 long nmatch; /* number of lines in match */ 3684 long nmatch; /* number of lines in match */
3684 linenr_T sub_firstlnum; /* nr of first sub line */ 3685 linenr_T sub_firstlnum; /* nr of first sub line */
3685 char_u *sub_firstline; /* allocated copy of first sub line */ 3686 char_u *sub_firstline; /* allocated copy of first sub line */
3686 int endcolumn = FALSE; /* cursor in last column when done */ 3687 int endcolumn = FALSE; /* cursor in last column when done */
3688 pos_T old_cursor = curwin->w_cursor;
3687 3689
3688 cmd = eap->arg; 3690 cmd = eap->arg;
3689 if (!global_busy) 3691 if (!global_busy)
3690 { 3692 {
3691 sub_nsubs = 0; 3693 sub_nsubs = 0;
3820 */ 3822 */
3821 if (*cmd == 'g') 3823 if (*cmd == 'g')
3822 do_all = !do_all; 3824 do_all = !do_all;
3823 else if (*cmd == 'c') 3825 else if (*cmd == 'c')
3824 do_ask = !do_ask; 3826 do_ask = !do_ask;
3827 else if (*cmd == 'n')
3828 do_count = TRUE;
3825 else if (*cmd == 'e') 3829 else if (*cmd == 'e')
3826 do_error = !do_error; 3830 do_error = !do_error;
3827 else if (*cmd == 'r') /* use last used regexp */ 3831 else if (*cmd == 'r') /* use last used regexp */
3828 which_pat = RE_LAST; 3832 which_pat = RE_LAST;
3829 else if (*cmd == 'p') 3833 else if (*cmd == 'p')
3844 do_ic = 'I'; 3848 do_ic = 'I';
3845 else 3849 else
3846 break; 3850 break;
3847 ++cmd; 3851 ++cmd;
3848 } 3852 }
3853 if (do_count)
3854 do_ask = FALSE;
3849 3855
3850 /* 3856 /*
3851 * check for a trailing count 3857 * check for a trailing count
3852 */ 3858 */
3853 cmd = skipwhite(cmd); 3859 cmd = skipwhite(cmd);
4028 * previous match. */ 4034 * previous match. */
4029 matchcol = regmatch.endpos[0].col; 4035 matchcol = regmatch.endpos[0].col;
4030 prev_matchcol = matchcol; 4036 prev_matchcol = matchcol;
4031 4037
4032 /* 4038 /*
4033 * 2. If do_ask is set, ask for confirmation. 4039 * 2. If do_count is set only increase the counter.
4040 * If do_ask is set, ask for confirmation.
4034 */ 4041 */
4042 if (do_count)
4043 {
4044 /* For a multi-line match, put matchcol at the NUL at
4045 * the end of the line and set nmatch to one, so that
4046 * we continue looking for a match on the next line.
4047 * Avoids that ":s/\nB\@=//gc" get stuck. */
4048 if (nmatch > 1)
4049 {
4050 matchcol = STRLEN(sub_firstline);
4051 nmatch = 1;
4052 }
4053 sub_nsubs++;
4054 did_sub = TRUE;
4055 goto skip;
4056 }
4057
4035 if (do_ask) 4058 if (do_ask)
4036 { 4059 {
4037 /* change State to CONFIRM, so that the mouse works 4060 /* change State to CONFIRM, so that the mouse works
4038 * properly */ 4061 * properly */
4039 save_State = State; 4062 save_State = State;
4062 4085
4063 getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL); 4086 getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
4064 curwin->w_cursor.col = regmatch.endpos[0].col - 1; 4087 curwin->w_cursor.col = regmatch.endpos[0].col - 1;
4065 getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec); 4088 getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
4066 msg_start(); 4089 msg_start();
4067 for (i = 0; i < sc; ++i) 4090 for (i = 0; i < (long)sc; ++i)
4068 msg_putchar(' '); 4091 msg_putchar(' ');
4069 for ( ; i <= ec; ++i) 4092 for ( ; i <= (long)ec; ++i)
4070 msg_putchar('^'); 4093 msg_putchar('^');
4071 4094
4072 resp = getexmodeline('?', NULL, 0); 4095 resp = getexmodeline('?', NULL, 0);
4073 if (resp != NULL) 4096 if (resp != NULL)
4074 { 4097 {
4456 changed_lines(first_line, 0, last_line - i, i); 4479 changed_lines(first_line, 0, last_line - i, i);
4457 } 4480 }
4458 4481
4459 outofmem: 4482 outofmem:
4460 vim_free(sub_firstline); /* may have to free allocated copy of the line */ 4483 vim_free(sub_firstline); /* may have to free allocated copy of the line */
4484
4485 /* ":s/pat//n" doesn't move the cursor */
4486 if (do_count)
4487 curwin->w_cursor = old_cursor;
4488
4461 if (sub_nsubs) 4489 if (sub_nsubs)
4462 { 4490 {
4463 /* Set the '[ and '] marks. */ 4491 /* Set the '[ and '] marks. */
4464 curbuf->b_op_start.lnum = eap->line1; 4492 curbuf->b_op_start.lnum = eap->line1;
4465 curbuf->b_op_end.lnum = line2; 4493 curbuf->b_op_end.lnum = line2;
4469 { 4497 {
4470 if (endcolumn) 4498 if (endcolumn)
4471 coladvance((colnr_T)MAXCOL); 4499 coladvance((colnr_T)MAXCOL);
4472 else 4500 else
4473 beginline(BL_WHITE | BL_FIX); 4501 beginline(BL_WHITE | BL_FIX);
4474 if (!do_sub_msg() && do_ask) 4502 if (!do_sub_msg(do_count) && do_ask)
4475 MSG(""); 4503 MSG("");
4476 } 4504 }
4477 else 4505 else
4478 global_need_beginline = TRUE; 4506 global_need_beginline = TRUE;
4479 if (do_print) 4507 if (do_print)
4496 * Give message for number of substitutions. 4524 * Give message for number of substitutions.
4497 * Can also be used after a ":global" command. 4525 * Can also be used after a ":global" command.
4498 * Return TRUE if a message was given. 4526 * Return TRUE if a message was given.
4499 */ 4527 */
4500 static int 4528 static int
4501 do_sub_msg() 4529 do_sub_msg(count_only)
4530 int count_only; /* used 'n' flag for ":s" */
4502 { 4531 {
4503 /* 4532 /*
4504 * Only report substitutions when: 4533 * Only report substitutions when:
4505 * - more than 'report' substitutions 4534 * - more than 'report' substitutions
4506 * - command was typed by user, or number of changed lines > 'report' 4535 * - command was typed by user, or number of changed lines > 'report'
4507 * - giving messages is not disabled by 'lazyredraw' 4536 * - giving messages is not disabled by 'lazyredraw'
4508 */ 4537 */
4509 if (sub_nsubs > p_report 4538 if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
4510 && (KeyTyped || sub_nlines > 1 || p_report < 1) 4539 || count_only)
4511 && messaging()) 4540 && messaging())
4512 { 4541 {
4513 if (got_int) 4542 if (got_int)
4514 STRCPY(msg_buf, _("(Interrupted) ")); 4543 STRCPY(msg_buf, _("(Interrupted) "));
4515 else 4544 else
4516 msg_buf[0] = NUL; 4545 msg_buf[0] = NUL;
4517 if (sub_nsubs == 1) 4546 if (sub_nsubs == 1)
4518 STRCAT(msg_buf, _("1 substitution")); 4547 STRCAT(msg_buf, count_only ? _("1 match") : _("1 substitution"));
4519 else 4548 else
4520 sprintf((char *)msg_buf + STRLEN(msg_buf), _("%ld substitutions"), 4549 sprintf((char *)msg_buf + STRLEN(msg_buf),
4550 count_only ? _("%ld matches") : _("%ld substitutions"),
4521 sub_nsubs); 4551 sub_nsubs);
4522 if (sub_nlines == 1) 4552 if (sub_nlines == 1)
4523 STRCAT(msg_buf, _(" on 1 line")); 4553 STRCAT(msg_buf, _(" on 1 line"));
4524 else 4554 else
4525 sprintf((char *)msg_buf + STRLEN(msg_buf), _(" on %ld lines"), 4555 sprintf((char *)msg_buf + STRLEN(msg_buf), _(" on %ld lines"),
4559 void 4589 void
4560 ex_global(eap) 4590 ex_global(eap)
4561 exarg_T *eap; 4591 exarg_T *eap;
4562 { 4592 {
4563 linenr_T lnum; /* line number according to old situation */ 4593 linenr_T lnum; /* line number according to old situation */
4564 int ndone; 4594 int ndone = 0;
4565 int type; /* first char of cmd: 'v' or 'g' */ 4595 int type; /* first char of cmd: 'v' or 'g' */
4566 char_u *cmd; /* command argument */ 4596 char_u *cmd; /* command argument */
4567 4597
4568 char_u delim; /* delimiter, normally '/' */ 4598 char_u delim; /* delimiter, normally '/' */
4569 char_u *pat; 4599 char_u *pat;
4631 { 4661 {
4632 EMSG(_(e_invcmd)); 4662 EMSG(_(e_invcmd));
4633 return; 4663 return;
4634 } 4664 }
4635 4665
4666 #ifdef HAVE_SETJMP_H
4667 /*
4668 * Matching with a regexp may cause a very deep recursive call of
4669 * regmatch(). Vim will crash when running out of stack space.
4670 * Catch this here if the system supports it.
4671 * It's a bit slow, thus do it outside of the loop.
4672 */
4673 mch_startjmp();
4674 if (SETJMP(lc_jump_env) != 0)
4675 {
4676 mch_didjmp();
4677 # ifdef SIGHASARG
4678 if (lc_signal != SIGINT)
4679 # endif
4680 EMSG(_(e_complex));
4681 got_int = TRUE;
4682 goto jumpend;
4683 }
4684 #endif
4685
4636 /* 4686 /*
4637 * pass 1: set marks for each (not) matching line 4687 * pass 1: set marks for each (not) matching line
4638 */ 4688 */
4639 ndone = 0;
4640 for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum) 4689 for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum)
4641 { 4690 {
4642 /* a match on this line? */ 4691 /* a match on this line? */
4643 match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0); 4692 match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
4644 if ((type == 'g' && match) || (type == 'v' && !match)) 4693 if ((type == 'g' && match) || (type == 'v' && !match))
4646 ml_setmarked(lnum); 4695 ml_setmarked(lnum);
4647 ndone++; 4696 ndone++;
4648 } 4697 }
4649 line_breakcheck(); 4698 line_breakcheck();
4650 } 4699 }
4700
4701 #ifdef HAVE_SETJMP_H
4702 jumpend:
4703 mch_endjmp();
4704 #endif
4651 4705
4652 /* 4706 /*
4653 * pass 2: execute the command for each line that has been marked 4707 * pass 2: execute the command for each line that has been marked
4654 */ 4708 */
4655 if (got_int) 4709 if (got_int)
4717 if (msg_col == 0 && msg_scrolled == 0) 4771 if (msg_col == 0 && msg_scrolled == 0)
4718 msg_didout = FALSE; 4772 msg_didout = FALSE;
4719 4773
4720 /* If subsitutes done, report number of substitues, otherwise report 4774 /* If subsitutes done, report number of substitues, otherwise report
4721 * number of extra or deleted lines. */ 4775 * number of extra or deleted lines. */
4722 if (!do_sub_msg()) 4776 if (!do_sub_msg(FALSE))
4723 msgmore(curbuf->b_ml.ml_line_count - old_lcount); 4777 msgmore(curbuf->b_ml.ml_line_count - old_lcount);
4724 } 4778 }
4725 4779
4726 #ifdef FEAT_VIMINFO 4780 #ifdef FEAT_VIMINFO
4727 int 4781 int