: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? :)