Mercurial > vim
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(®match, curwin, curbuf, lnum, (colnr_T)0); | 4692 match = vim_regexec_multi(®match, 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 |