2.11BSD/src/ucb/ex/TODO

From gbergman@UCBBRAHMS Mon Jul 25 16:21:43 1983
Date: 25 Jul 83 16:16:52 PDT (Mon)
From: gbergman@UCBBRAHMS (George Mark Bergman)
Subject: Re:  editor bugs etc.
Message-Id: <8307252316.AA22776@UCBBRAHMS.ARPA>
Received: by UCBBRAHMS.ARPA (3.342/3.7)
	id AA22776; 25 Jul 83 16:16:52 PDT (Mon)
Received: from UCBBRAHMS.ARPA by UCBERNIE.ARPA (3.336/3.7)
	id AA13678; 25 Jul 83 16:21:17 PDT (Mon)
To: mckusick@UCBERNIE
Status: R

The following are (i) a short note from Mark Horton
in reply to a note of mine saying I'd been keeping notes
on editor bugs, had heard he had a new version, was
interested in hearing about it and perhaps sending
him notes on bugs not mentioned as corrected; (ii)
a long letter from me in which I do list bugs, features
I think would be desirable etc., (iii) an addendum I
sent the next day, (iv) brief jottings not yet sent.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
>From mark@cbosgd.UUCP Thu Jul 21 12:31:55 1983

The new version of vi isn't very different to the user.
The internals use terminfo instead of termcap, but the
user interface isn't affected by this (except that it
starts up faster).  The major new features are
	set showmode
		will cause an indication on the status line when
		you are in input mode
	vedit
		is a new invocation of vi for novices
	more function keys now work
	function keys work in both command and input mode
Of course, there are a few bug fixes too.

There is a binary in ~mark/bin/vi on ucbarpa.  It requires the
/etc/term heirarchy (there is no file called /etc/terminfo) which
was on ucbarpa once but might be gone now.  If you want to grab
them from whereever they still exist, please feel free to try them.
	Mark
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Sent to Mark Horton  23/7/83, about 11AM

Dear Mark,

     Well, your note didn't say you wanted me to send my comments
on editor bugs and suggestions, but you didn't say I shouldn't,
so I decided to do so.  I've tried to organize it into some sort
of sections.  I'd be interested to know which of the bugs mentioned
here you have already found and corrected.  (I may soon find out for
myself; the person in charge of this machine says he'll try to get a
copy of version 3.9 from UCBARPA if they still have it, and get it
running for me.  If you have any helpful information for him, he
is robert@brahms, Robert Gross.)
     Vedit sounds like a great idea.
     I should mention that throughout this letter, I have
avoided using actual control-characters, but faked them,
e.g. used ^ and H to get the appearance of ^H, since files with
real control-characters can be confusing when looked at in mail,
more, etc.  But this means that if you want to try any commands I
refer to that use them, you won't be able to yank and source them,
unless you replace my fakes with real control characters.
     The version I am using is 3.7.


PROBLEMS WITH COUNTS

     Some  vi operations that logically ought to be able to take
counts do not, while others misbehave with counts.  In this section,
``N'' will always denote a positive integer placed as a count before
a vi operation.
     The most gross case of misbehavior is that of N^B!
The effect is to redraw the screen 23N-44 lines further advanced.
(Probably the numbers depend on the screen-size of the terminal;
this is on a Z19, using termcap h19u.)  When N=1, this does indeed
move you a screenful backward, but for higher N it moves the window
forward some amount!  Further, whatever controls are supposed to
monitor whether the command would land one at an acceptable line-
number seem to have a different idea of what it is doing:  If you
aren't already familiar with these weird effects, try setting the
cursor near the end of a file that is more than 4 screenfuls long,
and hitting 3^B.  (You might then try an insert at the place you get
to, and a :f^] .)
     N/pattern/ would be useful, but is not allowed.
     ND would be a natural synonym for dN$, by analogy with NC for cN$,
but it doesn't work that way; it just ignores the N.
     Finally, if N is precisely the number of lines
from the current line to the end of the file,  N$  will still correctly
carry one to the last character of the file, but cN$, NC, dN$ and yN$
refuse to do anything!  (NY does work, not being a synonym for yN$.)
The failure of NC is particularly annoying; often when I am composing
something, I go back to somewhere in the middle of the next-to-
last line, say, and want to rewrite the rest of the sentence;
2cc would kill not only the part I want to rewrite but also the OK
beginning of the line, and 2C or 2c$ won't work.  I realize that I
could get around this by keeping an empty line at the end of the file,
but that should not be necessary.


PROBLEMS REGARDING SOURCE, MACROS, MAPPINGS
     These are enormously useful, but seem to have all kinds of hidden
restrictions.

     The Appendix to the Ex Reference Manual, "List of Changes from
Version 3.5 to Version 3.6" says ``A bug which prevented the source
command from working...from visual has been fixed''.  It is true that
one can now use  :so  from vi, but it still has a bug:  When
the scriptfile invoked contains a global command
and some other command(s) after it, everything after the first global
command is ignored.  The same appears to be true of scripts in named
buffers invoked from vi-bottom-line by  @x.

     (It is, perhaps, unexpected that one can invoke scripts with
multiline commands using @x from vi's bottom-line at all, since such
commands will not work if typed on vi's bottom line directly.
A script like
	s/$/a\
	b
invoked as @x will indeed work.  But strangely, if one tries to
invoke from the regular mode of vi the script
	:s/$/a\
	b
by putting it in buffer x and doing  @x, only the first line
will take effect.)
 
     Another serious restriction is that the command ``vi'' appears to
be ignored in sourced ex-scripts, and though the command Q in macros of
various flavors in vi (mapped characters, map!ed characters that contain
``...^V^[...Q...'';  @x scripts) does take one into ex, any ex
commands after it are ignored.
 
     I assume you are aware of whatever restrictions lead to the
error-message ``Cannot yank inside global/macro'', since you must
have written it, though ``inside'' seems to here have the peculiar
meaning ``after a text-changing operation of the macro.''
     The error-message ``Can't undo in global commands'' is more
mysterious, since I get it when I have a global command after
a text-changing command in an @x script (though not in a sourced file).
     Anyway, the fewer such restrictions these operations were subject
to, the more useful they would be!

     Although nested source commands are allowed (and I find them
useful), they leave the editor in a ``noprompt'' state.  This
can be gotten around by including ``se prompt'' as a line in the
outermost scriptfile, but I would hope the problem causing it could
be cured.

     When one tries to ``:unmap!'' a ``:map!'' command whose
right-hand-side begins with ^H (entered as ^V^H, of course), one
gets the message ``That macro wasn't mapped''.  (One can get around
this by using :unmap! ^V[character].)

     Certain termcaps apparently produce automatic mappings, which
unfortunately may interfere with useful vi commands.  In particular,
on a tvi, ^L gets mapped to a movement command, which makes it
unavailable for redrawing the screen, unless unmapped.


PROBLEMS WITH DIAGNOSTICS

"Hit return to continue" -- It took me a long time to realize that
when I got this diagnostic there was an alternative to hitting
return.  I suggest it be reworded
	"Hit Return or :"
However, the behavior of the editor when this diagnostic is given
seems to be inconsistent.  In particular, when the last of a serious
of commands is
	:e otherfile
and I get "Hit return to continue", then hitting : usually
has no different effect from hitting return (or any other
key), namely the screen is redrawn; yet I think that sometimes
in this situation it has brought me directly to the bottom line
as desired.  Very confusing.
     Would it be possible to have other alternatives than : and return
available, such as /pattern ?  Or, more simply, when one would presently
be given the diagnostic "Hit return to continue", why not just put the
editor into the state it would have if one then hit :, since one would
then still have the option of hitting return and getting into vi
proper, but it would not require the extra keystroke : to
begin a bottom-line command, nor would one go through the frequent
frustrating experience of absentmindedly starting to write a
bottom-line command, or a pattern-search, and then having to wait
while the screen was redrawn because one had hit a key other than :.

"Using open mode"
Again, it took me a long time to learn that when I tried to enter
vi and got this diagnostic, it meant that the system had somehow
lost the termcap for the terminal I was on, and that I would have
to do something to get the correct termcap into the environment.
Till I realized this, I generally ended up either struggling along
frustrated in open mode, or logging out and logging back in.  I suggest
that when someone calls for vi and the termcap is not appropriate,
the editor should not be invoked in any form, but instead, a message
be given such as:
     ``Your environment does not show a termcap entry permitting
the use of the visual editor.  If you are working on a terminal not
supporting vi (in particular, a device with no addressable cursor),
you may enter one of the other modes of the editor with the command
"open filename" or "ex filename".  If you are working on a terminal
that should support vi, your environment entries are incorrect and
should be corrected.  They presently show:
     TERM=....
     TERMCAP=....
If you know the correct name or abbreviation for your terminal-
type, type it at the end of the next line; if not hit return:
     % setenv TERM ''
     If the user typed an acceptable terminal-name, the message would
continue, telling how to get the appropriate termcap.  If the user
instead typed return, the message would ask him or her to type the
name of the manufacturer shown on the terminal, not
worrying about upper/lower-case distinctions, and a list of possible
terminal names and abbreviations would be given... .  This whole
program would not be part of the editor, so there would
be no problem of space within the existing crowded confines of
the editor code.

