开发者

VIM 7.2 Scripting problem with `:perldo` and multiple expressions

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].

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