...making Linux just a little more fun!

<-- 2c Tips | TAG Index | 1 | 2 | 3 | 4 | Knowledge Base | News Bytes -->

The Answer Gang

By Jim Dennis, Karl-Heinz Herrmann, Breen, Chris, and... (meet the Gang) ... the Editors of Linux Gazette... and You!



(?) Automatically selecting matched lines.

From Thomas Adam

Answered By: Tim Chase

This is a question that I posted to the Vim mailing-list. Tim Chase was kind enough to reply, and in some detail, so it ends up here. Thanks, Tim! :) -- Thomas Adam

Hello, all -

I'm trying to get Vim to automatically select (hilight) lines in a file that start with a particular phrase. Basically, I want it then to run a command over the selected text. Doing this manually is not a problem, but I am having a lot of trouble trying to automate it.

I was under the impression that "V%" is what I was after, yet each time I try it, Vim responds with: "V% is not an editor command". I'm overlooking something, but what?

(!) [Tim] I don't think Vim supports disjoint selecting like what I understand you want to do...in a single pass. However, each disjoint piece can be passed to your external program if you want. Perhaps something like:
:g/^\s*\n>/+,/^>\@!/-1! extern_command
Broken down, that's:
:g on every line that matches

^\s*\n> an empty line followed by a ">" on the next line

+ begin a range on the next line (the one with the ">")
, through

/^>\@!/ the next line that doesn't begin with a ">"

-1 adjust the 2nd range argument to be the previous line
because the previous search found the next line that
doesn't have a leading ">" so we have to backup a line

! pass the contents of the range through
external_command and replace the original contents with the
output of "external_command"

Thus, if you wanted to make your quotations in the mail-file all
sound like B1FF (assuming you have the bsd-games collection
installed), you could do

:g/^\s*\n>/+,/^>\@!/-1! b1ff
Any Ex command can take the place of "! b1ff" there, so if you just want to do normal Vi/Ex commands instead, they all work. If you want to indent those ranges one shift-width, you can do
:g/^\s*\n>/+,/^>\@!/-1>
Or if you want to delete all quotations, you can do
:g/^\s*\n>/+,/^>\@!/-1d
You can even selectively search and replace only in quotations with something like
:g/^\s*\n>/+,/^>\@!/-1 s/foo/bar/g
All sorts of handy combinations of things.
Or maybe I didn't understand your original post correctly, and all this is just a pedantic exercise in the joy of Ex ;)

This page edited and maintained by the Editors of Linux Gazette
HTML script maintained by Heather Stern of Starshine Technical Services, http://www.starshine.org/


Each TAG thread Copyright © its authors, 2004

Published in issue 108 of Linux Gazette November 2004

<-- 2c Tips | TAG Index | 1 | 2 | 3 | 4 | Knowledge Base | News Bytes -->
Tux