[comp.editors] vi mapping difficulty

dattier@vpnet.chi.il.us (David W. Tamkin) (03/09/91)

I'm having a problem with a key mapping in vi.  If anyone can help, I'd
surely appreciate it.

I want to clear out any lines that don't have text on them.  The purpose is
to separate paragraphs in quoted text.

So I have this in my .exrc:

map ^X :v/[0-9A-Za-z]/s/.*//^M

where ^X and ^M are ctrl-X and CR.  The ^X doesn't need a ^V to be entered,
but with or without it, or mapped to a printing character, the results are
the same.

Now, on some systems I call the mapping works fine.  On all of them, if I
type the command in, it works.  But on other systems (including those I call
most), if I try to use a mapping and call it by rebound key, these are the
effects:

If I've just read the file into the buffer and made no changes yet, it works.
Otherwise, one or two occurrences of the pattern get replaced and the
operation stops with "Can't undo in global" -- so who asked for an undo?

It's not a matter of the "modified" flag, because if I do :w or :w! to write
the buffer out and remove the flag, the operation (if called from a rebound
key) still aborts with "Can't undo in global."  If I :w and then :e %, it
will work if I use it before making any more changes.

Short of expecting the system administrators to install new versions of vi,
is there any way I can change the mapping to make it function?  Binding
:g/^[^0-9A-Za-z]*$/s///^M to a key acts the same way.

David Tamkin  PO Box 7002  Des Plaines IL  60018-7002  dattier@vpnet.chi.il.us
GEnie:D.W.TAMKIN  CIS:73720,1570  MCIMail:426-1818  708 518 6769  312 693 0591

"Parker Lewis Can't Lose" mailing list:   write flamingo-request@ddsw1.mcs.com

dylan@ibmpcug.co.uk (Matthew Farwell) (03/12/91)

In article <1991Mar08.205940.11108@vpnet.chi.il.us> dattier@vpnet.chi.il.us (David W. Tamkin) writes:
>I want to clear out any lines that don't have text on them.  The purpose is
>to separate paragraphs in quoted text.
>
>So I have this in my .exrc:
>
>map ^X :v/[0-9A-Za-z]/s/.*//^M
>
>where ^X and ^M are ctrl-X and CR.  The ^X doesn't need a ^V to be entered,
>but with or without it, or mapped to a printing character, the results are
>the same.
>
>Now, on some systems I call the mapping works fine.  On all of them, if I
>type the command in, it works.  But on other systems (including those I call
>most), if I try to use a mapping and call it by rebound key, these are the
>effects:
>
>If I've just read the file into the buffer and made no changes yet, it works.
>Otherwise, one or two occurrences of the pattern get replaced and the
>operation stops with "Can't undo in global" -- so who asked for an undo?
>
>It's not a matter of the "modified" flag, because if I do :w or :w! to write
>the buffer out and remove the flag, the operation (if called from a rebound
>key) still aborts with "Can't undo in global."  If I :w and then :e %, it
>will work if I use it before making any more changes.
>
>Short of expecting the system administrators to install new versions of vi,
>is there any way I can change the mapping to make it function?  Binding
>:g/^[^0-9A-Za-z]*$/s///^M to a key acts the same way.

I had a similar problem to this. My mapping was

map ^W 1G:1,/^$/g/: $/d^M

Where ^W is ctrl-W and ^M is ctrl-M.

