From: gbergman@ucbcartan (George Mark Bergman)
Date: Thu, 3 Nov 83 22:28:11 PST

Latest letter to Mark Horton re editor bugs etc.:

copies sent to
cc-03@ucbcory
ralph@ucbarpa, lindahl@topaz, mckusick@ucbernie 25/7/83
danh@kim  26/7
Mark Horton's reply: anderson@kim 30/7/83

Dear Mark,
     I got your reply to my last letter, but you don't say
whether you got the two preceding ones -- in particular, I'm
curious as to what you'd say about the peculiar behavior of
abbreviations terminated by \[character].  (E.g., suppose
someone did :ab ac artistic, and then, supposing the file was for
troffing, typed ac\fP. -- Try it!)  And likewise, about what
happens if you hit  @x,  when register  "x  contains
	x:g/foo/s//bar
(To see this wierd effect, you have to have a file with
an occurrence of ``foo'', and a distinctive  l a s t  line.)

     In an earlier letter I commented that the mapping that
the editor sets up to enable the tvi's right-arrow key makes
^L unavailable for refreshing the screen.  You replied that,
of course, the editor could not distinguish a ^L generated by
the arrow key from one typed as <ctrl>-L by the user.  True,
but some users, such as myself, are quite happy using hjkl
to move around the screen (I use them completely by reflex)
and so have no wish to enable special arrow keys, but do
want to have ^L available to redraw the screen when
a message or something messes it up.
     The problem with ^L occurred in using a tvi; now, using
a Z29 (in h19 mode), another version of the problem arises.
It has arrow keys that transmit things like ^]A, ^]B, etc.,
and version 3.9 not only maps these sequences, but also
map!s them.  What I found happening is that if in typing
I made a change somewhere in the body of a line and then
wanted to add something at the end of the line, I would often
type a  ^]  to end the first change and then an  A  to
begin the second, with less than a second between them, and
this sequence would then be map!ed into  ^]ka  or
something, landing me in a different place from the one
I wanted.  Aside from this major problem, there is the minor
inconvenience that the  map!  mechanism apparently waits
a second every time I type an  ^]  from insert mode to see
whether this is going to be one of the map!ed sequences, and
this makes exiting from insert mode sluggish.  My temporary
solution has been to write a file of the form
	unmap ^]A| unmap ^]B| ...|unmap! ^]A| unmap! ^]B| 
which I source every time I go into vi on the Z29.  I
guess what I should do is create simplified termcaps that
leave out the arrow keys for my own use when in version 3.7.
Kevin Layer tells me that when he puts 3.9 on all systems here,
there will be documentation on how to create terminfo files;
so I will be able to avoid these inconveniences in 3.9 as well.
     What would be better, for these two-or-more character sequences,
though, would be if the "timeout" feature on mappings
could involve a variable interval, which could be set in the
millisecond range for terminal-generated sequences (I suppose
it would have to depend on the baud rate), and longer
for user-mapped sequences.  The likelihood of the user
accidentally typing in one of the special sequences so fast
is negligible.
     Incidentally, I notice that when I type :map  to look
at the automatic mappings, these are labeled "up", "down" etc.,
though for mappings that I create the corresponding position
just shows a repeat of the mapped sequence.  Is there
any way the user can put mnemonics in with his own mappings?

     Two other minor points:

     In your reply to my first letter, where I suggested that
N/pattern should take one to the Nth occurrence of /pattern,
you said that N/pattern actually resets the window size to N
while carrying one to /pattern.  The tutorial says the same,
I believe, but nonetheless, it doesn't work!
     When one has pulled a command into a buffer,
say "x, and invoked it with @x, if one then tries to get
a copy of this command by doing "xp, it doesn't seem to work.
The way I've found to make it work is to do any other
yank-and-put (using, say, the last-deleted
buffer).  This somehow unfreezes the mechanism, and (after undoing
this last put, unless one wanted it), one can then successfully
do "xp.
				Yours,
					George

(Message inbox:32)
Date: Sun, 10 Jun 84 16:29:50 pdt
From: gbergman@ucbcartan (George Mark Bergman)
To: cc-03@ucbcory, danh@kim, decvax!tarsa, gbergman@ucbcartan,
        hplabs!intelca!omsvax!isosvax!root, ihnp4!burl!we13!ltuxa!jab,
        leblanc@ucbdali, lindahl@topaz, mckusick@ucbernie, [email-masked],
        ralph@ucbarpa, reiser@ruby, [email-masked], unisoft!eryk,
        uw-beaver!ubc-vision!mprvaxa!sonnens
