[comp.unix.questions] thanks for prepend answers, forwarding a Vi macro

daniel@island.uu.net (Dan Smith "fast screens, loud music, slow car") (07/15/90)

	I got a lot of good answers for my question about prepending
a line globally in Vi.  Thanks to everyone!  The best answers were
perl in nature :-)  It's obvious there's a need for a tool that would
interactively allow one to browse an ls-lR from another site, pick out
items of interest, and give ftp or uucp scripts as output.  Hmm, perhaps
a combo of grabchars and perl (or most likely perl by itself) could do this?  
Wish I had more time to write it, I could use this!

	One that I enjoyed (but which depends on the input already being
somewhat massaged (to ls -R format)) was a Vi macro.  Since the poster
(isfrance.encore.fr!kstock (Kevin Stock)) cannot post to the net, I'll
forward it at the bottom of this message.

				Daniel


?From well!apple!isfrance.encore.fr!kstock Mon Jul  9 13:32:04 1990

Hello Daniel,

[ NOTE:	I am e-mailing this because my machine is unable to post at present.
[	Please feel free to post it if you would like to do so.

I've often wanted to do something like this, and ended up resorting to
awk to do it. In fact, I nearly passed over your message, but decided
in the end to take up the challenge.

You can't do it with a simple s// command because it only matches on
individual lines, not across line boundaries. So you need a macro.

What I came up with was:

	:se nowrapscan
	:map q /\<spool\>^V^MI:.,/^$/-1s,^,^V^[:s.:$./,.^V^["sdd@s+Q
	:map Q q

Instructions for use:

	Create a file containing the above (^V, ^M, ^[ are control chars)
	Load up your file with the ls output
	Add a blank line to the end of the ls
	:source  the macro file
	Go to the start of your ls file
	Press  q  and watch the fun!

Warning: it gets confused on empty directories. Unreadable ones don't
cause it any bother but aren't treated very usefully.

Sample input:

	/usr/spool
	FAIRE_DE_LA_PLACE
	LOCKS
	Qspool
	annex
	at
	batch
	dump

	/usr/spool/LOCKS:
	can not access directory /usr/spool/LOCKS

	/usr/spool/Qspool:
	can not access directory /usr/spool/Qspool

	/usr/spool/lpap:

	/usr/spool/lpct:

	/usr/spool/lpd:
	can not access directory /usr/spool/lpd

	/usr/spool/lplb:
	cfA015gouldfr
	dfA015gouldfr
	lock
	status

Result using the above input:
(Note the lines marked with a * which show the results of unreadable
 or empty directories)

	/usr/spool/FAIRE_DE_LA_PLACE
	/usr/spool/LOCKS
	/usr/spool/Qspool
	/usr/spool/annex
	/usr/spool/at
	/usr/spool/batch
	/usr/spool/dump

    *	/usr/spool/LOCKS/can not access directory /usr/spool/LOCKS

    *	/usr/spool/Qspool/can not access directory /usr/spool/Qspool

    *	/usr/spool/lpap/
    *	/usr/spool/lpap//usr/spool/lpct:

	/usr/spool/lpd/can not access directory /usr/spool/lpd

	/usr/spool/lplb/cfA015gouldfr
	/usr/spool/lplb/dfA015gouldfr
	/usr/spool/lplb/lock
	/usr/spool/lplb/status

Explanation:

The procedure is to turn each directory name into a substitution command
which tags the directory name (plus an extra /) onto the front of each
subsequent file name.

:se nowrapscan

	This is so that it stops at the end of file.

:map q /\<spool\>^V^MI:.,/^$/-1s,^,^V^[:s.:$./,.^V^["sdd@s+Q

	To spilt this up into its component parts:

	/\<spool\>	obviously, go to the next spool entry
			notice the word boundaries, so it doesn't match Qspool

	I:.,/^$/-1s,^,	add the start of a substitution command to the line
			note that this substitution will use , as a delimiter
			to avoid confusion with the / in the directory name

			"/usr/spool:" thus becomes ":.,/^$/-1s,^,/usr/spool:"

	:s.:$./,.	turn the : at the end of the name into the rest
			of the substitution command

			"/usr/spool:" has now become ":.,/^$/-1s,^,/usr/spool/,"

	"sdd		delete the line, saving it in the named buffer "s

	@s		execute the substitution command

	+		move to the first line not altered

	Q		repeat the process

:map Q q

	This is just to allow us to do tail recursion, which vi doesn't
	allow to be done explicitly.

As an exercise for the reader: modify the macro so that it deals with
empty and unreadable directories properly.

Incidentally, someone recently posted a Turing Machine Emulator in vi to
the net recently. I can send you a copy if you'd like one. My thanks to
Dave Hitz for writing it and showing me just how flexible VI is.

Thanks again for the challenge!

> 	Oh, and before we get into editor wars...I am trying to learn
> GNU Emacs...it's just hard to make the shift after 8 years of vi ;-)

Anybody got a turing machine emulator for Emacs? :-)

  ,---------------.
,-+-------------. |    Kevin Stock
| | E N C O R E | |
| `-------------+-'    kstock@gouldfr.encore.fr
`---------------'      kstock@gouldfr.UUCP


-- 
   dansmith@well.sf.ca.us   uunet!island!daniel   unicom!daniel@pacbell.com
(415)332 3278 (H), 491 0765 x 250 (W) disclaimer: Island's coffee was laced :-)