:g/^\s\{8}/-s/^\(.\{8}\).*\n\zs\s\{8}/\1

I don't understand that regex completely - but it deletes
lines of data :-)

Looks like it globably matches the 'blank start' lines, then
searches in that for the pattern - thus deleting the third
line...

That's really odd...the "\zs" *should* be forcing the substitute
to start on the "next" line.  I suspect I've stumbled across an
odd bug?  Switching it to the following

  :g/^\s\{8}/-s/^\(.\{8}\)\(.*\n\)\s\{8}/\1\2\1

worked, though in theory *should* be the same sort of thing. It's also much shorter and more readable than the "\=" version I sent second.

What's the -s do as compared to just s after the g/pattern/

The -s is a range/offset ("-", which is the same as "-1", meaning "back one line") and the command ("s"ubstitute).

For your bedtime reading, they break down as

:g          on every line
/^\s\{8}/   starting with 8 whitespace characters
-           go to the previous line
s/          and substitute
^             from the beginning of the line
\(.\{8}\)     make note of 8 "whatever"s as "\1"

==========[non-working]========
.*            and skip the rest of the line
\n            and a newline
\zs           and start the replacement here
              treating everything before the \zs as
              merely required context
==========[working]============
\(.*\n\)      make note of the rest of the line as "\2"
===============================

\s\{8}     the 8 whitespace characters we want to replace


The replacement in the first [non-working] *should* simply be the thing we tagged as \1. In the second [working] version, the replacement is "the first tagged thing followed by the second tagged thing (namely, the whole previous line remains untouched) followed by the first thing tagged thing again"

> :g/^\s\+/k a|?^\S?y|'a|s/^\s\+/\=strpart(@", 0, strlen(submatch(0)))


That works....  dunno what it does... but that works.... :-)

I'm going to record that little gem, and put it aside for a bedtime puzzle I think.

It helps to break it at the pipes :)

:g/^\s\+       on lines beginning with some whitespace
k a            mark that line as "a"
|              and
?^\S?          search backwards for a line beginning w/ non-ws
y              yanking that line into the scratch register
|              and
'a             jump back to the "a" mark we placed earlier
|              and
s/             do a substitute
^\s\+          of the leading whitespace[*]
/              with
\=             the results of this expression
strpart(           a piece of
@",                the stuff we yanked previously
0,                 starting at the beginning
strlen(            and running for the length of
submatch(0)        the whitespace[*] we're replacing
))

It's a bit terse to say the least, and has slightly odd behaviors if you have staircased indentation like

first line
    second line
         third line

where you'll end up with

first line
firssecond line
firsseconthird line

I'm glad they should save you oodles of time...that's one of the great things about Vim :)

-tim
(is this email a sign I need to get a life? :)


Reply via email to