Subject: more editor bugs & ideas

     Here's another letter of comments on the editor that I'm
sending to Mark Horton (mark@cbosgd).
     If any of you to whom I'm sending this aren't interested in
staying on this mailing list, just let me know.
     Horton replied to an earlier letter by saying he had no idea
when he'd have any time to work on the editor again, so I don't
expect replies from him to this and further such letters in the near
future.
     For those who are not familiar with the subject of item "A."
below, modeline is a feature that he added without publicizing it much,
whereby if any line in the vicinity of the top or bottom of the file
(top and bottom 10 lines?  I don't remember) contains the string
vi: or ex: and then another :, everything between these is
interpreted as a command and executed when this file is read by the
editor.  There was a big squall in net.news when someone discovered
it by chance (an accidental string of this sort occurred in their
/etc/password; fortunately the "command" was meaningless, and evoked
a diagnostic from the editor).  Some serious dangers of this
feature were pointed out by various contributors, one of whom described
for all who were interested how to eliminate it from the source file.

Dear Mark,
     Here's another few month's collection of comments...

A.  Modeline
     I presume that in following the net.news discussion of the
``MAJOR BUG (modeline)'' you saw my two contributions; but I'll
summarize the relevant points (not in the order I made them):

1)  One possible feature that would be about as convenient as
the modeline, and would avoid the dangers that people have pointed
out, would be `enhanced tags', in which the 3d entry of a line of the
tags file could be not merely a pattern search, but an arbitrary
command line.

2)  I described (both in net.news and in an earlier letter to you) a
mapping in my EXINIT which makes one keystroke yank the current line
(or the next N lines if preceded by a count) to a named buffer
and then execute that buffer.  If one keeps a set of initializing
commands within a file to which they are to apply, one can then
easily execute them on beginning an editing session, which gives
almost the convenience of the modeline feature, without the dangers,
and has an enormous range of other uses.  So I think the modeline
feature could be dropped.

     Let me add to those points:

3)  A modeline
	vi:r %:
leads to an infinite recursion!  Fortunately, ^C cuts it off.

4)  I agree with others' comments in net.news that if the modeline
feature is not dropped altogether, it should be a settable option
with default ``nomodeline''.

5)  It should certainly be off when ``novice'' is set!

B.  Tags
     Having mentioned these in point A(1), I will give some other
comments I have:  One of your update documents mentions the fixing
of a bug that left ``nomagic'' set if the file named in the tags
file did not exist.  Very good, but one still ends up with ``nomagic''
if the file exists but the pattern-search is unsuccessful!
     It would also be nice if the tags file could include file addresses
of the form ~user/filename, in particular ~/filename, and if the
command :set tags= recognized the same.  (I suppose this makes no
difference to people who get their tags from ctags, but for me, the
tags file is maintained as a collection of items I have been working on
recently, or mean to soon, and entries are put in or removed by
hand regularly.)

C.  Reversal of n and N
     I also mentioned in one of my net.news comments a peculiar behavior
that often seems to occur after I've been using my yank-and-execute
mapping a lot, in which, after a command-line pattern-search :/pattern
(rather than simply /pattern), the screen-mode commands n and N give
searches in the reverse of the expected direction, with ? and /
respectively instead of vice versa.  Perhaps you can figure out what
causes this; if not, would it help for me to do something like make
a core dump of the editor when it is happening and send it to you?
(I don't know how to send a nonascii file, though... .)
     A few more observations on this behavior:  Though I commonly
discover it when I am using my yank-and-execute mapping, it has
happened on at least one occasion when I hadn't use that at all,
so far as I could recall.  It may actually happen quite frequently,
but people just don't notice it because they usually use /pattern
instead of :/pattern.  (My mapping makes it more convenient for
me to use the latter when the pattern is complicated, or I want to
store it for repeated use.)

D.  Update on dangerous recursions
     Discovering that ^C interrupted the recursive modeline led me
to test it out on a recursive mapping, :ab x ( x ).  It interrupts
it OK.  Problem solved courtesy of 4.2BSD, I guess.

     I will collect under the next heading my usual list of:

E.  Minor bugs and modest suggestions

     ye and yE yank one character less than they should.

     If the command Ne (N a count) would land one on a 1-letter
word, one generally lands at the end of the next word instead
(even if it is also a 1-letter word.  Exception: if one starts
at or after the end of the preceding word, e behaves as it should.)

     Note also that in the line
	Sentence... .  Sentence
if the cursor is on the second S, the command ( causes no motion
at all.

     I suggest that the motion commands { and } should accept indented
lines as paragraph-starts, or at least that there should be some
way of requesting this in the ":set para=" command.  After all, these
motions shouldn't be useful only to people writing troff files!

     In general, the command NC (where N is a count) changes material
from the cursor position to the end of the Nth line, leaving material
before the cursor on the current line unchanged.  But if the line
is indented, and the cursor is on or before the first nonwhite
character, the preceding white text (spaces and tabs) is lost.

     It should be possible to use
	:unmap #1	:unmap! #1	:unab #1
when function-keys have been mapped.

     Sometimes a noisy phone-line, termcap padding errors, etc.
cause just one or two lines of the screen to be messed up, and one
may only wish to refresh those lines.  Could a command be introduced
which would do this?  Ironically, on a dumb terminal one can generally
do this by moving the cursor over the line, but not on a smart terminal.
Another way one can do it is ddP, but I would sometimes feel uneasy
about unnecessarily modifying the text.  I would
suggest that the form of the command be 1^L (2^L for 2 lines, etc.).
Currently, ^L apparently ignores counts.  (Actually, I'm writing at
the moment on a tvi, so I've verified this for ^R rather than ^L.)

     If one uses the source command, and the file sourced contains
a command
	:e newfile
where newfile does not already exist, the diagnostic ``No such file
or directory'' aborts the sourcing process.  One ought to be able to
use such commands in a sourced file.

     In vi screen command mode, ^[ is supposed to ``cancel partially
formed commands'' and generally does so without protesting, but if the
partially formed command is a count (e.g., if one has typed 110 instead
of 10 and wishes to start over) it feeps, which depending on one's
terminal can be a minor or a major annoyance.  (Also depending on
whether someone is trying to sleep in the next room.)

     The diagnostic, ``First address exceeds second'' should not be
needed with one-address commands!  The case where a series of addresses
before a command, of which the first may exceed the second, is most
useful is when the last address is a pattern-search preceded
by a ";", e.g.
	:$;?^\.PP?-r otherfile
but let me give simpler examples; of the two commands
	:3,1,2ka	:1,3,2ka
the first correctly marks line 2, but the second is aborted by the
diagnostic quoted.

F.  A feature that would be very desirable, and might or might not
be easy to implement.

     In general, when one is inserting text on a smart terminal in vi,
the context below the text being added is pushed downward, line by line,
till none is left on the screen.  I would like a settable option that
kept a certain number of lines of following context on the screen
during additions.  The point is that one should see the material that
what one is writing will have to mesh with.  What would be involved in
implementing this would, of course, depend on terminal capabilities.
If it would be difficult to keep an arbitrary number of lines,
would it at least be possible to have an option that would keep one
line, using the special bottom-line feature of some terminals?

G.  More radical suggestions (wishlist).

1)  Editing text with _u_n_d_e_r_l_i_n_i_n_g.
     Although one of the valuable features of vi is the explicitness
with which most nonprinting characters are shown, this can be annoying
when one wants to deal with text in which many characters
are ``emphasized'' using the sequence _^H; e.g. nroff output.  I
suggest a settable option under which such sequences would be shown as
with ul.
     I realize that this would involve working out a great number
of details, e.g. would motion commands treat _^Hx as one
character or as three?  How would the nth column be defined?  How
would one place the cursor on one of the elements of the string
_^Hx for editing purposes?  What would be done with _^H^A or _^H_^H....?
     I think the best solution would be to treat _^Hx as a single
character for the purposes of motion commands, definition of nth
column, deletions, etc. when this option was set.  In terms of placing
the cursor, two possibilities occur to me.  One would be to only allow
the cursor to sit on the underlined character ``as a whole'', and to
have changes in underlining done by special commands: perhaps ^E as a
toggle to turn emphasis on and off in insert mode, _ to change
underlining in screen command mode as ~ changes capitalization
("_" is at present a synonym to "^", except
that it takes counts.  ^ could be modified to take
counts, and _ then used as suggested above), and \e in replacement
patterns.  The other would be to consider a cursor sitting ``on''
a sequence _^Hx to actually be on the x, and to set things up so that
if the cursor is on any of the other members of this sequence, the
sequence is ``expanded'' on the screen, i.e. shown as it is in the
present vi.  Then define a single vi command so as not to skip over
the _ and ^H in such a sequence; namely ^H.  (This would mean
making a distinction between h and ^H in screen command mode.)
This one motion would allow one to edit parts of such a sequence.

2)  Editing several files at once.
     When I have to do work that involves more than one file, the
repeated use of :w|e#, yanking text to named buffers to move it, losing
marked lines when I return to a previous file, etc.  becomes
annoying.  I think it would be desirable if one could make a group
of files behave like one file during an editing session, and move
around within that file as comfortably as one move within one file.
     I suggest that visually, each file be separated from the next
by a pattern
:::::::::::::::::::
as when ``more'' is applied to a group of files.
For ``Go to file 3, line 20'' I suggest a screen command syntax
*3*20G.  *-1* and *+2* could mean ``the preceding file'' and ``the
file after next'' in such commands.  (The initial * could be optional
if there is no preceding + or -, as in the first example.)  In a
command such as :w, the default address range would be all of the file
to which the current line belongs (i.e.,
it would be a synonym for :*.*w)  To write all files, I suggest :**w.
:q, :x and ZZ would quit the editing session entirely, while :*1*q
would remove the buffer of file 1 from the object being edited.
On the other hand, relative motions such as 10j, H, etc. would work
within the ``visible object'', the union of the files.
%s/pattern/repl/ would apply to the file containing the current line,
and would have the synonym *.*s/pattern/repl/, while
*1,2,4*s/pattern/repl/ would affect the 3 indicated files, and
**s/pattern/repl/ would affect all files.

3)  Input and output of shell escapes.
     The various commands involving shell escapes that you have
set up allow four possible relations between the text being edited
and the input and output of the commands: none (:!command);
specified line-range as input with output not affecting text
(:address-range w !command); no input from text but output inserted at
specified line (:address r !command); and specified input from text
with output replacing input (:address-range !command).
     It would be nice to have more flexibility; in particular, to
be able to include input from the file and place the output somewhere
else in the file without destroying the input text, and to input
more than one segment of text, e.g.
	!egrep -f[addr.range] [other.addr.range] > [place of insertion]
Obviously, there would be a problem of setting up a syntax that would
avoid confusion with strings that look like address-ranges in the
shell command.  Perhaps \[...\] could enclose address-ranges where
I have used [...] above.

4)  ;
    The ; syntax, allowing one to do a pattern-search starting
from a specified line is useful, but in setting up 2-address commands,
one does not necessarily want the point from which one starts the
search for the second address to be the first address.  If this business
were being set up now, I would suggest that
	address;/pattern/
should simply be a way of specifying the result of doing the indicated
pattern-search relative to the indicated address, so that
	:address1,address2;/pattern/d
would delete from address1 to the location found by the pattern-search
relative to address2.  Since people are used to the existing
syntax of ;, I suggest that some other symbol be used in the above
way, e.g. ], so that
	:address1,address2]/pattern/d
could be interpreted as described.

5) Insertions into long lines on smart terminals at low or medium
baud rate (e.g. 1200).
     This is annoying because the material coming after the point
of insertion begins to wrap around, and the cursor must jump back and
forth, inserting characters at the beginning of the
continuation line, then going back to the point of insertion, and so
on.  (At least, this is my experience on my Z29.  I haven't done
editing by phone connection on any other smart terminal.)  It's
actually nicer on a dumb terminal, where the editor just overwrites,
and shows you the result after you escape.  I suppose that the need
for the cursor to jump back and forth is due to the deficiency of the
terminals -- has anyone suggested to terminal manufacturers that along
with the wraparound feature, they add a feature which ``remembers''
when a line is a continuation of the preceding line, and automatically
pushes material from the preceding line into the continuation line
when characters are added to the former, eliminating the need to send
all these instructions in over a slow line?  (Do terminal manufacturers
listen to editor-software specialists?)  If not, it might just
be best to not show the pushed-over earlier material till the insertion
is complete.

6)  Filename convention
     This is really a suggestion for UNIX generally, but it could be
implemented on the editor separately.  It is that for any file,
filename/.. denote the directory in which the file lies.  (This
does not mean that every file should be treated as a directory, or
that the ls command should show filename/..; it would just
be a convenient way to refer to the directory containing a given
nondirectory file, consistent with the existing convention for
directories.)  Within the editor, the important cases would be
%/.. and #/.., allowing commands such as:
	:1,10w %/../othername

			All for now! Yours,
				George