Background task
To eliminate X-Y problems I'll say what I'm doing: I'm trying to use :perldo
in VIM 7.2 to complete two tasks:
- Clear all trailing whitespace, including (clearing not deleting) lines that only have whitespace
s/\s+$//;
- Remove non-tab whitespace that exists before the first-non space character
s/^ (\s*) (?=\S) / s#[^\t]##g;$_ /xe;
I'd like to do this all with one pass. Currently, using :perldo
, I can get this working with two passes. (by using :perldo twice)
The command should look like this:
:perldo s/\s+$//; s/^ (\s*) (?=\S) / s#[^\t]##g;$_ /xe;
Perl background
In order to understand this problem you must know a little bit about Perl s///
automagically binds to the default variable $_
which the regex is free to modify. Most core functions operate on $_
by default.
perl -e'$_="foo"; s/foo/bar/; s/bar/baz/; print'
# will print baz
The assumption is that you can chain expressions using :perldo
in VIM and that it will work logically.
VIM not being nice
Now my VIM problem is better demonstrated with code -- I've reduced it to a simple test. Open a new buffer place the following text into it:
aa bb
aa
bb
Now run this :perldo s/a/z/; s/b/z/;
The buffer now has:
za zb
aa
zb
Why was the first regex unsu开发者_运维知识库ccessful on the second row, and yet the second regex was successful by itself, and on the first row?
It appears the whole Perl expression you pass to :perldo
must return a true / defined value, or the results are discarded, per-line.
Try this, nothing happens on any line:
:perldo s/a/z/; s/b/z/; 0
Try this, it works on all 3 lines as expected:
:perldo s/a/z/; s/b/z; 1
An example in the :perldo
documentation hints at this:
:perldo $_ = reverse($_);1
but unfortunately it doesn't say explicitly what's going on.
Don't know what :perldo
is doing exactly, but if you run something like
:perldo s/a/z/+s/b/z/
then you get something more like you'd expect.
Seems to me like only the last command is run on all lines in [range].
精彩评论