(This removes all blank headers when you're entering a news article)

This works fine when you type it in. It even works when its a macro, but
it beeps at me. I can undo it, but then it doesn't work. Anyone got
any ideas? (Other than this, my problem is similar to above)

Dylan.
-- 
Matthew J Farwell: dylan@ibmpcug.co.uk || ...!uunet!ukc!ibmpcug!dylan
If you've ever wondered how to get triangles from a cow, you need
	butter, milk and cheese and an equilateral chainsaw.

gast@lanai.cs.ucla.edu (David Gast) (03/13/91)

In article <1991Mar08.205940.11108@vpnet.chi.il.us> dattier@vpnet.chi.il.us (David W. Tamkin) writes:
>I'm having a problem with a key mapping in vi.  If anyone can help, I'd
>surely appreciate it.

>I want to clear out any lines that don't have text on them.  The purpose is
>to separate paragraphs in quoted text.  So I have this in my .exrc:

	map ^X :v/[0-9A-Za-z]/s/.*//^M

I use EXINIT instead of .exrc.  One line from that EXINIT say:

		map #4 mz:%s/[	 ][	 ]*$//^M`z

where there is a tab and a space between every [ and ] pair.  The mz and
`z are to return me the same place in the file.
 
This macro is not exactly the same as yours.  First, it deletes trailing
white space; secondly, it defines text to be any printable character while
yours defines text to be only alphanumeric text.  You can easily make the
change if you really desire your semantics.  In particular, I use mine
to make d} work (paragraphs are not recognized where a line contains tabs
and/or blanks) and to get rid of trailing white space; however, in re-reading
your posting, I think you want to make a paragraph break whenever rn (or
some other news server) has inserted a > (or related character) at the
beginning of a blank line so that a line that only contains characters
like "<>=" is made empty.  Is that what you mean by quoted text?  Thus,
you could use as the left hand side of the s command:

	^[^a-zA-Z0-9][^a-zA-Z0-9]*$

where all the ^s are literal.  Please note, however, while, I think, the
the change immediately above describes what you wrote, it may not be what
you want.  For example, any lines that contain only a { or } (from a C
program perhaps) will also be deleted.  You *may* want to change only
those lines beginning with > or only those lines containing >*.

My macro is superior in terms of speed (only an issue for large files)
because s is much faster than v/g.  If you don't believe it, try two
identical command on /usr/dict/words and notice the difference in time.
That is, you should only use v or g when you want to do something that
s alone cannot do like delete the line or change a different line.

>If I've just read the file into the buffer and made no changes yet, it works.
>Otherwise, one or two occurrences of the pattern get replaced and the
>operation stops with "Can't undo in global" -- so who asked for an undo?

I have never had this happen with my macro and I don't see why you are
having difficulties.  I did not try to investigate either.

David

dattier@vpnet.chi.il.us (David W. Tamkin) (03/15/91)

gast@lanai.cs.ucla.edu (David Gast) wrote in <1991Mar13.084943.934@cs.ucla.edu>:

| In article <1991Mar08.205940.11108@vpnet.chi.il.us> [I wrote:]

| >I want to clear out any lines that don't have text on them.  The purpose is
| >to separate paragraphs in quoted text.  So I have this in my .exrc:
| >	map ^X :v/[0-9A-Za-z]/s/.*//^M

| I use map #4 mz:%s/[	 ][	 ]*$//^M`z
| where there is a tab and a space between every [ and ] pair.

| In re-reading your posting, I think you want to make a paragraph break
| whenever rn (or some other news server) has inserted a > (or related
| character) at the beginning of a blank line so that a line that only
| contains characters like "<>=" is made empty.  Is that what you mean by
| quoted text?

Yupper, that's what I meant, not only in rn but also in elm.

| Thus, you could use as the left hand side of the s command:
| 	^[^a-zA-Z0-9][^a-zA-Z0-9]*$
| where all the carets are literal.  Please note, however, while, I think,
| the change immediately above describes what you wrote, it may not be what
| you want.  For example, any lines that contain only a { or } (from a C
| program perhaps) will also be deleted.  You *may* want to change only
| those lines beginning with > or only those lines containing >*.

Yes, it's equivalent to what I wrote and it is what I want.  With unabashed
plagiarism from Barbara Tongue, when I see code, I run.  Not everyone (and
I'm an example) cites text with right-side angle brackets.  I do not intend
to preserve braces nor to operate only on lines with initial right-side angle
brackets.

I did, however, shorten the search string to /^[^0-9A-Za-z]*$/.  It doesn't
bother me if the report function includes lines that were blank all along
when it gives the count of lines changed, and I don't see any other
difference.  Perhaps when I put it into .exrc once and for all, I'll use
the longer form you recommend.

| My macro is superior in terms of speed (only an issue for large files)
| because s is much faster than v/g.  If you don't believe it, try two
| identical command on /usr/dict/words and notice the difference in time.
| That is, you should only use v or g when you want to do something that
| s alone cannot do like delete the line or change a different line.

Your advice did the trick.  Oh, I didn't even try to compare speeds, but :%s
works here and :g and :v do not, so speed comparisons don't even come into
play.

| >If I've just read the file into the buffer and made no changes yet, it works.
| >Otherwise, one or two occurrences of the pattern get replaced and the
| >operation stops with "Can't undo in global" -- so who asked for an undo?

| I have never had this happen with my macro and I don't see why you are
| having difficulties.  I did not try to investigate either.

Of course it doesn't happen with your macro.  Your macro doesn't have a
global operator in it.  Per your suggestion I changed the :v (:g syntax had
not worked either) to :%s with a search string.  It worked fine and was
reversible with u.  [Carelessly I first used :%s/[^0-9A-Za-z]*$// with only a
right anchor and managed to drop the end punctuation of every paragraph and
of every sentence that ended at the right margin.  With only a left anchor
I'd lose initial parentheses and asterisks, so clearly both anchors are
necessary.]

/* begin 100% unadulterated, unalloyed, certifiable speculation in a vacuum */

I guess that this is the problem: a key rebound with ":map" (unlike :map!)
is supposed to perform a reversible function, so including a :v or a :g in a
mapping might be the problem.  The undo buffer says that here is this
(possibly null, if the last operation was a, A, i, I, o, or O) text, and here
are two pointers into the current buffer, and the undo text used to go from
pointer #1 to pointer #2 instead of the (possibly null, if the last operation
was d or D) text that is between those points in the edit buffer now.  If you
use :v or :g you can make several changes to scattered, disparate, disjunct
areas of the text, and the undo buffer can't keep track of all those
beginnings and endings.  :%, on the other hand, simply holds the entire
previous condition of the document in the undo buffer and puts the pointers
at the beginning and the end, so :% is legal in mappings.

It was the :v or the :g that caused it, not the s command itself.

In fact, that goes along with my experience: the old macro, perhaps, was
changing one occurrence of the pattern (well, with :v syntax, one absence of
the pattern) or one group of consecutive lines that had (actually lacked) the
pattern.  That could well be that if there already was a blank line ahead of
any other line that fit (failed) the pattern (with the :v syntax a blank line
will always qualify as failing a pattern unless it's v/^$/), it changed the
blank line to still blank, reported "1 line changed" and quickly overwrote "1
line changed" with "Can't undo in global."  Yes, upon further experimentation
I saw that it was saying "1 line changed" but it was really hard to catch. 
If all the changes had been in a contiguous range of lines, it would have
been undoable and the macro would have proceeded.

So why would it work when I first read in a file?  Because, perhaps, it was
saving the entire document in the undo buffer and setting the undo pointers
at the beginning and ending of the edit buffer.  After any other changes the
numbered buffers would have started filling, and a :w wouldn't clear them
out, but an :e or :n would.  For some reason, having used the numbered
buffers makes a difference.

/* end speculation */

So you and I have different reasons for avoiding globals.  We very likely
have different reasons for reading netnews, but we both got here just the
same.  Thank you again, Mr. Gast.

David Tamkin  PO Box 7002  Des Plaines IL  60018-7002  dattier@vpnet.chi.il.us
GEnie:D.W.TAMKIN  CIS:73720,1570  MCIMail:426-1818  708 518 6769  312 693 0591

"Parker Lewis Can't Lose" mailing list:   write flamingo-request@ddsw1.mcs.com