On Do, 27 Aug 2015, Gary Johnson wrote:
> On 2015-08-27, Christian Brabandt wrote:
> > Hi Quinn!
> >
> > On Do, 27 Aug 2015, Quinn Strahl wrote:
> >
> > > I was just reminded of another little grievance I have with
> > > :g/^/norm -- it sets the last search pattern to /^/, a very
> > > unintended side-effect.
> >
> > But that is what :g is for.
>
> Yes, but Quinn's point is that it wouldn't be necessary to use :g
> and a dummy pattern if :normal worked the way that :g does, that is,
> if ":{range}normal {commands}" first marked the lines in {range},
> then went back and executed {commands} on those marked lines.
Okay, I can understand that. So here is a patch.
It is a little bit tricky, since if you simply mark the lines while a :g
command is running, this would cancel your :g command (because we need
to clear the marks once the :normal is done). So here is an approach,
that only marks the lines, if no :g command is running, else we fall
back to the old behaviour.
E.g. for this file
1
2
This is a bit a silly example, but it explains my point:
:g/^/1,2norm! yyp
will still behave like the old behaviour (since we can't mark the lines,
as then after the :norm! finishes all marks for the :g would be gone)
e.g. result in:
1
1
1
1
1
2
But :g/^/norm yyp and :%norm! yyp will result in
1
1
2
2
Included in the patch is a test and updated documentation.
Best
Christian
--
Stilblüten aus Schreiben von Versicherungsnehmern:
Der Unfall ist dadurch entstanden, daß der Volkswagen weiterfuhr. Er
mußte verfolgt werden, ehe er schließlich anhielt. Als wir ihm eine
Tracht Prügel verabreichten, geschah es.
--
--
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -214,9 +214,12 @@ 8g8 Find an illegal UTF-8 byte sequenc
:{range}norm[al][!] {commands} *:normal-range*
Execute Normal mode commands {commands} for each line
in the {range}. Before executing the {commands}, the
- cursor is positioned in the first column of the range,
- for each line. Otherwise it's the same as the
- ":normal" command without a range.
+ lines in the range will be marked (similar to how the
+ |:global| command works) unless a |:g| command is active
+ and the cursor is positioned on each marked line in
+ the first column of the range.
+ Otherwise it's the same as the ":normal" command
+ without a range.
{not in Vi}
{not available when |+ex_extra| feature was disabled
at compile time}
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -9967,6 +9967,7 @@ ex_normal(eap)
int save_insertmode = p_im;
int save_finish_op = finish_op;
int save_opcount = opcount;
+ linenr_T lnum = 0;
#ifdef FEAT_MBYTE
char_u *arg = NULL;
int l;
@@ -10066,21 +10067,39 @@ ex_normal(eap)
* range given, execute it just once, without positioning the cursor
* first.
*/
+ if (eap->addr_count != 0 && !global_busy)
+ {
+ /* mark the lines on which to act */
+ for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
+ ml_setmarked(lnum);
+ }
+
do
{
if (eap->addr_count != 0)
{
- curwin->w_cursor.lnum = eap->line1++;
+ /* do not mark the lines, if called from :global */
+ if (!global_busy)
+ lnum = ml_firstmarked();
+ else
+ /* go line by line */
+ lnum = eap->line1++;
+ if (lnum == 0)
+ break;
+ curwin->w_cursor.lnum = lnum;
curwin->w_cursor.col = 0;
}
-
exec_normal_cmd(
#ifdef FEAT_MBYTE
arg != NULL ? arg :
#endif
eap->arg, eap->forceit ? REMAP_NONE : REMAP_YES, FALSE);
}
- while (eap->addr_count > 0 && eap->line1 <= eap->line2 && !got_int);
+ while (!got_int && (eap->addr_count > 0 && eap->line1 <= eap->line2));
+
+ /* clear rest of the marks */
+ if (!global_busy)
+ ml_clearmarked();
}
/* Might not return to the main loop when in an event handler. */
diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak
--- a/src/testdir/Make_amiga.mak
+++ b/src/testdir/Make_amiga.mak
@@ -57,6 +57,7 @@ SCRIPTS = test1.out test3.out test4.out
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
+ test_normal.out \
test_options.out \
test_perl.out \
test_qf_title.out \
diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -56,6 +56,7 @@ SCRIPTS = test3.out test4.out test5.out
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
+ test_normal.out \
test_options.out \
test_perl.out \
test_qf_title.out \
diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -78,6 +78,7 @@ SCRIPTS = test3.out test4.out test5.out
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
+ test_normal.out \
test_options.out \
test_perl.out \
test_qf_title.out \
diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak
--- a/src/testdir/Make_os2.mak
+++ b/src/testdir/Make_os2.mak
@@ -58,6 +58,7 @@ SCRIPTS = test1.out test3.out test4.out
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
+ test_normal.out \
test_options.out \
test_perl.out \
test_qf_title.out \
diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -117,6 +117,7 @@ SCRIPT = test1.out test2.out test3.out
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
+ test_normal.out \
test_options.out \
test_perl.out \
test_qf_title.out \
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -54,6 +54,7 @@ SCRIPTS = test1.out test2.out test3.out
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
+ test_normal.out \
test_options.out \
test_perl.out \
test_qf_title.out \
diff --git a/src/testdir/test_normal.in b/src/testdir/test_normal.in
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_normal.in
@@ -0,0 +1,30 @@
+Test for using :g together with :normal
+
+STARTTEST
+:so small.vim
+:if !has("eval") | e! test.ok | w! test.out | qa! | endif
+:/^Start Test1$/,/^End Test1$/g/^\d/norm! yyp
+:/^Start Test2$/+,/^End Test2$/-norm! yyp
+:/^Start Test1/,$wq! test.out
+ENDTEST
+
+Start Test1
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+End Test1
+
+Start Test2
+a
+b
+c
+d
+e
+End Test2
diff --git a/src/testdir/test_normal.ok b/src/testdir/test_normal.ok
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_normal.ok
@@ -0,0 +1,35 @@
+Start Test1
+1
+1
+2
+2
+3
+3
+4
+4
+5
+5
+6
+6
+7
+7
+8
+8
+9
+9
+10
+10
+End Test1
+
+Start Test2
+a
+a
+b
+b
+c
+c
+d
+d
+e
+e
+End Test2