"No such file or directory" -- I think there should be a distinction
between these two cases, because of the important distinction in the
consequences when the user tries to quit the editor:
If the directory exists, the file is created, but
if not, the results are more complicated -- I seem to recall on one
occasion simply losing what I had written on my second try
at quitting; though I just now did an experiment and this time
repeated ZZ's and :x's simply gave repeated error messages.

"File already exists..." -- The ``List of changes from 3.5 to 3.6'' says
``If you get I/O errors, the file is considered "not edited"... .''
I presume that this correction is somehow the cause of the fact that
I frequently get the above message when trying to leave the editor
on a machine with version 3.7, and have to use
      :w! %|q
to exit.  But I've never seen any evidence that there were I/O errors;
it mainly seems to happen when I've written some lines to another
file in the process of editing.  So the criteria the editor is using
to decide when there have been ``I/O errors'' should be rechecked.

"no such command from open/visual" -- This confused me in my first
few days of using the editor, when I didn't understand that one
couldn't use i and a (in either their vi or ex senses) from the bottom
line of vi.  A message "i -- no such command from open/visual"
was perplexing because I knew that "i" was indeed a vi command.
Perhaps it should say  "no such command from open/visual bottom line".

MISCELLANEOUS PROBLEMS

     In ex search and replacement patterns, \\ is supposed to represent
a real \-character, but something goes wrong when this occurs
at the end of a global command.  E.g., though
     :s/^/\\
works OK (in vi or ex), the variant
     :.g/^/s//\\
definitely does not.  In vi it turns everything off, in ex it seems to
behave as though there were just a single \, and in a scriptfile,
it -- does something still different, which you can discover if you
don't know!

The Ex Reference Manual says, ``For sanity with use from within
visual mode, ex ignores a ":" preceding any command.''  But it
ignores it in the wrong place! -- not at the beginning of the
command line, but just before the command letter itself.  I.e.,
it accepts 1,3:s/^/     /, but not :1,3s/^/    /.

SUGGESTIONS FOR MINOR ADDED CAPABILITIES

   In a multiline substitute command with the "c" option, when
each line is displayed one has three choices: y, n or break.  There
are some further options that would be useful.  One would be "p" --
at present, "p" can only be included on the command line, which
means that one has a choice between seeing the result of every
substitution or none.  In practice, one would generally like to see
the results of the first few cases to make sure that the command one has
written does what one meant it to, and maybe a few tricky cases that
come up; but not every case!   Another might be "u" -- to undo the last
case for which one gave a "y".  Still another might be an option that
would mean ``undo the "c" option -- I see that the substitute command
is doing what I wanted, go ahead and finish it without me.''
    In a command  g/pattern/p,  the pattern in question is occasionally
such that it takes a while to figure out where on the line it occurs.
For this purpose, an option that ``pointed out'' the instance of the
pattern, in the same manner that the pattern to be replaced is pointed
out in substitute command with option c, would be desirable.
    When  g/pattern/p  gives more than a screenful of lines, it would
be nice to have it piped through the equivalent of ``more''.

    ex has the command line option "-", which ``is useful in processing
editor scripts''.  But if one wants to use a script in the course of
an otherwise interactive editing session, it would be desirable to have
a corresponding resettable option ``:se -'' (or ``:se nofb'').

     In strings in pattern-searches, it would be useful to have
^ and $ retain their ``magic'', so that /x[a$]/ could
search for all occurrences of  x  before an  a  or a newline.
(Of course, one would then have to decide whether  /x[^y]/ should
include the case of  x  followed by a newline or not.)

    Just as ex allows the command :vi, so I think that vi should
have some bottom-line command equivalent to the regular-mode
command  Q.  When one has done some text-changing bottom-line
commands, and realizes one wants to go into ex, it can be time-
consuming to hit return and then Q, and wait for the screen to be
redrawn for vi before one gets the ex prompt.

     The option of putting several commands on one line, separated
by, "|" is particularly useful in the vi bottom-line mode, because
it avoids having the screen redrawn several times.  It would be
useful to be able sometimes do the same thing with non-bottom-line
commands, e.g. in editing a troff file at a low baud rate on a dumb
terminal one might like to be able to do  i\fI^]3Ea\fR^]  without
watching the line get redrawn twice.  Perhaps some key that would
cause any sequence of commands to be ``held'' until some complementary
key was hit would be useful.
     It would also be desirable to have a sequence of commands that had
been given in this way available as one unit to be repeated by ``.'',
if desired.

     The parenthesis-matching facility with % might be extended
to match ` with ' and <  with  >.

     I will mention one facility that I discovered by surprize is
possessed by  ed  but not  ex  --  sequences such as  \1  can be used
within  ed  search-patterns.  E.g. (for the most trivial case)
     /\(.\)\1/
will search for doubled letters.


DEBATABLE SUGGESTIONS
     I will mention here some possible changes which have the
difficulty that they would change the meaning of existing commands,
so that it could be argued that the disadvantage of users having
to change their habits might outweigh the advantages.

     First, one might try to resolve, one way or another, the
contradiction between the count arguments taken by the join commands
in  vi and  ex:  In ex, jN joins N+1 lines; in vi, NJ joins N lines
(except if N=1).

     Second, the movement commands  tx  and  Tx  of vi (x any character)
seem poorly defined.  Just as fx will ignore the character on which
the cursor is presently sitting, even if it is an  x,  and move to the
next occurrence, so I would think that  tx  should ignore the character
immediately after the cursor, and  Tx  the character immediately before
the cursor.  The point is that when one does  Nfx,  and finds that one
had failed to count one occurrence of  x  and fallen short of where one
wanted to go, one can hit  ;  and get there.  Likewise, on doing  Ntx
and finding one has fallen short, one should be able to hit  ;  and get
to the the next occurrence; but at present, hitting  ;  leaves
the cursor in the same position; one must hit  ``2;''  to get any
further.  In effect,  Ntx  is presently defined as  Nfxh;  I am
suggesting that it be defined as  lNfxh.

     The sequences  cw, dw  and  yw  are presently violations of the
principle that  c[movement],  d[movement]  and  y[movement]  change,
delete, or yank everything from the current cursor position through
the endpoint of the movement command.  cw does what one would expect of
ce (in fact, they seem to be synonyms), while there is no way to get
the effect which  cw  would have if it were treated ``consistently''.
(E.g., if I have a line beginning  ``And if'', and I want to change it
to ``If'', I cannot just put the cursor on the A and hit  cwI^].)  dw
and  yw  delete up to the character immediately before the point to
which ``w'' would take the cursor.  I would have to agree that this
behavior of dw and  yw  is more useful than that which a literal
interpretation of the movement rule would lead to; but perhaps it
would become still more useful if when applied to the last word on
a line, it deleted or yanked the space immediately before the word
along with the word... .  On the other hand, one could argue for
making a distinction between  cw  and  ce.

     Though I see the motivation for the above definitions,
I see no sensible reason why  Y  should be equivalent to  yy,  when
C  and  D  are equivalent to  c$  and  d$.  I would vote for changing
Y  to mean  y$.

RADICAL SUGGESTIONS

     Is there any reason for maintaining the distinction between
the ``:'' state of vi, and  ex  itself?  At present, there are
relative advantages that lead one to choose to go into one or the
other for a given operation:  From the vi-: state, it is easier
to return to the regular vi state; from ex, one has a more powerful
range of commands; and it is easier to give a series of commands
because each carriage-return gives one a new prompt.  My suggestion
is that from vi, ``:'' should carry you directly to ex, and when you
are in ex, carriage-return (^M) after a command should give you a new
prompt, while ^] should put you into vi.  Conceivably, things might be
simplified even further, and carriage return rather than : could
be the key that would carry one from the regular mode of vi into ex:

			 .-------.	.-------.
	.-------. a,i... | basic |  ^M	|	|
	|  vi   |<------ |	 |----->|  ex	|<---.
	| insert|	 |   vi  |	|	|    |^M
	|  mode | ------>|	 |<-----| mode 	| ---'
	`-------'  ^]	 |  mode |   ^]	|	|
			 `-------'	`-------'

(Of course, ^M presently has a meaning in vi, but
it has a synonym +.)  Clearly, there would also be no need for a
special "Hit return to continue" state.
     I have not distinguished vi and open in the above diagram.
My idea here is that ^] would actually return you to either vi
or open, whichever you had last been in, and that to switch
to the other, you could enter ex and type vi^] or o^] respectively.
(Or you could type  vi^M, respectively o^M, and further ex commands,
and the mode would be saved for the next time you hit a ^].)  Or
alternatively, these could be made settable options: se visual
respectively se novisual.
     Having gotten used to the editor as it now exists, I admit that
I feel uneasy about the above idea -- the sense of knowing that
I am ``still in vi'' when I hit :, and not that ``other land'' of ex, 
represents a kind of of orientation that it is disconcerting
to abandon.  But I can't see any logical disadvantage in making
such a change.  Can you?  Certainly, there would be things that
would have to be thought out, such as what happens to bottom-line
vi pattern-searches.  My thought would be that ``/'' from vi should
give :/ (i.e., put one in ex at the start of a pattern-search),
and ^] after a pattern-search should put one into vi at the appropriate
character on the line, in contrast to ^M after a pattern search,
which would leave one in ex at the appropriate line.  In general,
I think such changes would lead to greater simplicity and learnability
of the editor.
     I would also hope that excursions between vi and ex and back
could be allowed in scriptfiles.  It might also be desirable for
ex to have, in addition to a concept of ``current line'', one of
``current cursor position''... .

     Well, on to another subject.  One of the inconveniences I
found very vexing when first learning to use the editor was that
when in either vi insert mode, or ex/vi-bottom-line, it was very hard
to edit what I was doing.  Within insert mode the only ``editing''
I could do, without escaping, was with the three operations ^H,
^W and the kill character.  And on a slow line with a dumb terminal,
escaping to make changes could be very time-consuming because large
parts of the screen would insist on being redrawn.  Perhaps some
other control-character could serve as
a modified escape, that allowed one to edit what one had entered
in the current insertion without having everything below it redrawn,
and then return to it.  Obviously, if carried to its logical
limit this idea could lead to ridiculous nests of
editing operations; but there would be no need to carry it to its
logical limit.
     Anyway, the problem of editing ex-style commands
was even worse, because there was no way to ``escape and
revise''.  I eventually learned enough to realize that the solution
was to edit complicated commands in another file and source it.
But it is sometimes very useful to have the text on which the
commands are to act in front of you when composing them (e.g., you can
yank and modify various pieces), which led to the variant of writing
command lines within the file I was editing, and then writing
those lines into another file and sourcing that, without ever leaving
the current file.  But this is distracting to deal with
when concentrating on the editing task itself, which led me
to divise a scriptfile which would handle the writing-to-another-file-
and-sourcing for me.  Or actually, several such files:  One for
single-line commands to be used essentially once; one for single-line
commands that I would want to use on the same file during various
editing sessions, and so would want to keep available in that
file, and one for multi-line commands (to be used once).  When
I first got the idea, I thought one scriptfile would be enough, and
I would call it ``do'', so that the command to execute a script I
had written in a file I was editing would be ``:so do''.  The
file it would write to and source would be ``do.again'', so that
if I wanted to reuse it, I could ``:so do.again''.  When I realized
the need for several versions, ``do'' became a directory.  Here,
for your amusement, are the three files.  (Re the lines ``se prompt'',
cf. my comment on that under PROBLEMS WITH SOURCE etc.):

  do/1  (for 1-time use of 1-line commands)
	.w! ~/do/again
	d
	so #
	se prompt

  do/1+  (like above, without deleting the command)
	.w! ~/do/again
	so #
	se prompt

  do/:  (to use this, write a multi-line command script, put : at
  the beginning of the first line, put the cursor on the last
  line of the script, and then source the following:)
	?^:?s/:/
	,''w! ~/do/again
	,''d
	so #
	se prompt

(I also created another version to use in case the script had
to have an internal line beginning with ``:'', so that this couldn't
unambiguously mark the beginning of the script.  This used
a line which explicitly specified the address-range of the script.
But I have never had a need for it, so I will not bother you with it.)
    Finally, having gotten an account on a machine with a version 3
editor recently, I have divised still another way of doing this.  I
have put in my EXINIT the command

	'map ^A "ayy:@a^M'

and now, gratifyingly, the single stroke ^A has essentially the effect
of ``:so do/1+''  -- except for the restrictions to which vi ``map''
commands are subject.  But I've only been using this for a
couple of weeks; so I have yet to learn how chafing those restrictions
will or won't be.
     Anyway, it might be worth thinking about whether some of these
things that I've done with macros should be incorporated in some form
into the editor itself; or else whether these macros might be written
up in the documentation (or some tutorials) on the editor.

     Next subject: Complicated pattern-searches in long files
can be time-consuming.  I have seen the point mentioned
that if a pattern-description can be begun with "^",
this can speed up the search -- since the pattern-comparisons need
only be begun at beginnings of lines.  In some cases, this might
not be possible, but the user might be aware of some other
character or character-sequence in the search-pattern
that will occur relatively rarely in the file.  In such cases it would
be desirable if the user could specify one spot from which the pattern
search should start, working forward and backward from there, to
minimize false starts.  E.g., if for some reason one wants to
delete every word containing the letter m, the script
	%s/[^ ]*m[^ ]*//
would become much less time-consuming if one could mark the point
at which to begin, say writing
	%s/[^ ]*\!m[^ ]*//
so as to instruct the editor to search for m's, and each time
one was found, to find the longest possible strings of non-space
characters before and after it, and delete these.   (This is a silly
example, but I think the idea is clear.)

     Something that I've seriously felt the need for is the
capability of searching for lines that satisfy more than one
condition.  If one just wants to locate such lines, one can
of course leave the editor and do a pipeline of two or
more greps; but it would be nice to be able to perform global
commands on such lines.

    Finally, any possibility of introducing the capability of searching
for patterns including embedded newlines, a la sed?  Multiple windows,
a la emacs?

ADDENDA
     I logged in this morning on an adm3a at 300 baud to go over this
letter once more before sending it, and ran into another bug!  I had
done 15^D to get a large scroll despite the low speed, and at one point
I saw a line with a typo scrolling up.  So I noted its line-number, 402
and without waiting for the screen to stop moving typed something like
402Gfsrd.  What happened was that the change was made on line 407 rather
than 402 -- presumably the cursor was sent to where 402 had been when
the command was received... .
     Editing this letter this morning reminded me of another feature I
have thought would be desirable for editing on dumb terminals at low
speeds:  An option that would cause lines read from a file or typed
in at the bottom of the screen to appear double spaced, with @ signs
@
between them, such as one gets when one deletes a line on such a
@
terminal.  (I have faked this effect here, though the fake will not be
@
very successful if you have  se nu  or  se list  on.)  The point is that
@
editing operations that presently cause painfully slow screen-redrawings
would simply put material in in place of these fillers -- as happens
now when one is lucky enough to be adding material just above a place
where material was previously deleted.

		-  *  -  *  -  *  -  *  -  *  -

    I hope you've found some things of interest in this hodgepodge.

				Yours,
				George (gbergman@brahms)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
23/7/83, about 8PM

     Maybe thinking about the editor while writing my previous
``note'' to you has made me more conscious of these things,
but for some reason, I've discovered several more peculiarities of
the the Version 3.7 editor today!

     First, the abbreviation feature has a strange bug (feature?)
involving the backslash:  If some string X is the abbreviation
for a string Y, and if X is typed (following a space etc)
immediately followed by a \ and another character c, the
result is not Y\c by cY\.  The case where I discovered this
was a doubly complicated one: I had an abbreviation of
the form
	:ab x x\yZ
where x and  y  were characters and Z was a string of characters.  
So when I typed  x,  it presumably first expanded it as x\yZ,
then performed the transformation I just described on the x\y
turning it into  yx\yZ\, and thus giving the result yx\yZ\Z.
This turns out to be one of the cases that can't be unmapped
without doing :una ^Vx.  Further, I just tried a similar case
with x replaced by a string of more than one character
(namely, :ab if if\pq)  and I find I can't unmap that at all.
     I also find that an abbreviated string containing | (which
must be inserted using ^V|, of course) is difficult to unmap.

     Second, some peculiarities about where the cursor ends
up after a yank.  If the yank involved a forward movement,
the cursor stays where it is, which is the beginning
of the yanked segment.  If the yank involves a backwards
movement, the place where the cursor originally was is not
the same as the beginning of the yanked segment, and there
seems to be some confusion as to which principle is followed:
y- or yk moves the cursor up, while yb leaves it fixed.
Unfortunately, there is a snake in the grass with yb: If
you hit p after it, the yanked word will not appear after
the position where the cursor has remained, but
after the position to which it would have gone if it had moved
to the beginning of the yanked segment!  Likewise if you
you hit an x... .
     (You have no idea how much trouble I'm
having with those "if"'s.  Of course, I could quit the editor
and come back in, and I would lose that crazy abbreviation
that way.)

     I also notice that if the cursor is at the end of a word
or between words, 2e behaves the same as e!

     Finally, I note that d^, when the cursor is before the first
nonwhite character, is another exception to the principle that
d[motion] deletes everything through the endpoint of [motion].
Similarly with c^ and y^.

- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *
discovered next day (not yet sent):

error with yb does not just concern p and x: any command is
executed as though cursor is at destination of backward in-line
yank.

N^B does not work consistently?  (Not on a medium-length file in Kim)

Can get endless-loop mapping if abbreviation forms word within
abbreviated.  E.g. :ab x ( x )
``word'' must be delimited on left by space, tab,
newline, start-of-insert; on right by any punctuation.  Why
special ``no tail recursion'' rule?
     Things like that ``if'' abbreviation can be undone using
:una i^Vf!

Mention desirability of Np

copies sent to ralph@ucbarpa, lindahl@topaz 25/7/83

From gbergman@UCBCARTAN Mon Aug  1 14:19:27 1983
Date: 1 Aug 83 14:14:06 PDT (Mon)
From: gbergman@UCBCARTAN (George Mark Bergman)
Subject: Re:  editor
Message-Id: <8308012114.AA00627@UCBCARTAN.ARPA>
Received: by UCBCARTAN.ARPA (3.342/3.7)
	id AA00627; 1 Aug 83 14:14:06 PDT (Mon)
Received: from UCBCARTAN.ARPA by UCBERNIE.ARPA (3.336/3.7)
	id AA19324; 1 Aug 83 14:19:12 PDT (Mon)
To: mckusick@UCBERNIE
Status: R

Here's Mark Horton's reply to my letter on bugs

>From mark@cbosgd.UUCP Thu Jul 28 14:38:55 1983

Sorry this has taken so long, but your note was too long to digest
in the cracks between the other stuff I do.  Anyway, you've clearly
put a great deal of thought into this, and I appreciate your input.
I'll reply individually to your thoughts, and keep them on file
for use (someday) when vi gets rewritten.  Some of them are just
plain bugs that ought to be fixed soon anyway.

	PROBLEMS WITH COUNTS

	     The most gross case of misbehavior is that of N^B!
	The effect is to redraw the screen 23N-44 lines further advanced.
	(Probably the numbers depend on the screen-size of the terminal;
	this is on a Z19, using termcap h19u.)  When N=1, this does indeed
	move you a screenful backward, but for higher N it moves the window
	forward some amount!  Further, whatever controls are supposed to
	monitor whether the command would land one at an acceptable line-
	number seem to have a different idea of what it is doing:  If you
	aren't already familiar with these weird effects, try setting the
	cursor near the end of a file that is more than 4 screenfuls long,
	and hitting 3^B.  (You might then try an insert at the place you get
	to, and a :f^] .)
This is a known bug, and was fixed in 3.8.  The count is supposed to subtract
(LINES-1)*N from the line number, but there's + that should be a -, so it
goes forward instead.  The check is correct, so it's possible to go off
the end of the buffer.
	     N/pattern/ would be useful, but is not allowed.
N/pattern/ resets the window size (silly but true) to N.
	     ND would be a natural synonym for dN$, by analogy with NC for cN$,
	but it doesn't work that way; it just ignores the N.
	     Finally, if N is precisely the number of lines
	from the current line to the end of the file,  N$  will still correctly
	carry one to the last character of the file, but cN$, NC, dN$ and yN$
	refuse to do anything!  (NY does work, not being a synonym for yN$.)
	The failure of NC is particularly annoying; often when I am composing
	something, I go back to somewhere in the middle of the next-to-
	last line, say, and want to rewrite the rest of the sentence;
	2cc would kill not only the part I want to rewrite but also the OK
	beginning of the line, and 2C or 2c$ won't work.  I realize that I
	could get around this by keeping an empty line at the end of the file,
	but that should not be necessary.
While you're making valid observations here, are you aware that you can delete
the current sentence with d} ?  I think that's what you really want.


	PROBLEMS REGARDING SOURCE, MACROS, MAPPINGS
	     These are enormously useful, but seem to have all kinds of hidden
	restrictions.

	     The Appendix to the Ex Reference Manual, "List of Changes from
	Version 3.5 to Version 3.6" says ``A bug which prevented the source
	command from working...from visual has been fixed''.  It is true that
	one can now use  :so  from vi, but it still has a bug:  When
	the scriptfile invoked contains a global command
	and some other command(s) after it, everything after the first global
	command is ignored.  The same appears to be true of scripts in named
	buffers invoked from vi-bottom-line by  @x.
Sounds like a bug.

	     (It is, perhaps, unexpected that one can invoke scripts with
	multiline commands using @x from vi's bottom-line at all, since such
	commands will not work if typed on vi's bottom line directly.
	A script like
		s/$/a\
		b
	invoked as @x will indeed work.  But strangely, if one tries to
	invoke from the regular mode of vi the script
		:s/$/a\
		b
	by putting it in buffer x and doing  @x, only the first line
	will take effect.)
In 3.7 (or 3.8, I'm not sure), you can say
	:s/$/a^V^Mb
to get a newline on the RHS.  Of course, this doesn't mean there isn't
a bug in scripts.
	 
	     Another serious restriction is that the command ``vi'' appears to
	be ignored in sourced ex-scripts, and though the command Q in macros of
	various flavors in vi (mapped characters, map!ed characters that contain
	``...^V^[...Q...'';  @x scripts) does take one into ex, any ex
	commands after it are ignored.
The internals of getting a character from the tty are completely different
in ex and vi.  Pushing input for one doesn't affect the other.  So there
isn't much hope of changing this situation.
	 
	     I assume you are aware of whatever restrictions lead to the
	error-message ``Cannot yank inside global/macro'', since you must
	have written it, though ``inside'' seems to here have the peculiar
	meaning ``after a text-changing operation of the macro.''
	     The error-message ``Can't undo in global commands'' is more
	mysterious, since I get it when I have a global command after
	a text-changing command in an @x script (though not in a sourced file).
	     Anyway, the fewer such restrictions these operations were subject
	to, the more useful they would be!
It's the way undo is done - the text for undo is saved in the "last deleted"
buffer, and yank puts text there too.  Couple this with the fact that globals
and macros can be undone as a unit (they save their state before the first change)
and you'll see that the two notions can't coexist.  Of course, you can always
yank into a named buffer, even inside a macro.

	     Although nested source commands are allowed (and I find them
	useful), they leave the editor in a ``noprompt'' state.  This
	can be gotten around by including ``se prompt'' as a line in the
	outermost scriptfile, but I would hope the problem causing it could
	be cured.
Bug, I guess.

	     When one tries to ``:unmap!'' a ``:map!'' command whose
	right-hand-side begins with ^H (entered as ^V^H, of course), one
	gets the message ``That macro wasn't mapped''.  (One can get around
	this by using :unmap! ^V[character].)
Bug, I guess.

	     Certain termcaps apparently produce automatic mappings, which
	unfortunately may interfere with useful vi commands.  In particular,
	on a tvi, ^L gets mapped to a movement command, which makes it
	unavailable for redrawing the screen, unless unmapped.
Well, there's no way for vi to tell the difference between ^L that the
user typed as ^L and ^L that the user typed as right arrow.  However, there
are a number of terminals that are upward compatible with the adm3a and use
^L for right arrow.  Vi has a special case for these built in - if the
terminal has insert/delete line, and ^L is right arrow, then ^R will redraw
the screen.


	PROBLEMS WITH DIAGNOSTICS

	"Hit return to continue" -- It took me a long time to realize that
	when I got this diagnostic there was an alternative to hitting
	return.  I suggest it be reworded
		"Hit Return or :"
	However, the behavior of the editor when this diagnostic is given
	seems to be inconsistent.  In particular, when the last of a serious
	of commands is
		:e otherfile
	and I get "Hit return to continue", then hitting : usually
	has no different effect from hitting return (or any other
	key), namely the screen is redrawn; yet I think that sometimes
	in this situation it has brought me directly to the bottom line
	as desired.  Very confusing.
	     Would it be possible to have other alternatives than : and return
	available, such as /pattern ?  Or, more simply, when one would presently
	be given the diagnostic "Hit return to continue", why not just put the
	editor into the state it would have if one then hit :, since one would
	then still have the option of hitting return and getting into vi
	proper, but it would not require the extra keystroke : to
	begin a bottom-line command, nor would one go through the frequent
	frustrating experience of absentmindedly starting to write a
	bottom-line command, or a pattern-search, and then having to wait
	while the screen was redrawn because one had hit a key other than :.
There is an internal difference between "ex mode" (where it doesn't keep a
screen image) and "vi mode" (where it does).  Any : command that outputs more
than 1 line puts you into "ex mode", requiring "hit return to continue"
before clearing the screen and redrawing it with known stuff.  There is no
hope of this changing - the code is too spaghetti-ized already.  In the worst
case, the ! command scribbles on the screen and there's nothing vi can do
to know what the command did.

What you really want is for vi to check for typeahead and avert the refresh
when it's going to have to redo it anyway.  My curses does this, but I simply
don't have time to rewrite vi to use it.  This would also solve the other
problem you mention where macros ought to redraw the screen only once.
If you saw the insides of the code, you'd see it needs a rewrite to do this.
Each command knows the screen things to do to fix the screen.

What most of us do is hit DEL when the screen is being drawn with something
we don't want to see.  This aborts the update and leaves junk on the screen.
Then you move the cursor where you want it, and if the screen is still
garbaged, hit ^L.  Ugly but effective.

	"Using open mode"
	Again, it took me a long time to learn that when I tried to enter
	vi and got this diagnostic, it meant that the system had somehow
	lost the termcap for the terminal I was on, and that I would have
	to do something to get the correct termcap into the environment.
	Till I realized this, I generally ended up either struggling along
	frustrated in open mode, or logging out and logging back in.  I suggest
	that when someone calls for vi and the termcap is not appropriate,
	the editor should not be invoked in any form, but instead, a message
	be given such as:
	     ``Your environment does not show a termcap entry permitting
	the use of the visual editor.  If you are working on a terminal not
	supporting vi (in particular, a device with no addressable cursor),
	you may enter one of the other modes of the editor with the command
	"open filename" or "ex filename".  If you are working on a terminal
	that should support vi, your environment entries are incorrect and
	should be corrected.  They presently show:
	     TERM=....
	     TERMCAP=....
	If you know the correct name or abbreviation for your terminal-
	type, type it at the end of the next line; if not hit return:
	     % setenv TERM ''
	     If the user typed an acceptable terminal-name, the message would
	continue, telling how to get the appropriate termcap.  If the user
	instead typed return, the message would ask him or her to type the
	name of the manufacturer shown on the terminal, not
	worrying about upper/lower-case distinctions, and a list of possible
	terminal names and abbreviations would be given... .  This whole
	program would not be part of the editor, so there would
	be no problem of space within the existing crowded confines of
	the editor code.
This, of course, doesn't belong in vi, but in login or tset.  In fact,
tset is much friendlier these days.  Vi will print a better diagnostic
if it knows you're on a "generic" terminal type such as "dialup" - in
terminfo there's a capability to indicate this, so it can print
	I don't know what kind of terminal you have - all I have is "patchboard"
3.7 can't do this because it can't tell the difference between a generic
terminal and a hardcopy terminal.

	"No such file or directory" -- I think there should be a distinction
	between these two cases, because of the important distinction in the
	consequences when the user tries to quit the editor:
The kernel doesn't distinguish, so it's hard for vi to.  This is just a perror
string.
	If the directory exists, the file is created, but
	if not, the results are more complicated -- I seem to recall on one
	occasion simply losing what I had written on my second try
	at quitting; though I just now did an experiment and this time
	repeated ZZ's and :x's simply gave repeated error messages.
Well, if it can't be reproduced, it doesn't stand much chance of getting fixed.
(Not that it would if you could reproduce it, of course.)

	"File already exists..." -- The ``List of changes from 3.5 to 3.6'' says
	``If you get I/O errors, the file is considered "not edited"... .''
	I presume that this correction is somehow the cause of the fact that
	I frequently get the above message when trying to leave the editor
	on a machine with version 3.7, and have to use
	      :w! %|q
Ick!  Most of us just type
	:wq!
which is equivalent and much shorter.
	to exit.  But I've never seen any evidence that there were I/O errors;
	it mainly seems to happen when I've written some lines to another
	file in the process of editing.  So the criteria the editor is using
	to decide when there have been ``I/O errors'' should be rechecked.
Actually, if you get ANY error (e.g. :foo<cr>) it resets the "buffer modified"
condition.  I have finally been convinced this is not right.  For a while, I
considered it a necessary evil in case your /tmp/Ex* file got an I/O error.

	"no such command from open/visual" -- This confused me in my first
	few days of using the editor, when I didn't understand that one
	couldn't use i and a (in either their vi or ex senses) from the bottom
	line of vi.  A message "i -- no such command from open/visual"
	was perplexing because I knew that "i" was indeed a vi command.
	Perhaps it should say  "no such command from open/visual bottom line".
OK.

	MISCELLANEOUS PROBLEMS

	     In ex search and replacement patterns, \\ is supposed to represent
	a real \-character, but something goes wrong when this occurs
	at the end of a global command.  E.g., though
	     :s/^/\\
	works OK (in vi or ex), the variant
	     :.g/^/s//\\
	definitely does not.  In vi it turns everything off, in ex it seems to
	behave as though there were just a single \, and in a scriptfile,
	it -- does something still different, which you can discover if you
	don't know!
Backslash is special at the end of a line in global.  You need more \\'s.

	The Ex Reference Manual says, ``For sanity with use from within
	visual mode, ex ignores a ":" preceding any command.''  But it
	ignores it in the wrong place! -- not at the beginning of the
	command line, but just before the command letter itself.  I.e.,
	it accepts 1,3:s/^/     /, but not :1,3s/^/    /.
Hmm.

	SUGGESTIONS FOR MINOR ADDED CAPABILITIES

	   In a multiline substitute command with the "c" option, when
	each line is displayed one has three choices: y, n or break.  There
	are some further options that would be useful.  One would be "p" --
	at present, "p" can only be included on the command line, which
	means that one has a choice between seeing the result of every
	substitution or none.  In practice, one would generally like to see
	the results of the first few cases to make sure that the command one has
	written does what one meant it to, and maybe a few tricky cases that
	come up; but not every case!   Another might be "u" -- to undo the last
	case for which one gave a "y".  Still another might be an option that
	would mean ``undo the "c" option -- I see that the substitute command
	is doing what I wanted, go ahead and finish it without me.''
If I were going to do something this involved (I didn't know anybody used the
c option anymore - most people use "n" and "." in vi) I would do query-replace
ala EMACS right.
	    In a command  g/pattern/p,  the pattern in question is occasionally
	such that it takes a while to figure out where on the line it occurs.
	For this purpose, an option that ``pointed out'' the instance of the
	pattern, in the same manner that the pattern to be replaced is pointed
	out in substitute command with option c, would be desirable.
	    When  g/pattern/p  gives more than a screenful of lines, it would
	be nice to have it piped through the equivalent of ``more''.
Nice but unlikely.  Unless, of course, you have page mode in your tty driver,
like we do, in which case you get it for free.

	    ex has the command line option "-", which ``is useful in processing
	editor scripts''.  But if one wants to use a script in the course of
	an otherwise interactive editing session, it would be desirable to have
	a corresponding resettable option ``:se -'' (or ``:se nofb'').
Seems like a good idea.

	     In strings in pattern-searches, it would be useful to have
	^ and $ retain their ``magic'', so that /x[a$]/ could
	search for all occurrences of  x  before an  a  or a newline.
	(Of course, one would then have to decide whether  /x[^y]/ should
	include the case of  x  followed by a newline or not.)
This sounds pretty hard to do.

	    Just as ex allows the command :vi, so I think that vi should
	have some bottom-line command equivalent to the regular-mode
	command  Q.  When one has done some text-changing bottom-line
	commands, and realizes one wants to go into ex, it can be time-
	consuming to hit return and then Q, and wait for the screen to be
	redrawn for vi before one gets the ex prompt.
This would be ugly, since the ex command routine would have to return an
indication to the vi routine to exit back to the top level ex command.
But I suppose it could be done.

	     The option of putting several commands on one line, separated
	by, "|" is particularly useful in the vi bottom-line mode, because
	it avoids having the screen redrawn several times.  It would be
	useful to be able sometimes do the same thing with non-bottom-line
	commands, e.g. in editing a troff file at a low baud rate on a dumb
	terminal one might like to be able to do  i\fI^]3Ea\fR^]  without
	watching the line get redrawn twice.  Perhaps some key that would
	cause any sequence of commands to be ``held'' until some complementary
	key was hit would be useful.
	     It would also be desirable to have a sequence of commands that had
	been given in this way available as one unit to be repeated by ``.'',
	if desired.
See above.  And get yourself a terminal with insert/delete char!

	     The parenthesis-matching facility with % might be extended
	to match ` with ' and <  with  >.
OK.

	     I will mention one facility that I discovered by surprize is
	possessed by  ed  but not  ex  --  sequences such as  \1  can be used
	within  ed  search-patterns.  E.g. (for the most trivial case)
	     /\(.\)\1/
	will search for doubled letters.
This surprises me.


	DEBATABLE SUGGESTIONS
	     I will mention here some possible changes which have the
	difficulty that they would change the meaning of existing commands,
	so that it could be argued that the disadvantage of users having
	to change their habits might outweigh the advantages.

	     First, one might try to resolve, one way or another, the
	contradiction between the count arguments taken by the join commands
	in  vi and  ex:  In ex, jN joins N+1 lines; in vi, NJ joins N lines
	(except if N=1).
Yeah, ex should be N, not N+1.

	     Second, the movement commands  tx  and  Tx  of vi (x any character)
	seem poorly defined.  Just as fx will ignore the character on which
	the cursor is presently sitting, even if it is an  x,  and move to the
	next occurrence, so I would think that  tx  should ignore the character
	immediately after the cursor, and  Tx  the character immediately before
	the cursor.  The point is that when one does  Nfx,  and finds that one
	had failed to count one occurrence of  x  and fallen short of where one
	wanted to go, one can hit  ;  and get there.  Likewise, on doing  Ntx
	and finding one has fallen short, one should be able to hit  ;  and get
	to the the next occurrence; but at present, hitting  ;  leaves
	the cursor in the same position; one must hit  ``2;''  to get any
	further.  In effect,  Ntx  is presently defined as  Nfxh;  I am
	suggesting that it be defined as  lNfxh.
Agreed.

	     The sequences  cw, dw  and  yw  are presently violations of the
	principle that  c[movement],  d[movement]  and  y[movement]  change,
	delete, or yank everything from the current cursor position through
	the endpoint of the movement command.  cw does what one would expect of
	ce (in fact, they seem to be synonyms), while there is no way to get
	the effect which  cw  would have if it were treated ``consistently''.
	(E.g., if I have a line beginning  ``And if'', and I want to change it
	to ``If'', I cannot just put the cursor on the A and hit  cwI^].)  dw
	and  yw  delete up to the character immediately before the point to
	which ``w'' would take the cursor.  I would have to agree that this
	behavior of dw and  yw  is more useful than that which a literal
	interpretation of the movement rule would lead to; but perhaps it
	would become still more useful if when applied to the last word on
	a line, it deleted or yanked the space immediately before the word
	along with the word... .  On the other hand, one could argue for
	making a distinction between  cw  and  ce.
This is to make the user interface friendlier, and is a fact of life.
If I wanted to change "And if" to "If", I'd type "dw~".

	     Though I see the motivation for the above definitions,
	I see no sensible reason why  Y  should be equivalent to  yy,  when
	C  and  D  are equivalent to  c$  and  d$.  I would vote for changing
	Y  to mean  y$.  
The users wouldn't stand for such a change.  Too many are used to it like it is.
But you could always map it.

	RADICAL SUGGESTIONS

	     Is there any reason for maintaining the distinction between
	the ``:'' state of vi, and  ex  itself?  At present, there are
	relative advantages that lead one to choose to go into one or the
	other for a given operation:  From the vi-: state, it is easier
	to return to the regular vi state; from ex, one has a more powerful
	range of commands; and it is easier to give a series of commands
	because each carriage-return gives one a new prompt.  My suggestion
	is that from vi, ``:'' should carry you directly to ex, and when you
	are in ex, carriage-return (^M) after a command should give you a new
	prompt, while ^] should put you into vi.  Conceivably, things might be
	simplified even further, and carriage return rather than : could
	be the key that would carry one from the regular mode of vi into ex:
The basic problem here is that if : put you into ex mode, you'd have to redraw
the screen when you hit return.  The motivation for : commands is that you
don't have to go through a conceptually hard mode change and wait for a
screen redraw.

				 .-------.	.-------.
		.-------. a,i... | basic |  ^M	|	|
		|  vi   |<------ |	 |----->|  ex	|<---.
		| insert|	 |   vi  |	|	|    |^M
		|  mode | ------>|	 |<-----| mode 	| ---'
		`-------'  ^]	 |  mode |   ^]	|	|
				 `-------'	`-------'

	(Of course, ^M presently has a meaning in vi, but
	it has a synonym +.)  Clearly, there would also be no need for a
	special "Hit return to continue" state.
	     I have not distinguished vi and open in the above diagram.
	My idea here is that ^] would actually return you to either vi
	or open, whichever you had last been in, and that to switch
	to the other, you could enter ex and type vi^] or o^] respectively.
	(Or you could type  vi^M, respectively o^M, and further ex commands,
	and the mode would be saved for the next time you hit a ^].)  Or
	alternatively, these could be made settable options: se visual
	respectively se novisual.
	     Having gotten used to the editor as it now exists, I admit that
	I feel uneasy about the above idea -- the sense of knowing that
	I am ``still in vi'' when I hit :, and not that ``other land'' of ex, 
	represents a kind of of orientation that it is disconcerting
	to abandon.  But I can't see any logical disadvantage in making
	such a change.  Can you?  Certainly, there would be things that
	would have to be thought out, such as what happens to bottom-line
	vi pattern-searches.  My thought would be that ``/'' from vi should
	give :/ (i.e., put one in ex at the start of a pattern-search),
	and ^] after a pattern-search should put one into vi at the appropriate
	character on the line, in contrast to ^M after a pattern search,
	which would leave one in ex at the appropriate line.  In general,
	I think such changes would lead to greater simplicity and learnability
	of the editor.
	     I would also hope that excursions between vi and ex and back
	could be allowed in scriptfiles.  It might also be desirable for
	ex to have, in addition to a concept of ``current line'', one of
	``current cursor position''... .

	     Well, on to another subject.  One of the inconveniences I
	found very vexing when first learning to use the editor was that
	when in either vi insert mode, or ex/vi-bottom-line, it was very hard
	to edit what I was doing.  Within insert mode the only ``editing''
	I could do, without escaping, was with the three operations ^H,
	^W and the kill character.  And on a slow line with a dumb terminal,
	escaping to make changes could be very time-consuming because large
	parts of the screen would insist on being redrawn.  Perhaps some
	other control-character could serve as
	a modified escape, that allowed one to edit what one had entered
	in the current insertion without having everything below it redrawn,
	and then return to it.  Obviously, if carried to its logical
	limit this idea could lead to ridiculous nests of
	editing operations; but there would be no need to carry it to its
	logical limit.
Why not just get a terminal with insert char?  You're paying in performance
for having an obsolete terminal.
	     Anyway, the problem of editing ex-style commands
	was even worse, because there was no way to ``escape and
	revise''.  I eventually learned enough to realize that the solution
	was to edit complicated commands in another file and source it.
This is a standard complaint about a moded editor.  It couldn't be fixed
without taking away the property of ESC ending command lines.  Besides,
allowing editing on the bottom line would really break a lot of code.
	But it is sometimes very useful to have the text on which the
	commands are to act in front of you when composing them (e.g., you can
	yank and modify various pieces), which led to the variant of writing
	command lines within the file I was editing, and then writing
	those lines into another file and sourcing that, without ever leaving
	the current file.  But this is distracting to deal with
	when concentrating on the editing task itself, which led me
	to divise a scriptfile which would handle the writing-to-another-file-
	and-sourcing for me.  Or actually, several such files:  One for
	single-line commands to be used essentially once; one for single-line
	commands that I would want to use on the same file during various
	editing sessions, and so would want to keep available in that
	file, and one for multi-line commands (to be used once).  When
	I first got the idea, I thought one scriptfile would be enough, and
	I would call it ``do'', so that the command to execute a script I
	had written in a file I was editing would be ``:so do''.  The
	file it would write to and source would be ``do.again'', so that
	if I wanted to reuse it, I could ``:so do.again''.  When I realized
	the need for several versions, ``do'' became a directory.  Here,
	for your amusement, are the three files.  (Re the lines ``se prompt'',
	cf. my comment on that under PROBLEMS WITH SOURCE etc.):

	  do/1  (for 1-time use of 1-line commands)
		.w! ~/do/again
		d
		so #
		se prompt

	  do/1+  (like above, without deleting the command)
		.w! ~/do/again
		so #
		se prompt

	  do/:  (to use this, write a multi-line command script, put : at
	  the beginning of the first line, put the cursor on the last
	  line of the script, and then source the following:)
		?^:?s/:/
		,''w! ~/do/again
		,''d
		so #
		se prompt

	(I also created another version to use in case the script had
	to have an internal line beginning with ``:'', so that this couldn't
	unambiguously mark the beginning of the script.  This used
	a line which explicitly specified the address-range of the script.
	But I have never had a need for it, so I will not bother you with it.)
	    Finally, having gotten an account on a machine with a version 3
	editor recently, I have divised still another way of doing this.  I
	have put in my EXINIT the command

		'map ^A "ayy:@a^M'

	and now, gratifyingly, the single stroke ^A has essentially the effect
	of ``:so do/1+''  -- except for the restrictions to which vi ``map''
	commands are subject.  But I've only been using this for a
	couple of weeks; so I have yet to learn how chafing those restrictions
	will or won't be.
	     Anyway, it might be worth thinking about whether some of these
	things that I've done with macros should be incorporated in some form
	into the editor itself; or else whether these macros might be written
	up in the documentation (or some tutorials) on the editor.

	     Next subject: Complicated pattern-searches in long files
	can be time-consuming.  I have seen the point mentioned
	that if a pattern-description can be begun with "^",
	this can speed up the search -- since the pattern-comparisons need
	only be begun at beginnings of lines.  In some cases, this might
	not be possible, but the user might be aware of some other
	character or character-sequence in the search-pattern
	that will occur relatively rarely in the file.  In such cases it would
	be desirable if the user could specify one spot from which the pattern
	search should start, working forward and backward from there, to
	minimize false starts.  E.g., if for some reason one wants to
	delete every word containing the letter m, the script
		%s/[^ ]*m[^ ]*//
	would become much less time-consuming if one could mark the point
	at which to begin, say writing
		%s/[^ ]*\!m[^ ]*//
	so as to instruct the editor to search for m's, and each time
	one was found, to find the longest possible strings of non-space
	characters before and after it, and delete these.   (This is a silly
	example, but I think the idea is clear.)
Isn't worth doing - this is fast enough for most people in most cases.

	     Something that I've seriously felt the need for is the
	capability of searching for lines that satisfy more than one
	condition.  If one just wants to locate such lines, one can
	of course leave the editor and do a pipeline of two or
	more greps; but it would be nice to be able to perform global
	commands on such lines.
You want the PWB "or" operator.  This is hard to put in - their code
is really convoluted.

	    Finally, any possibility of introducing the capability of searching
	for patterns including embedded newlines, a la sed?
Newlines aren't stored - the data structure is an array of lines.
So this is nearly impossible.
	Multiple windows, a la emacs?
Would be easy after a rewrite, but impossible with current code.
What you really want is a window manager, anyway, most of the time.

	ADDENDA
	     I logged in this morning on an adm3a at 300 baud to go over this
	letter once more before sending it, and ran into another bug!  I had
	done 15^D to get a large scroll despite the low speed, and at one point
	I saw a line with a typo scrolling up.  So I noted its line-number, 402
	and without waiting for the screen to stop moving typed something like
	402Gfsrd.  What happened was that the change was made on line 407 rather
	than 402 -- presumably the cursor was sent to where 402 had been when
	the command was received... .
Knowing the internals of vi, I'd say this is impossible.  It probably just
screwed up your screen from line noise (or your terminal isn't truly full
duplex), or you got the wrong line number.
	     Editing this letter this morning reminded me of another feature I
	have thought would be desirable for editing on dumb terminals at low
	speeds:  An option that would cause lines read from a file or typed
	in at the bottom of the screen to appear double spaced, with @ signs
	@
	between them, such as one gets when one deletes a line on such a
	@
	terminal.  (I have faked this effect here, though the fake will not be
	@
	very successful if you have  se nu  or  se list  on.)  The point is that
	@
	editing operations that presently cause painfully slow screen-redrawings
	would simply put material in in place of these fillers -- as happens
	now when one is lucky enough to be adding material just above a place
	where material was previously deleted.
Again, it would cost less to buy a real terminal.  You can get one for $500
or so now from Falco or Liberty or Zenith.

Thanks again for the input.

	Mark


From gbergman@UCBCARTAN Fri Jul 29 16:07:10 1983
Date: 29 Jul 83 16:02:06 PDT (Fri)
From: gbergman@UCBCARTAN (George Mark Bergman)
Subject: editor
Message-Id: <8307292302.AA09635@UCBCARTAN.ARPA>
Received: by UCBCARTAN.ARPA (3.342/3.7)
	id AA09635; 29 Jul 83 16:02:06 PDT (Fri)
Received: from UCBCARTAN.ARPA by UCBERNIE.ARPA (3.336/3.7)
	id AA06658; 29 Jul 83 16:07:04 PDT (Fri)
To: cc-03@ucbcory, danh@kim, lindahl@topaz, mckusick@ernie, ralph@ucbarpa
Status: RO

29/7/83
    I got a reply from Horton: a copy of my (first) letter,
annotated with comments that this should indeed be fixed, that
would be impossible, etc..  I'll send a copy to anyone who'd
like (or a copy of his comment on some specific bug they're
interested in).  Meanwhile, I'll send you my reply to him, since
it discusses still more bugs and possible improvements.

Dear Mark,
     Got your comments on my first letter!  Did you get the second,
shorter one?  Glad to see that some things, at least, can be fixed.
     Robert has put version 3.9 on this machine and I'm using it.
Using movement arrows within insert mode is amusing; though when there
is documentation, there should be a warning to the user that these
prevent ``u'' from undoing anything before those commands.  But
the first thing there needs to be documentation for is vedit!  Is
any being written?
     In your comment on ``Can't yank inside global/macro'' you said
that one can, of course, always yank to a named buffer.  I checked,
in the case of @a scripts, and the answer is yes and no:  The yank
works, but one still gets that diagnostic, and anything else in the
sequence of commands is aborted.
     And concerning the diagnostic ``Can't undo in global commands'' --
I understand what you say about why one can't, but it still seems an
unenlightening and perhaps inappropriate diagnostic to get when one has
done  @a  and buffer  a  contains say
	x:g/foo/s//bar
Here the initial ``x'', deleting the character the cursor was on when
the command was given, creates the text-modified condition which,
as I mention, seems to cause globals in @-scripts to give this
diagnostic.  I've just tested the above script -- several times,
because I found it hard to believe what was happening -- and it did
indeed give the diagnostic in question, but instead of replacing foo's
with bar's, it replaced the first line containing a foo with a copy of
the last line of the file! I leave it to you to figure that one out!
(This is on version 3.9.  Incidentally, I've used a true ^M in that
script, so it is ready for you to try.)

     Further observations on some of the bugs I mentioned in my
second letter:  The business with  yb  is both more general and more
complicated than I realized.  The general fact seems to be that when
one does a yank to a position earlier on the same line, the cursor does
not move, but the editor thinks it has, so that any subsequent command,
e.g. a movement, a delete, etc., has the effect that it would if it had
been done with the cursor starting from the new position.  The
complication is that yanks to named buffers don't behave the same as
simple yanks: They also leave the cursor unmoved, but what they actually
yank into the buffer is the text from the cursor location to the end of
the line; and whether they cause the editor to consider the cursor to
be in a different location from where it really is seems to depend on
the movement in question:  with "ayNb, no, with "ayN|, yes (where N
again stands for a positive integer).  So what I called a snake in the
grass seems to be a can of worms!
     In experimenting with this, incidentally, I've found that, while a
put from a named buffer can be undone with u, if one attempts the
command U, ``undo all changes made since coming onto this line'', only
changes made since the last named-buffer-put are undone.
 
     I mentioned various abbreviations that were hard to unabbreviate,
but could be done with the help of ^V -- but that I had found no way
to undo
	:ab if if\pq
To be precise, I had found that  :una ^Vif,  :una ^V^Vif,  and
:una    ^Vif  where each ^V represents two ^V's typed in, didn't work.
I've finally found something that does:  :una i^Vf.

     I find the diagnostic ``No tail recursion'' strange,
since the occurrence of an abbreviation at the end of the item
abbreviated shouldn't cause a recursive loop; while circumstances that
do cause such a loop, namely the occurrence of the abbreviation within
the item abbreviated, preceded by a space and followed by punctuation,
are not censored, e.g. :ab x ( x ), or with more subtle effect,
:ab x x sup 2.
     It seems that if one has :ab x word,  then the abbreviation works
when x is preceded by a beginning-of-insert, a space, a tab, or a
newline, and followed by most any nonalphabetic character.  For
word-processing use, it would be natural to allow it to also be
preceeded by (, ", `, [, perhaps even a user-specified set of
characters.

     To my list of vi commands which I think should be able to take
counts, add p and P.  I often want to put in a large number of copies of
one or more lines, as ``forms'' in which I will enter various kinds of
additional data, and it would be convenient to be able to do compose
such a line and then duplicate it the desired number of times all at
once.  What I currently do is produce a copy and then go
yypk2yypk4yyp... till I have enough.

     Two more commands I think would be useful:  (1) One which "puts" to
the screen (in the sense of g/pattern/p, i.e. without affecting the
buffer) the contents, or the first lines in cases that are longer than
one line, of all nonempty buffers, named or numbered, with an
indication, of course, of which each was.  (Ideally one would like to
be able to specify some subset of the buffers, whether one wants the
first line, or everything, or some specified number of lines, etc..) 
(2) One which would show the script of the command stored to be used as
``.''.  (And perhaps ditto with the last search pattern.)
     Oh, yes: it would also be nice to have a way to give commands
without having them displace the one specified to be repeated by ``.'',
e.g. if one wants to do a certain change time after time at various
points in the file (using ``n'' and ``.'') but occasionally sees other
changes to be made along the way.  An alternative to the above would be
a way to read the command stored to be used as ``.'' into a named
buffer, so that one can give other commands and then return to
that one.  This would also allow one to reread the text of the command:
useful if it isn't behaving as one meant it to.
     
     You might as well send any future mail to me here as
gbergman@cartan -- I was using brahms while cartan's terminals were
being moved but I'll probably be using cartan more from now on.  But
I'll check mail on both.  (However, I'll be on vacation in New York
State from the 3d to the 16th of August.)
						Best regards,
						George

From gbergman@ucbcartan Fri Sep 23 13:57:06 1983
Date: Fri, 23 Sep 83 13:53:36 PDT
From: gbergman@ucbcartan (George Mark Bergman)
Message-Id: <8309232053.AA02960@ucbcartan.ARPA>
Received: by ucbcartan.ARPA (4.6/3.7)
	id AA02960; Fri, 23 Sep 83 13:53:36 PDT
Received: from ucbcartan.ARPA by UCBERNIE.ARPA (3.336/3.7)
	id AA20684; 23 Sep 83 13:57:01 PDT (Fri)
To: cc-03@ucbcory, danh@kim, lindahl@topaz, mckusick@ucbernie, ralph@ucbarpa
Status: RO

Latest letter on ex~vi to Horton:

Dear Mark,

     I hope I can assume that after my long letter to which you
replied, you did get my two shorter notes (one sent the same day,
the other about a week later); and that you've simply been to busy
to think about them or reply.
     However, since I have had bad experiences with Mail, I am worried
that either you may never have gotten them or that you may have replied
and your replies not reached me.  I hope you can send me a one-liner to
relieve my doubts.

     Not many bugs to report this time, but I will modify or discuss
a few of the suggestions I've made before.

     One that I want to modify is my suggestion that % should also
match < with > and ` with '.  All right in itself, but terrible if it
would also mean that with  :set match,  every time one typed a > or a '
the cursor would look for the last occurrence of < or `, since <, >, and
' can occur in ways that have nothing to do with matching.  So I think
that making matchable pairs user-specifiable would be much more useful.
Faith Fich (who send her regards -- she and Mike were our neighbors till
a month ago, but have left for their new jobs at U. Seattle) suggested
that user-settable matches would be particularly useful for those
like herself who use distinct opening and closing delimiters with eqn.
Actually, on further thought this isn't quite right, since eqn
delimiters behave differently from parentheses -- if I want to use =
as my delimiter to enter equation mode, and & as my delimiter to leave
it, then eqn will not give any special treatment to &'s in text mode or
='s in equation mode; so perhaps a different kind of matching for
that kind of use might be desirable; one would set  :set dmatch =&
for the delimiters suggested above; or :set dmatch $$  if one uses  $
for both delimiters as in the eqn tutorials.  I know checkeq is
supposed to serve this function; but it would certainly be convenient
to have it in the editor; and anyway, my experience was that checkeq
didn't understand that one could have distinct opening and closing
delimiters.  (But this is a disinterested suggestion; I haven't used
eqn for a long time; I put in my equations in raw troff.)

     The suggestion in my long original letter about an alternative to
the diagnostic "using open mode" was based on a misunderstanding -- but
one that might be worth making a reality.  I had been assuming,
since tutorials referred to the "three states" ex, vi, and open, and
since I knew one could enter the editor by typing  % ex filename or
% vi filename, that a third way to enter the editor was by typing
% open filename, and that this is what one should do when editing
with a device not having an addressable cursor (which I had never done).
So I supposed that the diagnostic "using open mode" would only be
received if one were trying to use the wrong mode of the editor for the
tty type shown in  one's environment.  Perhaps one should indeed have
special way to enter the editor when one intended to edit in "open
mode".  (If "open" has other uses as a command, the command might be
"vo" or "op".)  Then if a user gave the command vi and his
environment did not indicate a device with an addressable cursor, it
would indeed be appropriate to give a diagnostic informing him that his
environment was not compatible with this command.  I suggest this
because of the frustrating experiences I had as a beginner, of
being put into open mode (because my tty type had somehow been lost)
and not knowing what I could do about it.

     I am somewhat confused by your explanation that editor scripts
that would go back and forth between ex and vi modes (using the :vi
and Q commands) are impossible because "The internals of getting a
character from the tty are completely different in ex and vi.  Pushing
input for one doesn't affect the other."  A vi "script" (i.e. a mapping
or a macro called by @x) can presently include bottom-line commands
called with ":".  I would suppose that the way such commands get
characters from the terminal is about the same as the way ex does.
You also write that "Any : command that outputs more than 1 line puts
you into "ex mode"," -- is this a different sense of "ex mode"?  If
not, what happens when a vi script does this?
     I mentioned that the :so command from vi ignored anything after
any global command in the sourced file.  I also find that it will not
accept the ex commands i and a; I realize that a prohibition against
these is part of the way vi's bottom line differs from genuine ex.
I've just done some experimenting, and I find that a script sourced
from the bottom line of vi also interprets the command vi as a command
to edit another file.  Do we really want script files to be interpreted
so differently when sourced from ex mode and from the bottom line of vi?
Or if these differences are inevitable, can't the vi version at least
have the positive difference of being able to go to visual mode with
^M^M or something, and continue following the script, interpreting
characters as screen mode commands, just as a mapping or @x macro will
if it has gone down to the bottom line with ":" and come back again?
     I am also still reluctant to give up the idea of a version of the
editor in which there is no difference between the line-oriented mode
and the bottom line of the visual mode.  Suppose you took the editor as
it exists now, and modified it so that in visual mode, ":" was
interpreted as "Q", and in ex mode, ^[ was interpreted as ^Mvi.  The one
obvious disadvantage would be that it would insist on redrawing the
screen after minor editing operations in ex mode.  So suppose you made
it remember the previous state of the screen every time it entered ex
mode, and make the necessary adjustments on return to visual mode if the
editing done was fairly trivial -- using the same criteria it now uses
after bottom-line commands.  What would be the problem?
     Of course, I know I am quite ignorant of what is involved, and what
I am suggesting as possible may be quite impossible, or may have to wait
for that far-off day when you rewrite the editor.

     You write that some of the restrictions on global commands are due
to the fact that the state of the buffer before the command is stored in
the "last deleted" buffer.  But couldn't this situation be modified?
Let's call the "last deleted" buffer buffer 0, since material from it
seems to progress up to 1, 2, etc. with successive changes made.
Suppose things were set up so that during the operation of a global or
macro, deleted material, yanked material, etc. went by default into
buffer 1 instead of 0...?  Or alternatively, that the state before the
global were saved in buffer 9, and this was then set outside of the
chain of buffers into which material got pushed with successive
deletions, during the operation of the global?  Would this eliminate
the objection to nested globals as well?  Presumably, in a global within
a global, the previous state would be stored in buffer 1, and new yanks
put by default in buffer 2 (if the first of the above suggestions were
followed).
     You mention in your comments to my letter that the difficulty of
editing command lines "is a standard complaint about a moded editor"
that would be hard to fix.  But I point out in that same letter how
appropriate macros or script-files can overcome that difficulty.  (My
files "do/1", "do/:" and the "map ^A ..." in my EXINIT.)  It should be
possible to introduce commands that would have the
same effects as those macros.  (Or at least, to describe such macros
in the documentation.  I have realized, by the way, that ^A was a poor
choice of character for me to map, because it occurs in the output of
function keys on a lot of terminals.)

     It would be nice to extend the kinds of "regular expressions"
allowed in searches, e.g. a la egrep.  Sometimes I also want to indicate
something like "a substring of precisely 40 characters".  This can be
rendered as "........................................" at present,
but things like that can easily lead to commands that
exceed length limits.  (Suppose one wants to look for a string of
40 successive characters other than whitespace.  [^ ][^ ][^ ] ... is
too long.)  Have you checked out what I mentioned in my first long
letter, that ed allows you to search for (e.g.) successive
identical characters as \(.\)\1?

     Let me pass on a suggestion made recently in a system message by
someone named nye.  He was worried about what would happen
if while one person was editing a file, someone else with write
permission for that file also began editing it.  Presumably, whoever
did a "write" last would overwrite the other person's work.  He
suggested that there be a diagnostic "file has been changed since last
write" for such a situation.  (In particular, he wondered what would
happen if he got his mail by editing /usr/spool/mail/name, rather than
by using Mail -- which is certainly tempting if one is more comfortable
with the editor than with Mail -- and if unbeknownst to him new mail
arrived while he was editing.)

     I have discovered the hard way that when one has done a
vi -r filename  and decided one was satisfied with the version that
was saved, ZZ or :x are  n o t  the same as  :wq  -- the first two
discard the saved file, and only the last one writes it over the
previous version.  (I actually haven't checked this out on version 3.9.
I tried to, and found that robert hadn't brought
/usr/lib/ex3.9{preserve,recover}, if that's what they're still
called, from arpa along with the rest of 3.9.  But he's getting them for
me.)  If you don't want to make  ZZ  and  :x  actually equivalent to
:wq, you might at least make them give error messages forcing the
user to make the explicit choice of :wq to keep the saved version, or :q
to discard it.

     I've been having fun using recursive "map" commands from time to
time.  For example, a file of mailing addresses of Math Departments is
being prepared, for use with a new Computer Services command "label".
This requires that each address constitute one line of the file, with
the intended lines of each label separated by
semicolons rather than newlines, each being no longer than 34
characters.  At present, the lines in the file are of the form
[university-name];[city-state-zip]
and I wanted to find cases where the university name the secretaries
had typed in was over 34 characters long.  So I did
:map ^A +36^V|F;^A0
Then, when I hit ^A, the cursor went bopping down the file, passing
through each line at which it could find a ";" before the 36th position,
but stopping when it hit a line where it could not.  When I had
corrected such a line, by abbreviating a long word or whatever, I could
hit ^A again and find the next case.  The "0" at the end of the map
command is to prevent the "No tail recursion" rule from aborting my
mapping.  It has no other effect, because it is never reached.
     Of course, the above example of a recursive mapping is guaranteed
to stop eventually, if only by reaching the end of the file.  But I find
that mappings that can go on indefinitely are very hard to stop.  E.g.
:map q ax^[q0
I've tried some like that, and sometimes hitting <break> or whatever
enough times successfully stops them (often leaving a bit of a mess --
characters that ought to have come after the string of x's embedded
among them), while other times the only thing I can do is to go to
another terminal and kill the editing process.  Maybe it is to prevent
things like that that you put in the "No tail recursion" rule --
though clearly it can be gotten around.  Might it not be better to
somehow make the editor not quite so deaf to <break>s during such a
process?

     I will mention one curious experience which I have not been able to
reproduce.  I use :set nu.  After a delete near the beginning of a file,
I found myself looking at a screen with line-numbers beginning around
-2!  The lines with nonpositive numbers were blank, if I recall; lines
1, 2, etc. were as they should be.  I mentioned this to someone
who said he'd had the same thing had happened at times, but had
never been able to figure out what conditions caused it.

					Best regards,
					George

From gbergman@ucbcartan Thu Nov  3 22:32:01 1983
Received: from ucbcartan.ARPA by ucbernie.ARPA (4.17/4.13)
	id AA25163; Thu, 3 Nov 83 22:31:44 pst
Date: Thu, 3 Nov 83 22:28:11 PST
From: gbergman@ucbcartan (George Mark Bergman)
Message-Id: <8311040628.AA06097@ucbcartan.ARPA>
Received: by ucbcartan.ARPA (4.6/3.7)
	id AA06097; Thu, 3 Nov 83 22:28:11 PST
To: cc-03@BERKELEY, danh@kim, lindahl@topaz, mckusick@ucbernie, ralph@ucbarpa
Status: R

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, priili@Ardc.ARPA,
        ralph@ucbarpa, reiser@ruby, romine@seismo.ARPA, 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