Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 unsuccessful on the second row, and yet the second regex was successful by itself, and on the first row?

like image 674
NO WAR WITH RUSSIA Avatar asked Feb 01 '10 20:02

NO WAR WITH RUSSIA


2 Answers

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.

like image 107
Brian Carper Avatar answered Nov 03 '22 08:11

Brian Carper


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.

like image 5
mob Avatar answered Nov 03 '22 07:11

mob