Tuesday, June 18, 2013

Re: g[lobal] with s[ubstitute]

diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -635,6 +635,12 @@
compiled without the |+insert_expand| feature}
CTRL-Y to scroll the screen down {not in Vi, not available when
compiled without the |+insert_expand| feature}
+ 'Q' to quit substituting for all invocations of :s in a :g
+ command (only when inside a :g command) {not in Vi}
+ 'A' to substitute all matches for all invocations of :s
+ in a :g command (only when inside a :g command) {not
+ in Vi}
+ '?' to display a small help banner {not in Vi}
If the 'edcompatible' option is on, Vim remembers the [c] flag and
toggles it each time you use it, but resets it when you give a new
search pattern.
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4384,6 +4384,7 @@
{
sub_nsubs = 0;
sub_nlines = 0;
+ global_do_ask = TRUE;
}
start_nsubs = sub_nsubs;

@@ -4811,7 +4812,7 @@
/*
* Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
*/
- while (do_ask)
+ while (do_ask && global_do_ask)
{
if (exmode_active)
{
@@ -4898,25 +4899,29 @@
#ifdef FEAT_FOLDING
curwin->w_p_fen = save_p_fen;
#endif
- if (msg_row == Rows - 1)
- msg_didout = FALSE; /* avoid a scroll-up */
- msg_starthere();
- i = msg_scroll;
- msg_scroll = 0; /* truncate msg when
- needed */
- msg_no_more = TRUE;
- /* write message same highlighting as for
- * wait_return */
- smsg_attr(hl_attr(HLF_R),
- (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
- msg_no_more = FALSE;
- msg_scroll = i;
- showruler(TRUE);
- windgoto(msg_row, msg_col);
- RedrawingDisabled = temp;
+ if (msg_row == Rows - 1)
+ msg_didout = FALSE; /* avoid a scroll-up */
+ msg_starthere();
+ i = msg_scroll;
+ msg_scroll = 0; /* truncate msg when
+ needed */
+ msg_no_more = TRUE;
+ /* write message same highlighting as for
+ * wait_return */
+ if (global_busy)
+ smsg_attr(hl_attr(HLF_R),
+ (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y/Q/A/?)?"), sub);
+ else
+ smsg_attr(hl_attr(HLF_R),
+ (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y/?)?"), sub);
+ msg_no_more = FALSE;
+ msg_scroll = i;
+ showruler(TRUE);
+ windgoto(msg_row, msg_col);
+ RedrawingDisabled = temp;

#ifdef USE_ON_FLY_SCROLL
- dont_scroll = FALSE; /* allow scrolling here */
+ dont_scroll = FALSE; /* allow scrolling here */
#endif
++no_mapping; /* don't map this key */
++allow_keys; /* allow special keys */
@@ -4933,14 +4938,41 @@
if (orig_line != NULL)
ml_replace(lnum, orig_line, FALSE);
}
+ if (typed == '?')
+ {
+ int need_wait_return_save = need_wait_return;
+ int no_wait_return_save = no_wait_return;
+
+ msg_starthere();
+ MSG_PUTS((char_u *)"y\t- substitute this match\n");
+ MSG_PUTS((char_u *)"n\t- skip this match\n");
+ MSG_PUTS((char_u *)"l\t- substitute this match and quit\n");
+ MSG_PUTS((char_u *)"a\t- substitute this match and all remaining\n");
+ MSG_PUTS((char_u *)"q\t- quit\n");
+ MSG_PUTS((char_u *)"<C-E>\t- scroll screen up\n");
+ MSG_PUTS((char_u *)"<C-Y>\t- scroll screen down\n");
+ if (global_busy)
+ {
+ MSG_PUTS((char_u *)"A\t- substitute all matches globally (on all :g matches)\n");
+ MSG_PUTS((char_u *)"Q\t- quit globally (on all :g matches)\n");
+ }
+ need_wait_return = TRUE;
+ no_wait_return = FALSE;
+ msg_end();
+ need_wait_return = need_wait_return_save;
+ no_wait_return = no_wait_return_save;
+ }

need_wait_return = FALSE; /* no hit-return prompt */
if (typed == 'q' || typed == ESC || typed == Ctrl_C
+ || (typed == 'Q' && global_busy)
#ifdef UNIX
|| typed == intr_char
#endif
)
{
+ if (typed == 'Q')
+ ++global_busy; /* break :g command */
got_quit = TRUE;
break;
}
@@ -4955,6 +4987,12 @@
line2 = lnum;
break;
}
+ if (typed == 'A' && global_busy)
+ {
+ if (global_busy)
+ global_do_ask = FALSE;
+ break;
+ }
if (typed == 'a')
{
do_ask = FALSE;
@@ -5448,6 +5486,7 @@
type = *eap->cmd;
cmd = eap->arg;
which_pat = RE_LAST; /* default: use last used regexp */
+ global_do_ask = TRUE; /* for a :s command with c flag */

/*
* undocumented vi feature:
@@ -5529,6 +5568,7 @@

ml_clearmarked(); /* clear rest of the marks */
vim_regfree(regmatch.regprog);
+ global_do_ask = TRUE; /* reset flag */
}

/*
diff --git a/src/globals.h b/src/globals.h
--- a/src/globals.h
+++ b/src/globals.h
@@ -1197,6 +1197,7 @@
*/
EXTERN long sub_nsubs; /* total number of substitutions */
EXTERN linenr_T sub_nlines; /* total number of lines changed */
+EXTERN int global_do_ask INIT(= TRUE); /* c flag for :s command */

/* table to store parsed 'wildmode' */
EXTERN char_u wim_flags[4];
Hi Tim!

On Di, 18 Jun 2013, Tim Chase wrote:

> On 2013-06-18 09:46, Christian Brabandt wrote:
> > On Mon, June 17, 2013 01:12, Bee wrote:
> > > Also if I use 'a' to replace all, search/replace does not exit,
> > > again needing ^C.
> > >
> > > :g/}/s/;/; /gc
> >
> > So basically, you need to "quit"/"all" for each line again.
> >
> > Here is a patch, that makes "q" abort for all invocations of :s
> > commands commands when used in conjuction with :g and 'a' work
> > across all invocations of ':s' commands when using :g
>
> I'm not sure Bram would except this, as it does break traditional
> behavior. Granted, *MOST* of the time, your patch does what I want.
> However, there have been times that I've wanted to have selective
> control for a given block:
>
> :g/Henry/'{;'}s/William/Mary/gc
>
> where I want to review whether this particular paragraph containing
> "Henry" is one in which I want to do the substitutions, in which case
> I either do or don't want to do all the substitutions in the
> paragraph. Your patch breaks that.
>
> I think I'd prefer it as an extra response to the confirmation:
>
> :g/foo/s/bar/baz/gc
> ...
> replace with baz (y/n/a/A/q/Q/l/^E/^Y)?
>
> where "Q" would quit globally like your patch does while "q" would
> just quit for this invocation of :s and "A" would answer "All"
> globally, while the "a" would do all of the replacements for the
> current invocation. Ideally, this prompt would be dynamically created
> so that the "A" and "Q" options only show up in the event we're
> nested inside a :g command; if not inside a :g command then the
> prompt remains as it currently is. From my quick testing here, Vim
> ignores the capital letters when replying to this question, so it's
> not like the new uses would mask behavior someone might have been
> using.

Attached is an updated patch, implementing your suggestions, as well as
a hit '?' to show a help banner.

Bram, if this gets merged, I think it makes sense to also merge the 'u'
flag for undo the last substitution (that I have posted a while ago).

regards,
Christian

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment